From 159d71fe55c81dfb0acf53e695b0a2f0e26cb615 Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Fri, 15 May 2020 12:59:16 -0400 Subject: [PATCH] Implement OP_CMPEQB --- src/soc/alu/main_stage.py | 9 +++++++++ src/soc/alu/output_stage.py | 7 ++++++- src/soc/alu/test/test_pipe_caller.py | 11 ++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/soc/alu/main_stage.py b/src/soc/alu/main_stage.py index 3d5a3f45..afa97224 100644 --- a/src/soc/alu/main_stage.py +++ b/src/soc/alu/main_stage.py @@ -68,6 +68,15 @@ class ALUMainStage(PipeModBase): comb += o.eq(Cat(self.i.a[0:16], Repl(self.i.a[15], 64-16))) with m.If(self.i.ctx.op.data_len == 4): comb += o.eq(Cat(self.i.a[0:32], Repl(self.i.a[31], 64-32))) + with m.Case(InternalOp.OP_CMPEQB): + eqs = Signal(8, reset_less=True) + src1 = Signal(8, reset_less=True) + comb += src1.eq(self.i.a[0:8]) + for i in range(8): + comb += eqs[i].eq(src1 == self.i.b[8*i:8*(i+1)]) + comb += self.o.cr0.eq(Cat(Const(0, 2), eqs.any(), Const(0, 1))) + + ###### sticky overflow and context, both pass-through ##### diff --git a/src/soc/alu/output_stage.py b/src/soc/alu/output_stage.py index 2f04ac9f..12537957 100644 --- a/src/soc/alu/output_stage.py +++ b/src/soc/alu/output_stage.py @@ -40,6 +40,7 @@ class ALUOutputStage(PipeModBase): # TODO: if o[63] is XORed with "operand == OP_CMP" # that can be used as a test # see https://bugs.libre-soc.org/show_bug.cgi?id=305#c60 + comb += is_cmp.eq(self.i.ctx.op.insn_type == InternalOp.OP_CMP) comb += msb_test.eq(o[-1] ^ is_cmp) comb += is_zero.eq(o == 0) @@ -48,7 +49,11 @@ class ALUOutputStage(PipeModBase): comb += so.eq(self.i.so | self.i.ov) comb += self.o.o.eq(o) - comb += self.o.cr0.eq(Cat(so, is_zero, is_positive, is_negative)) + with m.If(self.i.ctx.op.insn_type != InternalOp.OP_CMPEQB): + comb += self.o.cr0.eq(Cat(so, is_zero, is_positive, is_negative)) + with m.Else(): + comb += self.o.cr0.eq(self.i.cr0) + comb += self.o.so.eq(so) comb += self.o.ctx.eq(self.i.ctx) diff --git a/src/soc/alu/test/test_pipe_caller.py b/src/soc/alu/test/test_pipe_caller.py index c38d5c47..f9497c7c 100644 --- a/src/soc/alu/test/test_pipe_caller.py +++ b/src/soc/alu/test/test_pipe_caller.py @@ -151,6 +151,14 @@ class ALUTestCase(FHDLTestCase): initial_regs[1] = random.randint(0, (1<<64)-1) self.run_tst_program(Program(lst), initial_regs) + def test_cmpeqb(self): + lst = ["cmpeqb cr0, 1, 2"] + for i in range(20): + initial_regs = [0] * 32 + initial_regs[1] = i + initial_regs[2] = 0x01030507090b0d0f11 + self.run_tst_program(Program(lst), initial_regs, {}) + def test_ilang(self): rec = CompALUOpSubset() @@ -244,7 +252,8 @@ class TestRunner(FHDLTestCase): self.assertEqual(cr_expected, cr_actual, code) op = yield dec2.e.insn_type - if op == InternalOp.OP_CMP.value: + if op == InternalOp.OP_CMP.value or \ + op == InternalOp.OP_CMPEQB.value: bf = yield dec2.dec.BF cr_actual = yield alu.n.data_o.cr0 cr_expected = sim.crl[bf].get_range().value -- 2.30.2