1
2
3
4
5 package rewritearm64
6
7 import (
8 "math/bits"
9
10 "cmd/compile/internal/ssa"
11 "cmd/compile/internal/ssa/ssaop"
12 )
13
14
15 func arm64BFWidth(mask, rshift int64) int64 {
16 shiftedMask := int64(uint64(mask) >> uint64(rshift))
17 if shiftedMask == 0 {
18 panic("ARM64 BF mask is zero")
19 }
20 return nto(shiftedMask)
21 }
22
23
24
25
26
27
28 func arm64Invert(op ssaop.Op) ssaop.Op {
29 switch op {
30 case ssaop.OpARM64LessThan:
31 return ssaop.OpARM64GreaterThan
32 case ssaop.OpARM64LessThanU:
33 return ssaop.OpARM64GreaterThanU
34 case ssaop.OpARM64GreaterThan:
35 return ssaop.OpARM64LessThan
36 case ssaop.OpARM64GreaterThanU:
37 return ssaop.OpARM64LessThanU
38 case ssaop.OpARM64LessEqual:
39 return ssaop.OpARM64GreaterEqual
40 case ssaop.OpARM64LessEqualU:
41 return ssaop.OpARM64GreaterEqualU
42 case ssaop.OpARM64GreaterEqual:
43 return ssaop.OpARM64LessEqual
44 case ssaop.OpARM64GreaterEqualU:
45 return ssaop.OpARM64LessEqualU
46 case ssaop.OpARM64Equal, ssaop.OpARM64NotEqual:
47 return op
48 case ssaop.OpARM64LessThanF:
49 return ssaop.OpARM64GreaterThanF
50 case ssaop.OpARM64GreaterThanF:
51 return ssaop.OpARM64LessThanF
52 case ssaop.OpARM64LessEqualF:
53 return ssaop.OpARM64GreaterEqualF
54 case ssaop.OpARM64GreaterEqualF:
55 return ssaop.OpARM64LessEqualF
56 case ssaop.OpARM64NotLessThanF:
57 return ssaop.OpARM64NotGreaterThanF
58 case ssaop.OpARM64NotGreaterThanF:
59 return ssaop.OpARM64NotLessThanF
60 case ssaop.OpARM64NotLessEqualF:
61 return ssaop.OpARM64NotGreaterEqualF
62 case ssaop.OpARM64NotGreaterEqualF:
63 return ssaop.OpARM64NotLessEqualF
64 default:
65 panic("unreachable")
66 }
67 }
68
69
70
71
72
73
74 func arm64Negate(op ssaop.Op) ssaop.Op {
75 switch op {
76 case ssaop.OpARM64LessThan:
77 return ssaop.OpARM64GreaterEqual
78 case ssaop.OpARM64LessThanU:
79 return ssaop.OpARM64GreaterEqualU
80 case ssaop.OpARM64GreaterThan:
81 return ssaop.OpARM64LessEqual
82 case ssaop.OpARM64GreaterThanU:
83 return ssaop.OpARM64LessEqualU
84 case ssaop.OpARM64LessEqual:
85 return ssaop.OpARM64GreaterThan
86 case ssaop.OpARM64LessEqualU:
87 return ssaop.OpARM64GreaterThanU
88 case ssaop.OpARM64GreaterEqual:
89 return ssaop.OpARM64LessThan
90 case ssaop.OpARM64GreaterEqualU:
91 return ssaop.OpARM64LessThanU
92 case ssaop.OpARM64Equal:
93 return ssaop.OpARM64NotEqual
94 case ssaop.OpARM64NotEqual:
95 return ssaop.OpARM64Equal
96 case ssaop.OpARM64LessThanF:
97 return ssaop.OpARM64NotLessThanF
98 case ssaop.OpARM64NotLessThanF:
99 return ssaop.OpARM64LessThanF
100 case ssaop.OpARM64LessEqualF:
101 return ssaop.OpARM64NotLessEqualF
102 case ssaop.OpARM64NotLessEqualF:
103 return ssaop.OpARM64LessEqualF
104 case ssaop.OpARM64GreaterThanF:
105 return ssaop.OpARM64NotGreaterThanF
106 case ssaop.OpARM64NotGreaterThanF:
107 return ssaop.OpARM64GreaterThanF
108 case ssaop.OpARM64GreaterEqualF:
109 return ssaop.OpARM64NotGreaterEqualF
110 case ssaop.OpARM64NotGreaterEqualF:
111 return ssaop.OpARM64GreaterEqualF
112 default:
113 panic("unreachable")
114 }
115 }
116
117
118
119
120 func ccARM64Eval(op ssaop.Op, flags *ssa.Value) int {
121 fop := flags.Op
122 if fop == ssaop.OpARM64InvertFlags {
123 return -ccARM64Eval(op, flags.Args[0])
124 }
125 if fop != ssaop.OpARM64FlagConstant {
126 return 0
127 }
128 fc := ssa.FlagConstant(flags.AuxInt)
129 b2i := func(b bool) int {
130 if b {
131 return 1
132 }
133 return -1
134 }
135 switch op {
136 case ssaop.OpARM64Equal:
137 return b2i(fc.Eq())
138 case ssaop.OpARM64NotEqual:
139 return b2i(fc.Ne())
140 case ssaop.OpARM64LessThan:
141 return b2i(fc.Lt())
142 case ssaop.OpARM64LessThanU:
143 return b2i(fc.Ult())
144 case ssaop.OpARM64GreaterThan:
145 return b2i(fc.Gt())
146 case ssaop.OpARM64GreaterThanU:
147 return b2i(fc.Ugt())
148 case ssaop.OpARM64LessEqual:
149 return b2i(fc.Le())
150 case ssaop.OpARM64LessEqualU:
151 return b2i(fc.Ule())
152 case ssaop.OpARM64GreaterEqual:
153 return b2i(fc.Ge())
154 case ssaop.OpARM64GreaterEqualU:
155 return b2i(fc.Uge())
156 }
157 return 0
158 }
159
160
161 func isARM64BFMask(lsb, mask, rshift int64) bool {
162 shiftedMask := int64(uint64(mask) >> uint64(rshift))
163 return shiftedMask != 0 && ssa.IsPowerOfTwo(shiftedMask+1) && nto(shiftedMask)+lsb < 64
164 }
165
166
167 func nto(x int64) int64 {
168 return int64(ssa.Ntz64(^x))
169 }
170
171 func rotateRight64(v, rotate int64) int64 {
172 return int64(bits.RotateLeft64(uint64(v), int(-rotate)))
173 }
174
View as plain text