Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pulley: Implement get_frame_pointer #9658

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions cranelift/codegen/src/isa/pulley_shared/inst.isle
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@
;; Nothing.
(Nop)

;; Get the stack pointer.
(GetSp (dst WritableXReg))
;; Move a special register (e.g. sp, fp, lr, etc) in to a general-purpose
;; register
(GetSpecial
(dst WritableXReg)
(reg XReg))

;; Return.
(Ret)
Expand Down Expand Up @@ -371,11 +374,17 @@
(rule (pulley_trap_if cond size src1 src2 code)
(SideEffectNoResult.Inst (MInst.TrapIf cond size src1 src2 code)))

(decl pulley_get_sp () XReg)
(rule (pulley_get_sp)
(let ((reg WritableXReg (temp_writable_xreg))
(_ Unit (emit (MInst.GetSp reg))))
reg))
(decl sp_reg () XReg)
(extern constructor sp_reg sp_reg)

(decl fp_reg () XReg)
(extern constructor fp_reg fp_reg)

(decl pulley_get_special (XReg) XReg)
(rule (pulley_get_special reg)
(let ((dst WritableXReg (temp_writable_xreg))
(_ Unit (emit (MInst.GetSpecial dst reg))))
dst))

(decl pulley_xconst8 (i8) XReg)
(rule (pulley_xconst8 x)
Expand Down
2 changes: 1 addition & 1 deletion cranelift/codegen/src/isa/pulley_shared/inst/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ fn pulley_emit<P>(

Inst::Nop => todo!(),

Inst::GetSp { dst } => enc::get_sp(sink, dst),
Inst::GetSpecial { dst, reg } => enc::xmov(sink, dst, reg),

Inst::Ret => enc::ret(sink),

Expand Down
11 changes: 8 additions & 3 deletions cranelift/codegen/src/isa/pulley_shared/inst/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,12 @@ fn pulley_get_operands(inst: &mut Inst, collector: &mut impl OperandVisitor) {
collector.reg_use(src2);
}

Inst::GetSp { dst } => {
Inst::GetSpecial { dst, reg } => {
collector.reg_def(dst);
// Note that this is explicitly ignored as this is only used for
// special register that don't participate in register allocation
// such as the stack pointer, frame pointer, etc.
let _ = reg;
}

Inst::LoadExtName {
Expand Down Expand Up @@ -563,9 +567,10 @@ impl Inst {

Inst::Ret => format!("ret"),

Inst::GetSp { dst } => {
Inst::GetSpecial { dst, reg } => {
let dst = format_reg(*dst.to_reg());
format!("{dst} = get_sp")
let reg = format_reg(**reg);
format!("xmov {dst}, {reg}")
}

Inst::LoadExtName { dst, name, offset } => {
Expand Down
7 changes: 6 additions & 1 deletion cranelift/codegen/src/isa/pulley_shared/lower.isle
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@
;;;; Rules for `get_stack_pointer` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (get_stack_pointer))
(pulley_get_sp))
(pulley_get_special (sp_reg)))

;;;; Rules for `get_frame_pointer` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(rule (lower (get_frame_pointer))
(pulley_get_special (fp_reg)))

;;;; Rules for `return` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Expand Down
9 changes: 9 additions & 0 deletions cranelift/codegen/src/isa/pulley_shared/lower/isle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::ir::{condcodes::*, immediates::*, types::*, *};
use crate::isa::pulley_shared::{
abi::*,
inst::{FReg, OperandSize, VReg, WritableFReg, WritableVReg, WritableXReg, XReg},
lower::regs,
*,
};
use crate::machinst::{
Expand Down Expand Up @@ -105,6 +106,14 @@ where
fn emit(&mut self, arg0: &MInst) -> Unit {
self.lower_ctx.emit(arg0.clone().into());
}

fn sp_reg(&mut self) -> XReg {
XReg::new(regs::stack_reg()).unwrap()
}

fn fp_reg(&mut self) -> XReg {
XReg::new(regs::fp_reg()).unwrap()
}
}

/// The main entry point for lowering with ISLE.
Expand Down

This file was deleted.

70 changes: 70 additions & 0 deletions cranelift/filetests/filetests/isa/pulley32/special_regs.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
test compile precise-output
set preserve_frame_pointers
target pulley32

function %get_stack_pointer() -> i32 {
block0:
v0 = get_stack_pointer.i32
return v0
}

; VCode:
; x30 = xconst8 -16
; x27 = xadd32 x27, x30
; store64 sp+8, x28 // flags = notrap aligned
; store64 sp+0, x29 // flags = notrap aligned
; x29 = xmov x27
; block0:
; xmov x0, x27
; x28 = load64_u sp+8 // flags = notrap aligned
; x29 = load64_u sp+0 // flags = notrap aligned
; x30 = xconst8 16
; x27 = xadd32 x27, x30
; ret
;
; Disassembled:
; xconst8 spilltmp0, -16
; xadd32 sp, sp, spilltmp0
; store64_offset8 sp, 8, lr
; store64 sp, fp
; xmov fp, sp
; xmov x0, sp
; load64_offset8 lr, sp, 8
; load64 fp, sp
; xconst8 spilltmp0, 16
; xadd32 sp, sp, spilltmp0
; ret

function %get_frame_pointer() -> i32 {
block0:
v0 = get_frame_pointer.i32
return v0
}

; VCode:
; x30 = xconst8 -16
; x27 = xadd32 x27, x30
; store64 sp+8, x28 // flags = notrap aligned
; store64 sp+0, x29 // flags = notrap aligned
; x29 = xmov x27
; block0:
; xmov x0, x29
; x28 = load64_u sp+8 // flags = notrap aligned
; x29 = load64_u sp+0 // flags = notrap aligned
; x30 = xconst8 16
; x27 = xadd32 x27, x30
; ret
;
; Disassembled:
; xconst8 spilltmp0, -16
; xadd32 sp, sp, spilltmp0
; store64_offset8 sp, 8, lr
; store64 sp, fp
; xmov fp, sp
; xmov x0, fp
; load64_offset8 lr, sp, 8
; load64 fp, sp
; xconst8 spilltmp0, 16
; xadd32 sp, sp, spilltmp0
; ret

This file was deleted.

70 changes: 70 additions & 0 deletions cranelift/filetests/filetests/isa/pulley64/special_regs.clif
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
test compile precise-output
set preserve_frame_pointers
target pulley64

function %get_stack_pointer() -> i64 {
block0:
v0 = get_stack_pointer.i64
return v0
}

; VCode:
; x30 = xconst8 -16
; x27 = xadd32 x27, x30
; store64 sp+8, x28 // flags = notrap aligned
; store64 sp+0, x29 // flags = notrap aligned
; x29 = xmov x27
; block0:
; xmov x0, x27
; x28 = load64_u sp+8 // flags = notrap aligned
; x29 = load64_u sp+0 // flags = notrap aligned
; x30 = xconst8 16
; x27 = xadd32 x27, x30
; ret
;
; Disassembled:
; xconst8 spilltmp0, -16
; xadd32 sp, sp, spilltmp0
; store64_offset8 sp, 8, lr
; store64 sp, fp
; xmov fp, sp
; xmov x0, sp
; load64_offset8 lr, sp, 8
; load64 fp, sp
; xconst8 spilltmp0, 16
; xadd32 sp, sp, spilltmp0
; ret

function %get_frame_pointer() -> i64 {
block0:
v0 = get_frame_pointer.i64
return v0
}

; VCode:
; x30 = xconst8 -16
; x27 = xadd32 x27, x30
; store64 sp+8, x28 // flags = notrap aligned
; store64 sp+0, x29 // flags = notrap aligned
; x29 = xmov x27
; block0:
; xmov x0, x29
; x28 = load64_u sp+8 // flags = notrap aligned
; x29 = load64_u sp+0 // flags = notrap aligned
; x30 = xconst8 16
; x27 = xadd32 x27, x30
; ret
;
; Disassembled:
; xconst8 spilltmp0, -16
; xadd32 sp, sp, spilltmp0
; store64_offset8 sp, 8, lr
; store64 sp, fp
; xmov fp, sp
; xmov x0, fp
; load64_offset8 lr, sp, 8
; load64 fp, sp
; xconst8 spilltmp0, 16
; xadd32 sp, sp, spilltmp0
; ret

1 change: 0 additions & 1 deletion pulley/fuzz/src/interp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ fn extended_op_is_safe_for_fuzzing(op: &ExtendedOp) -> bool {
match op {
ExtendedOp::Trap(_) => true,
ExtendedOp::Nop(_) => true,
ExtendedOp::GetSp(GetSp { dst, .. }) => !dst.is_special(),
ExtendedOp::CallIndirectHost(_) => false,
}
}
6 changes: 0 additions & 6 deletions pulley/src/interp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1239,12 +1239,6 @@ impl ExtendedOpVisitor for Interpreter<'_> {
ControlFlow::Break(Done::Trap(self.pc.as_ptr()))
}

fn get_sp(&mut self, dst: XReg) -> ControlFlow<Done> {
let sp = self.state[XReg::sp].get_u64();
self.state[dst].set_u64(sp);
ControlFlow::Continue(())
}

/// This instructions is sort of like a `call` instruction except that it
/// delegates to the host itself. That means that ABI details are baked in
/// here such as where various arguments are.
Expand Down
2 changes: 0 additions & 2 deletions pulley/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,6 @@ macro_rules! for_each_extended_op {
/// Do nothing.
nop = Nop;

/// Copy the special `sp` stack pointer register into an `x` register.
get_sp = GetSp { dst: XReg };
/// A special opcode to use an indirect function call to reenter the
/// host from the interpreter.
///
Expand Down