From cb755f29fb5a4de76a704a6293bf9fe997fecc90 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 12 Dec 2024 09:56:06 -0800 Subject: [PATCH 1/3] pulley: Move `fp`/`lr` out of `XReg` set This commit moves the `fp` and `lr` registers out of the `XReg` register set and into the `MachineState` per-VM. These are automatically modified and read with `push_frame` and `pop_frame`. Dedicated `xmov_{fp,lr}` instructions were added for use in Wasmtime's trampolines which directly read these registers. --- .../codegen/src/isa/pulley_shared/abi.rs | 47 +++-------- .../codegen/src/isa/pulley_shared/inst.isle | 6 -- .../src/isa/pulley_shared/inst/regs.rs | 6 +- .../codegen/src/isa/pulley_shared/lower.isle | 6 +- .../src/isa/pulley_shared/lower/isle.rs | 8 -- .../filetests/isa/pulley32/call.clif | 80 +++++++++---------- .../filetests/isa/pulley32/special_regs.clif | 10 +-- .../filetests/isa/pulley64/call.clif | 80 +++++++++---------- .../filetests/isa/pulley64/special_regs.clif | 10 +-- crates/wasmtime/src/runtime/vm/interpreter.rs | 18 +++-- pulley/src/interp.rs | 69 ++++++++++++---- pulley/src/lib.rs | 6 ++ pulley/src/regs.rs | 13 +-- tests/disas/pulley/epoch-simple.wat | 2 +- 14 files changed, 179 insertions(+), 182 deletions(-) diff --git a/cranelift/codegen/src/isa/pulley_shared/abi.rs b/cranelift/codegen/src/isa/pulley_shared/abi.rs index d8e68c43ef76..5304cd9de1a2 100644 --- a/cranelift/codegen/src/isa/pulley_shared/abi.rs +++ b/cranelift/codegen/src/isa/pulley_shared/abi.rs @@ -344,45 +344,24 @@ where let incoming_args_diff = frame_layout.tail_args_size - frame_layout.incoming_args_size; if incoming_args_diff > 0 { + // Pulley does not generate/probestack/stack checks/etc and doesn't + // expose the direct ability to modify fp/lr, so simulate a pop, + // perform the sp adjustment, then perform the same push that was + // done previously in the prologue. + // + // Note that for now this'll generate `push_frame pop_frame` pairs + // in the prologue which isn't great, and updating that is left for + // a future refactoring to only do a `push_frame` once (e.g. skip + // the one above if this block is going to be executed) + if setup_frame { + insts.push(RawInst::PopFrame.into()); + } // Decrement SP by the amount of additional incoming argument space // we need insts.extend(Self::gen_sp_reg_adjust(-(incoming_args_diff as i32))); if setup_frame { - // Write the lr position on the stack again, as it hasn't - // changed since it was pushed in `gen_prologue_frame_setup` - insts.push( - Inst::gen_store( - Amode::SpOffset { offset: 8 }, - lr_reg(), - I64, - MemFlags::trusted(), - ) - .into(), - ); - insts.push( - Inst::gen_load( - writable_fp_reg(), - Amode::SpOffset { - offset: i32::try_from(incoming_args_diff).unwrap(), - }, - I64, - MemFlags::trusted(), - ) - .into(), - ); - insts.push( - Inst::gen_store( - Amode::SpOffset { offset: 0 }, - fp_reg(), - I64, - MemFlags::trusted(), - ) - .into(), - ); - - // Finally, sync the frame pointer with SP. - insts.push(Self::I::gen_move(writable_fp_reg(), stack_reg(), I64)); + insts.push(RawInst::PushFrame.into()); } } diff --git a/cranelift/codegen/src/isa/pulley_shared/inst.isle b/cranelift/codegen/src/isa/pulley_shared/inst.isle index d9470260e2d6..015b547fb96f 100644 --- a/cranelift/codegen/src/isa/pulley_shared/inst.isle +++ b/cranelift/codegen/src/isa/pulley_shared/inst.isle @@ -380,12 +380,6 @@ (decl sp_reg () XReg) (extern constructor sp_reg sp_reg) -(decl fp_reg () XReg) -(extern constructor fp_reg fp_reg) - -(decl lr_reg () XReg) -(extern constructor lr_reg lr_reg) - (decl pulley_get_special (XReg) XReg) (rule (pulley_get_special reg) (let ((dst WritableXReg (temp_writable_xreg)) diff --git a/cranelift/codegen/src/isa/pulley_shared/inst/regs.rs b/cranelift/codegen/src/isa/pulley_shared/inst/regs.rs index f274db871142..f99559a977c9 100644 --- a/cranelift/codegen/src/isa/pulley_shared/inst/regs.rs +++ b/cranelift/codegen/src/isa/pulley_shared/inst/regs.rs @@ -89,10 +89,10 @@ define_registers! { x_reg(24) => x24, writable_x24; x_reg(25) => x25, writable_x25; x_reg(26) => x26, writable_x26; + x_reg(27) => x27, writable_x27; + x_reg(28) => x28, writable_x28; - x_reg(27) => stack_reg, writable_stack_reg; - x_reg(28) => lr_reg, writable_lr_reg; - x_reg(29) => fp_reg, writable_fp_reg; + x_reg(29) => stack_reg, writable_stack_reg; x_reg(30) => spilltmp_reg, writable_spilltmp_reg; x_reg(31) => spilltmp2_reg, writable_spilltmp2_reg; diff --git a/cranelift/codegen/src/isa/pulley_shared/lower.isle b/cranelift/codegen/src/isa/pulley_shared/lower.isle index 157ba189f328..8c5dc9a63269 100644 --- a/cranelift/codegen/src/isa/pulley_shared/lower.isle +++ b/cranelift/codegen/src/isa/pulley_shared/lower.isle @@ -86,13 +86,11 @@ ;;;; Rules for `get_frame_pointer` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(rule (lower (get_frame_pointer)) - (pulley_get_special (fp_reg))) +(rule (lower (get_frame_pointer)) (pulley_xmov_fp)) ;;;; Rules for `get_return_address` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(rule (lower (get_return_address)) - (pulley_get_special (lr_reg))) +(rule (lower (get_return_address)) (pulley_xmov_lr)) ;;;; Rules for `return` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/cranelift/codegen/src/isa/pulley_shared/lower/isle.rs b/cranelift/codegen/src/isa/pulley_shared/lower/isle.rs index d5107b9950da..25f831b3d8d4 100644 --- a/cranelift/codegen/src/isa/pulley_shared/lower/isle.rs +++ b/cranelift/codegen/src/isa/pulley_shared/lower/isle.rs @@ -107,14 +107,6 @@ where XReg::new(regs::stack_reg()).unwrap() } - fn fp_reg(&mut self) -> XReg { - XReg::new(regs::fp_reg()).unwrap() - } - - fn lr_reg(&mut self) -> XReg { - XReg::new(regs::lr_reg()).unwrap() - } - fn cond_invert(&mut self, cond: &Cond) -> Cond { cond.invert() } diff --git a/cranelift/filetests/filetests/isa/pulley32/call.clif b/cranelift/filetests/filetests/isa/pulley32/call.clif index 449043f0bdab..2ee71a199aa2 100644 --- a/cranelift/filetests/filetests/isa/pulley32/call.clif +++ b/cranelift/filetests/filetests/isa/pulley32/call.clif @@ -231,34 +231,34 @@ block0: ; xstore64 sp+104, x18 // flags = notrap aligned ; xstore64 sp+96, x19 // flags = notrap aligned ; xstore64 sp+88, x20 // flags = notrap aligned -; xstore64 sp+80, x21 // flags = notrap aligned -; xstore64 sp+72, x23 // flags = notrap aligned -; xstore64 sp+64, x24 // flags = notrap aligned -; xstore64 sp+56, x25 // flags = notrap aligned +; xstore64 sp+80, x23 // flags = notrap aligned +; xstore64 sp+72, x24 // flags = notrap aligned +; xstore64 sp+64, x25 // flags = notrap aligned +; xstore64 sp+56, x26 // flags = notrap aligned ; block0: ; x0 = load_addr OutgoingArg(0) ; call CallInfo { dest: TestCase(%g), uses: [CallArgPair { vreg: p0i, preg: p0i }], defs: [CallRetPair { vreg: Writable { reg: p0i }, preg: p0i }, CallRetPair { vreg: Writable { reg: p1i }, preg: p1i }, CallRetPair { vreg: Writable { reg: p2i }, preg: p2i }, CallRetPair { vreg: Writable { reg: p3i }, preg: p3i }, CallRetPair { vreg: Writable { reg: p4i }, preg: p4i }, CallRetPair { vreg: Writable { reg: p5i }, preg: p5i }, CallRetPair { vreg: Writable { reg: p6i }, preg: p6i }, CallRetPair { vreg: Writable { reg: p7i }, preg: p7i }, CallRetPair { vreg: Writable { reg: p8i }, preg: p8i }, CallRetPair { vreg: Writable { reg: p9i }, preg: p9i }, CallRetPair { vreg: Writable { reg: p10i }, preg: p10i }, CallRetPair { vreg: Writable { reg: p11i }, preg: p11i }, CallRetPair { vreg: Writable { reg: p12i }, preg: p12i }, CallRetPair { vreg: Writable { reg: p13i }, preg: p13i }, CallRetPair { vreg: Writable { reg: p14i }, preg: p14i }, CallRetPair { vreg: Writable { reg: p15i }, preg: p15i }], clobbers: PRegSet { bits: [0, 65279, 4294967295, 0] }, callee_conv: Fast, caller_conv: Fast, callee_pop_size: 0 } -; xmov x18, x13 -; xmov x20, x11 -; x24 = xload64 OutgoingArg(0) // flags = notrap aligned +; xmov x23, x13 +; xmov x25, x11 +; x18 = xload64 OutgoingArg(0) // flags = notrap aligned ; x11 = xload64 OutgoingArg(8) // flags = notrap aligned ; x13 = xload64 OutgoingArg(16) // flags = notrap aligned -; x19 = xload64 OutgoingArg(24) // flags = notrap aligned -; x21 = xload64 OutgoingArg(32) // flags = notrap aligned -; xadd64 x25, x0, x1 -; xadd64 x23, x2, x3 +; x24 = xload64 OutgoingArg(24) // flags = notrap aligned +; x26 = xload64 OutgoingArg(32) // flags = notrap aligned +; xadd64 x20, x0, x1 +; xadd64 x19, x2, x3 ; xadd64 x5, x4, x5 ; xadd64 x6, x6, x7 ; xadd64 x7, x8, x9 -; xmov x0, x20 +; xmov x0, x25 ; xadd64 x4, x10, x0 -; xmov x10, x18 +; xmov x10, x23 ; xadd64 x8, x12, x10 ; xadd64 x14, x14, x15 -; xadd64 x15, x24, x11 +; xadd64 x15, x18, x11 ; xadd64 x13, x11, x13 -; xadd64 x0, x19, x21 -; xadd64 x1, x25, x23 +; xadd64 x0, x24, x26 +; xadd64 x1, x20, x19 ; xadd64 x2, x5, x6 ; xadd64 x3, x7, x4 ; xadd64 x14, x8, x14 @@ -273,10 +273,10 @@ block0: ; x18 = xload64 sp+104 // flags = notrap aligned ; x19 = xload64 sp+96 // flags = notrap aligned ; x20 = xload64 sp+88 // flags = notrap aligned -; x21 = xload64 sp+80 // flags = notrap aligned -; x23 = xload64 sp+72 // flags = notrap aligned -; x24 = xload64 sp+64 // flags = notrap aligned -; x25 = xload64 sp+56 // flags = notrap aligned +; x23 = xload64 sp+80 // flags = notrap aligned +; x24 = xload64 sp+72 // flags = notrap aligned +; x25 = xload64 sp+64 // flags = notrap aligned +; x26 = xload64 sp+56 // flags = notrap aligned ; stack_free32 112 ; pop_frame ; ret @@ -287,33 +287,33 @@ block0: ; xstore64le_offset32 sp, 104, x18 ; xstore64le_offset32 sp, 96, x19 ; xstore64le_offset32 sp, 88, x20 -; xstore64le_offset32 sp, 80, x21 -; xstore64le_offset32 sp, 72, x23 -; xstore64le_offset32 sp, 64, x24 -; xstore64le_offset32 sp, 56, x25 +; xstore64le_offset32 sp, 80, x23 +; xstore64le_offset32 sp, 72, x24 +; xstore64le_offset32 sp, 64, x25 +; xstore64le_offset32 sp, 56, x26 ; xmov x0, sp ; call 0x0 // target = 0x3a -; xmov x18, x13 -; xmov x20, x11 -; xload64le_offset32 x24, sp, 0 +; xmov x23, x13 +; xmov x25, x11 +; xload64le_offset32 x18, sp, 0 ; xload64le_offset32 x11, sp, 8 ; xload64le_offset32 x13, sp, 16 -; xload64le_offset32 x19, sp, 24 -; xload64le_offset32 x21, sp, 32 -; xadd64 x25, x0, x1 -; xadd64 x23, x2, x3 +; xload64le_offset32 x24, sp, 24 +; xload64le_offset32 x26, sp, 32 +; xadd64 x20, x0, x1 +; xadd64 x19, x2, x3 ; xadd64 x5, x4, x5 ; xadd64 x6, x6, x7 ; xadd64 x7, x8, x9 -; xmov x0, x20 +; xmov x0, x25 ; xadd64 x4, x10, x0 -; xmov x10, x18 +; xmov x10, x23 ; xadd64 x8, x12, x10 ; xadd64 x14, x14, x15 -; xadd64 x15, x24, x11 +; xadd64 x15, x18, x11 ; xadd64 x13, x11, x13 -; xadd64 x0, x19, x21 -; xadd64 x1, x25, x23 +; xadd64 x0, x24, x26 +; xadd64 x1, x20, x19 ; xadd64 x2, x5, x6 ; xadd64 x3, x7, x4 ; xadd64 x14, x8, x14 @@ -328,10 +328,10 @@ block0: ; xload64le_offset32 x18, sp, 104 ; xload64le_offset32 x19, sp, 96 ; xload64le_offset32 x20, sp, 88 -; xload64le_offset32 x21, sp, 80 -; xload64le_offset32 x23, sp, 72 -; xload64le_offset32 x24, sp, 64 -; xload64le_offset32 x25, sp, 56 +; xload64le_offset32 x23, sp, 80 +; xload64le_offset32 x24, sp, 72 +; xload64le_offset32 x25, sp, 64 +; xload64le_offset32 x26, sp, 56 ; stack_free32 112 ; pop_frame ; ret diff --git a/cranelift/filetests/filetests/isa/pulley32/special_regs.clif b/cranelift/filetests/filetests/isa/pulley32/special_regs.clif index bdad9d89b973..21326ce5ff3c 100644 --- a/cranelift/filetests/filetests/isa/pulley32/special_regs.clif +++ b/cranelift/filetests/filetests/isa/pulley32/special_regs.clif @@ -11,7 +11,7 @@ block0: ; VCode: ; push_frame ; block0: -; xmov x0, x27 +; xmov x0, x29 ; pop_frame ; ret ; @@ -30,13 +30,13 @@ block0: ; VCode: ; push_frame ; block0: -; xmov x0, x29 +; xmov_fp x0 ; pop_frame ; ret ; ; Disassembled: ; push_frame -; xmov x0, fp +; xmov_fp x0 ; pop_frame ; ret @@ -49,13 +49,13 @@ block0: ; VCode: ; push_frame ; block0: -; xmov x0, x28 +; xmov_lr x0 ; pop_frame ; ret ; ; Disassembled: ; push_frame -; xmov x0, lr +; xmov_lr x0 ; pop_frame ; ret diff --git a/cranelift/filetests/filetests/isa/pulley64/call.clif b/cranelift/filetests/filetests/isa/pulley64/call.clif index 67b401aa3b5f..d35537d9a324 100644 --- a/cranelift/filetests/filetests/isa/pulley64/call.clif +++ b/cranelift/filetests/filetests/isa/pulley64/call.clif @@ -231,34 +231,34 @@ block0: ; xstore64 sp+104, x18 // flags = notrap aligned ; xstore64 sp+96, x19 // flags = notrap aligned ; xstore64 sp+88, x20 // flags = notrap aligned -; xstore64 sp+80, x21 // flags = notrap aligned -; xstore64 sp+72, x23 // flags = notrap aligned -; xstore64 sp+64, x24 // flags = notrap aligned -; xstore64 sp+56, x25 // flags = notrap aligned +; xstore64 sp+80, x23 // flags = notrap aligned +; xstore64 sp+72, x24 // flags = notrap aligned +; xstore64 sp+64, x25 // flags = notrap aligned +; xstore64 sp+56, x26 // flags = notrap aligned ; block0: ; x0 = load_addr OutgoingArg(0) ; call CallInfo { dest: TestCase(%g), uses: [CallArgPair { vreg: p0i, preg: p0i }], defs: [CallRetPair { vreg: Writable { reg: p0i }, preg: p0i }, CallRetPair { vreg: Writable { reg: p1i }, preg: p1i }, CallRetPair { vreg: Writable { reg: p2i }, preg: p2i }, CallRetPair { vreg: Writable { reg: p3i }, preg: p3i }, CallRetPair { vreg: Writable { reg: p4i }, preg: p4i }, CallRetPair { vreg: Writable { reg: p5i }, preg: p5i }, CallRetPair { vreg: Writable { reg: p6i }, preg: p6i }, CallRetPair { vreg: Writable { reg: p7i }, preg: p7i }, CallRetPair { vreg: Writable { reg: p8i }, preg: p8i }, CallRetPair { vreg: Writable { reg: p9i }, preg: p9i }, CallRetPair { vreg: Writable { reg: p10i }, preg: p10i }, CallRetPair { vreg: Writable { reg: p11i }, preg: p11i }, CallRetPair { vreg: Writable { reg: p12i }, preg: p12i }, CallRetPair { vreg: Writable { reg: p13i }, preg: p13i }, CallRetPair { vreg: Writable { reg: p14i }, preg: p14i }, CallRetPair { vreg: Writable { reg: p15i }, preg: p15i }], clobbers: PRegSet { bits: [0, 65279, 4294967295, 0] }, callee_conv: Fast, caller_conv: Fast, callee_pop_size: 0 } -; xmov x18, x13 -; xmov x20, x11 -; x24 = xload64 OutgoingArg(0) // flags = notrap aligned +; xmov x23, x13 +; xmov x25, x11 +; x18 = xload64 OutgoingArg(0) // flags = notrap aligned ; x11 = xload64 OutgoingArg(8) // flags = notrap aligned ; x13 = xload64 OutgoingArg(16) // flags = notrap aligned -; x19 = xload64 OutgoingArg(24) // flags = notrap aligned -; x21 = xload64 OutgoingArg(32) // flags = notrap aligned -; xadd64 x25, x0, x1 -; xadd64 x23, x2, x3 +; x24 = xload64 OutgoingArg(24) // flags = notrap aligned +; x26 = xload64 OutgoingArg(32) // flags = notrap aligned +; xadd64 x20, x0, x1 +; xadd64 x19, x2, x3 ; xadd64 x5, x4, x5 ; xadd64 x6, x6, x7 ; xadd64 x7, x8, x9 -; xmov x0, x20 +; xmov x0, x25 ; xadd64 x4, x10, x0 -; xmov x10, x18 +; xmov x10, x23 ; xadd64 x8, x12, x10 ; xadd64 x14, x14, x15 -; xadd64 x15, x24, x11 +; xadd64 x15, x18, x11 ; xadd64 x13, x11, x13 -; xadd64 x0, x19, x21 -; xadd64 x1, x25, x23 +; xadd64 x0, x24, x26 +; xadd64 x1, x20, x19 ; xadd64 x2, x5, x6 ; xadd64 x3, x7, x4 ; xadd64 x14, x8, x14 @@ -273,10 +273,10 @@ block0: ; x18 = xload64 sp+104 // flags = notrap aligned ; x19 = xload64 sp+96 // flags = notrap aligned ; x20 = xload64 sp+88 // flags = notrap aligned -; x21 = xload64 sp+80 // flags = notrap aligned -; x23 = xload64 sp+72 // flags = notrap aligned -; x24 = xload64 sp+64 // flags = notrap aligned -; x25 = xload64 sp+56 // flags = notrap aligned +; x23 = xload64 sp+80 // flags = notrap aligned +; x24 = xload64 sp+72 // flags = notrap aligned +; x25 = xload64 sp+64 // flags = notrap aligned +; x26 = xload64 sp+56 // flags = notrap aligned ; stack_free32 112 ; pop_frame ; ret @@ -287,33 +287,33 @@ block0: ; xstore64le_offset32 sp, 104, x18 ; xstore64le_offset32 sp, 96, x19 ; xstore64le_offset32 sp, 88, x20 -; xstore64le_offset32 sp, 80, x21 -; xstore64le_offset32 sp, 72, x23 -; xstore64le_offset32 sp, 64, x24 -; xstore64le_offset32 sp, 56, x25 +; xstore64le_offset32 sp, 80, x23 +; xstore64le_offset32 sp, 72, x24 +; xstore64le_offset32 sp, 64, x25 +; xstore64le_offset32 sp, 56, x26 ; xmov x0, sp ; call 0x0 // target = 0x3a -; xmov x18, x13 -; xmov x20, x11 -; xload64le_offset32 x24, sp, 0 +; xmov x23, x13 +; xmov x25, x11 +; xload64le_offset32 x18, sp, 0 ; xload64le_offset32 x11, sp, 8 ; xload64le_offset32 x13, sp, 16 -; xload64le_offset32 x19, sp, 24 -; xload64le_offset32 x21, sp, 32 -; xadd64 x25, x0, x1 -; xadd64 x23, x2, x3 +; xload64le_offset32 x24, sp, 24 +; xload64le_offset32 x26, sp, 32 +; xadd64 x20, x0, x1 +; xadd64 x19, x2, x3 ; xadd64 x5, x4, x5 ; xadd64 x6, x6, x7 ; xadd64 x7, x8, x9 -; xmov x0, x20 +; xmov x0, x25 ; xadd64 x4, x10, x0 -; xmov x10, x18 +; xmov x10, x23 ; xadd64 x8, x12, x10 ; xadd64 x14, x14, x15 -; xadd64 x15, x24, x11 +; xadd64 x15, x18, x11 ; xadd64 x13, x11, x13 -; xadd64 x0, x19, x21 -; xadd64 x1, x25, x23 +; xadd64 x0, x24, x26 +; xadd64 x1, x20, x19 ; xadd64 x2, x5, x6 ; xadd64 x3, x7, x4 ; xadd64 x14, x8, x14 @@ -328,10 +328,10 @@ block0: ; xload64le_offset32 x18, sp, 104 ; xload64le_offset32 x19, sp, 96 ; xload64le_offset32 x20, sp, 88 -; xload64le_offset32 x21, sp, 80 -; xload64le_offset32 x23, sp, 72 -; xload64le_offset32 x24, sp, 64 -; xload64le_offset32 x25, sp, 56 +; xload64le_offset32 x23, sp, 80 +; xload64le_offset32 x24, sp, 72 +; xload64le_offset32 x25, sp, 64 +; xload64le_offset32 x26, sp, 56 ; stack_free32 112 ; pop_frame ; ret diff --git a/cranelift/filetests/filetests/isa/pulley64/special_regs.clif b/cranelift/filetests/filetests/isa/pulley64/special_regs.clif index 448a806b6500..8b90c1b4349c 100644 --- a/cranelift/filetests/filetests/isa/pulley64/special_regs.clif +++ b/cranelift/filetests/filetests/isa/pulley64/special_regs.clif @@ -11,7 +11,7 @@ block0: ; VCode: ; push_frame ; block0: -; xmov x0, x27 +; xmov x0, x29 ; pop_frame ; ret ; @@ -30,13 +30,13 @@ block0: ; VCode: ; push_frame ; block0: -; xmov x0, x29 +; xmov_fp x0 ; pop_frame ; ret ; ; Disassembled: ; push_frame -; xmov x0, fp +; xmov_fp x0 ; pop_frame ; ret @@ -49,13 +49,13 @@ block0: ; VCode: ; push_frame ; block0: -; xmov x0, x28 +; xmov_lr x0 ; pop_frame ; ret ; ; Disassembled: ; push_frame -; xmov x0, lr +; xmov_lr x0 ; pop_frame ; ret diff --git a/crates/wasmtime/src/runtime/vm/interpreter.rs b/crates/wasmtime/src/runtime/vm/interpreter.rs index a0ec7a8e196a..9836d0450742 100644 --- a/crates/wasmtime/src/runtime/vm/interpreter.rs +++ b/crates/wasmtime/src/runtime/vm/interpreter.rs @@ -73,8 +73,8 @@ impl InterpreterRef<'_> { // correct as it's not saving all callee-save state. let setjmp = Setjmp { sp: self.0[XReg::sp].get_ptr(), - fp: self.0[XReg::fp].get_ptr(), - lr: self.0[XReg::lr].get_ptr(), + fp: self.0.fp(), + lr: self.0.lr(), }; // Run the interpreter as much as possible until it finishes, and then @@ -117,8 +117,8 @@ impl InterpreterRef<'_> { }; debug_assert!(self.0[XReg::sp].get_ptr() == setjmp.sp); - debug_assert!(self.0[XReg::fp].get_ptr() == setjmp.fp); - debug_assert!(self.0[XReg::lr].get_ptr() == setjmp.lr); + debug_assert!(self.0.fp() == setjmp.fp); + debug_assert!(self.0.lr() == setjmp.lr); ret } @@ -128,7 +128,7 @@ impl InterpreterRef<'_> { fn trap(&mut self, pc: NonNull, kind: Option, setjmp: Setjmp) { let regs = TrapRegisters { pc: pc.as_ptr() as usize, - fp: self.0[XReg::fp].get_ptr::() as usize, + fp: self.0.fp() as usize, }; tls::with(|s| { let s = s.unwrap(); @@ -179,9 +179,11 @@ impl InterpreterRef<'_> { /// them. fn longjmp(&mut self, setjmp: Setjmp) { let Setjmp { sp, fp, lr } = setjmp; - self.0[XReg::sp].set_ptr(sp); - self.0[XReg::fp].set_ptr(fp); - self.0[XReg::lr].set_ptr(lr); + unsafe { + self.0[XReg::sp].set_ptr(sp); + self.0.set_fp(fp); + self.0.set_lr(lr); + } } /// Handles the `call_indirect_host` instruction, dispatching the `sig` diff --git a/pulley/src/interp.rs b/pulley/src/interp.rs index 9ddff068e30c..72d427b439e0 100644 --- a/pulley/src/interp.rs +++ b/pulley/src/interp.rs @@ -180,6 +180,26 @@ impl Vm { }, }) } + + /// Returns the current `fp` register value. + pub fn fp(&self) -> *mut u8 { + self.state.fp + } + + /// Returns the current `lr` register value. + pub fn lr(&self) -> *mut u8 { + self.state.lr + } + + /// Sets the current `fp` register value. + pub unsafe fn set_fp(&mut self, fp: *mut u8) { + self.state.fp = fp; + } + + /// Sets the current `lr` register value. + pub unsafe fn set_lr(&mut self, lr: *mut u8) { + self.state.lr = lr; + } } /// The type of a register in the Pulley machine state. @@ -364,9 +384,6 @@ impl Default for XRegVal { #[allow(missing_docs)] impl XRegVal { - /// Sentinel return address that signals the end of the call stack. - pub const HOST_RETURN_ADDR: Self = Self(XRegUnion { i64: -1 }); - pub fn new_i32(x: i32) -> Self { let mut val = XRegVal::default(); val.set_i32(x); @@ -564,6 +581,8 @@ pub struct MachineState { x_regs: [XRegVal; XReg::RANGE.end as usize], f_regs: [FRegVal; FReg::RANGE.end as usize], v_regs: [VRegVal; VReg::RANGE.end as usize], + fp: *mut u8, + lr: *mut u8, stack: Vec, done_reason: Option>, } @@ -579,6 +598,8 @@ impl fmt::Debug for MachineState { v_regs, stack: _, done_reason: _, + fp: _, + lr: _, } = self; struct RegMap<'a, R>(&'a [R], fn(u8) -> alloc::string::String); @@ -646,6 +667,9 @@ index_reg!(XReg, XRegVal, x_regs); index_reg!(FReg, FRegVal, f_regs); index_reg!(VReg, VRegVal, v_regs); +/// Sentinel return address that signals the end of the call stack. +const HOST_RETURN_ADDR: *mut u8 = usize::MAX as *mut u8; + impl MachineState { fn with_stack(stack: Vec) -> Self { assert!(stack.len() > 0); @@ -655,6 +679,8 @@ impl MachineState { v_regs: Default::default(), stack, done_reason: None, + fp: HOST_RETURN_ADDR, + lr: HOST_RETURN_ADDR, }; // Take care to construct SP such that we preserve pointer provenance @@ -664,8 +690,6 @@ impl MachineState { let sp = sp.as_mut_ptr(); let sp = unsafe { sp.add(len) }; state[XReg::sp] = XRegVal::new_ptr(sp); - state[XReg::fp] = XRegVal::HOST_RETURN_ADDR; - state[XReg::lr] = XRegVal::HOST_RETURN_ADDR; state } @@ -904,26 +928,25 @@ impl OpVisitor for Interpreter<'_> { } fn ret(&mut self) -> ControlFlow { - let lr = self.state[XReg::lr]; - if lr == XRegVal::HOST_RETURN_ADDR { + let lr = self.state.lr; + if lr == HOST_RETURN_ADDR { self.done_return_to_host() } else { - let return_addr = lr.get_ptr(); - self.pc = unsafe { UnsafeBytecodeStream::new(NonNull::new_unchecked(return_addr)) }; + self.pc = unsafe { UnsafeBytecodeStream::new(NonNull::new_unchecked(lr)) }; ControlFlow::Continue(()) } } fn call(&mut self, offset: PcRelOffset) -> ControlFlow { let return_addr = self.pc.as_ptr(); - self.state[XReg::lr].set_ptr(return_addr.as_ptr()); + self.state.lr = return_addr.as_ptr(); self.pc_rel_jump::(offset); ControlFlow::Continue(()) } fn call_indirect(&mut self, dst: XReg) -> ControlFlow { let return_addr = self.pc.as_ptr(); - self.state[XReg::lr].set_ptr(return_addr.as_ptr()); + self.state.lr = return_addr.as_ptr(); // SAFETY: part of the unsafe contract of the interpreter is only valid // bytecode is interpreted, so the jump destination is part of the validity // of the bytecode itself. @@ -1505,18 +1528,18 @@ impl OpVisitor for Interpreter<'_> { } fn push_frame(&mut self) -> ControlFlow { - self.push::(self.state[XReg::lr].get_ptr::())?; - self.push::(self.state[XReg::fp].get_ptr::())?; - self.state[XReg::fp] = self.state[XReg::sp]; + self.push::(self.state.lr)?; + self.push::(self.state.fp)?; + self.state.fp = self.state[XReg::sp].get_ptr(); ControlFlow::Continue(()) } fn pop_frame(&mut self) -> ControlFlow { - self.set_sp_unchecked(self.state[XReg::fp].get_ptr::()); + self.set_sp_unchecked(self.state.fp); let fp = self.pop(); let lr = self.pop(); - self.state[XReg::fp].set_ptr::(fp); - self.state[XReg::lr].set_ptr::(lr); + self.state.fp = fp; + self.state.lr = lr; ControlFlow::Continue(()) } @@ -2244,4 +2267,16 @@ impl ExtendedOpVisitor for Interpreter<'_> { } ControlFlow::Continue(()) } + + fn xmov_fp(&mut self, dst: XReg) -> ControlFlow { + let fp = self.state.fp; + self.state[dst].set_ptr(fp); + ControlFlow::Continue(()) + } + + fn xmov_lr(&mut self, dst: XReg) -> ControlFlow { + let lr = self.state.lr; + self.state[dst].set_ptr(lr); + ControlFlow::Continue(()) + } } diff --git a/pulley/src/lib.rs b/pulley/src/lib.rs index 2781c793f3ed..8e038cd31380 100644 --- a/pulley/src/lib.rs +++ b/pulley/src/lib.rs @@ -512,6 +512,12 @@ macro_rules! for_each_extended_op { /// assembled into the final object that Wasmtime will interpret. call_indirect_host = CallIndirectHost { id: u8 }; + /// Gets the special "fp" register and moves it into `dst`. + xmov_fp = XmovFp { dst: XReg }; + + /// Gets the special "lr" register and moves it into `dst`. + xmov_lr = XmovLr { dst: XReg }; + /// `dst = byteswap(low32(src))` bswap32 = Bswap32 { dst: XReg, src: XReg }; /// `dst = byteswap(src)` diff --git a/pulley/src/regs.rs b/pulley/src/regs.rs index b094239745d2..bc38cbfd5949 100644 --- a/pulley/src/regs.rs +++ b/pulley/src/regs.rs @@ -69,17 +69,11 @@ macro_rules! impl_reg { pub enum XReg { x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, - x20, x21, x22, x23, x24, x25, x26, + x20, x21, x22, x23, x24, x25, x26, x27, x28, /// The special `sp` stack pointer register. sp, - /// The special `lr` link register. - lr, - - /// The special `fp` frame pointer register. - fp, - /// The special `spilltmp0` scratch register. spilltmp0, @@ -93,10 +87,7 @@ impl XReg { /// Is this `x` register a special register? pub fn is_special(self) -> bool { - matches!( - self, - Self::sp | Self::lr | Self::fp | Self::spilltmp0 | Self::spilltmp1 - ) + matches!(self, Self::sp | Self::spilltmp0 | Self::spilltmp1) } } diff --git a/tests/disas/pulley/epoch-simple.wat b/tests/disas/pulley/epoch-simple.wat index 7cf6a2e0afeb..8a138229344c 100644 --- a/tests/disas/pulley/epoch-simple.wat +++ b/tests/disas/pulley/epoch-simple.wat @@ -14,5 +14,5 @@ ;; br_if_xulteq64 x6, x7, 0x9 // target = 0x26 ;; 24: pop_frame ;; ret -;; 26: call 0xbd // target = 0xe3 +;; 26: call 0xbf // target = 0xe5 ;; 2b: jump 0xfffffffffffffff9 // target = 0x24 From f3541f7f0aada6f8e5001a85a7aedde153a0913d Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 12 Dec 2024 10:01:41 -0800 Subject: [PATCH 2/3] Fix pulley tests --- pulley/src/regs.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/pulley/src/regs.rs b/pulley/src/regs.rs index bc38cbfd5949..e73add4165ca 100644 --- a/pulley/src/regs.rs +++ b/pulley/src/regs.rs @@ -301,8 +301,6 @@ mod tests { #[test] fn special_x_regs() { assert!(XReg::sp.is_special()); - assert!(XReg::lr.is_special()); - assert!(XReg::fp.is_special()); assert!(XReg::spilltmp0.is_special()); assert!(XReg::spilltmp1.is_special()); } From a820174ff7c4f2c54790797d134d7c5bce4ac0fc Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 13 Dec 2024 08:53:57 -0800 Subject: [PATCH 3/3] Free up `spilltmp1` register Also unused in CLIF --- .../src/isa/pulley_shared/inst/regs.rs | 6 +- .../filetests/isa/pulley32/call.clif | 96 +++++++++---------- .../filetests/isa/pulley32/special_regs.clif | 2 +- .../filetests/isa/pulley64/call.clif | 96 +++++++++---------- .../filetests/isa/pulley64/special_regs.clif | 2 +- pulley/src/regs.rs | 7 +- 6 files changed, 103 insertions(+), 106 deletions(-) diff --git a/cranelift/codegen/src/isa/pulley_shared/inst/regs.rs b/cranelift/codegen/src/isa/pulley_shared/inst/regs.rs index f99559a977c9..434abecaebcf 100644 --- a/cranelift/codegen/src/isa/pulley_shared/inst/regs.rs +++ b/cranelift/codegen/src/isa/pulley_shared/inst/regs.rs @@ -91,10 +91,10 @@ define_registers! { x_reg(26) => x26, writable_x26; x_reg(27) => x27, writable_x27; x_reg(28) => x28, writable_x28; + x_reg(29) => x29, writable_x29; - x_reg(29) => stack_reg, writable_stack_reg; - x_reg(30) => spilltmp_reg, writable_spilltmp_reg; - x_reg(31) => spilltmp2_reg, writable_spilltmp2_reg; + x_reg(30) => stack_reg, writable_stack_reg; + x_reg(31) => spilltmp_reg, writable_spilltmp_reg; f_reg(0) => f0, writable_f0; f_reg(1) => f1, writable_f1; diff --git a/cranelift/filetests/filetests/isa/pulley32/call.clif b/cranelift/filetests/filetests/isa/pulley32/call.clif index 2ee71a199aa2..e7aa59e63fe2 100644 --- a/cranelift/filetests/filetests/isa/pulley32/call.clif +++ b/cranelift/filetests/filetests/isa/pulley32/call.clif @@ -228,37 +228,37 @@ block0: ; VCode: ; push_frame ; stack_alloc32 112 -; xstore64 sp+104, x18 // flags = notrap aligned -; xstore64 sp+96, x19 // flags = notrap aligned +; xstore64 sp+104, x17 // flags = notrap aligned +; xstore64 sp+96, x18 // flags = notrap aligned ; xstore64 sp+88, x20 // flags = notrap aligned -; xstore64 sp+80, x23 // flags = notrap aligned -; xstore64 sp+72, x24 // flags = notrap aligned -; xstore64 sp+64, x25 // flags = notrap aligned -; xstore64 sp+56, x26 // flags = notrap aligned +; xstore64 sp+80, x21 // flags = notrap aligned +; xstore64 sp+72, x22 // flags = notrap aligned +; xstore64 sp+64, x23 // flags = notrap aligned +; xstore64 sp+56, x29 // flags = notrap aligned ; block0: ; x0 = load_addr OutgoingArg(0) ; call CallInfo { dest: TestCase(%g), uses: [CallArgPair { vreg: p0i, preg: p0i }], defs: [CallRetPair { vreg: Writable { reg: p0i }, preg: p0i }, CallRetPair { vreg: Writable { reg: p1i }, preg: p1i }, CallRetPair { vreg: Writable { reg: p2i }, preg: p2i }, CallRetPair { vreg: Writable { reg: p3i }, preg: p3i }, CallRetPair { vreg: Writable { reg: p4i }, preg: p4i }, CallRetPair { vreg: Writable { reg: p5i }, preg: p5i }, CallRetPair { vreg: Writable { reg: p6i }, preg: p6i }, CallRetPair { vreg: Writable { reg: p7i }, preg: p7i }, CallRetPair { vreg: Writable { reg: p8i }, preg: p8i }, CallRetPair { vreg: Writable { reg: p9i }, preg: p9i }, CallRetPair { vreg: Writable { reg: p10i }, preg: p10i }, CallRetPair { vreg: Writable { reg: p11i }, preg: p11i }, CallRetPair { vreg: Writable { reg: p12i }, preg: p12i }, CallRetPair { vreg: Writable { reg: p13i }, preg: p13i }, CallRetPair { vreg: Writable { reg: p14i }, preg: p14i }, CallRetPair { vreg: Writable { reg: p15i }, preg: p15i }], clobbers: PRegSet { bits: [0, 65279, 4294967295, 0] }, callee_conv: Fast, caller_conv: Fast, callee_pop_size: 0 } -; xmov x23, x13 -; xmov x25, x11 -; x18 = xload64 OutgoingArg(0) // flags = notrap aligned +; xmov x20, x13 +; xmov x22, x11 +; x29 = xload64 OutgoingArg(0) // flags = notrap aligned ; x11 = xload64 OutgoingArg(8) // flags = notrap aligned ; x13 = xload64 OutgoingArg(16) // flags = notrap aligned -; x24 = xload64 OutgoingArg(24) // flags = notrap aligned -; x26 = xload64 OutgoingArg(32) // flags = notrap aligned -; xadd64 x20, x0, x1 -; xadd64 x19, x2, x3 +; x21 = xload64 OutgoingArg(24) // flags = notrap aligned +; x23 = xload64 OutgoingArg(32) // flags = notrap aligned +; xadd64 x18, x0, x1 +; xadd64 x17, x2, x3 ; xadd64 x5, x4, x5 ; xadd64 x6, x6, x7 ; xadd64 x7, x8, x9 -; xmov x0, x25 +; xmov x0, x22 ; xadd64 x4, x10, x0 -; xmov x10, x23 +; xmov x10, x20 ; xadd64 x8, x12, x10 ; xadd64 x14, x14, x15 -; xadd64 x15, x18, x11 +; xadd64 x15, x29, x11 ; xadd64 x13, x11, x13 -; xadd64 x0, x24, x26 -; xadd64 x1, x20, x19 +; xadd64 x0, x21, x23 +; xadd64 x1, x18, x17 ; xadd64 x2, x5, x6 ; xadd64 x3, x7, x4 ; xadd64 x14, x8, x14 @@ -270,13 +270,13 @@ block0: ; xadd64 x14, x0, x14 ; xadd64 x13, x13, x13 ; xadd64 x0, x14, x13 -; x18 = xload64 sp+104 // flags = notrap aligned -; x19 = xload64 sp+96 // flags = notrap aligned +; x17 = xload64 sp+104 // flags = notrap aligned +; x18 = xload64 sp+96 // flags = notrap aligned ; x20 = xload64 sp+88 // flags = notrap aligned -; x23 = xload64 sp+80 // flags = notrap aligned -; x24 = xload64 sp+72 // flags = notrap aligned -; x25 = xload64 sp+64 // flags = notrap aligned -; x26 = xload64 sp+56 // flags = notrap aligned +; x21 = xload64 sp+80 // flags = notrap aligned +; x22 = xload64 sp+72 // flags = notrap aligned +; x23 = xload64 sp+64 // flags = notrap aligned +; x29 = xload64 sp+56 // flags = notrap aligned ; stack_free32 112 ; pop_frame ; ret @@ -284,36 +284,36 @@ block0: ; Disassembled: ; push_frame ; stack_alloc32 112 -; xstore64le_offset32 sp, 104, x18 -; xstore64le_offset32 sp, 96, x19 +; xstore64le_offset32 sp, 104, x17 +; xstore64le_offset32 sp, 96, x18 ; xstore64le_offset32 sp, 88, x20 -; xstore64le_offset32 sp, 80, x23 -; xstore64le_offset32 sp, 72, x24 -; xstore64le_offset32 sp, 64, x25 -; xstore64le_offset32 sp, 56, x26 +; xstore64le_offset32 sp, 80, x21 +; xstore64le_offset32 sp, 72, x22 +; xstore64le_offset32 sp, 64, x23 +; xstore64le_offset32 sp, 56, x29 ; xmov x0, sp ; call 0x0 // target = 0x3a -; xmov x23, x13 -; xmov x25, x11 -; xload64le_offset32 x18, sp, 0 +; xmov x20, x13 +; xmov x22, x11 +; xload64le_offset32 x29, sp, 0 ; xload64le_offset32 x11, sp, 8 ; xload64le_offset32 x13, sp, 16 -; xload64le_offset32 x24, sp, 24 -; xload64le_offset32 x26, sp, 32 -; xadd64 x20, x0, x1 -; xadd64 x19, x2, x3 +; xload64le_offset32 x21, sp, 24 +; xload64le_offset32 x23, sp, 32 +; xadd64 x18, x0, x1 +; xadd64 x17, x2, x3 ; xadd64 x5, x4, x5 ; xadd64 x6, x6, x7 ; xadd64 x7, x8, x9 -; xmov x0, x25 +; xmov x0, x22 ; xadd64 x4, x10, x0 -; xmov x10, x23 +; xmov x10, x20 ; xadd64 x8, x12, x10 ; xadd64 x14, x14, x15 -; xadd64 x15, x18, x11 +; xadd64 x15, x29, x11 ; xadd64 x13, x11, x13 -; xadd64 x0, x24, x26 -; xadd64 x1, x20, x19 +; xadd64 x0, x21, x23 +; xadd64 x1, x18, x17 ; xadd64 x2, x5, x6 ; xadd64 x3, x7, x4 ; xadd64 x14, x8, x14 @@ -325,13 +325,13 @@ block0: ; xadd64 x14, x0, x14 ; xadd64 x13, x13, x13 ; xadd64 x0, x14, x13 -; xload64le_offset32 x18, sp, 104 -; xload64le_offset32 x19, sp, 96 +; xload64le_offset32 x17, sp, 104 +; xload64le_offset32 x18, sp, 96 ; xload64le_offset32 x20, sp, 88 -; xload64le_offset32 x23, sp, 80 -; xload64le_offset32 x24, sp, 72 -; xload64le_offset32 x25, sp, 64 -; xload64le_offset32 x26, sp, 56 +; xload64le_offset32 x21, sp, 80 +; xload64le_offset32 x22, sp, 72 +; xload64le_offset32 x23, sp, 64 +; xload64le_offset32 x29, sp, 56 ; stack_free32 112 ; pop_frame ; ret diff --git a/cranelift/filetests/filetests/isa/pulley32/special_regs.clif b/cranelift/filetests/filetests/isa/pulley32/special_regs.clif index 21326ce5ff3c..05d619ad4190 100644 --- a/cranelift/filetests/filetests/isa/pulley32/special_regs.clif +++ b/cranelift/filetests/filetests/isa/pulley32/special_regs.clif @@ -11,7 +11,7 @@ block0: ; VCode: ; push_frame ; block0: -; xmov x0, x29 +; xmov x0, x30 ; pop_frame ; ret ; diff --git a/cranelift/filetests/filetests/isa/pulley64/call.clif b/cranelift/filetests/filetests/isa/pulley64/call.clif index d35537d9a324..1ab2f1adcc52 100644 --- a/cranelift/filetests/filetests/isa/pulley64/call.clif +++ b/cranelift/filetests/filetests/isa/pulley64/call.clif @@ -228,37 +228,37 @@ block0: ; VCode: ; push_frame ; stack_alloc32 112 -; xstore64 sp+104, x18 // flags = notrap aligned -; xstore64 sp+96, x19 // flags = notrap aligned +; xstore64 sp+104, x17 // flags = notrap aligned +; xstore64 sp+96, x18 // flags = notrap aligned ; xstore64 sp+88, x20 // flags = notrap aligned -; xstore64 sp+80, x23 // flags = notrap aligned -; xstore64 sp+72, x24 // flags = notrap aligned -; xstore64 sp+64, x25 // flags = notrap aligned -; xstore64 sp+56, x26 // flags = notrap aligned +; xstore64 sp+80, x21 // flags = notrap aligned +; xstore64 sp+72, x22 // flags = notrap aligned +; xstore64 sp+64, x23 // flags = notrap aligned +; xstore64 sp+56, x29 // flags = notrap aligned ; block0: ; x0 = load_addr OutgoingArg(0) ; call CallInfo { dest: TestCase(%g), uses: [CallArgPair { vreg: p0i, preg: p0i }], defs: [CallRetPair { vreg: Writable { reg: p0i }, preg: p0i }, CallRetPair { vreg: Writable { reg: p1i }, preg: p1i }, CallRetPair { vreg: Writable { reg: p2i }, preg: p2i }, CallRetPair { vreg: Writable { reg: p3i }, preg: p3i }, CallRetPair { vreg: Writable { reg: p4i }, preg: p4i }, CallRetPair { vreg: Writable { reg: p5i }, preg: p5i }, CallRetPair { vreg: Writable { reg: p6i }, preg: p6i }, CallRetPair { vreg: Writable { reg: p7i }, preg: p7i }, CallRetPair { vreg: Writable { reg: p8i }, preg: p8i }, CallRetPair { vreg: Writable { reg: p9i }, preg: p9i }, CallRetPair { vreg: Writable { reg: p10i }, preg: p10i }, CallRetPair { vreg: Writable { reg: p11i }, preg: p11i }, CallRetPair { vreg: Writable { reg: p12i }, preg: p12i }, CallRetPair { vreg: Writable { reg: p13i }, preg: p13i }, CallRetPair { vreg: Writable { reg: p14i }, preg: p14i }, CallRetPair { vreg: Writable { reg: p15i }, preg: p15i }], clobbers: PRegSet { bits: [0, 65279, 4294967295, 0] }, callee_conv: Fast, caller_conv: Fast, callee_pop_size: 0 } -; xmov x23, x13 -; xmov x25, x11 -; x18 = xload64 OutgoingArg(0) // flags = notrap aligned +; xmov x20, x13 +; xmov x22, x11 +; x29 = xload64 OutgoingArg(0) // flags = notrap aligned ; x11 = xload64 OutgoingArg(8) // flags = notrap aligned ; x13 = xload64 OutgoingArg(16) // flags = notrap aligned -; x24 = xload64 OutgoingArg(24) // flags = notrap aligned -; x26 = xload64 OutgoingArg(32) // flags = notrap aligned -; xadd64 x20, x0, x1 -; xadd64 x19, x2, x3 +; x21 = xload64 OutgoingArg(24) // flags = notrap aligned +; x23 = xload64 OutgoingArg(32) // flags = notrap aligned +; xadd64 x18, x0, x1 +; xadd64 x17, x2, x3 ; xadd64 x5, x4, x5 ; xadd64 x6, x6, x7 ; xadd64 x7, x8, x9 -; xmov x0, x25 +; xmov x0, x22 ; xadd64 x4, x10, x0 -; xmov x10, x23 +; xmov x10, x20 ; xadd64 x8, x12, x10 ; xadd64 x14, x14, x15 -; xadd64 x15, x18, x11 +; xadd64 x15, x29, x11 ; xadd64 x13, x11, x13 -; xadd64 x0, x24, x26 -; xadd64 x1, x20, x19 +; xadd64 x0, x21, x23 +; xadd64 x1, x18, x17 ; xadd64 x2, x5, x6 ; xadd64 x3, x7, x4 ; xadd64 x14, x8, x14 @@ -270,13 +270,13 @@ block0: ; xadd64 x14, x0, x14 ; xadd64 x13, x13, x13 ; xadd64 x0, x14, x13 -; x18 = xload64 sp+104 // flags = notrap aligned -; x19 = xload64 sp+96 // flags = notrap aligned +; x17 = xload64 sp+104 // flags = notrap aligned +; x18 = xload64 sp+96 // flags = notrap aligned ; x20 = xload64 sp+88 // flags = notrap aligned -; x23 = xload64 sp+80 // flags = notrap aligned -; x24 = xload64 sp+72 // flags = notrap aligned -; x25 = xload64 sp+64 // flags = notrap aligned -; x26 = xload64 sp+56 // flags = notrap aligned +; x21 = xload64 sp+80 // flags = notrap aligned +; x22 = xload64 sp+72 // flags = notrap aligned +; x23 = xload64 sp+64 // flags = notrap aligned +; x29 = xload64 sp+56 // flags = notrap aligned ; stack_free32 112 ; pop_frame ; ret @@ -284,36 +284,36 @@ block0: ; Disassembled: ; push_frame ; stack_alloc32 112 -; xstore64le_offset32 sp, 104, x18 -; xstore64le_offset32 sp, 96, x19 +; xstore64le_offset32 sp, 104, x17 +; xstore64le_offset32 sp, 96, x18 ; xstore64le_offset32 sp, 88, x20 -; xstore64le_offset32 sp, 80, x23 -; xstore64le_offset32 sp, 72, x24 -; xstore64le_offset32 sp, 64, x25 -; xstore64le_offset32 sp, 56, x26 +; xstore64le_offset32 sp, 80, x21 +; xstore64le_offset32 sp, 72, x22 +; xstore64le_offset32 sp, 64, x23 +; xstore64le_offset32 sp, 56, x29 ; xmov x0, sp ; call 0x0 // target = 0x3a -; xmov x23, x13 -; xmov x25, x11 -; xload64le_offset32 x18, sp, 0 +; xmov x20, x13 +; xmov x22, x11 +; xload64le_offset32 x29, sp, 0 ; xload64le_offset32 x11, sp, 8 ; xload64le_offset32 x13, sp, 16 -; xload64le_offset32 x24, sp, 24 -; xload64le_offset32 x26, sp, 32 -; xadd64 x20, x0, x1 -; xadd64 x19, x2, x3 +; xload64le_offset32 x21, sp, 24 +; xload64le_offset32 x23, sp, 32 +; xadd64 x18, x0, x1 +; xadd64 x17, x2, x3 ; xadd64 x5, x4, x5 ; xadd64 x6, x6, x7 ; xadd64 x7, x8, x9 -; xmov x0, x25 +; xmov x0, x22 ; xadd64 x4, x10, x0 -; xmov x10, x23 +; xmov x10, x20 ; xadd64 x8, x12, x10 ; xadd64 x14, x14, x15 -; xadd64 x15, x18, x11 +; xadd64 x15, x29, x11 ; xadd64 x13, x11, x13 -; xadd64 x0, x24, x26 -; xadd64 x1, x20, x19 +; xadd64 x0, x21, x23 +; xadd64 x1, x18, x17 ; xadd64 x2, x5, x6 ; xadd64 x3, x7, x4 ; xadd64 x14, x8, x14 @@ -325,13 +325,13 @@ block0: ; xadd64 x14, x0, x14 ; xadd64 x13, x13, x13 ; xadd64 x0, x14, x13 -; xload64le_offset32 x18, sp, 104 -; xload64le_offset32 x19, sp, 96 +; xload64le_offset32 x17, sp, 104 +; xload64le_offset32 x18, sp, 96 ; xload64le_offset32 x20, sp, 88 -; xload64le_offset32 x23, sp, 80 -; xload64le_offset32 x24, sp, 72 -; xload64le_offset32 x25, sp, 64 -; xload64le_offset32 x26, sp, 56 +; xload64le_offset32 x21, sp, 80 +; xload64le_offset32 x22, sp, 72 +; xload64le_offset32 x23, sp, 64 +; xload64le_offset32 x29, sp, 56 ; stack_free32 112 ; pop_frame ; ret diff --git a/cranelift/filetests/filetests/isa/pulley64/special_regs.clif b/cranelift/filetests/filetests/isa/pulley64/special_regs.clif index 8b90c1b4349c..941e2d27ab29 100644 --- a/cranelift/filetests/filetests/isa/pulley64/special_regs.clif +++ b/cranelift/filetests/filetests/isa/pulley64/special_regs.clif @@ -11,7 +11,7 @@ block0: ; VCode: ; push_frame ; block0: -; xmov x0, x29 +; xmov x0, x30 ; pop_frame ; ret ; diff --git a/pulley/src/regs.rs b/pulley/src/regs.rs index e73add4165ca..deaa08deb19f 100644 --- a/pulley/src/regs.rs +++ b/pulley/src/regs.rs @@ -69,7 +69,7 @@ macro_rules! impl_reg { pub enum XReg { x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, - x20, x21, x22, x23, x24, x25, x26, x27, x28, + x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, /// The special `sp` stack pointer register. sp, @@ -77,8 +77,6 @@ pub enum XReg { /// The special `spilltmp0` scratch register. spilltmp0, - /// The special `spilltmp1` scratch register. - spilltmp1, } impl XReg { @@ -87,7 +85,7 @@ impl XReg { /// Is this `x` register a special register? pub fn is_special(self) -> bool { - matches!(self, Self::sp | Self::spilltmp0 | Self::spilltmp1) + matches!(self, Self::sp | Self::spilltmp0) } } @@ -302,7 +300,6 @@ mod tests { fn special_x_regs() { assert!(XReg::sp.is_special()); assert!(XReg::spilltmp0.is_special()); - assert!(XReg::spilltmp1.is_special()); } #[test]