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
5package s390x
6
7import (
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.
26type CCMask uint8
27
28const (
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.
62func (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.
68func (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
79func (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
128func (CCMask) CanBeAnSSAAux() {}
129