Skip to content

Commit

Permalink
Port the YJIT defined opcode; fix C_ARG_REGS (#342)
Browse files Browse the repository at this point in the history
  • Loading branch information
noahgibbs authored and k0kubun committed Aug 25, 2022
1 parent 994537d commit a2bbf82
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 24 deletions.
8 changes: 7 additions & 1 deletion bootstraptest/test_yjit_new_backend.rb
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,13 @@ def foo(n)
foo(3)
}


# defined
assert_equal '[nil, "method"]', %q{
def foo()
[defined?(a), defined?(foo)]
end
foo()
}



Expand Down
3 changes: 0 additions & 3 deletions yjit/src/asm/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,6 @@ pub const R13B: X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 8, reg_type: RegType::
pub const R14B: X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 8, reg_type: RegType::GP, reg_no: 14 });
pub const R15B: X86Opnd = X86Opnd::Reg(X86Reg { num_bits: 8, reg_type: RegType::GP, reg_no: 15 });

// C argument registers on this platform
pub const C_ARG_REGS: [X86Opnd; 6] = [RDI, RSI, RDX, RCX, R8, R9];

//===========================================================================

/// Shorthand for memory operand with base register and displacement
Expand Down
4 changes: 2 additions & 2 deletions yjit/src/backend/arm64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ impl Assembler
}
},
Op::CCall => {
assert!(opnds.len() < C_ARG_REGS.len());
assert!(opnds.len() < C_ARG_OPNDS.len());

// For each of the operands we're going to first load them
// into a register and then move them into the correct
Expand All @@ -202,7 +202,7 @@ impl Assembler
// which is both the return value and first argument register
for (idx, opnd) in opnds.into_iter().enumerate().rev() {
let value = asm.load(opnd);
asm.mov(Opnd::Reg(C_ARG_REGREGS[idx]), value);
asm.mov(C_ARG_OPNDS[idx], value);
}

// Now we push the CCall without any arguments so that it
Expand Down
4 changes: 2 additions & 2 deletions yjit/src/backend/x86_64/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@ impl Assembler
// C function call
Op::CCall => {
// Temporary
assert!(insn.opnds.len() < C_ARG_REGS.len());
assert!(insn.opnds.len() < _C_ARG_OPNDS.len());

// For each operand
for (idx, opnd) in insn.opnds.iter().enumerate() {
mov(cb, C_ARG_REGS[idx], insn.opnds[idx].into());
mov(cb, X86Opnd::Reg(_C_ARG_OPNDS[idx].unwrap_reg()), insn.opnds[idx].into());
}

let ptr = insn.target.unwrap().unwrap_fun_ptr();
Expand Down
25 changes: 9 additions & 16 deletions yjit/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2177,11 +2177,12 @@ fn gen_setinstancevariable(
KeepCompiling
}
*/

fn gen_defined(
jit: &mut JITState,
ctx: &mut Context,
cb: &mut CodeBlock,
asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
let op_type = jit_get_arg(jit, 0);
Expand All @@ -2190,26 +2191,19 @@ fn gen_defined(

// Save the PC and SP because the callee may allocate
// Note that this modifies REG_SP, which is why we do it first
jit_prepare_routine_call(jit, ctx, cb, REG0);
jit_prepare_routine_call(jit, ctx, asm);

// Get the operands from the stack
let v_opnd = ctx.stack_pop(1);

// Call vm_defined(ec, reg_cfp, op_type, obj, v)
mov(cb, C_ARG_REGS[0], REG_EC);
mov(cb, C_ARG_REGS[1], REG_CFP);
mov(cb, C_ARG_REGS[2], uimm_opnd(op_type.into()));
jit_mov_gc_ptr(jit, cb, C_ARG_REGS[3], obj);
mov(cb, C_ARG_REGS[4], v_opnd);
call_ptr(cb, REG0, rb_vm_defined as *const u8);
let def_result = asm.ccall(rb_vm_defined as *const u8, vec![EC, CFP, op_type.into(), obj.into(), v_opnd]);

// if (vm_defined(ec, GET_CFP(), op_type, obj, v)) {
// val = pushval;
// }
jit_mov_gc_ptr(jit, cb, REG1, pushval);
cmp(cb, AL, imm_opnd(0));
mov(cb, RAX, uimm_opnd(Qnil.into()));
cmovnz(cb, RAX, REG1);
asm.test(def_result, Opnd::UImm(255));
let out_value = asm.csel_nz(pushval.into(), Qnil.into());

// Push the return value onto the stack
let out_type = if pushval.special_const_p() {
Expand All @@ -2218,11 +2212,12 @@ fn gen_defined(
Type::Unknown
};
let stack_ret = ctx.stack_push(out_type);
mov(cb, stack_ret, RAX);
asm.mov(stack_ret, out_value);

KeepCompiling
}

/*
fn gen_checktype(
jit: &mut JITState,
ctx: &mut Context,
Expand Down Expand Up @@ -5997,10 +5992,8 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_splatarray => Some(gen_splatarray),
YARVINSN_newrange => Some(gen_newrange),
YARVINSN_putstring => Some(gen_putstring),
/*
YARVINSN_expandarray => Some(gen_expandarray),
//YARVINSN_expandarray => Some(gen_expandarray),
YARVINSN_defined => Some(gen_defined),
*/
YARVINSN_checkkeyword => Some(gen_checkkeyword),
/*
YARVINSN_concatstrings => Some(gen_concatstrings),
Expand Down

0 comments on commit a2bbf82

Please sign in to comment.