127 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2019 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package s390x
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| )
 | |
| 
 | |
| // CCMask represents a 4-bit condition code mask. Bits that
 | |
| // are not part of the mask should be 0.
 | |
| //
 | |
| // Condition code masks represent the 4 possible values of
 | |
| // the 2-bit condition code as individual bits. Since IBM Z
 | |
| // is a big-endian platform bits are numbered from left to
 | |
| // right. The lowest value, 0, is represented by 8 (0b1000)
 | |
| // and the highest value, 3, is represented by 1 (0b0001).
 | |
| //
 | |
| // Note that condition code values have different semantics
 | |
| // depending on the instruction that set the condition code.
 | |
| // The names given here assume that the condition code was
 | |
| // set by an integer or floating point comparison. Other
 | |
| // instructions may use these same codes to indicate
 | |
| // different results such as a carry or overflow.
 | |
| type CCMask uint8
 | |
| 
 | |
| const (
 | |
| 	Never CCMask = 0 // no-op
 | |
| 
 | |
| 	// 1-bit masks
 | |
| 	Equal     CCMask = 1 << 3
 | |
| 	Less      CCMask = 1 << 2
 | |
| 	Greater   CCMask = 1 << 1
 | |
| 	Unordered CCMask = 1 << 0
 | |
| 
 | |
| 	// 2-bit masks
 | |
| 	EqualOrUnordered   CCMask = Equal | Unordered   // not less and not greater
 | |
| 	LessOrEqual        CCMask = Less | Equal        // ordered and not greater
 | |
| 	LessOrGreater      CCMask = Less | Greater      // ordered and not equal
 | |
| 	LessOrUnordered    CCMask = Less | Unordered    // not greater and not equal
 | |
| 	GreaterOrEqual     CCMask = Greater | Equal     // ordered and not less
 | |
| 	GreaterOrUnordered CCMask = Greater | Unordered // not less and not equal
 | |
| 
 | |
| 	// 3-bit masks
 | |
| 	NotEqual     CCMask = Always ^ Equal
 | |
| 	NotLess      CCMask = Always ^ Less
 | |
| 	NotGreater   CCMask = Always ^ Greater
 | |
| 	NotUnordered CCMask = Always ^ Unordered
 | |
| 
 | |
| 	// 4-bit mask
 | |
| 	Always CCMask = Equal | Less | Greater | Unordered
 | |
| 
 | |
| 	// useful aliases
 | |
| 	Carry    CCMask = GreaterOrUnordered
 | |
| 	NoCarry  CCMask = LessOrEqual
 | |
| 	Borrow   CCMask = NoCarry
 | |
| 	NoBorrow CCMask = Carry
 | |
| )
 | |
| 
 | |
| // Inverse returns the complement of the condition code mask.
 | |
| func (c CCMask) Inverse() CCMask {
 | |
| 	return c ^ Always
 | |
| }
 | |
| 
 | |
| // ReverseComparison swaps the bits at 0b0100 and 0b0010 in the mask,
 | |
| // reversing the behavior of greater than and less than conditions.
 | |
| func (c CCMask) ReverseComparison() CCMask {
 | |
| 	r := c & EqualOrUnordered
 | |
| 	if c&Less != 0 {
 | |
| 		r |= Greater
 | |
| 	}
 | |
| 	if c&Greater != 0 {
 | |
| 		r |= Less
 | |
| 	}
 | |
| 	return r
 | |
| }
 | |
| 
 | |
| func (c CCMask) String() string {
 | |
| 	switch c {
 | |
| 	// 0-bit mask
 | |
| 	case Never:
 | |
| 		return "Never"
 | |
| 
 | |
| 	// 1-bit masks
 | |
| 	case Equal:
 | |
| 		return "Equal"
 | |
| 	case Less:
 | |
| 		return "Less"
 | |
| 	case Greater:
 | |
| 		return "Greater"
 | |
| 	case Unordered:
 | |
| 		return "Unordered"
 | |
| 
 | |
| 	// 2-bit masks
 | |
| 	case EqualOrUnordered:
 | |
| 		return "EqualOrUnordered"
 | |
| 	case LessOrEqual:
 | |
| 		return "LessOrEqual"
 | |
| 	case LessOrGreater:
 | |
| 		return "LessOrGreater"
 | |
| 	case LessOrUnordered:
 | |
| 		return "LessOrUnordered"
 | |
| 	case GreaterOrEqual:
 | |
| 		return "GreaterOrEqual"
 | |
| 	case GreaterOrUnordered:
 | |
| 		return "GreaterOrUnordered"
 | |
| 
 | |
| 	// 3-bit masks
 | |
| 	case NotEqual:
 | |
| 		return "NotEqual"
 | |
| 	case NotLess:
 | |
| 		return "NotLess"
 | |
| 	case NotGreater:
 | |
| 		return "NotGreater"
 | |
| 	case NotUnordered:
 | |
| 		return "NotUnordered"
 | |
| 
 | |
| 	// 4-bit mask
 | |
| 	case Always:
 | |
| 		return "Always"
 | |
| 	}
 | |
| 
 | |
| 	// invalid
 | |
| 	return fmt.Sprintf("Invalid (%#x)", c)
 | |
| }
 |