wazevo: add bitwise ops and, or, xor, rotr, rotl (#1655)

Signed-off-by: Edoardo Vacchi <evacchi@users.noreply.github.com>
Co-authored-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
This commit is contained in:
Edoardo Vacchi
2023-08-25 07:42:51 +09:00
committed by GitHub
co-authored by Takeshi Yoneda
parent 9e4b8ea8c6
commit afd220b33b
18 changed files with 525 additions and 172 deletions
+149 -94
View File
@@ -247,7 +247,7 @@ L1 (SSA Block: blk0):
L3 (SSA Block: blk1):
ret
L2 (SSA Block: blk2):
movz x27, #0x3, LSL 0
movz x27, #0x3, lsl 0
str w27, [x0?]
exit_sequence x0?
`,
@@ -260,7 +260,7 @@ L3 (SSA Block: blk1):
ldr x30, [sp], #0x10
ret
L2 (SSA Block: blk2):
movz x27, #0x3, LSL 0
movz x27, #0x3, lsl 0
str w27, [x0]
exit_sequence x0
`,
@@ -559,7 +559,7 @@ L1 (SSA Block: blk0):
mov x0, x0?
mov x1, x1?
mov x2, x2?
movz w3, #0x5, LSL 0
movz w3, #0x5, lsl 0
bl f2
mov x4?, x0
str x1?, [x0?, #0x8]
@@ -591,7 +591,7 @@ L1 (SSA Block: blk0):
str x8, [x9, #0x8]
mov x0, x9
mov x1, x8
movz w3, #0x5, LSL 0
movz w3, #0x5, lsl 0
str x9, [sp]
str x8, [sp, #0x8]
bl f2
@@ -1308,6 +1308,61 @@ L1 (SSA Block: blk0):
ldr x19, [sp], #0x10
ldr x30, [sp], #0x10
ret
`,
},
{
name: "integer_bitwise",
m: testcases.IntegerBitwise.Module,
afterLoweringARM64: `
L1 (SSA Block: blk0):
mov x2?, x2
mov x3?, x3
mov x4?, x4
mov x5?, x5
and w6?, w2?, w3?
orr w7?, w2?, w3?
eor w8?, w2?, w3?
ror w9?, w2?, w3?
and x10?, x4?, x5?
orr x11?, x4?, x5?
eor x12?, x4?, x5?
eor x15?, x4?, x5?, lsl #8
sub x4?, xzr, x4?
ror x16?, x4?, x5?
ror x17?, x4?, x5?
str x17?, [#ret_space, #0x8]
str x16?, [#ret_space, #0x0]
mov x7, x15?
mov x6, x12?
mov x5, x11?
mov x4, x10?
mov x3, x9?
mov x2, x8?
mov x1, x7?
mov x0, x6?
ret
`,
afterFinalizeARM64: `
L1 (SSA Block: blk0):
str x30, [sp, #-0x10]!
mov x10, x2
mov x8, x4
mov x9, x5
and w0, w10, w3
orr w1, w10, w3
eor w2, w10, w3
ror w3, w10, w3
and x4, x8, x9
orr x5, x8, x9
eor x6, x8, x9
eor x7, x8, x9, lsl #8
sub x8, xzr, x8
ror x10, x8, x9
ror x8, x8, x9
str x8, [sp, #0x18]
str x10, [sp, #0x10]
ldr x30, [sp], #0x10
ret
`,
},
{
@@ -1558,7 +1613,7 @@ L1 (SSA Block: blk0):
madd w9?, w2?, w159?, wzr
orr w158?, wzr, #0x4
madd w11?, w2?, w158?, wzr
movz w157?, #0x5, LSL 0
movz w157?, #0x5, lsl 0
madd w13?, w2?, w157?, wzr
orr w156?, wzr, #0x6
madd w15?, w2?, w156?, wzr
@@ -1566,15 +1621,15 @@ L1 (SSA Block: blk0):
madd w17?, w2?, w155?, wzr
orr w154?, wzr, #0x8
madd w19?, w2?, w154?, wzr
movz w153?, #0x9, LSL 0
movz w153?, #0x9, lsl 0
madd w21?, w2?, w153?, wzr
movz w152?, #0xa, LSL 0
movz w152?, #0xa, lsl 0
madd w23?, w2?, w152?, wzr
movz w151?, #0xb, LSL 0
movz w151?, #0xb, lsl 0
madd w25?, w2?, w151?, wzr
orr w150?, wzr, #0xc
madd w27?, w2?, w150?, wzr
movz w149?, #0xd, LSL 0
movz w149?, #0xd, lsl 0
madd w29?, w2?, w149?, wzr
orr w148?, wzr, #0xe
madd w31?, w2?, w148?, wzr
@@ -1582,13 +1637,13 @@ L1 (SSA Block: blk0):
madd w33?, w2?, w147?, wzr
orr w146?, wzr, #0x10
madd w35?, w2?, w146?, wzr
movz w145?, #0x11, LSL 0
movz w145?, #0x11, lsl 0
madd w37?, w2?, w145?, wzr
movz w144?, #0x12, LSL 0
movz w144?, #0x12, lsl 0
madd w39?, w2?, w144?, wzr
movz w143?, #0x13, LSL 0
movz w143?, #0x13, lsl 0
madd w41?, w2?, w143?, wzr
movz w142?, #0x14, LSL 0
movz w142?, #0x14, lsl 0
madd w43?, w2?, w142?, wzr
add w44?, w41?, w43?
add w45?, w39?, w44?
@@ -1702,7 +1757,7 @@ L1 (SSA Block: blk0):
madd w10, w2, w10, wzr
orr w11, wzr, #0x4
madd w11, w2, w11, wzr
movz w12, #0x5, LSL 0
movz w12, #0x5, lsl 0
madd w12, w2, w12, wzr
orr w13, wzr, #0x6
madd w13, w2, w13, wzr
@@ -1710,15 +1765,15 @@ L1 (SSA Block: blk0):
madd w14, w2, w14, wzr
orr w15, wzr, #0x8
madd w15, w2, w15, wzr
movz w16, #0x9, LSL 0
movz w16, #0x9, lsl 0
madd w16, w2, w16, wzr
movz w17, #0xa, LSL 0
movz w17, #0xa, lsl 0
madd w17, w2, w17, wzr
movz w18, #0xb, LSL 0
movz w18, #0xb, lsl 0
madd w18, w2, w18, wzr
orr w19, wzr, #0xc
madd w19, w2, w19, wzr
movz w20, #0xd, LSL 0
movz w20, #0xd, lsl 0
madd w20, w2, w20, wzr
orr w21, wzr, #0xe
madd w21, w2, w21, wzr
@@ -1726,13 +1781,13 @@ L1 (SSA Block: blk0):
madd w22, w2, w22, wzr
orr w23, wzr, #0x10
madd w23, w2, w23, wzr
movz w24, #0x11, LSL 0
movz w24, #0x11, lsl 0
madd w24, w2, w24, wzr
movz w25, #0x12, LSL 0
movz w25, #0x12, lsl 0
madd w25, w2, w25, wzr
movz w26, #0x13, LSL 0
movz w26, #0x13, lsl 0
madd w26, w2, w26, wzr
movz w28, #0x14, LSL 0
movz w28, #0x14, lsl 0
madd w28, w2, w28, wzr
add w26, w26, w28
add w25, w25, w26
@@ -1952,7 +2007,7 @@ L1 (SSA Block: blk0):
add x6?, x4?, #0x4
subs xzr, x5?, x6?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
ldr x8?, [x1?, #0x8]
@@ -1969,7 +2024,7 @@ L1 (SSA Block: blk0):
add x9, x8, #0x4
subs xzr, x10, x9
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
ldr x9, [x1, #0x8]
@@ -1990,7 +2045,7 @@ L1 (SSA Block: blk0):
add x9, x10, #0x4
subs xzr, x8, x9
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
ldr x9, [x1, #0x8]
@@ -2001,7 +2056,7 @@ L1 (SSA Block: blk0):
add x10, x11, #0x8
subs xzr, x8, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
add x10, x9, x11
@@ -2011,7 +2066,7 @@ L1 (SSA Block: blk0):
add x10, x11, #0x4
subs xzr, x8, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
add x10, x9, x11
@@ -2021,7 +2076,7 @@ L1 (SSA Block: blk0):
add x10, x11, #0x8
subs xzr, x8, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
add x10, x9, x11
@@ -2031,17 +2086,17 @@ L1 (SSA Block: blk0):
add x10, x11, #0x1
subs xzr, x8, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
add x10, x9, x11
strb w2, [x10]
movz w10, #0x28, LSL 0
movz w10, #0x28, lsl 0
uxtw x11, w10
add x10, x11, #0x2
subs xzr, x8, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
add x10, x9, x11
@@ -2051,7 +2106,7 @@ L1 (SSA Block: blk0):
add x10, x11, #0x1
subs xzr, x8, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
add x10, x9, x11
@@ -2061,7 +2116,7 @@ L1 (SSA Block: blk0):
add x10, x11, #0x2
subs xzr, x8, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
add x10, x9, x11
@@ -2071,7 +2126,7 @@ L1 (SSA Block: blk0):
add x10, x11, #0x4
subs xzr, x8, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0]
exit_sequence x0
add x8, x9, x11
@@ -2092,7 +2147,7 @@ L1 (SSA Block: blk0):
add x6?, x4?, #0x4
subs xzr, x5?, x6?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
ldr x8?, [x1?, #0x8]
@@ -2102,7 +2157,7 @@ L1 (SSA Block: blk0):
add x13?, x12?, #0x8
subs xzr, x5?, x13?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x199?, x8?, x12?
@@ -2111,7 +2166,7 @@ L1 (SSA Block: blk0):
add x19?, x18?, #0x4
subs xzr, x5?, x19?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x198?, x8?, x18?
@@ -2120,7 +2175,7 @@ L1 (SSA Block: blk0):
add x25?, x24?, #0x8
subs xzr, x5?, x25?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x197?, x8?, x24?
@@ -2129,7 +2184,7 @@ L1 (SSA Block: blk0):
add x31?, x30?, #0x13
subs xzr, x5?, x31?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x196?, x8?, x30?
@@ -2138,7 +2193,7 @@ L1 (SSA Block: blk0):
add x37?, x36?, #0x17
subs xzr, x5?, x37?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x195?, x8?, x36?
@@ -2147,7 +2202,7 @@ L1 (SSA Block: blk0):
add x43?, x42?, #0x13
subs xzr, x5?, x43?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x194?, x8?, x42?
@@ -2156,7 +2211,7 @@ L1 (SSA Block: blk0):
add x49?, x48?, #0x17
subs xzr, x5?, x49?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x193?, x8?, x48?
@@ -2165,7 +2220,7 @@ L1 (SSA Block: blk0):
add x55?, x54?, #0x1
subs xzr, x5?, x55?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x192?, x8?, x54?
@@ -2174,7 +2229,7 @@ L1 (SSA Block: blk0):
add x61?, x60?, #0x10
subs xzr, x5?, x61?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x191?, x8?, x60?
@@ -2183,7 +2238,7 @@ L1 (SSA Block: blk0):
add x67?, x66?, #0x1
subs xzr, x5?, x67?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x190?, x8?, x66?
@@ -2192,7 +2247,7 @@ L1 (SSA Block: blk0):
add x73?, x72?, #0x10
subs xzr, x5?, x73?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x189?, x8?, x72?
@@ -2201,7 +2256,7 @@ L1 (SSA Block: blk0):
add x79?, x78?, #0x2
subs xzr, x5?, x79?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x188?, x8?, x78?
@@ -2210,7 +2265,7 @@ L1 (SSA Block: blk0):
add x85?, x84?, #0x11
subs xzr, x5?, x85?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x187?, x8?, x84?
@@ -2219,7 +2274,7 @@ L1 (SSA Block: blk0):
add x91?, x90?, #0x2
subs xzr, x5?, x91?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x186?, x8?, x90?
@@ -2228,7 +2283,7 @@ L1 (SSA Block: blk0):
add x97?, x96?, #0x11
subs xzr, x5?, x97?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x185?, x8?, x96?
@@ -2237,7 +2292,7 @@ L1 (SSA Block: blk0):
add x103?, x102?, #0x1
subs xzr, x5?, x103?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x184?, x8?, x102?
@@ -2246,7 +2301,7 @@ L1 (SSA Block: blk0):
add x109?, x108?, #0x10
subs xzr, x5?, x109?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x183?, x8?, x108?
@@ -2255,7 +2310,7 @@ L1 (SSA Block: blk0):
add x115?, x114?, #0x1
subs xzr, x5?, x115?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x182?, x8?, x114?
@@ -2264,7 +2319,7 @@ L1 (SSA Block: blk0):
add x121?, x120?, #0x10
subs xzr, x5?, x121?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x181?, x8?, x120?
@@ -2273,7 +2328,7 @@ L1 (SSA Block: blk0):
add x127?, x126?, #0x2
subs xzr, x5?, x127?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x180?, x8?, x126?
@@ -2282,7 +2337,7 @@ L1 (SSA Block: blk0):
add x133?, x132?, #0x11
subs xzr, x5?, x133?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x179?, x8?, x132?
@@ -2291,7 +2346,7 @@ L1 (SSA Block: blk0):
add x139?, x138?, #0x2
subs xzr, x5?, x139?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x178?, x8?, x138?
@@ -2300,7 +2355,7 @@ L1 (SSA Block: blk0):
add x145?, x144?, #0x11
subs xzr, x5?, x145?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x177?, x8?, x144?
@@ -2309,7 +2364,7 @@ L1 (SSA Block: blk0):
add x151?, x150?, #0x4
subs xzr, x5?, x151?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x176?, x8?, x150?
@@ -2318,7 +2373,7 @@ L1 (SSA Block: blk0):
add x157?, x156?, #0x13
subs xzr, x5?, x157?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x175?, x8?, x156?
@@ -2327,7 +2382,7 @@ L1 (SSA Block: blk0):
add x163?, x162?, #0x4
subs xzr, x5?, x163?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x174?, x8?, x162?
@@ -2336,7 +2391,7 @@ L1 (SSA Block: blk0):
add x169?, x168?, #0x13
subs xzr, x5?, x169?
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x0?]
exit_sequence x0?
add x173?, x8?, x168?
@@ -2390,7 +2445,7 @@ L1 (SSA Block: blk0):
add x10, x11, #0x4
subs xzr, x9, x10
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
ldr x10, [x1, #0x8]
@@ -2400,7 +2455,7 @@ L1 (SSA Block: blk0):
add x11, x12, #0x8
subs xzr, x9, x11
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x11, x10, x12
@@ -2409,7 +2464,7 @@ L1 (SSA Block: blk0):
add x11, x12, #0x4
subs xzr, x9, x11
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x11, x10, x12
@@ -2418,7 +2473,7 @@ L1 (SSA Block: blk0):
add x11, x12, #0x8
subs xzr, x9, x11
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x11, x10, x12
@@ -2427,7 +2482,7 @@ L1 (SSA Block: blk0):
add x11, x12, #0x13
subs xzr, x9, x11
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x11, x10, x12
@@ -2436,7 +2491,7 @@ L1 (SSA Block: blk0):
add x12, x13, #0x17
subs xzr, x9, x12
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x12, x10, x13
@@ -2445,7 +2500,7 @@ L1 (SSA Block: blk0):
add x12, x13, #0x13
subs xzr, x9, x12
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x12, x10, x13
@@ -2454,7 +2509,7 @@ L1 (SSA Block: blk0):
add x12, x13, #0x17
subs xzr, x9, x12
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x12, x10, x13
@@ -2463,7 +2518,7 @@ L1 (SSA Block: blk0):
add x12, x13, #0x1
subs xzr, x9, x12
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x12, x10, x13
@@ -2472,7 +2527,7 @@ L1 (SSA Block: blk0):
add x12, x13, #0x10
subs xzr, x9, x12
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x12, x10, x13
@@ -2481,7 +2536,7 @@ L1 (SSA Block: blk0):
add x12, x13, #0x1
subs xzr, x9, x12
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x12, x10, x13
@@ -2490,7 +2545,7 @@ L1 (SSA Block: blk0):
add x12, x13, #0x10
subs xzr, x9, x12
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x12, x10, x13
@@ -2499,7 +2554,7 @@ L1 (SSA Block: blk0):
add x12, x13, #0x2
subs xzr, x9, x12
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x12, x10, x13
@@ -2508,7 +2563,7 @@ L1 (SSA Block: blk0):
add x13, x14, #0x11
subs xzr, x9, x13
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x13, x10, x14
@@ -2517,7 +2572,7 @@ L1 (SSA Block: blk0):
add x14, x15, #0x2
subs xzr, x9, x14
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x14, x10, x15
@@ -2526,7 +2581,7 @@ L1 (SSA Block: blk0):
add x15, x16, #0x11
subs xzr, x9, x15
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x15, x10, x16
@@ -2535,7 +2590,7 @@ L1 (SSA Block: blk0):
add x16, x17, #0x1
subs xzr, x9, x16
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x16, x10, x17
@@ -2544,7 +2599,7 @@ L1 (SSA Block: blk0):
add x17, x18, #0x10
subs xzr, x9, x17
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x17, x10, x18
@@ -2553,7 +2608,7 @@ L1 (SSA Block: blk0):
add x18, x19, #0x1
subs xzr, x9, x18
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x18, x10, x19
@@ -2562,7 +2617,7 @@ L1 (SSA Block: blk0):
add x19, x20, #0x10
subs xzr, x9, x19
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x19, x10, x20
@@ -2571,7 +2626,7 @@ L1 (SSA Block: blk0):
add x20, x21, #0x2
subs xzr, x9, x20
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x20, x10, x21
@@ -2580,7 +2635,7 @@ L1 (SSA Block: blk0):
add x21, x22, #0x11
subs xzr, x9, x21
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x21, x10, x22
@@ -2589,7 +2644,7 @@ L1 (SSA Block: blk0):
add x22, x23, #0x2
subs xzr, x9, x22
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x22, x10, x23
@@ -2598,7 +2653,7 @@ L1 (SSA Block: blk0):
add x23, x24, #0x11
subs xzr, x9, x23
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x23, x10, x24
@@ -2607,7 +2662,7 @@ L1 (SSA Block: blk0):
add x24, x25, #0x4
subs xzr, x9, x24
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x24, x10, x25
@@ -2616,7 +2671,7 @@ L1 (SSA Block: blk0):
add x25, x26, #0x13
subs xzr, x9, x25
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x25, x10, x26
@@ -2625,7 +2680,7 @@ L1 (SSA Block: blk0):
add x26, x28, #0x4
subs xzr, x9, x26
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x26, x10, x28
@@ -2634,7 +2689,7 @@ L1 (SSA Block: blk0):
add x28, x29, #0x13
subs xzr, x9, x28
b.hs #0x20
movz x27, #0x4, LSL 0
movz x27, #0x4, lsl 0
str w27, [x8]
exit_sequence x8
add x8, x10, x29
@@ -2806,7 +2861,7 @@ L10 (SSA Block: blk5):
ret
L4 (SSA Block: blk9):
L11 (SSA Block: blk4):
movz w0, #0xd, LSL 0
movz w0, #0xd, lsl 0
ret
L5 (SSA Block: blk10):
L12 (SSA Block: blk3):
@@ -2822,7 +2877,7 @@ L14 (SSA Block: blk1):
ret
L8 (SSA Block: blk13):
L9 (SSA Block: blk6):
movz w0, #0xb, LSL 0
movz w0, #0xb, lsl 0
ret
`,
afterFinalizeARM64: `
@@ -2841,7 +2896,7 @@ L10 (SSA Block: blk5):
ret
L4 (SSA Block: blk9):
L11 (SSA Block: blk4):
movz w0, #0xd, LSL 0
movz w0, #0xd, lsl 0
ldr x30, [sp], #0x10
ret
L5 (SSA Block: blk10):
@@ -2861,7 +2916,7 @@ L14 (SSA Block: blk1):
ret
L8 (SSA Block: blk13):
L9 (SSA Block: blk6):
movz w0, #0xb, LSL 0
movz w0, #0xb, lsl 0
ldr x30, [sp], #0x10
ret
`,
@@ -69,7 +69,7 @@ func TestMachine_CompileGoFunctionTrampoline(t *testing.T) {
str x1, [x0, #0x460]
add x15, x0, #0x468
str d0, [x15], #0x8
movz w17, #0x6406, LSL 0
movz w17, #0x6406, lsl 0
str w17, [x0]
mov x27, sp
str x27, [x0, #0x38]
@@ -151,7 +151,7 @@ func TestMachine_CompileGoFunctionTrampoline(t *testing.T) {
str d1, [x15], #0x8
str x2, [x15], #0x8
str x3, [x15], #0x8
movz w17, #0x6406, LSL 0
movz w17, #0x6406, lsl 0
str w17, [x0]
mov x27, sp
str x27, [x0, #0x38]
@@ -733,21 +733,16 @@ func (i *instruction) String() (str string) {
case aluRRR:
size := is64SizeBitToSize(i.u3)
str = fmt.Sprintf("%s %s, %s, %s", aluOp(i.u1).String(),
formatVRegSized(i.rd.nr(), size), formatVRegSized(i.rn.nr(), size), formatVRegSized(i.rm.nr(), size))
formatVRegSized(i.rd.nr(), size), formatVRegSized(i.rn.nr(), size),
i.rm.format(size))
case aluRRRR:
size := is64SizeBitToSize(i.u3)
str = fmt.Sprintf("%s %s, %s, %s, %s", aluOp(i.u1).String(),
formatVRegSized(i.rd.nr(), size), formatVRegSized(i.rn.nr(), size), formatVRegSized(i.rm.nr(), size), formatVRegSized(i.ra.nr(), size))
case aluRRImm12:
size := is64SizeBitToSize(i.u3)
v, shiftBit := i.rm.imm12()
if shiftBit == 1 {
str = fmt.Sprintf("%s %s, %s, #%#x", aluOp(i.u1).String(),
formatVRegSized(i.rd.nr(), size), formatVRegSized(i.rn.nr(), size), uint64(v)<<12)
} else {
str = fmt.Sprintf("%s %s, %s, #%#x", aluOp(i.u1).String(),
formatVRegSized(i.rd.nr(), size), formatVRegSized(i.rn.nr(), size), v)
}
str = fmt.Sprintf("%s %s, %s, %s", aluOp(i.u1).String(),
formatVRegSized(i.rd.nr(), size), formatVRegSized(i.rn.nr(), size), i.rm.format(size))
case aluRRBitmaskImm:
size := is64SizeBitToSize(i.u3)
rd, rn := formatVRegSized(i.rd.nr(), size), formatVRegSized(i.rn.nr(), size)
@@ -770,16 +765,15 @@ func (i *instruction) String() (str string) {
aluOp(i.u1).String(),
formatVRegSized(i.rd.nr(), size),
formatVRegSized(i.rn.nr(), size),
formatVRegSized(i.rm.nr(), size),
i.rm.format(size),
)
case aluRRRExtend:
rm, e, _ := i.rm.er()
size := is64SizeBitToSize(i.u3)
str = fmt.Sprintf("%s %s, %s, %s %s", aluOp(i.u1).String(),
str = fmt.Sprintf("%s %s, %s, %s", aluOp(i.u1).String(),
formatVRegSized(i.rd.nr(), size),
formatVRegSized(i.rn.nr(), size),
formatVRegSized(rm, e.srcBits()),
e,
// Regardless of the source size, the register is formatted in 32-bit.
i.rm.format(32),
)
case bitRR:
size := is64SizeBitToSize(i.u2)
@@ -824,13 +818,13 @@ func (i *instruction) String() (str string) {
str = fmt.Sprintf("mov %s, %s", formatVRegSized(i.rd.nr(), 32), formatVRegSized(i.rn.nr(), 32))
case movZ:
size := is64SizeBitToSize(i.u3)
str = fmt.Sprintf("movz %s, #%#x, LSL %d", formatVRegSized(i.rd.nr(), size), uint16(i.u1), i.u2*16)
str = fmt.Sprintf("movz %s, #%#x, lsl %d", formatVRegSized(i.rd.nr(), size), uint16(i.u1), i.u2*16)
case movN:
size := is64SizeBitToSize(i.u3)
str = fmt.Sprintf("movn %s, #%#x, LSL %d", formatVRegSized(i.rd.nr(), size), uint16(i.u1), i.u2*16)
str = fmt.Sprintf("movn %s, #%#x, lsl %d", formatVRegSized(i.rd.nr(), size), uint16(i.u1), i.u2*16)
case movK:
size := is64SizeBitToSize(i.u3)
str = fmt.Sprintf("movk %s, #%#x, LSL %d", formatVRegSized(i.rd.nr(), size), uint16(i.u1), i.u2*16)
str = fmt.Sprintf("movk %s, #%#x, lsl %d", formatVRegSized(i.rd.nr(), size), uint16(i.u1), i.u2*16)
case extend:
fromBits, toBits := byte(i.u1), byte(i.u2)
@@ -1342,7 +1336,7 @@ func (a aluOp) String() string {
case aluOpUDiv64:
return "uDiv64"
case aluOpRotR:
return "rotR"
return "ror"
case aluOpLsr:
return "lsr"
case aluOpAsr:
@@ -1617,13 +1611,13 @@ const (
func (s shiftOp) String() string {
switch s {
case shiftOpLSL:
return "LSL"
return "lsl"
case shiftOpLSR:
return "LSR"
return "lsr"
case shiftOpASR:
return "ASR"
return "asr"
case shiftOpROR:
return "ROR"
return "ror"
}
panic(int(s))
}
@@ -814,6 +814,7 @@ func encodeAluRRImm12(op aluOp, rd, rn uint32, imm12 uint16, shiftBit byte, _64b
// https://developer.arm.com/documentation/ddi0596/2020-12/Index-by-Encoding/Data-Processing----Register?lang=en#addsub_shift
func encodeAluRRRShift(op aluOp, rd, rn, rm, amount uint32, shiftOp shiftOp, _64bit bool) uint32 {
var _31to24 uint32
var opc, n uint32
switch op {
case aluOpAdd:
_31to24 = 0b00001011
@@ -823,6 +824,17 @@ func encodeAluRRRShift(op aluOp, rd, rn, rm, amount uint32, shiftOp shiftOp, _64
_31to24 = 0b01001011
case aluOpSubS:
_31to24 = 0b01101011
case aluOpAnd, aluOpOrr, aluOpEor:
// "Logical (shifted register)".
switch op {
case aluOpAnd:
// all zeros
case aluOpOrr:
opc = 0b01
case aluOpEor:
opc = 0b10
}
_31to24 = 0b000_01010
default:
panic(op.String())
}
@@ -842,7 +854,7 @@ func encodeAluRRRShift(op aluOp, rd, rn, rm, amount uint32, shiftOp shiftOp, _64
default:
panic(shiftOp.String())
}
return _31to24<<24 | shift<<22 | rm<<16 | (amount << 10) | (rn << 5) | rd
return opc<<29 | n<<21 | _31to24<<24 | shift<<22 | rm<<16 | (amount << 10) | (rn << 5) | rd
}
// encodeAluRRR encodes as Data Processing (register), depending on aluOp.
@@ -880,7 +892,19 @@ func encodeAluRRR(op aluOp, rd, rn, rm uint32, _64bit, isRnSp bool) uint32 {
}
// "Shifted register" with shift = 0
_31to21 = 0b01101011_000
case aluOpLsl, aluOpAsr, aluOpLsr:
case aluOpAnd, aluOpOrr, aluOpEor:
// "Logical (shifted register)".
var opc, n uint32
switch op {
case aluOpAnd:
// all zeros
case aluOpOrr:
opc = 0b01
case aluOpEor:
opc = 0b10
}
_31to21 = 0b000_01010_000 | opc<<8 | n
case aluOpLsl, aluOpAsr, aluOpLsr, aluOpRotR:
// "Data-processing (2 source)".
_31to21 = 0b00011010_110
switch op {
@@ -890,6 +914,8 @@ func encodeAluRRR(op aluOp, rd, rn, rm uint32, _64bit, isRnSp bool) uint32 {
_15to10 = 0b001001
case aluOpAsr:
_15to10 = 0b001010
case aluOpRotR:
_15to10 = 0b001011
}
default:
panic(op.String())
@@ -116,6 +116,45 @@ func TestInstruction_encode(t *testing.T) {
{want: "fb633b8b", setup: func(i *instruction) {
i.asALU(aluOpAdd, operandNR(tmpRegVReg), operandNR(spVReg), operandNR(tmpRegVReg), true)
}},
{want: "2000020a", setup: func(i *instruction) {
i.asALU(aluOpAnd, operandNR(x0VReg), operandNR(x1VReg), operandNR(x2VReg), false)
}},
{want: "2000028a", setup: func(i *instruction) {
i.asALU(aluOpAnd, operandNR(x0VReg), operandNR(x1VReg), operandNR(x2VReg), true)
}},
{want: "2010028a", setup: func(i *instruction) {
i.asALU(aluOpAnd, operandNR(x0VReg), operandNR(x1VReg), operandSR(x2VReg, 4, shiftOpLSL), true)
}},
{want: "2030428a", setup: func(i *instruction) {
i.asALU(aluOpAnd, operandNR(x0VReg), operandNR(x1VReg), operandSR(x2VReg, 12, shiftOpLSR), true)
}},
{want: "2000022a", setup: func(i *instruction) {
i.asALU(aluOpOrr, operandNR(x0VReg), operandNR(x1VReg), operandNR(x2VReg), false)
}},
{want: "200002aa", setup: func(i *instruction) {
i.asALU(aluOpOrr, operandNR(x0VReg), operandNR(x1VReg), operandNR(x2VReg), true)
}},
{want: "201002aa", setup: func(i *instruction) {
i.asALU(aluOpOrr, operandNR(x0VReg), operandNR(x1VReg), operandSR(x2VReg, 4, shiftOpLSL), true)
}},
{want: "201082aa", setup: func(i *instruction) {
i.asALU(aluOpOrr, operandNR(x0VReg), operandNR(x1VReg), operandSR(x2VReg, 4, shiftOpASR), true)
}},
{want: "2000024a", setup: func(i *instruction) {
i.asALU(aluOpEor, operandNR(x0VReg), operandNR(x1VReg), operandNR(x2VReg), false)
}},
{want: "200002ca", setup: func(i *instruction) {
i.asALU(aluOpEor, operandNR(x0VReg), operandNR(x1VReg), operandNR(x2VReg), true)
}},
{want: "201002ca", setup: func(i *instruction) {
i.asALU(aluOpEor, operandNR(x0VReg), operandNR(x1VReg), operandSR(x2VReg, 4, shiftOpLSL), true)
}},
{want: "202cc21a", setup: func(i *instruction) {
i.asALU(aluOpRotR, operandNR(x0VReg), operandNR(x1VReg), operandNR(x2VReg), false)
}},
{want: "202cc29a", setup: func(i *instruction) {
i.asALU(aluOpRotR, operandNR(x0VReg), operandNR(x1VReg), operandNR(x2VReg), true)
}},
{want: "30000010", setup: func(i *instruction) { i.asAdr(v16VReg, 4) }},
{want: "50050030", setup: func(i *instruction) { i.asAdr(v16VReg, 169) }},
{want: "5000001c020000140000803f", setup: func(i *instruction) {
@@ -77,15 +77,15 @@ func TestMachine_lowerConstantI32(t *testing.T) {
val uint32
exp []string
}{
{val: 0, exp: []string{"movz w0, #0x0, LSL 0"}},
{val: 0xffff, exp: []string{"movz w0, #0xffff, LSL 0"}},
{val: 0xffff_0000, exp: []string{"movz w0, #0xffff, LSL 16"}},
{val: 0xffff_fffe, exp: []string{"movn w0, #0x1, LSL 0"}},
{val: 0, exp: []string{"movz w0, #0x0, lsl 0"}},
{val: 0xffff, exp: []string{"movz w0, #0xffff, lsl 0"}},
{val: 0xffff_0000, exp: []string{"movz w0, #0xffff, lsl 16"}},
{val: 0xffff_fffe, exp: []string{"movn w0, #0x1, lsl 0"}},
{val: 0x2, exp: []string{"orr w0, wzr, #0x2"}},
{val: 0x80000001, exp: []string{"orr w0, wzr, #0x80000001"}},
{val: 0xf00000f, exp: []string{
"movz w0, #0xf, LSL 0",
"movk w0, #0xf00, LSL 16",
"movz w0, #0xf, lsl 0",
"movk w0, #0xf00, lsl 16",
}},
} {
tc := tc
@@ -104,43 +104,43 @@ func TestMachine_lowerConstantI64(t *testing.T) {
val uint64
exp []string
}{
{val: 0x0, exp: []string{"movz x0, #0x0, LSL 0"}},
{val: 0x0, exp: []string{"movz x0, #0x0, lsl 0"}},
{val: 0x1, exp: []string{"orr x0, xzr, #0x1"}},
{val: 0x3, exp: []string{"orr x0, xzr, #0x3"}},
{val: 0xfff000, exp: []string{"orr x0, xzr, #0xfff000"}},
{val: 0x8001 << 16, exp: []string{"movz x0, #0x8001, LSL 16"}},
{val: 0x8001 << 32, exp: []string{"movz x0, #0x8001, LSL 32"}},
{val: 0x8001 << 48, exp: []string{"movz x0, #0x8001, LSL 48"}},
{val: invert(0x8001 << 16), exp: []string{"movn x0, #0x8001, LSL 16"}},
{val: invert(0x8001 << 32), exp: []string{"movn x0, #0x8001, LSL 32"}},
{val: invert(0x8001 << 48), exp: []string{"movn x0, #0x8001, LSL 48"}},
{val: 0x8001 << 16, exp: []string{"movz x0, #0x8001, lsl 16"}},
{val: 0x8001 << 32, exp: []string{"movz x0, #0x8001, lsl 32"}},
{val: 0x8001 << 48, exp: []string{"movz x0, #0x8001, lsl 48"}},
{val: invert(0x8001 << 16), exp: []string{"movn x0, #0x8001, lsl 16"}},
{val: invert(0x8001 << 32), exp: []string{"movn x0, #0x8001, lsl 32"}},
{val: invert(0x8001 << 48), exp: []string{"movn x0, #0x8001, lsl 48"}},
{val: 0x80000001 << 16, exp: []string{
"movz x0, #0x1, LSL 16",
"movk x0, #0x8000, LSL 32",
"movz x0, #0x1, lsl 16",
"movk x0, #0x8000, lsl 32",
}},
{val: 0x40000001, exp: []string{
"movz x0, #0x1, LSL 0",
"movk x0, #0x4000, LSL 16",
"movz x0, #0x1, lsl 0",
"movk x0, #0x4000, lsl 16",
}},
{val: 0xffffffffff001000, exp: []string{
"movn x0, #0xefff, LSL 0",
"movk x0, #0xff00, LSL 16",
"movn x0, #0xefff, lsl 0",
"movk x0, #0xff00, lsl 16",
}},
{val: 0xffff0000c466361f, exp: []string{
"movz x0, #0x361f, LSL 0",
"movk x0, #0xc466, LSL 16",
"movk x0, #0xffff, LSL 48",
"movz x0, #0x361f, lsl 0",
"movk x0, #0xc466, lsl 16",
"movk x0, #0xffff, lsl 48",
}},
{val: 0x89705f4136b4a598, exp: []string{
"movz x0, #0xa598, LSL 0",
"movk x0, #0x36b4, LSL 16",
"movk x0, #0x5f41, LSL 32",
"movk x0, #0x8970, LSL 48",
"movz x0, #0xa598, lsl 0",
"movk x0, #0x36b4, lsl 16",
"movk x0, #0x5f41, lsl 32",
"movk x0, #0x8970, lsl 48",
}},
{val: 0xffff_0001_0001_0001, exp: []string{
"movn x0, #0xfffe, LSL 0",
"movk x0, #0x1, LSL 16",
"movk x0, #0x1, LSL 32",
"movn x0, #0xfffe, lsl 0",
"movk x0, #0x1, lsl 16",
"movk x0, #0x1, lsl 32",
}},
} {
tc := tc
@@ -151,6 +151,12 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) {
m.lowerCall(instr)
case ssa.OpcodeIcmp:
m.lowerIcmp(instr)
case ssa.OpcodeBand:
m.lowerBitwiseAluOp(instr, aluOpAnd)
case ssa.OpcodeBor:
m.lowerBitwiseAluOp(instr, aluOpOrr)
case ssa.OpcodeBxor:
m.lowerBitwiseAluOp(instr, aluOpEor)
case ssa.OpcodeIshl:
m.lowerShifts(instr, extModeNone, aluOpLsl)
case ssa.OpcodeSshr:
@@ -165,6 +171,10 @@ func (m *machine) LowerInstr(instr *ssa.Instruction) {
} else {
m.lowerShifts(instr, extModeZeroExtend32, aluOpAsr)
}
case ssa.OpcodeRotl:
m.lowerRotl(instr)
case ssa.OpcodeRotr:
m.lowerRotr(instr)
case ssa.OpcodeSExtend, ssa.OpcodeUExtend:
from, to, signed := instr.ExtendData()
m.lowerExtend(instr.Arg(), instr.Return(), from, to, signed)
@@ -343,6 +353,61 @@ func (m *machine) lowerShifts(si *ssa.Instruction, ext extMode, aluOp aluOp) {
m.insert(alu)
}
func (m *machine) lowerBitwiseAluOp(si *ssa.Instruction, op aluOp) {
x, y := si.BinaryData()
if !x.Type().IsInt() {
panic("BUG?")
}
xDef, yDef := m.compiler.ValueDefinition(x), m.compiler.ValueDefinition(y)
rn := m.getOperand_NR(xDef, extModeNone)
rm := m.getOperand_SR_NR(yDef, extModeNone)
rd := operandNR(m.compiler.VRegOf(si.Return()))
alu := m.allocateInstr()
alu.asALU(op, rd, rn, rm, si.Return().Type().Bits() == 64)
m.insert(alu)
}
func (m *machine) lowerRotl(si *ssa.Instruction) {
x, y := si.BinaryData()
if !x.Type().IsInt() {
panic("BUG?")
}
// Encode rotl as neg + rotr: neg is really a sub against the zero-reg.
xDef, yDef := m.compiler.ValueDefinition(x), m.compiler.ValueDefinition(y)
rn := m.getOperand_NR(xDef, extModeNone)
rm := m.getOperand_NR(yDef, extModeNone)
rd := operandNR(m.compiler.VRegOf(si.Return()))
// Encode neg as sub $reg, xzr, $reg.
neg := m.allocateInstr()
neg.asALU(aluOpSub, rn, operandNR(xzrVReg), rn, si.Return().Type().Bits() == 64)
m.insert(neg)
alu := m.allocateInstr()
alu.asALU(aluOpRotR, rd, rn, rm, si.Return().Type().Bits() == 64)
m.insert(alu)
}
func (m *machine) lowerRotr(si *ssa.Instruction) {
x, y := si.BinaryData()
if !x.Type().IsInt() {
panic("BUG?")
}
xDef, yDef := m.compiler.ValueDefinition(x), m.compiler.ValueDefinition(y)
rn := m.getOperand_NR(xDef, extModeNone)
rm := m.getOperand_NR(yDef, extModeNone)
rd := operandNR(m.compiler.VRegOf(si.Return()))
alu := m.allocateInstr()
alu.asALU(aluOpRotR, rd, rn, rm, si.Return().Type().Bits() == 64)
m.insert(alu)
}
func (m *machine) lowerExtend(arg, ret ssa.Value, from, to byte, signed bool) {
rd := m.compiler.VRegOf(ret)
rn := m.getOperand_NR(m.compiler.ValueDefinition(arg), extModeNone)
@@ -40,19 +40,23 @@ const (
)
// String implements fmt.Stringer for debugging.
func (o operand) String() string {
func (o operand) format(size byte) string {
switch o.kind {
case operandKindNR:
return fmt.Sprintf("r%d", o.nr())
return formatVRegSized(o.nr(), size)
case operandKindSR:
r, amt, sop := o.sr()
return fmt.Sprintf("r%d, #%d, %s", r, amt, sop)
return fmt.Sprintf("%s, %s #%d", formatVRegSized(r, size), sop, amt)
case operandKindER:
r, eop, to := o.er()
return fmt.Sprintf("r%d, %s, %d", r, eop, to)
r, eop, _ := o.er()
return fmt.Sprintf("%s %s", formatVRegSized(r, size), eop)
case operandKindImm12:
imm12, shiftBit := o.imm12()
return fmt.Sprintf("#%d<<%d", imm12, 12*shiftBit)
if shiftBit == 1 {
return fmt.Sprintf("#%#x", uint64(imm12)<<12)
} else {
return fmt.Sprintf("#%#x", imm12)
}
default:
panic(fmt.Sprintf("unknown operand kind: %d", o.kind))
}
@@ -79,8 +79,8 @@ func TestMachine_getOperand_NR(t *testing.T) {
},
exp: operandNR(regalloc.VReg(100).SetRegType(regalloc.RegTypeInt)),
instructions: []string{
"movz w100?, #0xf, LSL 0",
"movk w100?, #0xf00, LSL 16",
"movz w100?, #0xf, lsl 0",
"movk w100?, #0xf00, lsl 16",
},
},
{
@@ -110,7 +110,7 @@ func (a addressMode) format(dstSizeBits byte) (ret string) {
ret = fmt.Sprintf("[%s, %s, %s #%#x]", base, formatVRegSized(a.rm, a.indexRegBits()), a.extOp, amount)
case addressModeKindRegScaled:
amount := a.sizeInBitsToShiftAmount(dstSizeBits)
ret = fmt.Sprintf("[%s, %s, LSL #%#x]", base, formatVRegSized(a.rm, a.indexRegBits()), amount)
ret = fmt.Sprintf("[%s, %s, lsl #%#x]", base, formatVRegSized(a.rm, a.indexRegBits()), amount)
case addressModeKindRegExtended:
ret = fmt.Sprintf("[%s, %s, %s]", base, formatVRegSized(a.rm, a.indexRegBits()), a.extOp)
case addressModeKindRegReg:
@@ -77,7 +77,7 @@ func TestAddressMode_format(t *testing.T) {
})
t.Run("addressModeKindRegScaled", func(t *testing.T) {
require.Equal(t,
"[x1, w0, LSL #0x1]",
"[x1, w0, lsl #0x1]",
addressMode{
kind: addressModeKindRegScaled,
rn: regalloc.FromRealReg(x1, regalloc.RegTypeInt),
@@ -87,7 +87,7 @@ func TestAddressMode_format(t *testing.T) {
}.format(16),
)
require.Equal(t,
"[x1, w0, LSL #0x1]",
"[x1, w0, lsl #0x1]",
addressMode{
kind: addressModeKindRegScaled,
rn: regalloc.FromRealReg(x1, regalloc.RegTypeInt),
@@ -97,7 +97,7 @@ func TestAddressMode_format(t *testing.T) {
}.format(16),
)
require.Equal(t,
"[x1, w0, LSL #0x2]",
"[x1, w0, lsl #0x2]",
addressMode{
kind: addressModeKindRegScaled,
rn: regalloc.FromRealReg(x1, regalloc.RegTypeInt),
@@ -107,7 +107,7 @@ func TestAddressMode_format(t *testing.T) {
}.format(32),
)
require.Equal(t,
"[x1, w0, LSL #0x2]",
"[x1, w0, lsl #0x2]",
addressMode{
kind: addressModeKindRegScaled,
rn: regalloc.FromRealReg(x1, regalloc.RegTypeInt),
@@ -117,7 +117,7 @@ func TestAddressMode_format(t *testing.T) {
}.format(32),
)
require.Equal(t,
"[x1, w0, LSL #0x3]",
"[x1, w0, lsl #0x3]",
addressMode{
kind: addressModeKindRegScaled,
rn: regalloc.FromRealReg(x1, regalloc.RegTypeInt),
@@ -127,7 +127,7 @@ func TestAddressMode_format(t *testing.T) {
}.format(64),
)
require.Equal(t,
"[x1, w0, LSL #0x3]",
"[x1, w0, lsl #0x3]",
addressMode{
kind: addressModeKindRegScaled,
rn: regalloc.FromRealReg(x1, regalloc.RegTypeInt),
@@ -508,8 +508,8 @@ func TestMachine_addConstToReg64(t *testing.T) {
ctx, _, m := newSetupWithMockContext()
ctx.vRegCounter = nextVRegID - 1
m.addConstToReg64(regalloc.FromRealReg(x15, regalloc.RegTypeInt), c)
require.Equal(t, `movz x101?, #0x1, LSL 0
movk x101?, #0x1, LSL 32
require.Equal(t, `movz x101?, #0x1, lsl 0
movk x101?, #0x1, lsl 32
add x100?, x15, x101?`, formatEmittedInstructionsInCurrentBlock(m))
})
}
@@ -170,12 +170,12 @@ func TestMachine_insertStackBoundsCheck(t *testing.T) {
{
requiredStackSize: 0xfff_0,
exp: `
movz x27, #0xfff0, LSL 0
movz x27, #0xfff0, lsl 0
sub x27, sp, x27
ldr x11, [x0, #0x28]
subs xzr, x27, x11
b.ge #0x14
movz x27, #0xfff0, LSL 0
movz x27, #0xfff0, lsl 0
str x27, [x0, #0x40]
ldr x27, [x0, #0x50]
bl w27
@@ -69,8 +69,8 @@ func TestMachine_resolveAddressingMode(t *testing.T) {
m.rootInstr = root
require.Equal(t, `
udf
movz x27, #0x1, LSL 0
movk x27, #0x4000, LSL 16
movz x27, #0x1, lsl 0
movk x27, #0x4000, lsl 16
ldr x17, [sp, x27]
`, m.Format())
})
@@ -249,7 +249,7 @@ func formatVRegSized(r regalloc.VReg, size byte) (ret string) {
ret = strings.Replace(ret, "x", "w", 1)
case 64:
default:
panic("BUG: invalid register size")
panic("BUG: invalid register size: " + strconv.Itoa(int(size)))
}
case 'v':
switch size {
@@ -570,6 +570,25 @@ blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i64, v5:i64)
v24:i32 = Icmp ge_u, v2, v3
v25:i32 = Icmp ge_u, v4, v5
Jump blk_ret, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25
`,
},
{
name: "integer bitwise", m: testcases.IntegerBitwise.Module,
exp: `
blk0: (exec_ctx:i64, module_ctx:i64, v2:i32, v3:i32, v4:i64, v5:i64)
v6:i32 = Band v2, v3
v7:i32 = Bor v2, v3
v8:i32 = Bxor v2, v3
v9:i32 = Rotr v2, v3
v10:i64 = Band v4, v5
v11:i64 = Bor v4, v5
v12:i64 = Bxor v4, v5
v13:i64 = Iconst_64 0x8
v14:i64 = Ishl v5, v13
v15:i64 = Bxor v4, v14
v16:i64 = Rotl v4, v5
v17:i64 = Rotr v4, v5
Jump blk_ret, v6, v7, v8, v9, v10, v11, v12, v15, v16, v17
`,
},
{
+50
View File
@@ -425,6 +425,36 @@ func (c *Compiler) lowerOpcode(op wasm.Opcode) {
builder.InsertInstruction(neg)
value := neg.Return()
state.push(value)
case wasm.OpcodeI32And, wasm.OpcodeI64And:
if state.unreachable {
return
}
y, x := state.pop(), state.pop()
and := builder.AllocateInstruction()
and.AsBand(x, y)
builder.InsertInstruction(and)
value := and.Return()
state.push(value)
case wasm.OpcodeI32Or, wasm.OpcodeI64Or:
if state.unreachable {
return
}
y, x := state.pop(), state.pop()
or := builder.AllocateInstruction()
or.AsBor(x, y)
builder.InsertInstruction(or)
value := or.Return()
state.push(value)
case wasm.OpcodeI32Xor, wasm.OpcodeI64Xor:
if state.unreachable {
return
}
y, x := state.pop(), state.pop()
xor := builder.AllocateInstruction()
xor.AsBxor(x, y)
builder.InsertInstruction(xor)
value := xor.Return()
state.push(value)
case wasm.OpcodeI32Shl, wasm.OpcodeI64Shl:
if state.unreachable {
return
@@ -455,6 +485,26 @@ func (c *Compiler) lowerOpcode(op wasm.Opcode) {
builder.InsertInstruction(ishl)
value := ishl.Return()
state.push(value)
case wasm.OpcodeI32Rotl, wasm.OpcodeI64Rotl:
if state.unreachable {
return
}
y, x := state.pop(), state.pop()
rotl := builder.AllocateInstruction()
rotl.AsRotl(x, y)
builder.InsertInstruction(rotl)
value := rotl.Return()
state.push(value)
case wasm.OpcodeI32Rotr, wasm.OpcodeI64Rotr:
if state.unreachable {
return
}
y, x := state.pop(), state.pop()
rotr := builder.AllocateInstruction()
rotr.AsRotr(x, y)
builder.InsertInstruction(rotr)
value := rotr.Return()
state.push(value)
case wasm.OpcodeI32Clz, wasm.OpcodeI64Clz:
if state.unreachable {
return
+51 -1
View File
@@ -826,6 +826,11 @@ var instructionSideEffects = [opcodeEnd]sideEffect{
OpcodeImul: sideEffectFalse,
OpcodeIsub: sideEffectFalse,
OpcodeIcmp: sideEffectFalse,
OpcodeBand: sideEffectFalse,
OpcodeBor: sideEffectFalse,
OpcodeBxor: sideEffectFalse,
OpcodeRotl: sideEffectFalse,
OpcodeRotr: sideEffectFalse,
OpcodeFcmp: sideEffectFalse,
OpcodeFadd: sideEffectFalse,
OpcodeClz: sideEffectFalse,
@@ -879,6 +884,11 @@ func (i *Instruction) HasSideEffects() bool {
// instructionReturnTypes provides the function to determine the return types of an instruction.
var instructionReturnTypes = [opcodeEnd]returnTypesFn{
OpcodeBand: returnTypesFnSingle,
OpcodeBor: returnTypesFnSingle,
OpcodeBxor: returnTypesFnSingle,
OpcodeRotl: returnTypesFnSingle,
OpcodeRotr: returnTypesFnSingle,
OpcodeIshl: returnTypesFnSingle,
OpcodeSshr: returnTypesFnSingle,
OpcodeUshr: returnTypesFnSingle,
@@ -1083,6 +1093,30 @@ func (i *Instruction) AsFcmp(x, y Value, c FloatCmpCond) {
i.typ = TypeI32
}
// AsBand initializes this instruction as an integer bitwise and instruction with OpcodeBand.
func (i *Instruction) AsBand(x, amount Value) {
i.opcode = OpcodeBand
i.v = x
i.v2 = amount
i.typ = x.Type()
}
// AsBor initializes this instruction as an integer bitwise or instruction with OpcodeBor.
func (i *Instruction) AsBor(x, amount Value) {
i.opcode = OpcodeBor
i.v = x
i.v2 = amount
i.typ = x.Type()
}
// AsBxor initializes this instruction as an integer bitwise xor instruction with OpcodeBxor.
func (i *Instruction) AsBxor(x, amount Value) {
i.opcode = OpcodeBxor
i.v = x
i.v2 = amount
i.typ = x.Type()
}
// AsIshl initializes this instruction as an integer shift left instruction with OpcodeIshl.
func (i *Instruction) AsIshl(x, amount Value) {
i.opcode = OpcodeIshl
@@ -1107,6 +1141,22 @@ func (i *Instruction) AsSshr(x, amount Value) {
i.typ = x.Type()
}
// AsRotl initializes this instruction as a word rotate left instruction with OpcodeRotl.
func (i *Instruction) AsRotl(x, amount Value) {
i.opcode = OpcodeRotl
i.v = x
i.v2 = amount
i.typ = x.Type()
}
// AsRotr initializes this instruction as a word rotate right instruction with OpcodeRotr.
func (i *Instruction) AsRotr(x, amount Value) {
i.opcode = OpcodeRotr
i.v = x
i.v2 = amount
i.typ = x.Type()
}
// IcmpData returns the operands and comparison condition of this integer comparison instruction.
func (i *Instruction) IcmpData() (x, y Value, c IntegerCmpCond) {
return i.v, i.v2, IntegerCmpCond(i.u64)
@@ -1551,7 +1601,7 @@ func (i *Instruction) Format(b Builder) string {
}
}
instSuffix += "]"
case OpcodeIshl, OpcodeSshr, OpcodeUshr:
case OpcodeBand, OpcodeBor, OpcodeBxor, OpcodeRotr, OpcodeRotl, OpcodeIshl, OpcodeSshr, OpcodeUshr:
instSuffix = fmt.Sprintf(" %s, %s", i.v.Format(b), i.v2.Format(b))
case OpcodeUndefined:
case OpcodeClz, OpcodeCtz, OpcodePopcnt, OpcodeFneg, OpcodeFcvtFromSint, OpcodeFcvtFromUint, OpcodeFpromote,
@@ -653,6 +653,57 @@ var (
wasm.OpcodeEnd,
}, []wasm.ValueType{}),
}
IntegerBitwise = TestCase{
Name: "integer_bitwise",
Module: SingleFunctionModule(wasm.FunctionType{
Params: []wasm.ValueType{i32, i32, i64, i64},
Results: []wasm.ValueType{i32, i32, i32, i32, i64, i64, i64, i64, i64, i64},
}, []byte{
wasm.OpcodeLocalGet, 0,
wasm.OpcodeLocalGet, 1,
wasm.OpcodeI32And,
wasm.OpcodeLocalGet, 0,
wasm.OpcodeLocalGet, 1,
wasm.OpcodeI32Or,
wasm.OpcodeLocalGet, 0,
wasm.OpcodeLocalGet, 1,
wasm.OpcodeI32Xor,
wasm.OpcodeLocalGet, 0,
wasm.OpcodeLocalGet, 1,
wasm.OpcodeI32Rotr,
wasm.OpcodeLocalGet, 2,
wasm.OpcodeLocalGet, 3,
wasm.OpcodeI64And,
wasm.OpcodeLocalGet, 2,
wasm.OpcodeLocalGet, 3,
wasm.OpcodeI64Or,
wasm.OpcodeLocalGet, 2,
wasm.OpcodeLocalGet, 3,
wasm.OpcodeI64Xor,
wasm.OpcodeLocalGet, 2,
wasm.OpcodeLocalGet, 3,
wasm.OpcodeI64Const, 8,
wasm.OpcodeI64Shl,
wasm.OpcodeI64Xor,
wasm.OpcodeLocalGet, 2,
wasm.OpcodeLocalGet, 3,
wasm.OpcodeI64Rotl,
wasm.OpcodeLocalGet, 2,
wasm.OpcodeLocalGet, 3,
wasm.OpcodeI64Rotr,
wasm.OpcodeEnd,
}, []wasm.ValueType{}),
}
IntegerShift = TestCase{
Name: "integer_shift",
Module: SingleFunctionModule(wasm.FunctionType{