Load an immediate into a register in the backend (https://github.com/Shopify/zjit/pull/38)
This commit is contained in:
parent
7dd15abed3
commit
0aef948a1e
Notes:
git
2025-04-18 13:48:21 +00:00
@ -217,6 +217,10 @@ impl Assembler
|
|||||||
(Opnd::Mem(_) | Opnd::Reg(_), _) => {
|
(Opnd::Mem(_) | Opnd::Reg(_), _) => {
|
||||||
*left = asm.load(*left);
|
*left = asm.load(*left);
|
||||||
},
|
},
|
||||||
|
// The first operand can't be an immediate value
|
||||||
|
(Opnd::Value(_), _) => {
|
||||||
|
*left = asm.load(*left);
|
||||||
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -244,9 +248,15 @@ impl Assembler
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Insn::Test { left, right } => {
|
Insn::Test { left, right } => {
|
||||||
if let (Opnd::Mem(_), Opnd::Mem(_)) = (&left, &right) {
|
match (&left, &right) {
|
||||||
let loaded = asm.load(*right);
|
(Opnd::Mem(_), Opnd::Mem(_)) => {
|
||||||
*right = loaded;
|
*right = asm.load(*right);
|
||||||
|
}
|
||||||
|
// The first operand can't be an immediate value
|
||||||
|
(Opnd::UImm(_) | Opnd::Imm(_), _) => {
|
||||||
|
*left = asm.load(*left);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
asm.push_insn(insn);
|
asm.push_insn(insn);
|
||||||
},
|
},
|
||||||
|
@ -146,14 +146,8 @@ fn gen_fixnum_add(jit: &mut JITState, asm: &mut Assembler, left: InsnId, right:
|
|||||||
let left_opnd = jit.get_opnd(left)?;
|
let left_opnd = jit.get_opnd(left)?;
|
||||||
let right_opnd = jit.get_opnd(right)?;
|
let right_opnd = jit.get_opnd(right)?;
|
||||||
|
|
||||||
// Load left into a register if left is a constant. The backend doesn't support sub(imm, imm).
|
|
||||||
let left_reg = match left_opnd {
|
|
||||||
Opnd::Value(_) => asm.load(left_opnd),
|
|
||||||
_ => left_opnd,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add arg0 + arg1 and test for overflow
|
// Add arg0 + arg1 and test for overflow
|
||||||
let left_untag = asm.sub(left_reg, Opnd::Imm(1));
|
let left_untag = asm.sub(left_opnd, Opnd::Imm(1));
|
||||||
let out_val = asm.add(left_untag, right_opnd);
|
let out_val = asm.add(left_untag, right_opnd);
|
||||||
asm.jo(Target::SideExit(state.clone()));
|
asm.jo(Target::SideExit(state.clone()));
|
||||||
|
|
||||||
@ -164,14 +158,8 @@ fn gen_fixnum_add(jit: &mut JITState, asm: &mut Assembler, left: InsnId, right:
|
|||||||
fn gen_guard_type(jit: &mut JITState, asm: &mut Assembler, val: InsnId, guard_type: Type, state: &FrameState) -> Option<lir::Opnd> {
|
fn gen_guard_type(jit: &mut JITState, asm: &mut Assembler, val: InsnId, guard_type: Type, state: &FrameState) -> Option<lir::Opnd> {
|
||||||
let opnd = jit.get_opnd(val)?;
|
let opnd = jit.get_opnd(val)?;
|
||||||
if guard_type.is_subtype(Fixnum) {
|
if guard_type.is_subtype(Fixnum) {
|
||||||
// Load opnd into a register if opnd is a constant. The backend doesn't support test(imm, imm) yet.
|
|
||||||
let opnd_reg = match opnd {
|
|
||||||
Opnd::Value(_) => asm.load(opnd),
|
|
||||||
_ => opnd,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Check if opnd is Fixnum
|
// Check if opnd is Fixnum
|
||||||
asm.test(opnd_reg, Opnd::UImm(RUBY_FIXNUM_FLAG as u64));
|
asm.test(opnd, Opnd::UImm(RUBY_FIXNUM_FLAG as u64));
|
||||||
asm.jz(Target::SideExit(state.clone()));
|
asm.jz(Target::SideExit(state.clone()));
|
||||||
} else {
|
} else {
|
||||||
unimplemented!("unsupported type: {guard_type}");
|
unimplemented!("unsupported type: {guard_type}");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user