YJIT: implement missing asm.jg
instruction in backend (#8130)
YJIT: implement missing jg instruction in backend While trying to implement a specialize integer left shift, I ran into a problem where we have no way to do a greater-than comparison at the moment. Surprising we went this far without ever needing it.
This commit is contained in:
parent
83f9d80c0b
commit
5669a28fde
Notes:
git
2023-07-27 21:47:48 +00:00
Merged-By: maximecb <maximecb@ruby-lang.org>
@ -1079,6 +1079,9 @@ impl Assembler
|
|||||||
Insn::Jl(target) => {
|
Insn::Jl(target) => {
|
||||||
emit_conditional_jump::<{Condition::LT}>(cb, compile_side_exit(*target, self, ocb));
|
emit_conditional_jump::<{Condition::LT}>(cb, compile_side_exit(*target, self, ocb));
|
||||||
},
|
},
|
||||||
|
Insn::Jg(target) => {
|
||||||
|
emit_conditional_jump::<{Condition::GT}>(cb, compile_side_exit(*target, self, ocb));
|
||||||
|
},
|
||||||
Insn::Jbe(target) => {
|
Insn::Jbe(target) => {
|
||||||
emit_conditional_jump::<{Condition::LS}>(cb, compile_side_exit(*target, self, ocb));
|
emit_conditional_jump::<{Condition::LS}>(cb, compile_side_exit(*target, self, ocb));
|
||||||
},
|
},
|
||||||
|
@ -432,6 +432,9 @@ pub enum Insn {
|
|||||||
/// Jump if lower
|
/// Jump if lower
|
||||||
Jl(Target),
|
Jl(Target),
|
||||||
|
|
||||||
|
/// Jump if greater
|
||||||
|
Jg(Target),
|
||||||
|
|
||||||
// Unconditional jump to a branch target
|
// Unconditional jump to a branch target
|
||||||
Jmp(Target),
|
Jmp(Target),
|
||||||
|
|
||||||
@ -578,6 +581,7 @@ impl Insn {
|
|||||||
Insn::Jbe(_) => "Jbe",
|
Insn::Jbe(_) => "Jbe",
|
||||||
Insn::Je(_) => "Je",
|
Insn::Je(_) => "Je",
|
||||||
Insn::Jl(_) => "Jl",
|
Insn::Jl(_) => "Jl",
|
||||||
|
Insn::Jg(_) => "Jg",
|
||||||
Insn::Jmp(_) => "Jmp",
|
Insn::Jmp(_) => "Jmp",
|
||||||
Insn::JmpOpnd(_) => "JmpOpnd",
|
Insn::JmpOpnd(_) => "JmpOpnd",
|
||||||
Insn::Jne(_) => "Jne",
|
Insn::Jne(_) => "Jne",
|
||||||
@ -725,6 +729,7 @@ impl<'a> Iterator for InsnOpndIterator<'a> {
|
|||||||
Insn::Jbe(_) |
|
Insn::Jbe(_) |
|
||||||
Insn::Je(_) |
|
Insn::Je(_) |
|
||||||
Insn::Jl(_) |
|
Insn::Jl(_) |
|
||||||
|
Insn::Jg(_) |
|
||||||
Insn::Jmp(_) |
|
Insn::Jmp(_) |
|
||||||
Insn::Jne(_) |
|
Insn::Jne(_) |
|
||||||
Insn::Jnz(_) |
|
Insn::Jnz(_) |
|
||||||
@ -822,6 +827,7 @@ impl<'a> InsnOpndMutIterator<'a> {
|
|||||||
Insn::Jbe(_) |
|
Insn::Jbe(_) |
|
||||||
Insn::Je(_) |
|
Insn::Je(_) |
|
||||||
Insn::Jl(_) |
|
Insn::Jl(_) |
|
||||||
|
Insn::Jg(_) |
|
||||||
Insn::Jmp(_) |
|
Insn::Jmp(_) |
|
||||||
Insn::Jne(_) |
|
Insn::Jne(_) |
|
||||||
Insn::Jnz(_) |
|
Insn::Jnz(_) |
|
||||||
|
@ -673,6 +673,14 @@ impl Assembler
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Insn::Jg(target) => {
|
||||||
|
match compile_side_exit(*target, self, ocb) {
|
||||||
|
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jg_ptr(cb, code_ptr),
|
||||||
|
Target::Label(label_idx) => jg_label(cb, label_idx),
|
||||||
|
Target::SideExit { .. } => unreachable!("Target::SideExit should have been compiled by compile_side_exit"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
Insn::Jbe(target) => {
|
Insn::Jbe(target) => {
|
||||||
match compile_side_exit(*target, self, ocb) {
|
match compile_side_exit(*target, self, ocb) {
|
||||||
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jbe_ptr(cb, code_ptr),
|
Target::CodePtr(code_ptr) | Target::SideExitPtr(code_ptr) => jbe_ptr(cb, code_ptr),
|
||||||
|
@ -4325,6 +4325,45 @@ fn jit_rb_int_div(
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
fn jit_rb_int_lshift(
|
||||||
|
jit: &mut JITState,
|
||||||
|
asm: &mut Assembler,
|
||||||
|
ocb: &mut OutlinedCb,
|
||||||
|
_ci: *const rb_callinfo,
|
||||||
|
_cme: *const rb_callable_method_entry_t,
|
||||||
|
_block: Option<IseqPtr>,
|
||||||
|
_argc: i32,
|
||||||
|
_known_recv_class: *const VALUE,
|
||||||
|
) -> bool {
|
||||||
|
if asm.ctx.two_fixnums_on_stack(jit) != Some(true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
guard_two_fixnums(jit, asm, ocb);
|
||||||
|
|
||||||
|
let rhs = asm.stack_pop(1);
|
||||||
|
let lhs = asm.stack_pop(1);
|
||||||
|
|
||||||
|
// Ruby supports using a negative shift value
|
||||||
|
asm.comment("Guard shift negative");
|
||||||
|
let shift_val = asm.sub(rhs, 1.into());
|
||||||
|
asm.cmp(shift_val, 0.into());
|
||||||
|
asm.jl(Target::side_exit(Counter::lshift_range));
|
||||||
|
|
||||||
|
asm.cmp(shift_val, 63.into());
|
||||||
|
asm.jg(Target::side_exit(Counter::lshift_range));
|
||||||
|
|
||||||
|
// FIXME: we don't yet support shift with non-immediate values in the backend
|
||||||
|
// Do the shifting
|
||||||
|
let out_val = asm.lshift(lhs, shift_val);
|
||||||
|
asm.jo(Target::side_exit(Counter::lshift_overflow));
|
||||||
|
|
||||||
|
let ret_opnd = asm.stack_push(Type::Fixnum);
|
||||||
|
asm.mov(ret_opnd, out_val);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
fn jit_rb_int_aref(
|
fn jit_rb_int_aref(
|
||||||
jit: &mut JITState,
|
jit: &mut JITState,
|
||||||
asm: &mut Assembler,
|
asm: &mut Assembler,
|
||||||
@ -8371,6 +8410,7 @@ impl CodegenGlobals {
|
|||||||
|
|
||||||
self.yjit_reg_method(rb_cInteger, "*", jit_rb_int_mul);
|
self.yjit_reg_method(rb_cInteger, "*", jit_rb_int_mul);
|
||||||
self.yjit_reg_method(rb_cInteger, "/", jit_rb_int_div);
|
self.yjit_reg_method(rb_cInteger, "/", jit_rb_int_div);
|
||||||
|
//self.yjit_reg_method(rb_cInteger, "<<", jit_rb_int_lshift);
|
||||||
self.yjit_reg_method(rb_cInteger, "[]", jit_rb_int_aref);
|
self.yjit_reg_method(rb_cInteger, "[]", jit_rb_int_aref);
|
||||||
|
|
||||||
// rb_str_to_s() methods in string.c
|
// rb_str_to_s() methods in string.c
|
||||||
|
@ -335,6 +335,9 @@ make_counters! {
|
|||||||
opt_mod_zero,
|
opt_mod_zero,
|
||||||
opt_div_zero,
|
opt_div_zero,
|
||||||
|
|
||||||
|
lshift_range,
|
||||||
|
lshift_overflow,
|
||||||
|
|
||||||
opt_aref_argc_not_one,
|
opt_aref_argc_not_one,
|
||||||
opt_aref_arg_not_fixnum,
|
opt_aref_arg_not_fixnum,
|
||||||
opt_aref_not_array,
|
opt_aref_not_array,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user