self.assertEqual(expected, cu_out, code)
 
         rc = yield dec2.e.do.rc.data
+        rc_ok = yield dec2.e.do.rc.ok
         op = yield dec2.e.do.insn_type
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
-        print("check extra output", repr(code), cridx_ok, cridx)
+        print("check extra output", repr(code), "cr", cridx_ok, cridx,
+                                    "rc", rc, rc_ok)
 
-        if rc:
+        if rc and rc_ok:
             self.assertEqual(cridx_ok, 1, code)
             self.assertEqual(cridx, 0, code)
 
         # CR (CR0-7)
-        if cridx_ok:
+        if cridx_ok and rc and rc_ok:
             cr_expected = sim.crl[cridx].get_range().value
             cr_actual = res['cr_a']
             print("CR", cridx, cr_expected, cr_actual)
 
 # output stage
 from nmigen import (Module, Signal, Cat, Repl, Mux, Const)
 from nmutil.pipemodbase import PipeModBase
-from soc.fu.alu.pipe_data import ALUOutputData
-from soc.fu.shift_rot.pipe_data import ShiftRotInputData
+from soc.fu.shift_rot.pipe_data import (ShiftRotOutputData,
+                                       ShiftRotInputData)
 from ieee754.part.partsig import PartitionedSignal
 from soc.decoder.power_enums import MicrOp
 from soc.fu.shift_rot.rotator import Rotator
         return ShiftRotInputData(self.pspec)
 
     def ospec(self):
-        return ALUOutputData(self.pspec)
+        return ShiftRotOutputData(self.pspec)
 
     def elaborate(self, platform):
         m = Module()
 
--- /dev/null
+# This stage is intended to handle the gating of carry and overflow
+# out, summary overflow generation, and updating the condition
+# register
+from soc.fu.common_output_stage import CommonOutputStage
+from soc.fu.shift_rot.pipe_data import (ShiftRotOutputData,
+                                      ShiftRotOutputDataFinal)
+
+
+class ShiftRotOutputStage(CommonOutputStage):
+
+    def ispec(self):
+        return ShiftRotOutputData(self.pspec)
+
+    def ospec(self):
+        return ShiftRotOutputDataFinal(self.pspec)
+
 
         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
+# input to shiftrot final stage (common output)
+class ShiftRotOutputData(IntegerData):
+    regspec = [('INT', 'o', '0:63'),        # RT
+               ('CR', 'cr_a', '0:3'),
+               ('XER', 'xer_so', '32'),    # bit0: so
+               ('XER', 'xer_ca', '34,45'), # XER bit 34/45: CA/CA32
+               ]
+    def __init__(self, pspec):
+        super().__init__(pspec, True)
+        # convenience
+        self.cr0 = self.cr_a
+
+
+# output from shiftrot final stage (common output) - note that XER.so
+# is *not* included (the only reason it's in the input is because of CR0)
+class ShiftRotOutputDataFinal(IntegerData):
+    regspec = [('INT', 'o', '0:63'),        # RT
+               ('CR', 'cr_a', '0:3'),
+               ('XER', 'xer_ca', '34,45'), # XER bit 34/45: CA/CA32
+               ]
+    def __init__(self, pspec):
+        super().__init__(pspec, True)
+        # convenience
+        self.cr0 = self.cr_a
+
+
 class ShiftRotPipeSpec(CommonPipeSpec):
-    regspec = (ShiftRotInputData.regspec, ALUOutputData.regspec)
+    regspec = (ShiftRotInputData.regspec, ShiftRotOutputDataFinal.regspec)
     opsubsetkls = CompSROpSubset
 
 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.alu.output_stage import ALUOutputStage
+from soc.fu.shift_rot.output_stage import ShiftRotOutputStage
 
 class ShiftRotStages(PipeModBaseChain):
     def get_chain(self):
 
 class ShiftRotStageEnd(PipeModBaseChain):
     def get_chain(self):
-        out = ALUOutputStage(self.pspec)
+        out = ShiftRotOutputStage(self.pspec)
         return [out]
 
 
 
         pspec = ShiftRotPipeSpec(id_wid=2)
         alu = ShiftRotBasePipe(pspec)
         vl = rtlil.convert(alu, ports=alu.ports())
-        with open("pipeline.il", "w") as f:
+        with open("shift_rot_pipeline.il", "w") as f:
             f.write(vl)
 
 
 
         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)