Implement OP_CMPEQB
authorMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 16:59:16 +0000 (12:59 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Fri, 15 May 2020 16:59:16 +0000 (12:59 -0400)
src/soc/alu/main_stage.py
src/soc/alu/output_stage.py
src/soc/alu/test/test_pipe_caller.py

index 3d5a3f45402e80adc85ac14c9b21adc1e189c443..afa97224cf93b0de86b58bbe7194866e4c65374b 100644 (file)
@@ -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 #####
 
index 2f04ac9f7efc17780a87776be7709a8365a63b8d..1253795708f6f4e86c01378c0a1eca7a4cca441c 100644 (file)
@@ -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)
index c38d5c47cf14a0de38fbad66c2646d6d15b6faa4..f9497c7c78ddb35edd4ae68554821487693a21c3 100644 (file)
@@ -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