Implement mtocrf (which isn't different from mtcrf?)
authorMichael Nolan <mtnolan2640@gmail.com>
Sat, 16 May 2020 18:05:55 +0000 (14:05 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Sat, 16 May 2020 18:05:55 +0000 (14:05 -0400)
src/soc/cr/main_stage.py
src/soc/cr/test/test_pipe_caller.py

index 4a27fcd41c7295788d8bb90c3a22e7576811a3cc..1552c4b1f216cd0ea8b9d1ecbc4a42df21670017 100644 (file)
@@ -65,6 +65,13 @@ class CRMainStage(PipeModBase):
         # There's no field, just have to grab it directly from the insn
         comb += lut.eq(self.i.ctx.op.insn[6:10])
 
+
+        # Ugh. mtocrf and mtcrf have one random bit differentiating
+        # them. This bit is not in any particular field, so this
+        # extracts that bit from the instruction
+        move_one = Signal(reset_less=True)
+        comb += move_one.eq(self.i.ctx.op.insn[20])
+
         with m.Switch(op.insn_type):
             with m.Case(InternalOp.OP_MCRF):
                 # MCRF copies the 4 bits of crA to crB (for instance
@@ -108,6 +115,7 @@ class CRMainStage(PipeModBase):
                 fxm = Signal(xfx_fields['FXM'][0:-1].shape())
                 comb += fxm.eq(xfx_fields['FXM'][0:-1])
 
+                # mtcrf
                 mask = Signal(32, reset_less=True)
 
                 for i in range(8):
@@ -115,6 +123,7 @@ class CRMainStage(PipeModBase):
 
                 comb += cr_output.eq((self.i.a[0:32] & mask) |
                                      (self.i.cr & ~mask))
+                    
 
         comb += self.o.cr.eq(cr_output)
         comb += self.o.ctx.eq(self.i.ctx)
index 42133771a664f095bcb318f0557220811dcdf51e..ccb41a76faf9642fb0efa578272533cd6a244ee9 100644 (file)
@@ -92,7 +92,15 @@ class CRTestCase(FHDLTestCase):
             initial_regs[2] = random.randint(0, (1<<32)-1)
             self.run_tst_program(Program(lst), initial_regs=initial_regs,
                                  initial_cr=cr)
-        
+    def test_mtocrf(self):
+        for i in range(20):
+            mask = 1<<random.randint(0, 7)
+            lst = [f"mtocrf {mask}, 2"]
+            cr = random.randint(0, (1<<32)-1)
+            initial_regs = [0] * 32
+            initial_regs[2] = random.randint(0, (1<<32)-1)
+            self.run_tst_program(Program(lst), initial_regs=initial_regs,
+                                 initial_cr=cr)
 
     def test_ilang(self):
         rec = CompALUOpSubset()