self.lk = Signal(reset_less=True)
         self.rc = Data(1, "rc")
         self.oe = Data(1, "oe")
-        self.xer_in = Signal(reset_less=True)   # xer might be read
-        self.xer_out = Signal(reset_less=True)  # xer might be written
         self.invert_a = Signal(reset_less=True)
         self.zero_a = Signal(reset_less=True)
         self.input_carry = Signal(CryIn, reset_less=True)
         self.update  = Signal(reset_less=True) # LD/ST is "update" variant
         self.traptype  = Signal(5, reset_less=True) # see trap main_stage.py
         self.trapaddr  = Signal(13, reset_less=True)
+        self.read_cr_whole = Signal(reset_less=True)
+        self.write_cr_whole = Signal(reset_less=True)
+        self.write_cr0 = Signal(reset_less=True)
 
 
-class Decode2ToExecute1Type(Decode2ToOperand):
+class Decode2ToExecute1Type(RecordObject):
 
     def __init__(self, name=None, asmcode=True):
 
-        Decode2ToOperand.__init__(self, name=name)
+        RecordObject.__init__(self, name=name)
 
         if asmcode:
             self.asmcode = Signal(8, reset_less=True) # only for simulator
         self.read_spr1 = Data(SPR, name="spr1")
         #self.read_spr2 = Data(SPR, name="spr2") # only one needed
 
+        self.xer_in = Signal(reset_less=True)   # xer might be read
+        self.xer_out = Signal(reset_less=True)  # xer might be written
+
         self.read_fast1 = Data(3, name="fast1")
         self.read_fast2 = Data(3, name="fast2")
         self.write_fast1 = Data(3, name="fasto1")
         self.read_cr1 = Data(3, name="cr_in1")
         self.read_cr2 = Data(3, name="cr_in2")
         self.read_cr3 = Data(3, name="cr_in2")
-        self.read_cr_whole = Signal(reset_less=True)
         self.write_cr = Data(3, name="cr_out")
-        self.write_cr_whole = Signal(reset_less=True)
 
+        # decode operand data
+        self.do = Decode2ToOperand(name)
 
         self.namespace['CA32'] = self.spr['XER'][XER_bits['CA32']].value
 
     def handle_carry_(self, inputs, outputs, already_done):
-        inv_a = yield self.dec2.e.invert_a
+        inv_a = yield self.dec2.e.do.invert_a
         if inv_a:
             inputs[0] = ~inputs[0]
 
-        imm_ok = yield self.dec2.e.imm_data.ok
+        imm_ok = yield self.dec2.e.do.imm_data.ok
         if imm_ok:
-            imm = yield self.dec2.e.imm_data.data
+            imm = yield self.dec2.e.do.imm_data.data
             inputs.append(SelectableInt(imm, 64))
         assert len(outputs) >= 1
         print ("outputs", repr(outputs))
             self.spr['XER'][XER_bits['CA32']] = cy32
 
     def handle_overflow(self, inputs, outputs, div_overflow):
-        inv_a = yield self.dec2.e.invert_a
+        inv_a = yield self.dec2.e.do.invert_a
         if inv_a:
             inputs[0] = ~inputs[0]
 
-        imm_ok = yield self.dec2.e.imm_data.ok
+        imm_ok = yield self.dec2.e.do.imm_data.ok
         if imm_ok:
-            imm = yield self.dec2.e.imm_data.data
+            imm = yield self.dec2.e.do.imm_data.data
             inputs.append(SelectableInt(imm, 64))
         assert len(outputs) >= 1
         print ("handle_overflow", inputs, outputs, div_overflow)
         asmop = insns.get(asmcode, None)
 
         # sigh reconstruct the assembly instruction name
-        ov_en = yield self.dec2.e.oe.oe
-        ov_ok = yield self.dec2.e.oe.ok
+        ov_en = yield self.dec2.e.do.oe.oe
+        ov_ok = yield self.dec2.e.do.oe.ok
         if ov_en & ov_ok:
             asmop += "."
-        lk = yield self.dec2.e.lk
+        lk = yield self.dec2.e.do.lk
         if lk:
             asmop += "l"
         int_op = yield self.dec2.dec.op.internal_op
             if AA:
                 asmop += "a"
         if int_op == InternalOp.OP_MFCR.value:
