summaryrefslogtreecommitdiff
path: root/yjit/src/backend/x86_64/mod.rs
diff options
context:
space:
mode:
authorMaxime Chevalier-Boisvert <[email protected]>2022-05-19 15:01:20 -0400
committerTakashi Kokubun <[email protected]>2022-08-29 08:46:53 -0700
commit1b2ee62149d5fa8d8cbe2097f9fd7a3af31989c2 (patch)
tree26350c8aa8408b3ddbd4be9e19e7942433da2b00 /yjit/src/backend/x86_64/mod.rs
parent564f9503603ae261561193f69f1fbdef6a140aa1 (diff)
Implement target-specific insn splitting with Kevin. Add tests.
Diffstat (limited to 'yjit/src/backend/x86_64/mod.rs')
-rw-r--r--yjit/src/backend/x86_64/mod.rs46
1 files changed, 45 insertions, 1 deletions
diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs
index ed68e13eb6..65259a72f6 100644
--- a/yjit/src/backend/x86_64/mod.rs
+++ b/yjit/src/backend/x86_64/mod.rs
@@ -45,7 +45,7 @@ impl From<Opnd> for X86Opnd {
impl Assembler
{
// Get the list of registers from which we can allocate on this platform
- pub fn get_scrach_regs() -> Vec<Reg>
+ pub fn get_scratch_regs() -> Vec<Reg>
{
vec![
RAX_REG,
@@ -54,6 +54,40 @@ impl Assembler
}
// Emit platform-specific machine code
+ fn target_split(mut self) -> Assembler
+ {
+ let live_ranges: Vec<usize> = std::mem::take(&mut self.live_ranges);
+
+ self.transform_insns(|asm, index, op, opnds, target| {
+ match op {
+ Op::Add | Op::Sub | Op::And => {
+ match opnds.as_slice() {
+ // Instruction output whose live range spans beyond this instruction
+ [Opnd::InsnOut(out_idx), _] => {
+ if live_ranges[*out_idx] > index {
+ let opnd0 = asm.load(opnds[0]);
+ asm.push_insn(op, vec![opnd0, opnds[1]], None);
+ return;
+ }
+ },
+
+ [Opnd::Mem(_), _] => {
+ let opnd0 = asm.load(opnds[0]);
+ asm.push_insn(op, vec![opnd0, opnds[1]], None);
+ return;
+ },
+
+ _ => {}
+ }
+ },
+ _ => {}
+ };
+
+ asm.push_insn(op, opnds, target);
+ })
+ }
+
+ // Emit platform-specific machine code
pub fn target_emit(&self, cb: &mut CodeBlock)
{
// For each instruction
@@ -87,4 +121,14 @@ impl Assembler
};
}
}
+
+ // Optimize and compile the stored instructions
+ pub fn compile_with_regs(self, cb: &mut CodeBlock, regs: Vec<Reg>)
+ {
+ dbg!(self
+ .target_split()
+ .split_loads()
+ .alloc_regs(regs))
+ .target_emit(cb);
+ }
}