summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>2022-06-06 15:54:22 -0400
committerTakashi Kokubun <takashikkbn@gmail.com>2022-08-29 08:46:54 -0700
commit04e2ccede4e992a6e0d18ed506d76625ee7da8a3 (patch)
tree803b7c1116885e7c3840e662d480bcd2b8acbd3a
parent7c83a904a49a8ba3a1b78474a6d51a7a32178a4a (diff)
Change codegen.rs to use backend Assembler directly
-rw-r--r--yjit/src/backend/ir.rs17
-rw-r--r--yjit/src/backend/x86_64/mod.rs6
-rw-r--r--yjit/src/codegen.rs126
-rw-r--r--yjit/src/lib.rs7
4 files changed, 62 insertions, 94 deletions
diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs
index a578564afb..fa8a7b8e2b 100644
--- a/yjit/src/backend/ir.rs
+++ b/yjit/src/backend/ir.rs
@@ -84,6 +84,9 @@ pub enum Op
// C function call with N arguments (variadic)
CCall,
+ // C function return
+ CRet,
+
/*
// The following are conditional jump instructions. They all accept as their
// first operand an EIR_LABEL_NAME, which is used as the target of the jump.
@@ -661,6 +664,18 @@ macro_rules! def_push_1_opnd {
};
}
+macro_rules! def_push_1_opnd_no_out {
+ ($op_name:ident, $opcode:expr) => {
+ impl Assembler
+ {
+ pub fn $op_name(&mut self, opnd0: Opnd)
+ {
+ self.push_insn($opcode, vec![opnd0], None);
+ }
+ }
+ };
+}
+
macro_rules! def_push_2_opnd {
($op_name:ident, $opcode:expr) => {
impl Assembler
@@ -688,7 +703,9 @@ macro_rules! def_push_2_opnd_no_out {
def_push_2_opnd!(add, Op::Add);
def_push_2_opnd!(sub, Op::Sub);
def_push_2_opnd!(and, Op::And);
+def_push_1_opnd_no_out!(cret, Op::CRet);
def_push_1_opnd!(load, Op::Load);
+def_push_2_opnd_no_out!(store, Op::Store);
def_push_2_opnd_no_out!(mov, Op::Mov);
def_push_2_opnd_no_out!(lea, Op::Lea);
def_push_2_opnd_no_out!(cmp, Op::Cmp);
diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs
index f6ebcc5643..eb54ced2bf 100644
--- a/yjit/src/backend/x86_64/mod.rs
+++ b/yjit/src/backend/x86_64/mod.rs
@@ -109,8 +109,7 @@ impl Assembler
add(cb, insn.opnds[0].into(), insn.opnds[1].into())
},
- //TODO:
- //Store
+ Op::Store => mov(cb, insn.opnds[0].into(), insn.opnds[1].into()),
Op::Load => {
mov(cb, insn.out.into(), insn.opnds[0].into());
@@ -127,6 +126,9 @@ impl Assembler
Op::Mov => mov(cb, insn.opnds[0].into(), insn.opnds[1].into()),
+ // Load effective address
+ Op::Lea => lea(cb, insn.opnds[0].into(), insn.opnds[1].into()),
+
// Test and set flags
Op::Test => test(cb, insn.opnds[0].into(), insn.opnds[1].into()),
diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs
index a94eeb62ca..955d87eb68 100644
--- a/yjit/src/codegen.rs
+++ b/yjit/src/codegen.rs
@@ -54,7 +54,7 @@ enum CodegenStatus {
type InsnGenFn = fn(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
ocb: &mut OutlinedCb,
) -> CodegenStatus;
@@ -778,6 +778,9 @@ pub fn gen_single_block(
// Mark the start position of the block
blockref.borrow_mut().set_start_addr(cb.get_write_ptr());
+ // Create a backend assembler instance
+ let mut asm = Assembler::new();
+
// For each instruction to compile
// NOTE: could rewrite this loop with a std::iter::Iterator
while insn_idx < iseq_size {
@@ -832,7 +835,7 @@ pub fn gen_single_block(
}
// Call the code generation function
- status = gen_fn(&mut jit, &mut ctx, cb, ocb);
+ status = gen_fn(&mut jit, &mut ctx, &mut asm, ocb);
}
// If we can't compile this instruction
@@ -869,6 +872,9 @@ pub fn gen_single_block(
// Finish filling out the block
{
+ // Compile code into the code block
+ asm.compile(&mut jit, cb);
+
let mut block = jit.block.borrow_mut();
// Mark the end position of the block
@@ -887,19 +893,6 @@ pub fn gen_single_block(
return Err(());
}
- // TODO: we may want a feature for this called dump_insns? Can leave commented for now
- /*
- if (YJIT_DUMP_MODE >= 2) {
- // Dump list of compiled instrutions
- fprintf(stderr, "Compiled the following for iseq=%p:\n", (void *)iseq);
- for (uint32_t idx = block->blockid.idx; idx < insn_idx; ) {
- int opcode = yjit_opcode_at_pc(iseq, yjit_iseq_pc_at_idx(iseq, idx));
- fprintf(stderr, " %04d %s\n", idx, insn_name(opcode));
- idx += insn_len(opcode);
- }
- }
- */
-
// Block compiled successfully
Ok(blockref)
}
@@ -907,7 +900,7 @@ pub fn gen_single_block(
fn gen_nop(
_jit: &mut JITState,
_ctx: &mut Context,
- _cb: &mut CodeBlock,
+ _asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
// Do nothing
@@ -917,7 +910,7 @@ fn gen_nop(
fn gen_pop(
_jit: &mut JITState,
ctx: &mut Context,
- _cb: &mut CodeBlock,
+ _asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
// Decrement SP
@@ -925,90 +918,27 @@ fn gen_pop(
KeepCompiling
}
-
-
-
-/*
-fn gen_dup(
- _jit: &mut JITState,
- ctx: &mut Context,
- cb: &mut CodeBlock,
- _ocb: &mut OutlinedCb,
-) -> CodegenStatus {
- let dup_val = ctx.stack_pop(0);
- let (mapping, tmp_type) = ctx.get_opnd_mapping(StackOpnd(0));
-
- let loc0 = ctx.stack_push_mapping((mapping, tmp_type));
- mov(cb, REG0, dup_val);
- mov(cb, loc0, REG0);
-
- KeepCompiling
-}
-*/
-
-#[allow(dead_code)]
fn gen_dup(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
- let mut asm = Assembler::new();
-
let dup_val = ctx.ir_stack_pop(0);
let (mapping, tmp_type) = ctx.get_opnd_mapping(StackOpnd(0));
let loc0 = ctx.ir_stack_push_mapping((mapping, tmp_type));
asm.mov(loc0, dup_val);
- asm.compile(jit, cb);
-
- KeepCompiling
-}
-
-
-
-
-/*
-// duplicate stack top n elements
-fn gen_dupn(
- jit: &mut JITState,
- ctx: &mut Context,
- cb: &mut CodeBlock,
- _ocb: &mut OutlinedCb,
-) -> CodegenStatus {
- let nval: VALUE = jit_get_arg(jit, 0);
- let VALUE(n) = nval;
-
- // In practice, seems to be only used for n==2
- if n != 2 {
- return CantCompile;
- }
-
- let opnd1: X86Opnd = ctx.stack_opnd(1);
- let opnd0: X86Opnd = ctx.stack_opnd(0);
-
- let mapping1 = ctx.get_opnd_mapping(StackOpnd(1));
- let mapping0 = ctx.get_opnd_mapping(StackOpnd(0));
-
- let dst1: X86Opnd = ctx.stack_push_mapping(mapping1);
- mov(cb, REG0, opnd1);
- mov(cb, dst1, REG0);
-
- let dst0: X86Opnd = ctx.stack_push_mapping(mapping0);
- mov(cb, REG0, opnd0);
- mov(cb, dst0, REG0);
-
KeepCompiling
}
-*/
// duplicate stack top n elements
fn gen_dupn(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
@@ -1034,8 +964,6 @@ fn gen_dupn(
let dst0: Opnd = ctx.ir_stack_push_mapping(mapping0);
asm.mov(dst0, opnd0);
- asm.compile(jit, cb);
-
KeepCompiling
}
@@ -1043,24 +971,22 @@ fn gen_dupn(
fn gen_swap(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
_ocb: &mut OutlinedCb,
) -> CodegenStatus {
- stack_swap(jit, ctx, cb, 0, 1, REG0, REG1);
+ stack_swap(jit, ctx, asm, 0, 1, REG0, REG1);
KeepCompiling
}
fn stack_swap(
jit: &mut JITState,
ctx: &mut Context,
- cb: &mut CodeBlock,
+ asm: &mut Assembler,
offset0: u16,
offset1: u16,
_reg0: X86Opnd,
_reg1: X86Opnd,
) {
- let mut asm = Assembler::new();
-
let stack0_mem = ctx.ir_stack_opnd(offset0 as i32);
let stack1_mem = ctx.ir_stack_opnd(offset1 as i32);
@@ -1074,10 +1000,18 @@ fn stack_swap(
ctx.set_opnd_mapping(StackOpnd(offset0), mapping1);
ctx.set_opnd_mapping(StackOpnd(offset1), mapping0);
-
- asm.compile(jit, cb);
}
+
+
+
+
+
+
+
+
+
+/*
fn gen_putnil(
jit: &mut JITState,
ctx: &mut Context,
@@ -6069,6 +6003,7 @@ fn gen_opt_invokebuiltin_delegate(
KeepCompiling
}
+*/
/// Maps a YARV opcode to a code generation function (if supported)
fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
@@ -6078,10 +6013,12 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
match opcode {
YARVINSN_nop => Some(gen_nop),
- YARVINSN_pop => Some(gen_pop),
+ //YARVINSN_pop => Some(gen_pop),
YARVINSN_dup => Some(gen_dup),
YARVINSN_dupn => Some(gen_dupn),
YARVINSN_swap => Some(gen_swap),
+
+ /*
YARVINSN_putnil => Some(gen_putnil),
YARVINSN_putobject => Some(gen_putobject),
YARVINSN_putobject_INT2FIX_0_ => Some(gen_putobject_int2fix),
@@ -6163,6 +6100,7 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
YARVINSN_getspecial => Some(gen_getspecial),
YARVINSN_getclassvariable => Some(gen_getclassvariable),
YARVINSN_setclassvariable => Some(gen_setclassvariable),
+ */
// Unimplemented opcode, YJIT won't generate code for this yet
_ => None,
@@ -6350,6 +6288,7 @@ impl CodegenGlobals {
/// Register codegen functions for some Ruby core methods
fn reg_method_codegen_fns(&mut self) {
+ /*
unsafe {
// Specialization for C methods. See yjit_reg_method() for details.
self.yjit_reg_method(rb_cBasicObject, "!", jit_rb_obj_not);
@@ -6378,6 +6317,7 @@ impl CodegenGlobals {
jit_thread_s_current,
);
}
+ */
}
/// Get a mutable reference to the codegen globals instance
@@ -6442,6 +6382,7 @@ impl CodegenGlobals {
}
}
+/*
#[cfg(test)]
mod tests {
use super::*;
@@ -6704,3 +6645,4 @@ mod tests {
gen_leave(&mut jit, &mut context, &mut cb, &mut ocb);
}
}
+*/ \ No newline at end of file
diff --git a/yjit/src/lib.rs b/yjit/src/lib.rs
index 752b7872c1..e92186da7d 100644
--- a/yjit/src/lib.rs
+++ b/yjit/src/lib.rs
@@ -3,6 +3,13 @@
#![allow(clippy::too_many_arguments)] // :shrug:
#![allow(clippy::identity_op)] // Sometimes we do it for style
+
+// Temporary while switching to the new backend
+#![allow(dead_code)]
+#![allow(unused)]
+
+
+
mod asm;
mod backend;
mod codegen;