diff options
author | Kevin Newton <kddnewton@gmail.com> | 2022-08-04 10:31:16 -0400 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2022-08-29 08:47:06 -0700 |
commit | a95422a69167baba0e4d086b234ad5316d3c39fe (patch) | |
tree | 86ee1259f4cdc57c9d9ef867b8bcf195f7b63d19 | |
parent | 9db2ca723cac60c2d65865a4851c13cac58ff6a3 (diff) |
Binary OR instruction for the IR (https://github.com/Shopify/ruby/pull/355)
-rw-r--r-- | yjit/src/backend/arm64/mod.rs | 14 | ||||
-rw-r--r-- | yjit/src/backend/ir.rs | 5 | ||||
-rw-r--r-- | yjit/src/backend/x86_64/mod.rs | 6 |
3 files changed, 23 insertions, 2 deletions
diff --git a/yjit/src/backend/arm64/mod.rs b/yjit/src/backend/arm64/mod.rs index e0e889c16c..9dc49a7686 100644 --- a/yjit/src/backend/arm64/mod.rs +++ b/yjit/src/backend/arm64/mod.rs @@ -175,7 +175,7 @@ impl Assembler } } }, - Op::And => { + Op::And | Op::Or => { match (opnds[0], opnds[1]) { (Opnd::Reg(_), Opnd::Reg(_)) => { asm.and(opnds[0], opnds[1]); @@ -567,6 +567,9 @@ impl Assembler Op::And => { and(cb, insn.out.into(), insn.opnds[0].into(), insn.opnds[1].into()); }, + Op::Or => { + orr(cb, insn.out.into(), insn.opnds[0].into(), insn.opnds[1].into()); + }, Op::Not => { mvn(cb, insn.out.into(), insn.opnds[0].into()); }, @@ -887,6 +890,15 @@ mod tests { } #[test] + fn test_emit_or() { + let (mut asm, mut cb) = setup_asm(); + + let opnd = asm.or(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] fn test_emit_test() { let (mut asm, mut cb) = setup_asm(); diff --git a/yjit/src/backend/ir.rs b/yjit/src/backend/ir.rs index f634fb7678..99a084ff02 100644 --- a/yjit/src/backend/ir.rs +++ b/yjit/src/backend/ir.rs @@ -57,6 +57,10 @@ pub enum Op // binary AND operation. And, + // This is the same as the OP_ADD instruction, except that it performs the + // binary OR operation. + Or, + // 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. @@ -899,6 +903,7 @@ def_push_jcc!(jo, Op::Jo); 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_1_opnd!(not, Op::Not); def_push_1_opnd_no_out!(cpush, Op::CPush); def_push_0_opnd!(cpop, Op::CPop); diff --git a/yjit/src/backend/x86_64/mod.rs b/yjit/src/backend/x86_64/mod.rs index 13bb106b97..7074c8980b 100644 --- a/yjit/src/backend/x86_64/mod.rs +++ b/yjit/src/backend/x86_64/mod.rs @@ -113,7 +113,7 @@ impl Assembler }; match op { - Op::Add | Op::Sub | Op::And | Op::Cmp => { + Op::Add | Op::Sub | Op::And | Op::Cmp | Op::Or => { let (opnd0, opnd1) = match (opnds[0], opnds[1]) { (Opnd::Mem(_), Opnd::Mem(_)) => { (asm.load(opnds[0]), asm.load(opnds[1])) @@ -271,6 +271,10 @@ impl Assembler and(cb, insn.opnds[0].into(), insn.opnds[1].into()) }, + Op::Or => { + or(cb, insn.opnds[0].into(), insn.opnds[1].into()); + }, + Op::Not => { not(cb, insn.opnds[0].into()) }, |