diff options
author | Kevin Newton <kddnewton@gmail.com> | 2022-08-11 08:32:06 -0400 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2022-08-29 08:47:10 -0700 |
commit | 7f4ab24f2b99c87874a5540a55026ea5a3d43d3e (patch) | |
tree | 9430ef0ce2828c5f4621d2f4f2ce4735612f9ad6 /yjit/src/backend | |
parent | 4d811d7a2b92d110e3e70cb77e5f499acfa7112a (diff) | |
download | ruby-7f4ab24f2b99c87874a5540a55026ea5a3d43d3e.tar.gz |
Op::Xor for backend IR (https://github.com/Shopify/ruby/pull/397)
Diffstat (limited to 'yjit/src/backend')
-rw-r--r-- | yjit/src/backend/arm64/mod.rs | 15 | ||||
-rw-r--r-- | yjit/src/backend/ir.rs | 5 | ||||
-rw-r--r-- | yjit/src/backend/x86_64/mod.rs | 6 |
3 files changed, 24 insertions, 2 deletions
diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs index 440c4368c5..2cd893923a 100644 --- a/yjit/src/backend/arm64/mod.rs +++ b/yjit/src/backend/arm64/mod.rs @@ -216,7 +216,7 @@ impl Assembler } } }, - Op::And | Op::Or => { + Op::And | Op::Or | Op::Xor => { match (opnds[0], opnds[1]) { (Opnd::Reg(_), Opnd::Reg(_)) => { asm.push_insn(insn.op, vec![opnds[0], opnds[1]], insn.target, insn.text, insn.pos_marker); @@ -615,6 +615,9 @@ impl Assembler Op::Or => { orr(cb, insn.out.into(), insn.opnds[0].into(), insn.opnds[1].into()); }, + Op::Xor => { + eor(cb, insn.out.into(), insn.opnds[0].into(), insn.opnds[1].into()); + }, Op::Not => { mvn(cb, insn.out.into(), insn.opnds[0].into()); }, @@ -1085,6 +1088,16 @@ mod tests { } #[test] + fn test_emit_xor() { + let (mut asm, mut cb) = setup_asm(); + + let opnd = asm.xor(Opnd::Reg(X0_REG), Opnd::Reg(X1_REG)); + asm.store(Opnd::mem(64, Opnd::Reg(X2_REG), 0), opnd); + + asm.compile_with_num_regs(&mut cb, 1); + } + + #[test] #[cfg(feature = "disasm")] fn test_simple_disasm() -> std::result::Result<(), capstone::Error> { // Test drive Capstone with simple input diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs index 2dfb859fe9..ef8cd5e872 100644 --- a/yjit/src/backend/ir.rs +++ b/yjit/src/backend/ir.rs @@ -63,6 +63,10 @@ pub enum Op // binary OR operation. Or, + // This is the same as the OP_ADD instruction, except that it performs the + // binary XOR operation. + Xor, + // Perform the NOT operation on an individual operand, and return the result // as a new operand. This operand can then be used as the operand on another // instruction. @@ -992,6 +996,7 @@ def_push_2_opnd!(add, Op::Add); def_push_2_opnd!(sub, Op::Sub); def_push_2_opnd!(and, Op::And); def_push_2_opnd!(or, Op::Or); +def_push_2_opnd!(xor, Op::Xor); def_push_1_opnd!(not, Op::Not); def_push_2_opnd!(lshift, Op::LShift); def_push_2_opnd!(rshift, Op::RShift); diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index 417474ee68..d474c9fe59 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -139,7 +139,7 @@ impl Assembler }).collect(); match insn.op { - Op::Add | Op::Sub | Op::And | Op::Cmp | Op::Or | Op::Test => { + Op::Add | Op::Sub | Op::And | Op::Cmp | Op::Or | Op::Test | Op::Xor => { let (opnd0, opnd1) = match (insn.opnds[0], insn.opnds[1]) { (Opnd::Mem(_), Opnd::Mem(_)) => { (asm.load(opnds[0]), asm.load(opnds[1])) @@ -328,6 +328,10 @@ impl Assembler or(cb, insn.opnds[0].into(), insn.opnds[1].into()); }, + Op::Xor => { + xor(cb, insn.opnds[0].into(), insn.opnds[1].into()); + }, + Op::Not => { not(cb, insn.opnds[0].into()) }, |