diff options
author | Kevin Newton <[email protected]> | 2022-07-15 16:24:18 -0400 |
---|---|---|
committer | Takashi Kokubun <[email protected]> | 2022-08-29 08:47:01 -0700 |
commit | f9e24ca8dd5e498cd768eaf65bc07acdb268f175 (patch) | |
tree | 99f4c516a0df5e93b15109617ddc50fec7830062 /yjit/src/backend/x86_64/mod.rs | |
parent | 0da253e72cc80c1dbf8517f5217b59a64ec0f44e (diff) |
Conditionals (https://github.com/Shopify/ruby/pull/323)
* CSEL on AArch64
* Implement various Op::CSel* instructions
Diffstat (limited to 'yjit/src/backend/x86_64/mod.rs')
-rw-r--r-- | yjit/src/backend/x86_64/mod.rs | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index 31a907b55e..3ee46e5936 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -142,6 +142,17 @@ impl Assembler asm.push_insn(op, vec![opnd0, opnd1], target, text); }, + Op::CSelZ | Op::CSelNZ | Op::CSelE | Op::CSelNE | + Op::CSelL | Op::CSelLE | Op::CSelG | Op::CSelGE => { + let new_opnds = opnds.into_iter().map(|opnd| { + match opnd { + Opnd::Reg(_) | Opnd::InsnOut { .. } => opnd, + _ => asm.load(opnd) + } + }).collect(); + + asm.push_insn(op, new_opnds, target, text); + }, Op::Mov => { match (opnds[0], opnds[1]) { (Opnd::Mem(_), Opnd::Mem(_)) => { @@ -388,6 +399,39 @@ impl Assembler Op::Breakpoint => int3(cb), + Op::CSelZ => { + mov(cb, insn.out.into(), insn.opnds[1].into()); + cmovz(cb, insn.out.into(), insn.opnds[0].into()); + }, + Op::CSelNZ => { + mov(cb, insn.out.into(), insn.opnds[1].into()); + cmovnz(cb, insn.out.into(), insn.opnds[0].into()); + }, + Op::CSelE => { + mov(cb, insn.out.into(), insn.opnds[1].into()); + cmove(cb, insn.out.into(), insn.opnds[0].into()); + }, + Op::CSelNE => { + mov(cb, insn.out.into(), insn.opnds[1].into()); + cmovne(cb, insn.out.into(), insn.opnds[0].into()); + }, + Op::CSelL => { + mov(cb, insn.out.into(), insn.opnds[1].into()); + cmovl(cb, insn.out.into(), insn.opnds[0].into()); + }, + Op::CSelLE => { + mov(cb, insn.out.into(), insn.opnds[1].into()); + cmovle(cb, insn.out.into(), insn.opnds[0].into()); + }, + Op::CSelG => { + mov(cb, insn.out.into(), insn.opnds[1].into()); + cmovg(cb, insn.out.into(), insn.opnds[0].into()); + }, + Op::CSelGE => { + mov(cb, insn.out.into(), insn.opnds[1].into()); + cmovge(cb, insn.out.into(), insn.opnds[0].into()); + }, + // We want to keep the panic here because some instructions that // we feed to the backend could get lowered into other // instructions. So it's possible that some of our backend |