-            dec_insn = yield self.dec2.e.insn
+            dec_insn = yield self.dec2.e.do.insn
             if dec_insn & (1<<20) != 0: # sigh
                 asmop = 'mfocrf'
             else:
         # XXX TODO: for whatever weird reason this doesn't work
         # https://bugs.libre-soc.org/show_bug.cgi?id=390
         if int_op == InternalOp.OP_MTCRF.value:
-            dec_insn = yield self.dec2.e.insn
+            dec_insn = yield self.dec2.e.do.insn
             if dec_insn & (1<<20) != 0: # sigh
                 asmop = 'mtocrf'
             else:
                     already_done |= 2
 
         print ("carry already done?", bin(already_done))
-        carry_en = yield self.dec2.e.output_carry
+        carry_en = yield self.dec2.e.do.output_carry
         if carry_en:
             yield from self.handle_carry_(inputs, results, already_done)
 
                 if name == 'overflow':
                     overflow = output
 
-        ov_en = yield self.dec2.e.oe.oe
-        ov_ok = yield self.dec2.e.oe.ok
+        ov_en = yield self.dec2.e.do.oe.oe
+        ov_ok = yield self.dec2.e.do.oe.ok
         print ("internal overflow", overflow)
         if ov_en & ov_ok:
             yield from self.handle_overflow(inputs, results, overflow)
 
-        rc_en = yield self.dec2.e.rc.data
+        rc_en = yield self.dec2.e.do.rc.data
         if rc_en:
             self.handle_comparison(results)
 
 
     def elaborate(self, platform):
         m = Module()
         comb = m.d.comb
-        e, op = self.e, self.dec.op
+        e, op, do = self.e, self.dec.op, self.e.do
 
         # set up submodule decoders
         m.submodules.dec = self.dec
         m.submodules.dec_cr_out = dec_cr_out = DecodeCROut(self.dec)
 
         # copy instruction through...
