although shift-rot does not alter XER.so it still needs it as input for CR0
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 25 Aug 2020 13:30:04 +0000 (14:30 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 25 Aug 2020 13:30:04 +0000 (14:30 +0100)
src/soc/fu/shift_rot/main_stage.py
src/soc/fu/shift_rot/pipe_data.py
src/soc/fu/shift_rot/pipeline.py
src/soc/fu/shift_rot/test/test_pipe_caller.py

index c0459874e9e370717d2483f446aa952ddb6f48ae..9b0d3fc05c5675cf1c315c2ac93b200ce1b12699 100644 (file)
@@ -8,7 +8,7 @@
 # output stage
 from nmigen import (Module, Signal, Cat, Repl, Mux, Const)
 from nmutil.pipemodbase import PipeModBase
-from soc.fu.logical.pipe_data import LogicalOutputData
+from soc.fu.alu.pipe_data import ALUOutputData
 from soc.fu.shift_rot.pipe_data import ShiftRotInputData
 from ieee754.part.partsig import PartitionedSignal
 from soc.decoder.power_enums import MicrOp
@@ -28,7 +28,7 @@ class ShiftRotMainStage(PipeModBase):
         return ShiftRotInputData(self.pspec)
 
     def ospec(self):
-        return LogicalOutputData(self.pspec)
+        return ALUOutputData(self.pspec)
 
     def elaborate(self, platform):
         m = Module()
@@ -88,6 +88,7 @@ class ShiftRotMainStage(PipeModBase):
 
         ###### sticky overflow and context, both pass-through #####
 
+        comb += self.o.xer_so.data.eq(self.i.xer_so)
         comb += self.o.ctx.eq(self.i.ctx)
 
         return m
index 0477629670c0947d618a66c09b8595ca2aac1a92..cbcca907abc38b48eb9cecaeb7fbafb46ffba592 100644 (file)
@@ -1,12 +1,13 @@
 from soc.fu.shift_rot.sr_input_record import CompSROpSubset
 from soc.fu.pipe_data import IntegerData, CommonPipeSpec
-from soc.fu.logical.pipe_data import LogicalOutputData
+from soc.fu.alu.pipe_data import ALUOutputData
 
 
 class ShiftRotInputData(IntegerData):
     regspec = [('INT', 'ra', '0:63'),      # RA
                ('INT', 'rb', '0:63'),      # RB
                ('INT', 'rc', '0:63'),      # RS
+               ('XER', 'xer_so', '32'), # XER bit 32: SO
                ('XER', 'xer_ca', '34,45')] # XER bit 34/45: CA/CA32
     def __init__(self, pspec):
         super().__init__(pspec, False)
@@ -14,7 +15,10 @@ class ShiftRotInputData(IntegerData):
         self.a, self.b, self.rs = self.ra, self.rb, self.rc
 
 
-
+# sigh although ShiftRot never changes xer_ov it is just easier
+# right now to have it.  also SO never gets changed, although it
+# is an input (to create CR).  really need something similar to
+# MulOutputData which has xer_so yet derives from LogicalOutputData
 class ShiftRotPipeSpec(CommonPipeSpec):
-    regspec = (ShiftRotInputData.regspec, LogicalOutputData.regspec)
+    regspec = (ShiftRotInputData.regspec, ALUOutputData.regspec)
     opsubsetkls = CompSROpSubset
index 3a2a5ab8e0f6c7acdf770db75e79e3d7a8753b81..7af49a20e065e4c200985e1ac837faa45fa058b1 100644 (file)
@@ -2,7 +2,7 @@ from nmutil.singlepipe import ControlBase
 from nmutil.pipemodbase import PipeModBaseChain
 from soc.fu.shift_rot.input_stage import ShiftRotInputStage
 from soc.fu.shift_rot.main_stage import ShiftRotMainStage
-from soc.fu.logical.output_stage import LogicalOutputStage
+from soc.fu.alu.output_stage import ALUOutputStage
 
 class ShiftRotStages(PipeModBaseChain):
     def get_chain(self):
@@ -13,7 +13,7 @@ class ShiftRotStages(PipeModBaseChain):
 
 class ShiftRotStageEnd(PipeModBaseChain):
     def get_chain(self):
-        out = LogicalOutputStage(self.pspec)
+        out = ALUOutputStage(self.pspec)
         return [out]
 
 
index e84ebf04cdd1c766d5443d9f5e6aff8441179fba..0b2666b0f4a78ad91eeeda9703f9b0e2dd8ccf8f 100644 (file)
@@ -38,8 +38,9 @@ def get_cu_inputs(dec2, sim):
     yield from ALUHelpers.get_sim_int_rb(res, sim, dec2)  # RB
     yield from ALUHelpers.get_sim_int_rc(res, sim, dec2)  # RC
     yield from ALUHelpers.get_rd_sim_xer_ca(res, sim, dec2)  # XER.ca
+    yield from ALUHelpers.get_sim_xer_so(res, sim, dec2)  # XER.so
 
-    print("inputs", res)
+    print("alu get_cu_inputs", res)
 
     return res
 
@@ -54,6 +55,7 @@ def set_alu_inputs(alu, dec2, sim):
     yield from ALUHelpers.set_int_rb(alu, dec2, inp)
     yield from ALUHelpers.set_int_rc(alu, dec2, inp)
     yield from ALUHelpers.set_xer_ca(alu, dec2, inp)
+    yield from ALUHelpers.set_xer_so(alu, dec2, inp)
 
 
 # This test bench is a bit different than is usual. Initially when I
@@ -85,6 +87,25 @@ class ShiftRotTestCase(TestAccumulatorBase):
         print(initial_regs[1], initial_regs[2])
         self.add_case(Program(lst, bigendian), initial_regs)
 
+    def case_regression_rldicr_0(self):
+        lst = ["rldicr. 29, 19, 1, 21"]
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x3f
+        initial_regs[19] = 0x00000000ffff8000
+
+        initial_sprs = {'XER': 0xe00c0000}
+
+        self.add_case(Program(lst, bigendian), initial_regs,
+                                initial_sprs=initial_sprs)
+
+    def case_regression_rldicr_1(self):
+        lst = ["rldicr. 29, 19, 1, 21"]
+        initial_regs = [0] * 32
+        initial_regs[1] = 0x3f
+        initial_regs[19] = 0x00000000ffff8000
+
+        self.add_case(Program(lst, bigendian), initial_regs)
+
     def case_shift(self):
         insns = ["slw", "sld", "srw", "srd", "sraw", "srad"]
         for i in range(20):
@@ -297,14 +318,24 @@ class TestRunner(unittest.TestCase):
 
         yield from ALUHelpers.get_cr_a(res, alu, dec2)
         yield from ALUHelpers.get_xer_ca(res, alu, dec2)
+        yield from ALUHelpers.get_xer_ov(res, alu, dec2)
+        yield from ALUHelpers.get_xer_so(res, alu, dec2)
         yield from ALUHelpers.get_int_o(res, alu, dec2)
 
+        print ("hw outputs", res)
+
         yield from ALUHelpers.get_sim_int_o(sim_o, sim, dec2)
         yield from ALUHelpers.get_wr_sim_cr_a(sim_o, sim, dec2)
         yield from ALUHelpers.get_wr_sim_xer_ca(sim_o, sim, dec2)
+        yield from ALUHelpers.get_sim_xer_ov(sim_o, sim, dec2)
+        yield from ALUHelpers.get_sim_xer_so(sim_o, sim, dec2)
+
+        print ("sim outputs", sim_o)
 
         ALUHelpers.check_cr_a(self, res, sim_o, "CR%d %s" % (cridx, code))
         ALUHelpers.check_xer_ca(self, res, sim_o, code)
+        ALUHelpers.check_xer_so(self, res, sim_o, code)
+        ALUHelpers.check_xer_ov(self, res, sim_o, code)
         ALUHelpers.check_int_o(self, res, sim_o, code)