diff --git a/tests/disas/winch/aarch64/memory_offsets/index.wat b/tests/disas/winch/aarch64/memory_offsets/index.wat new file mode 100644 index 000000000000..d727a3bb3c98 --- /dev/null +++ b/tests/disas/winch/aarch64/memory_offsets/index.wat @@ -0,0 +1,1334 @@ +;;! target = "aarch64" +;;! test = "winch" + +(module + (type (;0;) (func (result f64 f32 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i64 f64))) + (global (;0;) (mut i32) i32.const 10) + (export "main" (func 0)) + (func (;0;) (type 0) (result f64 f32 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i64 f64) + call 1 + call 1 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + br 0 + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + f64.const 0x1.54e5e9c49a8a3p+224 (;=35900759953881640000000000000000000000000000000000000000000000000000;) + f32.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + i64.const 0 + f64.const 0x0p+0 (;=0;) + ) + (func (;1;) (type 0) (result f64 f32 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i64 f64) + f64.const 0x0p+0 (;=0;) + f32.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + i64.const 0 + f64.const 0x0p+0 (;=0;) + ) + (func (;2;) (type 0) (result f64 f32 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i64 f64) + f64.const 0x0p+0 (;=0;) + f32.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + i64.const 0 + f64.const 0x0p+0 (;=0;) + ) +) +;; wasm[0]::function[0]: +;; stp x29, x30, [sp, #-0x10]! +;; mov x29, sp +;; str x28, [sp, #-0x10]! +;; mov x28, sp +;; ldur x16, [x1, #8] +;; ldur x16, [x16, #0x18] +;; mov x17, #0 +;; movk x17, #0xf10 +;; add x16, x16, x17 +;; cmp sp, x16 +;; b.lo #0x8a8 +;; 2c: mov x9, x1 +;; sub x28, x28, #0x18 +;; mov sp, x28 +;; stur x1, [x28, #0x10] +;; stur x2, [x28, #8] +;; stur x0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0x8c0 +;; 64: add x28, x28, #0xc +;; mov sp, x28 +;; ldur x9, [x28, #0x7c] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #8 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #8 +;; bl #0x8c0 +;; 9c: add x28, x28, #8 +;; mov sp, x28 +;; ldur x9, [x28, #0xf0] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #4 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #4 +;; bl #0xaa0 +;; d4: add x28, x28, #4 +;; mov sp, x28 +;; mov x16, #0x164 +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0 +;; bl #0xaa0 +;; 108: ldr x9, [x28, #0x1d8] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0xaa0 +;; 138: add x28, x28, #0xc +;; mov sp, x28 +;; mov x16, #0x24c +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #8 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #8 +;; bl #0xaa0 +;; 174: add x28, x28, #8 +;; mov sp, x28 +;; ldr x9, [x28, #0x2c0] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #4 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #4 +;; bl #0xaa0 +;; 1ac: add x28, x28, #4 +;; mov sp, x28 +;; mov x16, #0x334 +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0 +;; bl #0xaa0 +;; 1e0: ldr x9, [x28, #0x3a8] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0xaa0 +;; 210: add x28, x28, #0xc +;; mov sp, x28 +;; mov x16, #0x41c +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #8 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #8 +;; bl #0xaa0 +;; 24c: add x28, x28, #8 +;; mov sp, x28 +;; ldr x9, [x28, #0x490] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #4 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #4 +;; bl #0xaa0 +;; 284: add x28, x28, #4 +;; mov sp, x28 +;; mov x16, #0x504 +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0 +;; bl #0xaa0 +;; 2b8: ldr x9, [x28, #0x578] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0xaa0 +;; 2e8: add x28, x28, #0xc +;; mov sp, x28 +;; mov x16, #0x5ec +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #8 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #8 +;; bl #0xaa0 +;; 324: add x28, x28, #8 +;; mov sp, x28 +;; ldr x9, [x28, #0x660] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #4 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #4 +;; bl #0xaa0 +;; 35c: add x28, x28, #4 +;; mov sp, x28 +;; mov x16, #0x6d4 +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0 +;; bl #0xaa0 +;; 390: ldr x9, [x28, #0x748] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0xaa0 +;; 3c0: add x28, x28, #0xc +;; mov sp, x28 +;; mov x16, #0x7bc +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #8 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #8 +;; bl #0xaa0 +;; 3fc: add x28, x28, #8 +;; mov sp, x28 +;; ldr x9, [x28, #0x830] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #4 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #4 +;; bl #0xaa0 +;; 434: add x28, x28, #4 +;; mov sp, x28 +;; mov x16, #0x8a4 +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0 +;; bl #0xaa0 +;; 468: ldr x9, [x28, #0x918] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0xaa0 +;; 498: add x28, x28, #0xc +;; mov sp, x28 +;; mov x16, #0x98c +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #8 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #8 +;; bl #0xaa0 +;; 4d4: add x28, x28, #8 +;; mov sp, x28 +;; ldr x9, [x28, #0xa00] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #4 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #4 +;; bl #0xaa0 +;; 50c: add x28, x28, #4 +;; mov sp, x28 +;; mov x16, #0xa74 +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0 +;; bl #0xaa0 +;; 540: ldr x9, [x28, #0xae8] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0xaa0 +;; 570: add x28, x28, #0xc +;; mov sp, x28 +;; mov x16, #0xb5c +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #8 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #8 +;; bl #0xaa0 +;; 5ac: add x28, x28, #8 +;; mov sp, x28 +;; ldr x9, [x28, #0xbd0] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #4 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #4 +;; bl #0xaa0 +;; 5e4: add x28, x28, #4 +;; mov sp, x28 +;; mov x16, #0xc44 +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0 +;; bl #0xaa0 +;; 618: ldr x9, [x28, #0xcb8] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0xaa0 +;; 648: add x28, x28, #0xc +;; mov sp, x28 +;; mov x16, #0xd2c +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #8 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #8 +;; bl #0xaa0 +;; 684: add x28, x28, #8 +;; mov sp, x28 +;; ldr x9, [x28, #0xda0] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #4 +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #4 +;; bl #0xaa0 +;; 6bc: add x28, x28, #4 +;; mov sp, x28 +;; mov x16, #0xe14 +;; ldr x9, [x28, x16, sxtx] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0 +;; bl #0xaa0 +;; 6f0: ldr x9, [x28, #0xe88] +;; sub x28, x28, #8 +;; mov sp, x28 +;; stur d0, [x28] +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; sub x28, x28, #0xc +;; mov sp, x28 +;; mov x1, x9 +;; mov x2, x9 +;; add x0, x28, #0xc +;; bl #0xaa0 +;; 720: add x28, x28, #0xc +;; mov sp, x28 +;; mov x16, #0xefc +;; ldr x9, [x28, x16, sxtx] +;; ldur x16, [x28, #0x64] +;; mov x17, #0xee4 +;; str x16, [x28, x17, sxtx] +;; ldur w16, [x28, #0x60] +;; str w16, [x28, #0xee0] +;; ldur x16, [x28, #0x58] +;; str x16, [x28, #0xed8] +;; ldur x16, [x28, #0x50] +;; str x16, [x28, #0xed0] +;; ldur x16, [x28, #0x48] +;; str x16, [x28, #0xec8] +;; ldur x16, [x28, #0x40] +;; str x16, [x28, #0xec0] +;; ldur x16, [x28, #0x38] +;; str x16, [x28, #0xeb8] +;; ldur x16, [x28, #0x30] +;; str x16, [x28, #0xeb0] +;; ldur x16, [x28, #0x28] +;; str x16, [x28, #0xea8] +;; ldur x16, [x28, #0x20] +;; str x16, [x28, #0xea0] +;; ldur x16, [x28, #0x18] +;; str x16, [x28, #0xe98] +;; ldur x16, [x28, #0x10] +;; str x16, [x28, #0xe90] +;; ldur x16, [x28, #8] +;; str x16, [x28, #0xe88] +;; ldur x16, [x28] +;; str x16, [x28, #0xe80] +;; add x28, x28, #0xe80 +;; mov sp, x28 +;; ldur x0, [x28, #0x6c] +;; ldur x16, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur x16, [x0] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #8] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x10] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x18] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x20] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x28] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x30] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x38] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x40] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x48] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x50] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x58] +;; ldur s31, [x28] +;; add x28, x28, #4 +;; mov sp, x28 +;; stur s31, [x0, #0x60] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x64] +;; add x28, x28, #0x18 +;; mov sp, x28 +;; mov sp, x28 +;; ldr x28, [sp], #0x10 +;; ldp x29, x30, [sp], #0x10 +;; ret +;; 8a8: .byte 0x1f, 0xc1, 0x00, 0x00 +;; +;; wasm[0]::function[1]: +;; stp x29, x30, [sp, #-0x10]! +;; mov x29, sp +;; str x28, [sp, #-0x10]! +;; mov x28, sp +;; ldur x16, [x1, #8] +;; ldur x16, [x16, #0x18] +;; mov x17, #0 +;; movk x17, #0x84 +;; add x16, x16, x17 +;; cmp sp, x16 +;; b.lo #0xa7c +;; 8ec: mov x9, x1 +;; sub x28, x28, #0x18 +;; mov sp, x28 +;; stur x1, [x28, #0x10] +;; stur x2, [x28, #8] +;; stur x0, [x28] +;; ldr d0, #0xa80 +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x16, #0 +;; stur x16, [x28] +;; ldr d31, #0xa80 +;; stur d31, [x28, #8] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x10] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x18] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x20] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x28] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x30] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x38] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x40] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x48] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x50] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x58] +;; ldr s31, #0xa88 +;; stur s31, [x28, #0x60] +;; ldr d31, #0xa80 +;; stur d31, [x28, #0x64] +;; ldur x0, [x28, #0x6c] +;; ldur x16, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur x16, [x0] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #8] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x10] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x18] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x20] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x28] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x30] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x38] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x40] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x48] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x50] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x58] +;; ldur s31, [x28] +;; add x28, x28, #4 +;; mov sp, x28 +;; stur s31, [x0, #0x60] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x64] +;; add x28, x28, #0x18 +;; mov sp, x28 +;; mov sp, x28 +;; ldr x28, [sp], #0x10 +;; ldp x29, x30, [sp], #0x10 +;; ret +;; a7c: .byte 0x1f, 0xc1, 0x00, 0x00 +;; a80: .byte 0x00, 0x00, 0x00, 0x00 +;; a84: .byte 0x00, 0x00, 0x00, 0x00 +;; a88: .byte 0x00, 0x00, 0x00, 0x00 +;; +;; wasm[0]::function[2]: +;; stp x29, x30, [sp, #-0x10]! +;; mov x29, sp +;; str x28, [sp, #-0x10]! +;; mov x28, sp +;; ldur x16, [x1, #8] +;; ldur x16, [x16, #0x18] +;; mov x17, #0 +;; movk x17, #0x84 +;; add x16, x16, x17 +;; cmp sp, x16 +;; b.lo #0xc5c +;; acc: mov x9, x1 +;; sub x28, x28, #0x18 +;; mov sp, x28 +;; stur x1, [x28, #0x10] +;; stur x2, [x28, #8] +;; stur x0, [x28] +;; ldr d0, #0xc60 +;; sub x28, x28, #0x6c +;; mov sp, x28 +;; mov x16, #0 +;; stur x16, [x28] +;; ldr d31, #0xc60 +;; stur d31, [x28, #8] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x10] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x18] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x20] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x28] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x30] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x38] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x40] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x48] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x50] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x58] +;; ldr s31, #0xc68 +;; stur s31, [x28, #0x60] +;; ldr d31, #0xc60 +;; stur d31, [x28, #0x64] +;; ldur x0, [x28, #0x6c] +;; ldur x16, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur x16, [x0] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #8] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x10] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x18] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x20] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x28] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x30] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x38] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x40] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x48] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x50] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x58] +;; ldur s31, [x28] +;; add x28, x28, #4 +;; mov sp, x28 +;; stur s31, [x0, #0x60] +;; ldur d31, [x28] +;; add x28, x28, #8 +;; mov sp, x28 +;; stur d31, [x0, #0x64] +;; add x28, x28, #0x18 +;; mov sp, x28 +;; mov sp, x28 +;; ldr x28, [sp], #0x10 +;; ldp x29, x30, [sp], #0x10 +;; ret +;; c5c: .byte 0x1f, 0xc1, 0x00, 0x00 +;; c60: .byte 0x00, 0x00, 0x00, 0x00 +;; c64: .byte 0x00, 0x00, 0x00, 0x00 +;; c68: .byte 0x00, 0x00, 0x00, 0x00 diff --git a/tests/misc_testsuite/winch/memory_offsets.wast b/tests/misc_testsuite/winch/memory_offsets.wast new file mode 100644 index 000000000000..b671cb923264 --- /dev/null +++ b/tests/misc_testsuite/winch/memory_offsets.wast @@ -0,0 +1,559 @@ +(module + (type (;0;) (func (result f64 f32 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i64 f64))) + (global (;0;) (mut i32) i32.const 10) + (export "main" (func 0)) + (func (;0;) (type 0) (result f64 f32 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i64 f64) + call 1 + call 1 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + call 2 + br 0 + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + drop + f64.const 0x1.54e5e9c49a8a3p+224 (;=35900759953881640000000000000000000000000000000000000000000000000000;) + f32.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + i64.const 0 + f64.const 0x0p+0 (;=0;) + ) + (func (;1;) (type 0) (result f64 f32 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i64 f64) + f64.const 0x0p+0 (;=0;) + f32.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + i64.const 0 + f64.const 0x0p+0 (;=0;) + ) + (func (;2;) (type 0) (result f64 f32 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 f64 i64 f64) + f64.const 0x0p+0 (;=0;) + f32.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + f64.const 0x0p+0 (;=0;) + i64.const 0 + f64.const 0x0p+0 (;=0;) + ) +) + +(assert_return (invoke "main") + (f64.const 0x0p+0) + (f32.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (f64.const 0x0p+0) + (i64.const 0) + (f64.const 0x0p+0) +) diff --git a/winch/codegen/src/isa/aarch64/address.rs b/winch/codegen/src/isa/aarch64/address.rs index 8ea19eb6f05f..af35e46bb049 100644 --- a/winch/codegen/src/isa/aarch64/address.rs +++ b/winch/codegen/src/isa/aarch64/address.rs @@ -1,12 +1,14 @@ //! Aarch64 addressing mode. use super::regs; -use crate::reg::Reg; -use crate::{Context as _, Result, format_err}; -use cranelift_codegen::VCodeConstant; -use cranelift_codegen::{ - ir::types, - isa::aarch64::inst::{AMode, PairAMode, SImm7Scaled, SImm9}, +use crate::Result; +use crate::{ + masm::{IntScratch, MacroAssembler as Masm, OperandSize, RegImm}, + reg::Reg, +}; +use cranelift_codegen::ir::{Type, types}; +use cranelift_codegen::isa::aarch64::inst::{ + AMode, ExtendOp, PairAMode, SImm7Scaled, SImm9, UImm12Scaled, }; /// Aarch64 indexing mode. @@ -21,47 +23,63 @@ pub(crate) enum Indexing { /// Memory address representation. #[derive(Debug, Copy, Clone)] pub(crate) enum Address { - /// Base register with an arbitrary offset. Potentially gets - /// lowered into multiple instructions during code emission - /// depending on the offset. + /// Base register with an arbitrary offset. Offset { /// Base register. base: Reg, /// Offset. offset: i64, }, - /// Specialized indexed register and offset variant using - /// the stack pointer. - IndexedSPOffset { - /// Offset. - offset: i64, - /// Indexing mode. + /// SP-indexed addressing mode for single register loads/stores. + SPIndexedSingle { + /// 9-bit signed offset. + offset: SImm9, + /// Indexing mode (pre or post). + indexing: Indexing, + }, + /// SP-indexed addressing mode for register pair loads/stores. + SPIndexedPair { + /// 7-bit signed scaled offset. + offset: SImm7Scaled, + /// Indexing mode (pre or post). indexing: Indexing, }, - /// Address of a constant in the constant pool. - Const(VCodeConstant), } impl Address { - /// Create a pre-indexed addressing mode from the stack pointer. - pub fn pre_indexed_from_sp(offset: i64) -> Self { - Self::IndexedSPOffset { + /// Create a pre-indexed addressing mode from the stack pointer for single register operations. + pub fn pre_indexed_from_sp(offset: SImm9) -> Self { + Self::SPIndexedSingle { offset, indexing: Indexing::Pre, } } - /// Create a post-indexed addressing mode from the stack pointer. - pub fn post_indexed_from_sp(offset: i64) -> Self { - Self::IndexedSPOffset { + /// Create a post-indexed addressing mode from the stack pointer for single register operations. + pub fn post_indexed_from_sp(offset: SImm9) -> Self { + Self::SPIndexedSingle { offset, indexing: Indexing::Post, } } - /// Create an offset addressing mode with - /// the shadow stack pointer register - /// as a base. + /// Create a pre-indexed addressing mode from the stack pointer for register pair operations. + pub fn pre_indexed_from_sp_for_pair(offset: SImm7Scaled) -> Self { + Self::SPIndexedPair { + offset, + indexing: Indexing::Pre, + } + } + + /// Create a post-indexed addressing mode from the stack pointer for register pair operations. + pub fn post_indexed_from_sp_for_pair(offset: SImm7Scaled) -> Self { + Self::SPIndexedPair { + offset, + indexing: Indexing::Post, + } + } + + /// Create an offset addressing mode with the shadow stack pointer register as a base. pub fn from_shadow_sp(offset: i64) -> Self { Self::Offset { base: regs::shadow_sp(), @@ -75,8 +93,7 @@ impl Address { // sp generally should not be used as a base register in an // address. In the cases where its usage is required and where // we are sure that it's 16-byte aligned, the address should - // be constructed via the `Self::pre_indexed_sp` and - // Self::post_indexed_sp functions. + // be constructed via the SP-indexed constructors. // For more details around the stack pointer and shadow stack // pointer see the docs at regs::shadow_sp(). assert!( @@ -86,77 +103,104 @@ impl Address { Self::Offset { base, offset } } - /// Create an address for a constant. - pub fn constant(data: VCodeConstant) -> Self { - Self::Const(data) - } - - /// Returns the register base and immediate offset of the given [`Address`]. - /// + /// Converts self to cranelift's [`PairAMode`]. /// # Panics - /// This function panics if the [`Address`] is not [`Address::Offset`]. - pub fn unwrap_offset(&self) -> (Reg, i64) { + /// This function panics if self cannot be converted to [`PairAMode`]. + /// NB: that all uses of this function currently guarantee that + /// the offset will fit in a 7-bit signed offset. + pub fn to_pair_addressing_mode(self) -> PairAMode { match self { - Self::Offset { base, offset } => (*base, *offset), - _ => panic!("Expected register and offset addressing mode"), - } - } -} - -// Conversions between `winch-codegen`'s addressing mode representation -// and `cranelift-codegen`s addressing mode representation for aarch64. - -impl TryFrom
for PairAMode { - type Error = crate::Error; - - fn try_from(addr: Address) -> Result { - use Address::*; - use Indexing::*; - - match addr { - IndexedSPOffset { offset, indexing } => { - let simm7 = SImm7Scaled::maybe_from_i64(offset, types::I64).with_context(|| { - format!("Failed to convert {offset} to signed scaled 7 bit offset") - })?; - - if indexing == Pre { - Ok(PairAMode::SPPreIndexed { simm7 }) + Self::SPIndexedPair { offset, indexing } => { + if indexing == Indexing::Pre { + PairAMode::SPPreIndexed { simm7: offset } } else { - Ok(PairAMode::SPPostIndexed { simm7 }) + PairAMode::SPPostIndexed { simm7: offset } } } - other => Err(format_err!( - "Could not convert {other:?} to addressing mode for register pairs" - )), + _ => panic!("Could not convert addressing mode to PairAMode"), } } -} -impl TryFrom
for AMode { - type Error = crate::Error; - - fn try_from(addr: Address) -> Result { + /// Converts self to cranelift's [`AMode`]. + /// The closure parameter ensures that the caller scope is kept in + /// sync with the scratch register used for materializing the + /// general register and offset addressing mode. + /// # Panics + /// This function panics if self cannot be converted to [`AMode`]. + pub fn to_addressing_mode( + self, + masm: &mut M, + size: OperandSize, + f: impl FnOnce(&mut M, AMode) -> Result<()>, + ) -> Result<()> { use Address::*; use Indexing::*; - match addr { - IndexedSPOffset { offset, indexing } => { - let simm9 = SImm9::maybe_from_i64(offset).ok_or_else(|| { - // TODO: non-string error - format_err!("Failed to convert {offset} to signed 9-bit offset") - })?; + match self { + SPIndexedSingle { offset, indexing } => { + let amode = if indexing == Pre { + AMode::SPPreIndexed { simm9: offset } + } else { + AMode::SPPostIndexed { simm9: offset } + }; - if indexing == Pre { - Ok(AMode::SPPreIndexed { simm9 }) + f(masm, amode) + } + Offset { base, offset } => { + if let Some(simm9) = SImm9::maybe_from_i64(offset) { + f( + masm, + AMode::Unscaled { + rn: base.into(), + simm9, + }, + ) + } else if let Some(uimm12) = + UImm12Scaled::maybe_from_i64(offset, map_to_scale_type(size)) + { + f( + masm, + AMode::UnsignedOffset { + rn: base.into(), + uimm12, + }, + ) } else { - Ok(AMode::SPPostIndexed { simm9 }) + masm.with_scratch::(|masm, temp| { + masm.mov(temp.writable(), RegImm::i64(offset), OperandSize::S64)?; + f( + masm, + AMode::RegExtended { + rn: base.into(), + rm: temp.inner().into(), + extendop: ExtendOp::SXTX, + }, + ) + }) } } - Offset { base, offset } => Ok(AMode::RegOffset { - rn: base.into(), - off: offset, - }), - Const(data) => Ok(AMode::Const { addr: data }), + _ => panic!("Could not convert addressing mode to AMode"), + } + } + + /// Returns the register base and immediate offset of the given [`Address`]. + /// + /// # Panics + /// This function panics if the [`Address`] is not [`Address::Offset`]. + pub fn unwrap_offset(&self) -> (Reg, i64) { + match self { + Self::Offset { base, offset } => (*base, *offset), + _ => panic!("Expected register and offset addressing mode"), } } } + +fn map_to_scale_type(size: OperandSize) -> Type { + match size { + OperandSize::S8 => types::I8, + OperandSize::S16 => types::I16, + OperandSize::S32 => types::I32, + OperandSize::S64 => types::I64, + OperandSize::S128 => types::I8X16, + } +} diff --git a/winch/codegen/src/isa/aarch64/asm.rs b/winch/codegen/src/isa/aarch64/asm.rs index 548e0b824736..cc6694a1c612 100644 --- a/winch/codegen/src/isa/aarch64/asm.rs +++ b/winch/codegen/src/isa/aarch64/asm.rs @@ -1,5 +1,5 @@ //! Assembler library implementation for Aarch64. -use super::{address::Address, regs}; +use super::regs; use crate::CallingConvention; use crate::aarch64::regs::zero; use crate::masm::{ @@ -12,7 +12,6 @@ use crate::{ reg::{Reg, WritableReg, writable}, }; -use cranelift_codegen::PatchRegion; use cranelift_codegen::isa::aarch64::inst::emit::{enc_arith_rrr, enc_move_wide, enc_movk}; use cranelift_codegen::isa::aarch64::inst::{ ASIMDFPModImm, FpuToIntOp, MoveWideConst, NZCV, UImm5, @@ -31,6 +30,7 @@ use cranelift_codegen::{ }, settings, }; +use cranelift_codegen::{PatchRegion, VCodeConstant}; use regalloc2::RegClass; use wasmtime_core::math::{f32_cvt_to_int_bounds, f64_cvt_to_int_bounds}; @@ -151,14 +151,13 @@ impl Assembler { } /// Adds a constant to the constant pool, returning its address. - pub fn add_constant(&mut self, constant: &[u8]) -> Address { + pub fn add_constant(&mut self, constant: &[u8]) -> VCodeConstant { let handle = self.pool.register(constant, &mut self.buffer); - Address::constant(handle) + handle } /// Store a pair of registers. - pub fn stp(&mut self, xt1: Reg, xt2: Reg, addr: Address) { - let mem: PairAMode = addr.try_into().unwrap(); + pub fn stp(&mut self, xt1: Reg, xt2: Reg, mem: PairAMode) { self.emit(Inst::StoreP64 { rt: xt1.into(), rt2: xt2.into(), @@ -168,9 +167,7 @@ impl Assembler { } /// Store a register. - pub fn str(&mut self, reg: Reg, addr: Address, size: OperandSize, flags: MemFlags) { - let mem: AMode = addr.try_into().unwrap(); - + pub fn str(&mut self, reg: Reg, mem: AMode, size: OperandSize, flags: MemFlags) { use OperandSize::*; let inst = match (reg.is_int(), size) { (_, S8) => Inst::Store8 { @@ -214,19 +211,19 @@ impl Assembler { } /// Load a signed register. - pub fn sload(&mut self, addr: Address, rd: WritableReg, size: OperandSize, flags: MemFlags) { - self.ldr(addr, rd, size, true, flags); + pub fn sload(&mut self, mem: AMode, rd: WritableReg, size: OperandSize, flags: MemFlags) { + self.ldr(mem, rd, size, true, flags); } /// Load an unsigned register. - pub fn uload(&mut self, addr: Address, rd: WritableReg, size: OperandSize, flags: MemFlags) { - self.ldr(addr, rd, size, false, flags); + pub fn uload(&mut self, mem: AMode, rd: WritableReg, size: OperandSize, flags: MemFlags) { + self.ldr(mem, rd, size, false, flags); } /// Load address into a register. fn ldr( &mut self, - addr: Address, + mem: AMode, rd: WritableReg, size: OperandSize, signed: bool, @@ -234,7 +231,6 @@ impl Assembler { ) { use OperandSize::*; let writable_reg = rd.map(Into::into); - let mem: AMode = addr.try_into().unwrap(); let inst = match (rd.to_reg().is_int(), signed, size) { (_, false, S8) => Inst::ULoad8 { @@ -293,10 +289,9 @@ impl Assembler { } /// Load a pair of registers. - pub fn ldp(&mut self, xt1: Reg, xt2: Reg, addr: Address) { + pub fn ldp(&mut self, xt1: Reg, xt2: Reg, mem: PairAMode) { let writable_xt1 = Writable::from_reg(xt1.into()); let writable_xt2 = Writable::from_reg(xt2.into()); - let mem = addr.try_into().unwrap(); self.emit(Inst::LoadP64 { rt: writable_xt1, @@ -326,7 +321,8 @@ impl Assembler { }); } _ => { - let addr = self.add_constant(&imm.to_bytes()); + let constant = self.add_constant(&imm.to_bytes()); + let addr = AMode::Const { addr: constant }; self.uload(addr, rd, size, TRUSTED_FLAGS); } } diff --git a/winch/codegen/src/isa/aarch64/masm.rs b/winch/codegen/src/isa/aarch64/masm.rs index ef72fa490c17..73da847bd2b4 100644 --- a/winch/codegen/src/isa/aarch64/masm.rs +++ b/winch/codegen/src/isa/aarch64/masm.rs @@ -30,8 +30,8 @@ use crate::{ use cranelift_codegen::{ Final, MachBufferFinalized, MachLabel, binemit::CodeOffset, - ir::{MemFlags, RelSourceLoc, SourceLoc}, - isa::aarch64::inst::{self, Cond, Imm12, ImmLogic, ImmShift, VectorSize}, + ir::{MemFlags, RelSourceLoc, SourceLoc, types}, + isa::aarch64::inst::{self, Cond, Imm12, ImmLogic, ImmShift, SImm7Scaled, SImm9, VectorSize}, settings, }; use regalloc2::RegClass; @@ -137,13 +137,20 @@ impl Masm for MacroAssembler { let fp = regs::fp(); let sp = regs::sp(); - let addr = Address::pre_indexed_from_sp(-16); - self.asm.stp(fp, lr, addr); + let offset = SImm7Scaled::maybe_from_i64(-16, types::I64) + .expect("Frame pointer offset of -16 is valid for pair addressing"); + let addr = Address::pre_indexed_from_sp_for_pair(offset); + self.asm.stp(fp, lr, addr.to_pair_addressing_mode()); self.asm.mov_rr(sp, writable!(fp), OperandSize::S64); - let addr = Address::pre_indexed_from_sp(-(SHADOW_STACK_POINTER_SLOT_SIZE as i64)); - self.asm - .str(regs::shadow_sp(), addr, OperandSize::S64, TRUSTED_FLAGS); + let offset = SImm9::maybe_from_i64(-(SHADOW_STACK_POINTER_SLOT_SIZE as i64)) + .expect("Shadow stack pointer slot size is valid for single addressing"); + let addr = Address::pre_indexed_from_sp(offset); + addr.to_addressing_mode(self, OperandSize::S64, |masm, mem| { + masm.asm + .str(regs::shadow_sp(), mem, OperandSize::S64, TRUSTED_FLAGS); + Ok(()) + })?; self.move_sp_to_shadow_sp(); Ok(()) @@ -207,20 +214,27 @@ impl Masm for MacroAssembler { // Pop the shadow stack pointer. It's assumed that at this point // `sp_offset` is 0 and therefore the real stack pointer should be // 16-byte aligned. - let addr = Address::post_indexed_from_sp(SHADOW_STACK_POINTER_SLOT_SIZE as i64); - self.asm.uload( - addr, - writable!(regs::shadow_sp()), - OperandSize::S64, - TRUSTED_FLAGS, - ); + let offset = SImm9::maybe_from_i64(SHADOW_STACK_POINTER_SLOT_SIZE as i64) + .expect("Shadow stack pointer slot size is valid for single addressing"); + let addr = Address::post_indexed_from_sp(offset); + addr.to_addressing_mode(self, OperandSize::S64, |masm, mem| { + masm.asm.uload( + mem, + writable!(regs::shadow_sp()), + OperandSize::S64, + TRUSTED_FLAGS, + ); + Ok(()) + })?; // Restore the link register and frame pointer. let lr = regs::lr(); let fp = regs::fp(); - let addr = Address::post_indexed_from_sp(16); + let offset = SImm7Scaled::maybe_from_i64(16, types::I64) + .expect("Frame pointer offset 16 is valid for pair addressing"); + let addr = Address::post_indexed_from_sp_for_pair(offset); - self.asm.ldp(fp, lr, addr); + self.asm.ldp(fp, lr, addr.to_pair_addressing_mode()); self.asm.ret(); Ok(()) } @@ -330,34 +344,40 @@ impl Masm for MacroAssembler { RegImm::Imm(v) => { match v { I::I32(_) | I::I64(_) => { - self.with_scratch::(|masm, scratch| { + self.with_scratch::(|masm, scratch| -> Result<()> { masm.asm.mov_ir(scratch.writable(), v, v.size()); - masm.asm.str(scratch.inner(), dst, size, TRUSTED_FLAGS); - }); + dst.to_addressing_mode(masm, size, |masm, mem| { + masm.asm.str(scratch.inner(), mem, size, TRUSTED_FLAGS); + Ok(()) + }) + })?; } imm @ (I::F32(_) | I::F64(_)) => { - self.with_scratch::(|masm, scratch| { + self.with_scratch::(|masm, scratch| -> Result<()> { masm.asm.mov_ir(scratch.writable(), imm, imm.size()); - masm.asm.str(scratch.inner(), dst, size, TRUSTED_FLAGS); - }); + dst.to_addressing_mode(masm, size, |masm, mem| { + masm.asm.str(scratch.inner(), mem, size, TRUSTED_FLAGS); + Ok(()) + }) + })?; } _ => bail!(CodeGenError::unsupported_wasm_type()), }; Ok(()) } - RegImm::Reg(r) => { - self.asm.str(r, dst, size, TRUSTED_FLAGS); + RegImm::Reg(r) => dst.to_addressing_mode(self, size, |masm, mem| { + masm.asm.str(r, mem, size, TRUSTED_FLAGS); Ok(()) - } + }), } } fn wasm_store(&mut self, src: Reg, dst: Self::Address, op_kind: StoreKind) -> Result<()> { self.with_aligned_sp(|masm| match op_kind { - StoreKind::Operand(size) => { - masm.asm.str(src, dst, size, UNTRUSTED_FLAGS); + StoreKind::Operand(size) => dst.to_addressing_mode(masm, size, |masm, mem| { + masm.asm.str(src, mem, size, UNTRUSTED_FLAGS); Ok(()) - } + }), StoreKind::Atomic(_size) => { Err(format_err!(CodeGenError::unimplemented_masm_instruction())) } @@ -400,8 +420,9 @@ impl Masm for MacroAssembler { } fn load(&mut self, src: Address, dst: WritableReg, size: OperandSize) -> Result<()> { - self.asm.uload(src, dst, size, TRUSTED_FLAGS); - Ok(()) + src.to_addressing_mode(self, size, |masm, mem| { + Ok(masm.asm.uload(mem, dst, size, TRUSTED_FLAGS)) + }) } fn load_ptr(&mut self, src: Self::Address, dst: WritableReg) -> Result<()> { @@ -415,19 +436,25 @@ impl Masm for MacroAssembler { if size == OperandSize::S128 { bail!(CodeGenError::UnimplementedWasmLoadKind) } else { - Ok(masm.asm.uload(src, dst, size, UNTRUSTED_FLAGS)) + src.to_addressing_mode(masm, size, |masm, mem| { + Ok(masm.asm.uload(mem, dst, size, UNTRUSTED_FLAGS)) + }) } } LoadKind::Splat(_) => bail!(CodeGenError::UnimplementedWasmLoadKind), LoadKind::ScalarExtend(extend_kind) => { if extend_kind.signed() { - masm.asm.sload(src, dst, size, UNTRUSTED_FLAGS); + src.to_addressing_mode(masm, size, |masm, mem| { + masm.asm.sload(mem, dst, size, UNTRUSTED_FLAGS); + Ok(()) + }) } else { - // unlike x64, unused bits are set to zero so we don't need to extend - masm.asm.uload(src, dst, size, UNTRUSTED_FLAGS); + src.to_addressing_mode(masm, size, |masm, mem| { + // unlike x64, unused bits are set to zero so we don't need to extend + masm.asm.uload(mem, dst, size, UNTRUSTED_FLAGS); + Ok(()) + }) } - - Ok(()) } LoadKind::VectorExtend(_vector_extend_kind) => { bail!(CodeGenError::UnimplementedWasmLoadKind) @@ -454,7 +481,10 @@ impl Masm for MacroAssembler { fn pop(&mut self, dst: WritableReg, size: OperandSize) -> Result<()> { let addr = self.address_from_sp(SPOffset::from_u32(self.sp_offset))?; - self.asm.uload(addr, dst, size, TRUSTED_FLAGS); + addr.to_addressing_mode(self, size, |masm, mem| { + masm.asm.uload(mem, dst, size, TRUSTED_FLAGS); + Ok(()) + })?; self.free_stack(size.bytes()) } @@ -971,7 +1001,10 @@ impl Masm for MacroAssembler { fn push(&mut self, reg: Reg, size: OperandSize) -> Result { self.reserve_stack(size.bytes())?; let address = self.address_from_sp(SPOffset::from_u32(self.sp_offset))?; - self.asm.str(reg, address, size, TRUSTED_FLAGS); + address.to_addressing_mode(self, size, |masm, mem| { + masm.asm.str(reg, mem, size, TRUSTED_FLAGS); + Ok(()) + })?; Ok(StackSlot { offset: SPOffset::from_u32(self.sp_offset),