-        for i in [e.insn, dec_a.insn_in, dec_b.insn_in,
+        for i in [do.insn, dec_a.insn_in, dec_b.insn_in,
                   dec_c.insn_in, dec_o.insn_in, dec_o2.insn_in, dec_rc.insn_in,
                   dec_oe.insn_in, dec_cr_in.insn_in, dec_cr_out.insn_in]:
             comb += i.eq(self.dec.opcode_in)
         comb += dec_c.sel_in.eq(op.in3_sel)
         comb += dec_o.sel_in.eq(op.out_sel)
         comb += dec_o2.sel_in.eq(op.out_sel)
-        comb += dec_o2.lk.eq(e.lk)
+        comb += dec_o2.lk.eq(do.lk)
         comb += dec_rc.sel_in.eq(op.rc_sel)
         comb += dec_oe.sel_in.eq(op.rc_sel) # XXX should be OE sel
         comb += dec_cr_in.sel_in.eq(op.cr_in)
         comb += e.nia.eq(0)    # XXX TODO (or remove? not sure yet)
         fu = op.function_unit
         itype = Mux(fu == Function.NONE, InternalOp.OP_ILLEGAL, op.internal_op)
-        comb += e.insn_type.eq(itype)
-        comb += e.fn_unit.eq(fu)
+        comb += do.insn_type.eq(itype)
+        comb += do.fn_unit.eq(fu)
 
         # registers a, b, c and out and out2 (LD/ST EA)
         comb += e.read_reg1.eq(dec_a.reg_out)
         comb += e.read_reg3.eq(dec_c.reg_out)
         comb += e.write_reg.eq(dec_o.reg_out)
         comb += e.write_ea.eq(dec_o2.reg_out)
-        comb += e.imm_data.eq(dec_b.imm_out) # immediate in RB (usually)
-        comb += e.zero_a.eq(dec_a.immz_out)  # RA==0 detected
+        comb += do.imm_data.eq(dec_b.imm_out) # immediate in RB (usually)
+        comb += do.zero_a.eq(dec_a.immz_out)  # RA==0 detected
 
         # rc and oe out
-        comb += e.rc.eq(dec_rc.rc_out)
-        comb += e.oe.eq(dec_oe.oe_out)
+        comb += do.rc.eq(dec_rc.rc_out)
+        comb += do.oe.eq(dec_oe.oe_out)
 
         # SPRs out
         comb += e.read_spr1.eq(dec_a.spr_out)
         comb += e.read_cr1.eq(dec_cr_in.cr_bitfield)
         comb += e.read_cr2.eq(dec_cr_in.cr_bitfield_b)
         comb += e.read_cr3.eq(dec_cr_in.cr_bitfield_o)
-        comb += e.read_cr_whole.eq(dec_cr_in.whole_reg)
-
         comb += e.write_cr.eq(dec_cr_out.cr_bitfield)
-        comb += e.write_cr_whole.eq(dec_cr_out.whole_reg)
+
+        comb += do.read_cr_whole.eq(dec_cr_in.whole_reg)
+        comb += do.write_cr_whole.eq(dec_cr_out.whole_reg)
+        comb += do.write_cr0.eq(dec_cr_out.cr_bitfield.ok)
 
         # decoded/selected instruction flags
-        comb += e.data_len.eq(op.ldst_len)
-        comb += e.invert_a.eq(op.inv_a)
-        comb += e.invert_out.eq(op.inv_out)
-        comb += e.input_carry.eq(op.cry_in)   # carry comes in
-        comb += e.output_carry.eq(op.cry_out) # carry goes out
-        comb += e.is_32bit.eq(op.is_32b)
-        comb += e.is_signed.eq(op.sgn)
+        comb += do.data_len.eq(op.ldst_len)
+        comb += do.invert_a.eq(op.inv_a)
+        comb += do.invert_out.eq(op.inv_out)
+        comb += do.input_carry.eq(op.cry_in)   # carry comes in
+        comb += do.output_carry.eq(op.cry_out) # carry goes out
+        comb += do.is_32bit.eq(op.is_32b)
+        comb += do.is_signed.eq(op.sgn)
         with m.If(op.lk):
-            comb += e.lk.eq(self.dec.LK) # XXX TODO: accessor
+            comb += do.lk.eq(self.dec.LK) # XXX TODO: accessor
 
-        comb += e.byte_reverse.eq(op.br)
-        comb += e.sign_extend.eq(op.sgn_ext)
-        comb += e.update.eq(op.upd) # LD/ST "update" mode.
+        comb += do.byte_reverse.eq(op.br)
+        comb += do.sign_extend.eq(op.sgn_ext)
+        comb += do.update.eq(op.upd) # LD/ST "update" mode.
 
         # These should be removed eventually
-        comb += e.input_cr.eq(op.cr_in)   # condition reg comes in
-        comb += e.output_cr.eq(op.cr_out) # condition reg goes in
+        comb += do.input_cr.eq(op.cr_in)   # condition reg comes in
+        comb += do.output_cr.eq(op.cr_out) # condition reg goes in
 
         # sigh this is exactly the sort of thing for which the
         # decoder is designed to not need.  MTSPR, MFSPR and others need
 
         # set the trapaddr to 0x700 for a td/tw/tdi/twi operation
         with m.If(op.internal_op == InternalOp.OP_TRAP):
-            comb += e.trapaddr.eq(0x70)    # addr=0x700 (strip first nibble)
+            comb += do.trapaddr.eq(0x70)    # addr=0x700 (strip first nibble)
 
         # illegal instruction must redirect to trap. this is done by
         # *overwriting* the decoded instruction and starting again.
         with m.If(op.internal_op == InternalOp.OP_ILLEGAL):
             comb += e.eq(0) # reset eeeeeverything
             # start again
-            comb += e.insn.eq(self.dec.opcode_in)
-            comb += e.insn_type.eq(InternalOp.OP_TRAP)
-            comb += e.fn_unit.eq(Function.TRAP)
-            comb += e.trapaddr.eq(0x70)    # addr=0x700 (strip first nibble)
-            comb += e.traptype.eq(TT_ILLEG) # request illegal instruction
+            comb += do.insn.eq(self.dec.opcode_in)
+            comb += do.insn_type.eq(InternalOp.OP_TRAP)
+            comb += do.fn_unit.eq(Function.TRAP)
+            comb += do.trapaddr.eq(0x70)    # addr=0x700 (strip first nibble)
+            comb += do.traptype.eq(TT_ILLEG) # request illegal instruction
 
         # trap: (note e.insn_type so this includes OP_ILLEGAL) set up fast regs
         # Note: OP_SC could actually be modified to just be a trap
-        with m.If((e.insn_type == InternalOp.OP_TRAP) |
-                  (e.insn_type == InternalOp.OP_SC)):
+        with m.If((do.insn_type == InternalOp.OP_TRAP) |
+                  (do.insn_type == InternalOp.OP_SC)):
             # TRAP write fast1 = SRR0
             comb += e.write_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
             comb += e.write_fast1.ok.eq(1)
             comb += e.write_fast2.ok.eq(1)
 
         # RFID: needs to read SRR0/1
-        with m.If(e.insn_type == InternalOp.OP_RFID):
+        with m.If(do.insn_type == InternalOp.OP_RFID):
             # TRAP read fast1 = SRR0
             comb += e.read_fast1.data.eq(FastRegs.SRR0) # constant: SRR0
             comb += e.read_fast1.ok.eq(1)
 
         # CRRegs register numbering is *unary* encoded
         # *sigh*.  numbering inverted on part-CRs.  because POWER.
         if name == 'full_cr': # full CR
-            return e.read_cr_whole, 0b11111111
+            return e.do.read_cr_whole, 0b11111111
         if name == 'cr_a': # CR A
             return e.read_cr1.ok, 1<<(7-e.read_cr1.data)
         if name == 'cr_b': # CR B
         CA = 1<<XERRegs.CA
         OV = 1<<XERRegs.OV
         if name == 'xer_so':
-            return (e.oe.oe[0] & e.oe.oe_ok) | e.xer_in, SO
+            return (e.do.oe.oe[0] & e.do.oe.oe_ok) | e.xer_in, SO
         if name == 'xer_ov':
-            return (e.oe.oe[0] & e.oe.oe_ok) | e.xer_in, OV
+            return (e.do.oe.oe[0] & e.do.oe.oe_ok) | e.xer_in, OV
         if name == 'xer_ca':
-            return (e.input_carry == CryIn.CA.value) | e.xer_in, CA
+            return (e.do.input_carry == CryIn.CA.value) | e.xer_in, CA
 
     # FAST regfile
 
         # CRRegs register numbering is *unary* encoded
         # *sigh*.  numbering inverted on part-CRs.  because POWER.
         if name == 'full_cr': # full CR
-            return e.write_cr_whole, 0b11111111
+            return e.do.write_cr_whole, 0b11111111
         if name == 'cr_a': # CR A
             return e.write_cr, 1<<(7-e.write_cr.data)
 
 
                   ('invert_a', 1),
                   ('zero_a', 1),
                   ('invert_out', 1),
-                  ('write_cr', Layout((("data", 3), ("ok", 1)))), # Data
+                  ('write_cr0', 1),
                   ('input_carry', CryIn),
                   ('output_carry', 1),
                   ('input_cr', 1),
         """
         res = []
         for fname, sig in self.fields.items():
-            eqfrom = other.fields[fname]
+            eqfrom = other.do.fields[fname]
             res.append(sig.eq(eqfrom))
         return res
 
 
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
                     yield instruction.eq(ins)          # raw binary instr.
                     yield Settle()
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     self.assertEqual(fn_unit, Function.ALU.value)
                     yield from set_alu_inputs(alu, pdecode2, sim)
                     yield
 
     def check_alu_outputs(self, alu, dec2, sim, code):
 
-        rc = yield dec2.e.rc.data
+        rc = yield dec2.e.do.rc.data
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
         if rc:
             self.assertEqual(cridx, 0, code)
 
-        oe = yield dec2.e.oe.oe
-        oe_ok = yield dec2.e.oe.ok
+        oe = yield dec2.e.do.oe.oe
+        oe_ok = yield dec2.e.do.oe.ok
         if not oe or not oe_ok:
             # if OE not enabled, XER SO and OV must correspondingly be false
             so_ok = yield alu.n.data_o.xer_so.ok
 
         """
         res = []
         for fname, sig in self.fields.items():
-            eqfrom = other.fields[fname]
+            eqfrom = other.do.fields[fname]
             res.append(sig.eq(eqfrom))
         return res
 
 
                     # then additional op-decoding is required, accordingly
                     yield Settle()
                     yield from self.set_inputs(branch, pdecode2, simulator)
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     self.assertEqual(fn_unit, Function.BRANCH.value, code)
                     yield
                     yield
         # TODO: check write_fast1 as well (should contain CTR)
 
         # TODO: this should be checking write_fast2
-        lk = yield dec2.e.lk
+        lk = yield dec2.e.do.lk
         branch_lk = yield branch.n.data_o.lr.ok
         self.assertEqual(lk, branch_lk, code)
         if lk:
 
         comb += self.o.o.ok.eq(self.i.o.ok)
         # CR0 to be set
         comb += self.o.cr0.data.eq(cr0)
-        comb += self.o.cr0.ok.eq(op.write_cr.ok)
+        comb += self.o.cr0.ok.eq(op.write_cr0)
         # context
         comb += self.o.ctx.eq(self.i.ctx)
 
 
         """naming (res) must conform to ALUFunctionUnit output regspec
         """
 
-        rc = yield dec2.e.rc.data
-        op = yield dec2.e.insn_type
+        rc = yield dec2.e.do.rc.data
+        op = yield dec2.e.do.insn_type
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
 
             self.assertEqual(branch_addr, sim.pc.CIA.value, code)
 
         # Link SPR
-        lk = yield dec2.e.lk
+        lk = yield dec2.e.do.lk
         branch_lk = 'fast2' in res
         self.assertEqual(lk, branch_lk, code)
         if lk:
 
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
                     yield instruction.eq(ins)          # raw binary instr.
                     yield Settle()
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     fuval = self.funit.value
                     self.assertEqual(fn_unit & fuval, fuval)
 
 
         print ("check extra output", repr(code), res)
 
         # full CR
-        whole_reg = yield dec2.e.write_cr_whole
+        whole_reg = yield dec2.e.do.write_cr_whole
         cr_en = yield dec2.e.write_cr.ok
         if whole_reg:
             full_cr = res['full_cr']
 
         """naming (res) must conform to LogicalFunctionUnit output regspec
         """
 
-        rc = yield dec2.e.rc.data
-        op = yield dec2.e.insn_type
+        rc = yield dec2.e.do.rc.data
+        op = yield dec2.e.do.insn_type
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
 
             print(f"expected {expected:x}, actual: {cu_out:x}")
             self.assertEqual(expected, cu_out, code)
 
-        rc = yield dec2.e.rc.data
-        op = yield dec2.e.insn_type
+        rc = yield dec2.e.do.rc.data
+        op = yield dec2.e.do.insn_type
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
             self.assertEqual(cr_expected, cr_actual, "CR%d %s" % (cridx, code))
 
         # XER.ca
-        cry_out = yield dec2.e.output_carry
+        cry_out = yield dec2.e.do.output_carry
         if cry_out:
             expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
             xer_ca = res['xer_ca']
 
         """naming (res) must conform to SPRFunctionUnit output regspec
         """
 
-        rc = yield dec2.e.rc.data
-        op = yield dec2.e.insn_type
+        rc = yield dec2.e.do.rc.data
+        op = yield dec2.e.do.insn_type
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
 
         """naming (res) must conform to TrapFunctionUnit output regspec
         """
 
-        rc = yield dec2.e.rc.data
-        op = yield dec2.e.insn_type
+        rc = yield dec2.e.do.rc.data
+        op = yield dec2.e.do.insn_type
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
 
         """
         res = []
         for fname, sig in self.fields.items():
-            eqfrom = other.fields[fname]
+            eqfrom = other.do.fields[fname]
             res.append(sig.eq(eqfrom))
         return res
 
 
     """naming (res) must conform to CRFunctionUnit input regspec
     """
     res = {}
-    full_reg = yield dec2.e.read_cr_whole
+    full_reg = yield dec2.e.do.read_cr_whole
 
     # full CR
     print(sim.cr.get_range().value)
         yield from ALUHelpers.set_int_rb(alu, dec2, inp)
 
     def assert_outputs(self, alu, dec2, simulator, code):
-        whole_reg = yield dec2.e.write_cr_whole
+        whole_reg = yield dec2.e.do.write_cr_whole
         cr_en = yield dec2.e.write_cr.ok
         if whole_reg:
             full_cr = yield alu.n.data_o.full_cr.data
                     yield Settle()
                     yield from self.set_inputs(alu, pdecode2, sim)
                     yield alu.p.valid_i.eq(1)
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     self.assertEqual(fn_unit, Function.CR.value, code)
                     yield
                     opname = code.split(' ')[0]
 
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
                     yield instruction.eq(ins)          # raw binary instr.
                     yield Settle()
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     self.assertEqual(fn_unit, Function.DIV.value)
                     yield from set_alu_inputs(alu, pdecode2, sim)
                     yield
 
     def check_alu_outputs(self, alu, dec2, sim, code):
 
-        rc = yield dec2.e.rc.data
+        rc = yield dec2.e.do.rc.data
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
         if rc:
             self.assertEqual(cridx, 0, code)
 
-        oe = yield dec2.e.oe.oe
-        oe_ok = yield dec2.e.oe.ok
+        oe = yield dec2.e.do.oe.oe
+        oe_ok = yield dec2.e.do.oe.ok
         if not oe or not oe_ok:
             # if OE not enabled, XER SO and OV must correspondingly be false
             so_ok = yield alu.n.data_o.xer_so.ok
 
         """
         res = []
         for fname, sig in self.fields.items():
-            eqfrom = other.fields[fname]
+            eqfrom = other.do.fields[fname]
             res.append(sig.eq(eqfrom))
         return res
 
 
                   ('zero_a', 1),
                   ('input_carry', CryIn),
                   ('invert_out', 1),
-                  ('write_cr', Layout((("data", 3), ("ok", 1)))), # Data
+                  ('write_cr0', 1),
                   ('output_carry', 1),
                   ('is_32bit', 1),
                   ('is_signed', 1),
         """
         res = []
         for fname, sig in self.fields.items():
-            eqfrom = other.fields[fname]
+            eqfrom = other.do.fields[fname]
             res.append(sig.eq(eqfrom))
         return res
 
 
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
                     yield instruction.eq(ins)          # raw binary instr.
                     yield Settle()
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     self.assertEqual(fn_unit, Function.LOGICAL.value, code)
                     yield from set_alu_inputs(alu, pdecode2, simulator)
                     yield
 
     def check_alu_outputs(self, alu, dec2, sim, code):
 
-        rc = yield dec2.e.rc.data
+        rc = yield dec2.e.do.rc.data
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
 
                   ('imm_data', Layout((("imm", 64), ("imm_ok", 1)))),
                   ('rc', Layout((("rc", 1), ("rc_ok", 1)))),
                   ('oe', Layout((("oe", 1), ("oe_ok", 1)))),
-                  ('write_cr', Layout((("data", 3), ("ok", 1)))), # Data
+                  ('write_cr0', 0),
                   ('input_carry', CryIn),
                   ('output_carry', 1),
                   ('input_cr', 1),
         """
         res = []
         for fname, sig in self.fields.items():
-            eqfrom = other.fields[fname]
+            eqfrom = other.do.fields[fname]
             res.append(sig.eq(eqfrom))
         return res
 
 
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
                     yield instruction.eq(ins)          # raw binary instr.
                     yield Settle()
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     self.assertEqual(fn_unit, Function.SHIFT_ROT.value)
                     yield from set_alu_inputs(alu, pdecode2, simulator)
                     yield
 
     def check_alu_outputs(self, alu, dec2, sim, code):
 
-        rc = yield dec2.e.rc.data
+        rc = yield dec2.e.do.rc.data
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
 
         """
         res = []
         for fname, sig in self.fields.items():
-            eqfrom = other.fields[fname]
+            eqfrom = other.do.fields[fname]
             res.append(sig.eq(eqfrom))
         return res
 
 
                     spr_out = yield pdecode2.e.write_spr.data
                     print ("dec2 spr/fast in", fast_out, spr_out)
 
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     self.assertEqual(fn_unit, Function.SPR.value)
                     yield from set_alu_inputs(alu, pdecode2, sim)
                     yield
 
     def check_alu_outputs(self, alu, dec2, sim, code):
 
-        rc = yield dec2.e.rc.data
+        rc = yield dec2.e.do.rc.data
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
 
             res['rc'] = sim.gpr(data).value
 
     def get_rd_sim_xer_ca(res, sim, dec2):
-        cry_in = yield dec2.e.input_carry
+        cry_in = yield dec2.e.do.input_carry
         xer_in = yield dec2.e.xer_in
         if xer_in or cry_in == CryIn.CA.value:
             expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
         if 'rb' in inp:
             yield alu.p.data_i.rb.eq(inp['rb'])
         # If there's an immediate, set the B operand to that
-        imm_ok = yield dec2.e.imm_data.imm_ok
+        imm_ok = yield dec2.e.do.imm_data.imm_ok
         if imm_ok:
-            data2 = yield dec2.e.imm_data.imm
+            data2 = yield dec2.e.do.imm_data.imm
             yield alu.p.data_i.rb.eq(data2)
 
     def set_int_rc(alu, dec2, inp):
             res['cr_a'] = yield alu.n.data_o.cr0.data
 
     def get_xer_so(res, alu, dec2):
-        oe = yield dec2.e.oe.oe
-        oe_ok = yield dec2.e.oe.ok
+        oe = yield dec2.e.do.oe.oe
+        oe_ok = yield dec2.e.do.oe.ok
         xer_out = yield dec2.e.xer_out
         if xer_out or (oe and oe_ok):
             res['xer_so'] = yield alu.n.data_o.xer_so.data[0]
 
     def get_xer_ov(res, alu, dec2):
-        oe = yield dec2.e.oe.oe
-        oe_ok = yield dec2.e.oe.ok
+        oe = yield dec2.e.do.oe.oe
+        oe_ok = yield dec2.e.do.oe.ok
         xer_out = yield dec2.e.xer_out
         if xer_out or (oe and oe_ok):
             res['xer_ov'] = yield alu.n.data_o.xer_ov.data
 
     def get_xer_ca(res, alu, dec2):
-        cry_out = yield dec2.e.output_carry
+        cry_out = yield dec2.e.do.output_carry
         xer_out = yield dec2.e.xer_out
         if xer_out or (cry_out):
             res['xer_ca'] = yield alu.n.data_o.xer_ca.data
             res['spr1'] = sim.spr[spr_name].value
 
     def get_wr_sim_xer_ca(res, sim, dec2):
-        cry_out = yield dec2.e.output_carry
+        cry_out = yield dec2.e.do.output_carry
         if cry_out:
             expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
             expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
             res['xer_ca'] = expected_carry | (expected_carry32 << 1)
 
     def get_sim_xer_ov(res, sim, dec2):
-        oe = yield dec2.e.oe.oe
-        oe_ok = yield dec2.e.oe.ok
+        oe = yield dec2.e.do.oe.oe
+        oe_ok = yield dec2.e.do.oe.ok
         xer_in = yield dec2.e.xer_in
         print ("get_sim_xer_ov", xer_in)
         if xer_in or (oe and oe_ok):
             res['xer_ov'] = expected_ov | (expected_ov32 << 1)
 
     def get_sim_xer_so(res, sim, dec2):
-        oe = yield dec2.e.oe.oe
-        oe_ok = yield dec2.e.oe.ok
+        oe = yield dec2.e.do.oe.oe
+        oe_ok = yield dec2.e.do.oe.ok
         xer_in = yield dec2.e.xer_in
         if xer_in or (oe and oe_ok):
             res['xer_so'] = 1 if sim.spr['XER'][XER_bits['SO']] else 0
 
                     yield pdecode2.dec.bigendian.eq(0)  # little / big?
                     yield instruction.eq(ins)          # raw binary instr.
                     yield Settle()
-                    fn_unit = yield pdecode2.e.fn_unit
+                    fn_unit = yield pdecode2.e.do.fn_unit
                     self.assertEqual(fn_unit, Function.TRAP.value)
                     yield from set_alu_inputs(alu, pdecode2, sim)
                     yield
 
     def check_alu_outputs(self, alu, dec2, sim, code):
 
-        rc = yield dec2.e.rc.data
+        rc = yield dec2.e.do.rc.data
         cridx_ok = yield dec2.e.write_cr.ok
         cridx = yield dec2.e.write_cr.data
 
 
         """
         res = []
         for fname, sig in self.fields.items():
-            eqfrom = other.fields[fname]
+            eqfrom = other.do.fields[fname]
             res.append(sig.eq(eqfrom))
         return res
 
 
         for funame, fu in fus.items():
             fnunit = fu.fnunit.value
             enable = Signal(name="en_%s" % funame, reset_less=True)
-            comb += enable.eq(self.ivalid_i & (dec2.e.fn_unit & fnunit).bool())
+            comb += enable.eq(self.ivalid_i &
+                             (dec2.e.do.fn_unit & fnunit).bool())
             with m.If(enable):
                 comb += fu.oper_i.eq_from_execute1(dec2.e)
                 comb += fu.issue_i.eq(self.issue_i)
 
     so = yield xregs.regs[xregs.SO].reg
     ov = yield xregs.regs[xregs.OV].reg
     ca = yield xregs.regs[xregs.CA].reg
-    oe = yield pdecode2.e.oe.oe
-    oe_ok = yield pdecode2.e.oe.oe_ok
+    oe = yield pdecode2.e.do.oe.oe
+    oe_ok = yield pdecode2.e.do.oe.oe_ok
 
     print ("before: so/ov-32/ca-32", so, bin(ov), bin(ca))
     print ("oe:", oe, oe_ok)