summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2022-08-04 10:31:16 -0400
committerTakashi Kokubun <takashikkbn@gmail.com>2022-08-29 08:47:06 -0700
commita95422a69167baba0e4d086b234ad5316d3c39fe (patch)
tree86ee1259f4cdc57c9d9ef867b8bcf195f7b63d19
parent9db2ca723cac60c2d65865a4851c13cac58ff6a3 (diff)
Binary OR instruction for the IR (https://github.com/Shopify/ruby/pull/355)
-rw-r--r--yjit/src/backend/arm64/mod.rs14
-rw-r--r--yjit/src/backend/ir.rs5
-rw-r--r--yjit/src/backend/x86_64/mod.rs6
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())
},