summaryrefslogtreecommitdiff
path: root/yjit/src/backend/x86_64/mod.rs
diff options
context:
space:
mode:
authorKevin Newton <[email protected]>2022-07-15 16:24:18 -0400
committerTakashi Kokubun <[email protected]>2022-08-29 08:47:01 -0700
commitf9e24ca8dd5e498cd768eaf65bc07acdb268f175 (patch)
tree99f4c516a0df5e93b15109617ddc50fec7830062 /yjit/src/backend/x86_64/mod.rs
parent0da253e72cc80c1dbf8517f5217b59a64ec0f44e (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.rs44
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