github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/internal/obj/s390x/condition_code.go (about)

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package s390x
     6  
     7  import (
     8  	"fmt"
     9  )
    10  
    11  // CCMask represents a 4-bit condition code mask. Bits that
    12  // are not part of the mask should be 0.
    13  //
    14  // Condition code masks represent the 4 possible values of
    15  // the 2-bit condition code as individual bits. Since IBM Z
    16  // is a big-endian platform bits are numbered from left to
    17  // right. The lowest value, 0, is represented by 8 (0b1000)
    18  // and the highest value, 3, is represented by 1 (0b0001).
    19  //
    20  // Note that condition code values have different semantics
    21  // depending on the instruction that set the condition code.
    22  // The names given here assume that the condition code was
    23  // set by an integer or floating point comparison. Other
    24  // instructions may use these same codes to indicate
    25  // different results such as a carry or overflow.
    26  type CCMask uint8
    27  
    28  const (
    29  	Never CCMask = 0 // no-op
    30  
    31  	// 1-bit masks
    32  	Equal     CCMask = 1 << 3
    33  	Less      CCMask = 1 << 2
    34  	Greater   CCMask = 1 << 1
    35  	Unordered CCMask = 1 << 0
    36  
    37  	// 2-bit masks
    38  	EqualOrUnordered   CCMask = Equal | Unordered   // not less and not greater
    39  	LessOrEqual        CCMask = Less | Equal        // ordered and not greater
    40  	LessOrGreater      CCMask = Less | Greater      // ordered and not equal
    41  	LessOrUnordered    CCMask = Less | Unordered    // not greater and not equal
    42  	GreaterOrEqual     CCMask = Greater | Equal     // ordered and not less
    43  	GreaterOrUnordered CCMask = Greater | Unordered // not less and not equal
    44  
    45  	// 3-bit masks
    46  	NotEqual     CCMask = Always ^ Equal
    47  	NotLess      CCMask = Always ^ Less
    48  	NotGreater   CCMask = Always ^ Greater
    49  	NotUnordered CCMask = Always ^ Unordered
    50  
    51  	// 4-bit mask
    52  	Always CCMask = Equal | Less | Greater | Unordered
    53  )
    54  
    55  // Inverse returns the complement of the condition code mask.
    56  func (c CCMask) Inverse() CCMask {
    57  	return c ^ Always
    58  }
    59  
    60  // ReverseComparison swaps the bits at 0b0100 and 0b0010 in the mask,
    61  // reversing the behavior of greater than and less than conditions.
    62  func (c CCMask) ReverseComparison() CCMask {
    63  	r := c & EqualOrUnordered
    64  	if c&Less != 0 {
    65  		r |= Greater
    66  	}
    67  	if c&Greater != 0 {
    68  		r |= Less
    69  	}
    70  	return r
    71  }
    72  
    73  func (c CCMask) String() string {
    74  	switch c {
    75  	// 0-bit mask
    76  	case Never:
    77  		return "Never"
    78  
    79  	// 1-bit masks
    80  	case Equal:
    81  		return "Equal"
    82  	case Less:
    83  		return "Less"
    84  	case Greater:
    85  		return "Greater"
    86  	case Unordered:
    87  		return "Unordered"
    88  
    89  	// 2-bit masks
    90  	case EqualOrUnordered:
    91  		return "EqualOrUnordered"
    92  	case LessOrEqual:
    93  		return "LessOrEqual"
    94  	case LessOrGreater:
    95  		return "LessOrGreater"
    96  	case LessOrUnordered:
    97  		return "LessOrUnordered"
    98  	case GreaterOrEqual:
    99  		return "GreaterOrEqual"
   100  	case GreaterOrUnordered:
   101  		return "GreaterOrUnordered"
   102  
   103  	// 3-bit masks
   104  	case NotEqual:
   105  		return "NotEqual"
   106  	case NotLess:
   107  		return "NotLess"
   108  	case NotGreater:
   109  		return "NotGreater"
   110  	case NotUnordered:
   111  		return "NotUnordered"
   112  
   113  	// 4-bit mask
   114  	case Always:
   115  		return "Always"
   116  	}
   117  
   118  	// invalid
   119  	return fmt.Sprintf("Invalid (%#x)", c)
   120  }