condition_code.go raw

   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  	// useful aliases
  55  	Carry    CCMask = GreaterOrUnordered
  56  	NoCarry  CCMask = LessOrEqual
  57  	Borrow   CCMask = NoCarry
  58  	NoBorrow CCMask = Carry
  59  )
  60  
  61  // Inverse returns the complement of the condition code mask.
  62  func (c CCMask) Inverse() CCMask {
  63  	return c ^ Always
  64  }
  65  
  66  // ReverseComparison swaps the bits at 0b0100 and 0b0010 in the mask,
  67  // reversing the behavior of greater than and less than conditions.
  68  func (c CCMask) ReverseComparison() CCMask {
  69  	r := c & EqualOrUnordered
  70  	if c&Less != 0 {
  71  		r |= Greater
  72  	}
  73  	if c&Greater != 0 {
  74  		r |= Less
  75  	}
  76  	return r
  77  }
  78  
  79  func (c CCMask) String() string {
  80  	switch c {
  81  	// 0-bit mask
  82  	case Never:
  83  		return "Never"
  84  
  85  	// 1-bit masks
  86  	case Equal:
  87  		return "Equal"
  88  	case Less:
  89  		return "Less"
  90  	case Greater:
  91  		return "Greater"
  92  	case Unordered:
  93  		return "Unordered"
  94  
  95  	// 2-bit masks
  96  	case EqualOrUnordered:
  97  		return "EqualOrUnordered"
  98  	case LessOrEqual:
  99  		return "LessOrEqual"
 100  	case LessOrGreater:
 101  		return "LessOrGreater"
 102  	case LessOrUnordered:
 103  		return "LessOrUnordered"
 104  	case GreaterOrEqual:
 105  		return "GreaterOrEqual"
 106  	case GreaterOrUnordered:
 107  		return "GreaterOrUnordered"
 108  
 109  	// 3-bit masks
 110  	case NotEqual:
 111  		return "NotEqual"
 112  	case NotLess:
 113  		return "NotLess"
 114  	case NotGreater:
 115  		return "NotGreater"
 116  	case NotUnordered:
 117  		return "NotUnordered"
 118  
 119  	// 4-bit mask
 120  	case Always:
 121  		return "Always"
 122  	}
 123  
 124  	// invalid
 125  	return fmt.Sprintf("Invalid (%#x)", c)
 126  }
 127