|
17 | 17 | // * Avoid using Neq32 for writeBarrier.enabled checks.
|
18 | 18 |
|
19 | 19 | // Lowering arithmetic
|
20 |
| -(Add64 x y) -> (ADD x y) |
21 |
| -(AddPtr x y) -> (ADD x y) |
22 |
| -(Add32 x y) -> (ADD x y) |
23 |
| -(Add16 x y) -> (ADD x y) |
24 |
| -(Add8 x y) -> (ADD x y) |
25 |
| -(Add32F x y) -> (FADDS x y) |
26 |
| -(Add64F x y) -> (FADDD x y) |
27 |
| - |
28 |
| -(Sub64 x y) -> (SUB x y) |
29 |
| -(SubPtr x y) -> (SUB x y) |
30 |
| -(Sub32 x y) -> (SUB x y) |
31 |
| -(Sub16 x y) -> (SUB x y) |
32 |
| -(Sub8 x y) -> (SUB x y) |
33 |
| -(Sub32F x y) -> (FSUBS x y) |
34 |
| -(Sub64F x y) -> (FSUBD x y) |
35 |
| - |
36 |
| -(Mul64 x y) -> (MUL x y) |
37 |
| -(Mul32 x y) -> (MULW x y) |
| 20 | +(Add64 ...) -> (ADD ...) |
| 21 | +(AddPtr ...) -> (ADD ...) |
| 22 | +(Add32 ...) -> (ADD ...) |
| 23 | +(Add16 ...) -> (ADD ...) |
| 24 | +(Add8 ...) -> (ADD ...) |
| 25 | +(Add32F ...) -> (FADDS ...) |
| 26 | +(Add64F ...) -> (FADDD ...) |
| 27 | + |
| 28 | +(Sub64 ...) -> (SUB ...) |
| 29 | +(SubPtr ...) -> (SUB ...) |
| 30 | +(Sub32 ...) -> (SUB ...) |
| 31 | +(Sub16 ...) -> (SUB ...) |
| 32 | +(Sub8 ...) -> (SUB ...) |
| 33 | +(Sub32F ...) -> (FSUBS ...) |
| 34 | +(Sub64F ...) -> (FSUBD ...) |
| 35 | + |
| 36 | +(Mul64 ...) -> (MUL ...) |
| 37 | +(Mul32 ...) -> (MULW ...) |
38 | 38 | (Mul16 x y) -> (MULW (SignExt16to32 x) (SignExt16to32 y))
|
39 | 39 | (Mul8 x y) -> (MULW (SignExt8to32 x) (SignExt8to32 y))
|
40 |
| -(Mul32F x y) -> (FMULS x y) |
41 |
| -(Mul64F x y) -> (FMULD x y) |
| 40 | +(Mul32F ...) -> (FMULS ...) |
| 41 | +(Mul64F ...) -> (FMULD ...) |
42 | 42 |
|
43 |
| -(Div32F x y) -> (FDIVS x y) |
44 |
| -(Div64F x y) -> (FDIVD x y) |
| 43 | +(Div32F ...) -> (FDIVS ...) |
| 44 | +(Div64F ...) -> (FDIVD ...) |
45 | 45 |
|
46 |
| -(Div64 x y) -> (DIV x y) |
47 |
| -(Div64u x y) -> (DIVU x y) |
48 |
| -(Div32 x y) -> (DIVW x y) |
49 |
| -(Div32u x y) -> (DIVUW x y) |
| 46 | +(Div64 [a] x y) -> (DIV x y) |
| 47 | +(Div64u ...) -> (DIVU ...) |
| 48 | +(Div32 [a] x y) -> (DIVW x y) |
| 49 | +(Div32u ...) -> (DIVUW ...) |
50 | 50 | (Div16 x y) -> (DIVW (SignExt16to32 x) (SignExt16to32 y))
|
51 | 51 | (Div16u x y) -> (DIVUW (ZeroExt16to32 x) (ZeroExt16to32 y))
|
52 | 52 | (Div8 x y) -> (DIVW (SignExt8to32 x) (SignExt8to32 y))
|
53 | 53 | (Div8u x y) -> (DIVUW (ZeroExt8to32 x) (ZeroExt8to32 y))
|
54 | 54 |
|
55 |
| -(Hmul64 x y) -> (MULH x y) |
56 |
| -(Hmul64u x y) -> (MULHU x y) |
| 55 | +(Hmul64 ...) -> (MULH ...) |
| 56 | +(Hmul64u ...) -> (MULHU ...) |
57 | 57 | (Hmul32 x y) -> (SRAI [32] (MUL (SignExt32to64 x) (SignExt32to64 y)))
|
58 | 58 | (Hmul32u x y) -> (SRLI [32] (MUL (ZeroExt32to64 x) (ZeroExt32to64 y)))
|
59 | 59 |
|
60 | 60 | // (x + y) / 2 -> (x / 2) + (y / 2) + (x & y & 1)
|
61 | 61 | (Avg64u <t> x y) -> (ADD (ADD <t> (SRLI <t> [1] x) (SRLI <t> [1] y)) (ANDI <t> [1] (AND <t> x y)))
|
62 | 62 |
|
63 |
| -(Mod64 x y) -> (REM x y) |
64 |
| -(Mod64u x y) -> (REMU x y) |
65 |
| -(Mod32 x y) -> (REMW x y) |
66 |
| -(Mod32u x y) -> (REMUW x y) |
| 63 | +(Mod64 [a] x y) -> (REM x y) |
| 64 | +(Mod64u ...) -> (REMU ...) |
| 65 | +(Mod32 [a] x y) -> (REMW x y) |
| 66 | +(Mod32u ...) -> (REMUW ...) |
67 | 67 | (Mod16 x y) -> (REMW (SignExt16to32 x) (SignExt16to32 y))
|
68 | 68 | (Mod16u x y) -> (REMUW (ZeroExt16to32 x) (ZeroExt16to32 y))
|
69 | 69 | (Mod8 x y) -> (REMW (SignExt8to32 x) (SignExt8to32 y))
|
70 | 70 | (Mod8u x y) -> (REMUW (ZeroExt8to32 x) (ZeroExt8to32 y))
|
71 | 71 |
|
72 |
| -(And64 x y) -> (AND x y) |
73 |
| -(And32 x y) -> (AND x y) |
74 |
| -(And16 x y) -> (AND x y) |
75 |
| -(And8 x y) -> (AND x y) |
| 72 | +(And64 ...) -> (AND ...) |
| 73 | +(And32 ...) -> (AND ...) |
| 74 | +(And16 ...) -> (AND ...) |
| 75 | +(And8 ...) -> (AND ...) |
76 | 76 |
|
77 |
| -(Or64 x y) -> (OR x y) |
78 |
| -(Or32 x y) -> (OR x y) |
79 |
| -(Or16 x y) -> (OR x y) |
80 |
| -(Or8 x y) -> (OR x y) |
| 77 | +(Or64 ...) -> (OR ...) |
| 78 | +(Or32 ...) -> (OR ...) |
| 79 | +(Or16 ...) -> (OR ...) |
| 80 | +(Or8 ...) -> (OR ...) |
81 | 81 |
|
82 |
| -(Xor64 x y) -> (XOR x y) |
83 |
| -(Xor32 x y) -> (XOR x y) |
84 |
| -(Xor16 x y) -> (XOR x y) |
85 |
| -(Xor8 x y) -> (XOR x y) |
| 82 | +(Xor64 ...) -> (XOR ...) |
| 83 | +(Xor32 ...) -> (XOR ...) |
| 84 | +(Xor16 ...) -> (XOR ...) |
| 85 | +(Xor8 ...) -> (XOR ...) |
86 | 86 |
|
87 | 87 | (Neg64 x) -> (SUB (MOVDconst) x)
|
88 | 88 | (Neg32 x) -> (SUB (MOVWconst) x)
|
89 | 89 | (Neg16 x) -> (SUB (MOVHconst) x)
|
90 | 90 | (Neg8 x) -> (SUB (MOVBconst) x)
|
91 |
| -(Neg32F x) -> (FNEGS x) |
92 |
| -(Neg64F x) -> (FNEGD x) |
| 91 | +(Neg32F ...) -> (FNEGS ...) |
| 92 | +(Neg64F ...) -> (FNEGD ...) |
93 | 93 |
|
94 | 94 | (Com64 x) -> (XORI [int64(-1)] x)
|
95 | 95 | (Com32 x) -> (XORI [int64(-1)] x)
|
96 | 96 | (Com16 x) -> (XORI [int64(-1)] x)
|
97 | 97 | (Com8 x) -> (XORI [int64(-1)] x)
|
98 | 98 |
|
99 |
| -(Sqrt x) -> (FSQRTD x) |
| 99 | +(Sqrt ...) -> (FSQRTD ...) |
100 | 100 |
|
101 | 101 | // Zero and sign extension
|
102 | 102 | // Shift left until the bits we want are at the top of the register.
|
|
118 | 118 | (ZeroExt16to64 <t> x) -> (SRLI [48] (SLLI <t> [48] x))
|
119 | 119 | (ZeroExt32to64 <t> x) -> (SRLI [32] (SLLI <t> [32] x))
|
120 | 120 |
|
121 |
| -(Cvt32to32F x) -> (FCVTSW x) |
122 |
| -(Cvt32to64F x) -> (FCVTDW x) |
123 |
| -(Cvt64to32F x) -> (FCVTSL x) |
124 |
| -(Cvt64to64F x) -> (FCVTDL x) |
| 121 | +(Cvt32to32F ...) -> (FCVTSW ...) |
| 122 | +(Cvt32to64F ...) -> (FCVTDW ...) |
| 123 | +(Cvt64to32F ...) -> (FCVTSL ...) |
| 124 | +(Cvt64to64F ...) -> (FCVTDL ...) |
125 | 125 |
|
126 |
| -(Cvt32Fto32 x) -> (FCVTWS x) |
127 |
| -(Cvt32Fto64 x) -> (FCVTLS x) |
128 |
| -(Cvt64Fto32 x) -> (FCVTWD x) |
129 |
| -(Cvt64Fto64 x) -> (FCVTLD x) |
| 126 | +(Cvt32Fto32 ...) -> (FCVTWS ...) |
| 127 | +(Cvt32Fto64 ...) -> (FCVTLS ...) |
| 128 | +(Cvt64Fto32 ...) -> (FCVTWD ...) |
| 129 | +(Cvt64Fto64 ...) -> (FCVTLD ...) |
130 | 130 |
|
131 |
| -(Cvt32Fto64F x) -> (FCVTDS x) |
132 |
| -(Cvt64Fto32F x) -> (FCVTSD x) |
| 131 | +(Cvt32Fto64F ...) -> (FCVTDS ...) |
| 132 | +(Cvt64Fto32F ...) -> (FCVTSD ...) |
133 | 133 |
|
134 |
| -(Round32F x) -> x |
135 |
| -(Round64F x) -> x |
| 134 | +(Round32F ...) -> (Copy ...) |
| 135 | +(Round64F ...) -> (Copy ...) |
136 | 136 |
|
137 | 137 | // From genericOps.go:
|
138 | 138 | // "0 if arg0 == 0, -1 if arg0 > 0, undef if arg0<0"
|
|
146 | 146 |
|
147 | 147 | // Truncations
|
148 | 148 | // We ignore the unused high parts of registers, so truncates are just copies.
|
149 |
| -(Trunc16to8 x) -> x |
150 |
| -(Trunc32to8 x) -> x |
151 |
| -(Trunc32to16 x) -> x |
152 |
| -(Trunc64to8 x) -> x |
153 |
| -(Trunc64to16 x) -> x |
154 |
| -(Trunc64to32 x) -> x |
| 149 | +(Trunc16to8 ...) -> (Copy ...) |
| 150 | +(Trunc32to8 ...) -> (Copy ...) |
| 151 | +(Trunc32to16 ...) -> (Copy ...) |
| 152 | +(Trunc64to8 ...) -> (Copy ...) |
| 153 | +(Trunc64to16 ...) -> (Copy ...) |
| 154 | +(Trunc64to32 ...) -> (Copy ...) |
155 | 155 |
|
156 | 156 | // Shifts
|
157 | 157 |
|
|
234 | 234 | (RotateLeft32 <t> x (MOVWconst [c])) -> (Or32 (Lsh32x64 <t> x (MOVWconst [c&31])) (Rsh32Ux64 <t> x (MOVWconst [-c&31])))
|
235 | 235 | (RotateLeft64 <t> x (MOVDconst [c])) -> (Or64 (Lsh64x64 <t> x (MOVDconst [c&63])) (Rsh64Ux64 <t> x (MOVDconst [-c&63])))
|
236 | 236 |
|
237 |
| -(Less64 x y) -> (SLT x y) |
| 237 | +(Less64 ...) -> (SLT ...) |
238 | 238 | (Less32 x y) -> (SLT (SignExt32to64 x) (SignExt32to64 y))
|
239 | 239 | (Less16 x y) -> (SLT (SignExt16to64 x) (SignExt16to64 y))
|
240 | 240 | (Less8 x y) -> (SLT (SignExt8to64 x) (SignExt8to64 y))
|
241 |
| -(Less64U x y) -> (SLTU x y) |
| 241 | +(Less64U ...) -> (SLTU ...) |
242 | 242 | (Less32U x y) -> (SLTU (ZeroExt32to64 x) (ZeroExt32to64 y))
|
243 | 243 | (Less16U x y) -> (SLTU (ZeroExt16to64 x) (ZeroExt16to64 y))
|
244 | 244 | (Less8U x y) -> (SLTU (ZeroExt8to64 x) (ZeroExt8to64 y))
|
245 |
| -(Less64F x y) -> (FLTD x y) |
246 |
| -(Less32F x y) -> (FLTS x y) |
| 245 | +(Less64F ...) -> (FLTD ...) |
| 246 | +(Less32F ...) -> (FLTS ...) |
247 | 247 |
|
248 | 248 | // Convert x <= y to !(y > x).
|
249 | 249 | (Leq64 x y) -> (Not (Less64 y x))
|
|
254 | 254 | (Leq32U x y) -> (Not (Less32U y x))
|
255 | 255 | (Leq16U x y) -> (Not (Less16U y x))
|
256 | 256 | (Leq8U x y) -> (Not (Less8U y x))
|
257 |
| -(Leq64F x y) -> (FLED x y) |
258 |
| -(Leq32F x y) -> (FLES x y) |
| 257 | +(Leq64F ...) -> (FLED ...) |
| 258 | +(Leq32F ...) -> (FLES ...) |
259 | 259 |
|
260 | 260 | // Convert x > y to y < x.
|
261 | 261 | (Greater64 x y) -> (Less64 y x)
|
|
286 | 286 | (Eq32 x y) -> (SEQZ (ZeroExt32to64 (SUB <x.Type> x y)))
|
287 | 287 | (Eq16 x y) -> (SEQZ (ZeroExt16to64 (SUB <x.Type> x y)))
|
288 | 288 | (Eq8 x y) -> (SEQZ (ZeroExt8to64 (SUB <x.Type> x y)))
|
289 |
| -(Eq64F x y) -> (FEQD x y) |
290 |
| -(Eq32F x y) -> (FEQS x y) |
| 289 | +(Eq64F ...) -> (FEQD ...) |
| 290 | +(Eq32F ...) -> (FEQS ...) |
291 | 291 |
|
292 | 292 | (NeqPtr x y) -> (SNEZ (SUB <x.Type> x y))
|
293 | 293 | (Neq64 x y) -> (SNEZ (SUB <x.Type> x y))
|
294 | 294 | (Neq32 x y) -> (SNEZ (ZeroExt32to64 (SUB <x.Type> x y)))
|
295 | 295 | (Neq16 x y) -> (SNEZ (ZeroExt16to64 (SUB <x.Type> x y)))
|
296 | 296 | (Neq8 x y) -> (SNEZ (ZeroExt8to64 (SUB <x.Type> x y)))
|
297 |
| -(Neq64F x y) -> (FNED x y) |
298 |
| -(Neq32F x y) -> (FNES x y) |
| 297 | +(Neq64F ...) -> (FNED ...) |
| 298 | +(Neq32F ...) -> (FNES ...) |
299 | 299 |
|
300 | 300 | // Loads
|
301 | 301 | (Load <t> ptr mem) && t.IsBoolean() -> (MOVBUload ptr mem)
|
|
386 | 386 | (ADD <ptr.Type> ptr (MOVDconst [s-moveSize(t.(*types.Type).Alignment(), config)]))
|
387 | 387 | mem)
|
388 | 388 |
|
389 |
| -(Convert x mem) -> (MOVconvert x mem) |
| 389 | +(Convert ...) -> (MOVconvert ...) |
390 | 390 |
|
391 | 391 | // Checks
|
392 | 392 | (IsNonNil p) -> (NeqPtr (MOVDconst) p)
|
393 |
| -(IsInBounds idx len) -> (Less64U idx len) |
394 |
| -(IsSliceInBounds idx len) -> (Leq64U idx len) |
| 393 | +(IsInBounds ...) -> (Less64U ...) |
| 394 | +(IsSliceInBounds ...) -> (Leq64U ...) |
395 | 395 |
|
396 | 396 | // Trivial lowering
|
397 |
| -(NilCheck ptr mem) -> (LoweredNilCheck ptr mem) |
398 |
| -(GetClosurePtr) -> (LoweredGetClosurePtr) |
399 |
| -(GetCallerSP) -> (LoweredGetCallerSP) |
400 |
| -(GetCallerPC) -> (LoweredGetCallerPC) |
| 397 | +(NilCheck ...) -> (LoweredNilCheck ...) |
| 398 | +(GetClosurePtr ...) -> (LoweredGetClosurePtr ...) |
| 399 | +(GetCallerSP ...) -> (LoweredGetCallerSP ...) |
| 400 | +(GetCallerPC ...) -> (LoweredGetCallerPC ...) |
401 | 401 |
|
402 | 402 | // Write barrier.
|
403 |
| -(WB {fn} destptr srcptr mem) -> (LoweredWB {fn} destptr srcptr mem) |
| 403 | +(WB ...) -> (LoweredWB ...) |
404 | 404 |
|
405 | 405 | (PanicBounds [kind] x y mem) && boundsABI(kind) == 0 -> (LoweredPanicBoundsA [kind] x y mem)
|
406 | 406 | (PanicBounds [kind] x y mem) && boundsABI(kind) == 1 -> (LoweredPanicBoundsB [kind] x y mem)
|
|
423 | 423 | mem)
|
424 | 424 |
|
425 | 425 | // Boolean ops; 0=false, 1=true
|
426 |
| -(AndB x y) -> (AND x y) |
427 |
| -(OrB x y) -> (OR x y) |
| 426 | +(AndB ...) -> (AND ...) |
| 427 | +(OrB ...) -> (OR ...) |
428 | 428 | (EqB x y) -> (XORI [1] (XOR <typ.Bool> x y))
|
429 |
| -(NeqB x y) -> (XOR x y) |
| 429 | +(NeqB ...) -> (XOR ...) |
430 | 430 | (Not x) -> (XORI [1] x)
|
431 | 431 |
|
432 | 432 | // Lowering pointer arithmetic
|
|
435 | 435 | (OffPtr [off] ptr) && is32Bit(off) -> (ADDI [off] ptr)
|
436 | 436 | (OffPtr [off] ptr) -> (ADD (MOVDconst [off]) ptr)
|
437 | 437 |
|
438 |
| -(Const8 [val]) -> (MOVBconst [val]) |
439 |
| -(Const16 [val]) -> (MOVHconst [val]) |
440 |
| -(Const32 [val]) -> (MOVWconst [val]) |
441 |
| -(Const64 [val]) -> (MOVDconst [val]) |
| 438 | +(Const8 ...) -> (MOVBconst ...) |
| 439 | +(Const16 ...) -> (MOVHconst ...) |
| 440 | +(Const32 ...) -> (MOVWconst ...) |
| 441 | +(Const64 ...) -> (MOVDconst ...) |
442 | 442 | (Const32F [val]) -> (FMVSX (MOVWconst [int64(int32(math.Float32bits(float32(math.Float64frombits(uint64(val))))))]))
|
443 | 443 | (Const64F [val]) -> (FMVDX (MOVDconst [val]))
|
444 | 444 | (ConstNil) -> (MOVDconst [0])
|
445 |
| -(ConstBool [b]) -> (MOVBconst [b]) |
| 445 | +(ConstBool ...) -> (MOVBconst ...) |
446 | 446 |
|
447 | 447 | // Convert 64 bit immediate to two 32 bit immediates, combine with add and shift.
|
448 | 448 | // The lower 32 bit immediate will be treated as signed,
|
|
456 | 456 | // Fold ADD+MOVDconst into ADDI where possible.
|
457 | 457 | (ADD (MOVDconst [off]) ptr) && is32Bit(off) -> (ADDI [off] ptr)
|
458 | 458 |
|
459 |
| -(Addr {sym} base) -> (MOVaddr {sym} base) |
| 459 | +(Addr ...) -> (MOVaddr ...) |
460 | 460 | (LocalAddr {sym} base _) -> (MOVaddr {sym} base)
|
461 | 461 |
|
462 | 462 | // Conditional branches
|
|
470 | 470 | (If cond yes no) -> (BNE cond yes no)
|
471 | 471 |
|
472 | 472 | // Calls
|
473 |
| -(StaticCall [argwid] {target} mem) -> (CALLstatic [argwid] {target} mem) |
474 |
| -(ClosureCall [argwid] entry closure mem) -> (CALLclosure [argwid] entry closure mem) |
475 |
| -(InterCall [argwid] entry mem) -> (CALLinter [argwid] entry mem) |
| 473 | +(StaticCall ...) -> (CALLstatic ...) |
| 474 | +(ClosureCall ...) -> (CALLclosure ...) |
| 475 | +(InterCall ...) -> (CALLinter ...) |
476 | 476 |
|
477 | 477 | // remove redundant *const ops
|
478 | 478 | (ADDI [0] x) -> x
|
0 commit comments