arm: use condition code registers for ARM ISA
authorCurtis Dunham <Curtis.Dunham@arm.com>
Tue, 29 Apr 2014 21:05:02 +0000 (16:05 -0500)
committerCurtis Dunham <Curtis.Dunham@arm.com>
Tue, 29 Apr 2014 21:05:02 +0000 (16:05 -0500)
Analogous to ee049bf (for x86).  Requires a bump of the checkpoint version
and corresponding upgrader code to move the condition code register values
to the new register file.

15 files changed:
src/arch/arm/ccregs.hh [new file with mode: 0644]
src/arch/arm/faults.cc
src/arch/arm/insts/static_inst.cc
src/arch/arm/intregs.hh
src/arch/arm/isa.cc
src/arch/arm/isa.hh
src/arch/arm/isa/operands.isa
src/arch/arm/miscregs.hh
src/arch/arm/nativetrace.cc
src/arch/arm/registers.hh
src/arch/arm/utility.cc
src/cpu/o3/O3CPU.py
src/cpu/simple_thread.hh
src/sim/serialize.hh
util/cpt_upgrader.py

diff --git a/src/arch/arm/ccregs.hh b/src/arch/arm/ccregs.hh
new file mode 100644 (file)
index 0000000..1818d9b
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2014 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Curtis Dunham
+ */
+#ifndef __ARCH_ARM_CCREGS_HH__
+#define __ARCH_ARM_CCREGS_HH__
+
+namespace ArmISA
+{
+
+enum ccRegIndex {
+    CCREG_NZ,
+    CCREG_C,
+    CCREG_V,
+    CCREG_GE,
+    CCREG_FP,
+    CCREG_ZERO,
+    NUM_CCREGS
+};
+
+const char * const ccRegName[NUM_CCREGS] = {
+    "nz",
+    "c",
+    "v",
+    "ge",
+    "fp",
+    "zero"
+};
+
+enum ConditionCode {
+    COND_EQ  =   0,
+    COND_NE, //  1
+    COND_CS, //  2
+    COND_CC, //  3
+    COND_MI, //  4
+    COND_PL, //  5
+    COND_VS, //  6
+    COND_VC, //  7
+    COND_HI, //  8
+    COND_LS, //  9
+    COND_GE, // 10
+    COND_LT, // 11
+    COND_GT, // 12
+    COND_LE, // 13
+    COND_AL, // 14
+    COND_UC  // 15
+};
+
+}
+
+#endif // __ARCH_ARM_CCREGS_HH__
index f8313efd2cd39ddb7efaa34d91f1a386136402d3..6c1992dd6039040ee8ced98c0fe9fcd0a0e536b5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012-2013 ARM Limited
+ * Copyright (c) 2010, 2012-2014 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -466,10 +466,10 @@ ArmFault::invoke(ThreadContext *tc, StaticInstPtr inst)
     SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR);
     SCR scr = tc->readMiscReg(MISCREG_SCR);
     CPSR saved_cpsr = tc->readMiscReg(MISCREG_CPSR);
-    saved_cpsr.nz = tc->readIntReg(INTREG_CONDCODES_NZ);
-    saved_cpsr.c = tc->readIntReg(INTREG_CONDCODES_C);
-    saved_cpsr.v = tc->readIntReg(INTREG_CONDCODES_V);
-    saved_cpsr.ge = tc->readIntReg(INTREG_CONDCODES_GE);
+    saved_cpsr.nz = tc->readCCReg(CCREG_NZ);
+    saved_cpsr.c = tc->readCCReg(CCREG_C);
+    saved_cpsr.v = tc->readCCReg(CCREG_V);
+    saved_cpsr.ge = tc->readCCReg(CCREG_GE);
 
     Addr curPc M5_VAR_USED = tc->pcState().pc();
     ITSTATE it = tc->pcState().itstate();
@@ -615,9 +615,9 @@ ArmFault::invoke64(ThreadContext *tc, StaticInstPtr inst)
     // Save process state into SPSR_ELx
     CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
     CPSR spsr = cpsr;
-    spsr.nz = tc->readIntReg(INTREG_CONDCODES_NZ);
-    spsr.c = tc->readIntReg(INTREG_CONDCODES_C);
-    spsr.v = tc->readIntReg(INTREG_CONDCODES_V);
+    spsr.nz = tc->readCCReg(CCREG_NZ);
+    spsr.c = tc->readCCReg(CCREG_C);
+    spsr.v = tc->readCCReg(CCREG_V);
     if (from64) {
         // Force some bitfields to 0
         spsr.q = 0;
@@ -628,7 +628,7 @@ ArmFault::invoke64(ThreadContext *tc, StaticInstPtr inst)
         spsr.it2 = 0;
         spsr.t = 0;
     } else {
-        spsr.ge = tc->readIntReg(INTREG_CONDCODES_GE);
+        spsr.ge = tc->readCCReg(CCREG_GE);
         ITSTATE it = tc->pcState().itstate();
         spsr.it2 = it.top6;
         spsr.it1 = it.bottom2;
index 260c29a84b33a43a91509a0bb1295df6aba39bce..9f878ac4d74386264abf6314024fd35a3b0df267 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013 ARM Limited
+ * Copyright (c) 2010-2014 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -335,7 +335,8 @@ ArmStaticInst::printReg(std::ostream &os, int reg) const
         ccprintf(os, "%s", ArmISA::miscRegName[rel_reg]);
         break;
       case CCRegClass:
-        panic("printReg: CCRegClass but ARM has no CC regs\n");
+        ccprintf(os, "cc_%s", ArmISA::ccRegName[rel_reg]);
+        break;
     }
 }
 
index f96db30d3d66bf13fef28cffa2b6f03292034e61..d92f58fc435f5935a638540c089c77a88d3aedaf 100644 (file)
@@ -115,11 +115,6 @@ enum IntRegIndex
     INTREG_UREG0,
     INTREG_UREG1,
     INTREG_UREG2,
-    INTREG_CONDCODES_NZ,
-    INTREG_CONDCODES_C,
-    INTREG_CONDCODES_V,
-    INTREG_CONDCODES_GE,
-    INTREG_FPCONDCODES,
     INTREG_DUMMY, // Dummy reg used to throw away int reg results
 
     INTREG_SP0,
index 38607a9aea35fe1058cbe91edc3625bb37c25b79..e76ff452d04bc7e61864a6aa69fa7a983c431361 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013 ARM Limited
+ * Copyright (c) 2010-2014 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -599,9 +599,9 @@ ISA::readMiscReg(int misc_reg, ThreadContext *tc)
       case MISCREG_NZCV:
         {
             CPSR cpsr = 0;
-            cpsr.nz   = tc->readIntReg(INTREG_CONDCODES_NZ);
-            cpsr.c    = tc->readIntReg(INTREG_CONDCODES_C);
-            cpsr.v    = tc->readIntReg(INTREG_CONDCODES_V);
+            cpsr.nz   = tc->readCCReg(CCREG_NZ);
+            cpsr.c    = tc->readCCReg(CCREG_C);
+            cpsr.v    = tc->readCCReg(CCREG_V);
             return cpsr;
         }
       case MISCREG_DAIF:
@@ -1688,9 +1688,9 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
             {
                 CPSR cpsr = val;
 
-                tc->setIntReg(INTREG_CONDCODES_NZ, cpsr.nz);
-                tc->setIntReg(INTREG_CONDCODES_C,  cpsr.c);
-                tc->setIntReg(INTREG_CONDCODES_V,  cpsr.v);
+                tc->setCCReg(CCREG_NZ, cpsr.nz);
+                tc->setCCReg(CCREG_C,  cpsr.c);
+                tc->setCCReg(CCREG_V,  cpsr.v);
             }
             break;
           case MISCREG_DAIF:
index c72d5d50f17c0cea88d9c5e7421d6d0a29a507f7..8341cd76b98e5e3681dd2ee0404927f14d596e34 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012-2013 ARM Limited
+ * Copyright (c) 2010, 2012-2014 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -268,19 +268,21 @@ namespace ArmISA
         int
         flattenFloatIndex(int reg) const
         {
+            assert(reg >= 0);
             return reg;
         }
 
-        // dummy
         int
         flattenCCIndex(int reg) const
         {
+            assert(reg >= 0);
             return reg;
         }
 
         int
         flattenMiscIndex(int reg) const
         {
+            assert(reg >= 0);
             int flat_idx = reg;
 
             if (reg == MISCREG_SPSR) {
index 7a12133774b370afaeedd9334d88eae314df8ea7..018c0956b9a80ca3e5b617365b8d3a655743453d 100644 (file)
@@ -1,5 +1,5 @@
 // -*- mode:c++ -*-
-// Copyright (c) 2010-2013 ARM Limited
+// Copyright (c) 2010-2014 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -151,8 +151,8 @@ let {{
         return ('IntReg', 'uw', idx, 'IsInteger', srtNormal,
                 maybePCRead, maybeAIWPCWrite)
 
-    def intRegCC(idx):
-        return ('IntReg', 'uw', idx, None, srtNormal)
+    def ccReg(idx):
+        return ('CCReg', 'uw', idx, None, srtNormal)
 
     def cntrlReg(idx, id = srtNormal, type = 'uw'):
         return ('ControlReg', type, idx, None, id)
@@ -221,31 +221,31 @@ def operands {{
     'X2': intRegX64('2'),
     'X3': intRegX64('3'),
 
-    #Pseudo integer condition code registers
-    'CondCodesNZ': intRegCC('INTREG_CONDCODES_NZ'),
-    'CondCodesC': intRegCC('INTREG_CONDCODES_C'),
-    'CondCodesV': intRegCC('INTREG_CONDCODES_V'),
-    'CondCodesGE': intRegCC('INTREG_CONDCODES_GE'),
-    'OptCondCodesNZ': intRegCC(
-            '''(condCode == COND_AL || condCode == COND_UC ||
-                condCode == COND_CC || condCode == COND_CS ||
-                condCode == COND_VS || condCode == COND_VC) ?
-               INTREG_ZERO : INTREG_CONDCODES_NZ'''),
-    'OptCondCodesC': intRegCC(
-            '''(condCode == COND_HI || condCode == COND_LS ||
+    # Condition code registers
+    'CondCodesNZ': ccReg('CCREG_NZ'),
+    'CondCodesC': ccReg('CCREG_C'),
+    'CondCodesV': ccReg('CCREG_V'),
+    'CondCodesGE': ccReg('CCREG_GE'),
+    'OptCondCodesNZ': ccReg(
+            '''((condCode == COND_AL || condCode == COND_UC ||
+                 condCode == COND_CC || condCode == COND_CS ||
+                 condCode == COND_VS || condCode == COND_VC) ?
+                CCREG_ZERO : CCREG_NZ)'''),
+    'OptCondCodesC': ccReg(
+             '''((condCode == COND_HI || condCode == COND_LS ||
                 condCode == COND_CS || condCode == COND_CC) ?
-               INTREG_CONDCODES_C : INTREG_ZERO'''),
-    'OptShiftRmCondCodesC': intRegCC(
-            '''(condCode == COND_HI || condCode == COND_LS ||
-                condCode == COND_CS || condCode == COND_CC ||
-                shiftType == ROR) ?
-               INTREG_CONDCODES_C : INTREG_ZERO'''),
-    'OptCondCodesV': intRegCC(
-            '''(condCode == COND_VS || condCode == COND_VC ||
-                condCode == COND_GE || condCode == COND_LT ||
-                condCode == COND_GT || condCode == COND_LE) ?
-               INTREG_CONDCODES_V : INTREG_ZERO'''),
-    'FpCondCodes': intRegCC('INTREG_FPCONDCODES'),
+               CCREG_C : CCREG_ZERO)'''),
+    'OptShiftRmCondCodesC': ccReg(
+            '''((condCode == COND_HI || condCode == COND_LS ||
+                 condCode == COND_CS || condCode == COND_CC ||
+                 shiftType == ROR) ?
+                CCREG_C : CCREG_ZERO)'''),
+    'OptCondCodesV': ccReg(
+            '''((condCode == COND_VS || condCode == COND_VC ||
+                 condCode == COND_GE || condCode == COND_LT ||
+                 condCode == COND_GT || condCode == COND_LE) ?
+                CCREG_V : CCREG_ZERO)'''),
+    'FpCondCodes': ccReg('CCREG_FP'),
 
     #Abstracted floating point reg operands
     'FpDest': floatReg('(dest + 0)'),
index 938df568810814e7310f2d18251b5d2028a13d16..e14722028e424ede2a6da960f1a72efe8f37ad49 100644 (file)
@@ -53,25 +53,6 @@ class ThreadContext;
 
 namespace ArmISA
 {
-    enum ConditionCode {
-        COND_EQ  =   0,
-        COND_NE, //  1
-        COND_CS, //  2
-        COND_CC, //  3
-        COND_MI, //  4
-        COND_PL, //  5
-        COND_VS, //  6
-        COND_VC, //  7
-        COND_HI, //  8
-        COND_LS, //  9
-        COND_GE, // 10
-        COND_LT, // 11
-        COND_GT, // 12
-        COND_LE, // 13
-        COND_AL, // 14
-        COND_UC  // 15
-    };
-
     enum MiscRegIndex {
         MISCREG_CPSR = 0,               //   0
         MISCREG_SPSR,                   //   1
index 9ba3fa84aed301ecd8c3b7508d1200884dcf353c..20f13e69e9baff126220e4212fa03e8e9ed31a08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011 ARM Limited
+ * Copyright (c) 2010-2011, 2014 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -116,10 +116,10 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
 
     //CPSR
     CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
-    cpsr.nz = tc->readIntReg(INTREG_CONDCODES_NZ);
-    cpsr.c = tc->readIntReg(INTREG_CONDCODES_C);
-    cpsr.v = tc->readIntReg(INTREG_CONDCODES_V);
-    cpsr.ge = tc->readIntReg(INTREG_CONDCODES_GE);
+    cpsr.nz = tc->readCCReg(CCREG_NZ);
+    cpsr.c = tc->readCCReg(CCREG_C);
+    cpsr.v = tc->readCCReg(CCREG_V);
+    cpsr.ge = tc->readCCReg(CCREG_GE);
 
     newState[STATE_CPSR] = cpsr;
     changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
@@ -130,7 +130,7 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
             tc->readFloatRegBits(i);
     }
     newState[STATE_FPSCR] = tc->readMiscRegNoEffect(MISCREG_FPSCR) |
-                            tc->readIntReg(INTREG_FPCONDCODES);
+                            tc->readCCReg(CCREG_FP);
 }
 
 void
index 09041f306aa6f0d63dae33be396ed77a86d2c512..23fc2045042cb088e7fdd542233025c85cb01430 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2011 ARM Limited
+ * Copyright (c) 2010-2011, 2014 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -45,6 +45,7 @@
 
 #include "arch/arm/generated/max_inst_regs.hh"
 #include "arch/arm/intregs.hh"
+#include "arch/arm/ccregs.hh"
 #include "arch/arm/miscregs.hh"
 
 namespace ArmISA {
@@ -68,8 +69,8 @@ typedef float FloatReg;
 // cop-0/cop-1 system control register
 typedef uint64_t MiscReg;
 
-// dummy typedef since we don't have CC regs
-typedef uint8_t CCReg;
+// condition code register; must be at least 32 bits for FpCondCodes
+typedef uint64_t CCReg;
 
 // Constants Related to the number of registers
 const int NumIntArchRegs = NUM_ARCH_INTREGS;
@@ -80,9 +81,11 @@ const int NumFloatSpecialRegs = 32;
 
 const int NumIntRegs = NUM_INTREGS;
 const int NumFloatRegs = NumFloatV8ArchRegs + NumFloatSpecialRegs;
-const int NumCCRegs = 0;
+const int NumCCRegs = NUM_CCREGS;
 const int NumMiscRegs = NUM_MISCREGS;
 
+#define ISA_HAS_CC_REGS
+
 const int TotalNumRegs = NumIntRegs + NumFloatRegs + NumMiscRegs;
 
 // semantically meaningful register indices
@@ -109,12 +112,13 @@ const int SyscallSuccessReg = ReturnValueReg;
 // These help enumerate all the registers for dependence tracking.
 const int FP_Reg_Base = NumIntRegs * (MODE_MAXMODE + 1);
 const int CC_Reg_Base = FP_Reg_Base + NumFloatRegs;
-const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs; // NumCCRegs == 0
+const int Misc_Reg_Base = CC_Reg_Base + NumCCRegs;
 const int Max_Reg_Index = Misc_Reg_Base + NumMiscRegs;
 
 typedef union {
     IntReg   intreg;
     FloatReg fpreg;
+    CCReg    ccreg;
     MiscReg  ctrlreg;
 } AnyReg;
 
index b0eec495c72cebbcb081ce5ac213777ecaf7a570..6d51d059196b33feef0d77af794100cfee91360a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009-2013 ARM Limited
+ * Copyright (c) 2009-2014 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -152,8 +152,8 @@ copyRegs(ThreadContext *src, ThreadContext *dest)
     for (int i = 0; i < NumFloatRegs; i++)
         dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
 
-    // Would need to add condition-code regs if implemented
-    assert(NumCCRegs == 0);
+    for (int i = 0; i < NumCCRegs; i++)
+        dest->setCCReg(i, src->readCCReg(i));
 
     for (int i = 0; i < NumMiscRegs; i++)
         dest->setMiscRegNoEffect(i, src->readMiscRegNoEffect(i));
index 4d215328e1016c6356a8f49343f626934b79589b..1b25b2e7bbba06a470dd01f9e527521d621d5369 100644 (file)
@@ -116,7 +116,7 @@ class DerivO3CPU(BaseCPU):
                                       "registers")
     # most ISAs don't use condition-code regs, so default is 0
     _defaultNumPhysCCRegs = 0
-    if buildEnv['TARGET_ISA'] == 'x86':
+    if buildEnv['TARGET_ISA'] in ('arm','x86'):
         # For x86, each CC reg is used to hold only a subset of the
         # flags, so we need 4-5 times the number of CC regs as
         # physical integer regs to be sure we don't run out.  In
index c5fae4e8efecd3d1678385b3c22b33a3dff1ec2f..710a5af78db8f39881d4b47723d793fa5a53be60 100644 (file)
@@ -273,6 +273,7 @@ class SimpleThread : public ThreadState
     {
 #ifdef ISA_HAS_CC_REGS
         int flatIndex = isa->flattenCCIndex(reg_idx);
+        assert(0 <= flatIndex);
         assert(flatIndex < TheISA::NumCCRegs);
         uint64_t regVal(readCCRegFlat(flatIndex));
         DPRINTF(CCRegs, "Reading CC reg %d (%d) as %#x.\n",
index 2bf85bdf53d7d096a895de5c3a0f16fbaca2da69..d3c9bb40b8ebdc1a59b37ca157ab47226772cb3c 100644 (file)
@@ -58,7 +58,7 @@ class EventQueue;
  * SimObject shouldn't cause the version number to increase, only changes to
  * existing objects such as serializing/unserializing more state, changing sizes
  * of serialized arrays, etc. */
-static const uint64_t gem5CheckpointVersion = 0x000000000000000c;
+static const uint64_t gem5CheckpointVersion = 0x000000000000000d;
 
 template <class T>
 void paramOut(std::ostream &os, const std::string &name, const T &param);
index df36047543a20b028ffd3192c6b94a55ba2be8d5..66c67102549402d030d6b7bf00a1c8400c49adae 100755 (executable)
@@ -574,6 +574,33 @@ def from_A(cpt):
 def from_B(cpt):
     cpt.set('Globals', 'numMainEventQueues', '1')
 
+# Checkpoint version D uses condition code registers for the ARM
+# architecture; previously the integer register file was used for these
+# registers. To upgrade, we move those 5 integer registers to the ccRegs
+# register file.
+def from_C(cpt):
+    if cpt.get('root','isa') == 'arm':
+        for sec in cpt.sections():
+            import re
+
+            re_cpu_match = re.match('^(.*sys.*\.cpu[^.]*)\.xc\.(.+)$', sec)
+            # Search for all the execution contexts
+            if not re_cpu_match:
+                continue
+
+            items = []
+            for (item,value) in cpt.items(sec):
+                items.append(item)
+            if 'ccRegs' not in items:
+                intRegs = cpt.get(sec, 'intRegs').split()
+
+                ccRegs = intRegs[38:43]
+                del      intRegs[38:43]
+
+                ccRegs.append('0') # CCREG_ZERO
+
+                cpt.set(sec, 'intRegs', ' '.join(intRegs))
+                cpt.set(sec, 'ccRegs',  ' '.join(ccRegs))
 
 migrations = []
 migrations.append(from_0)
@@ -588,6 +615,7 @@ migrations.append(from_8)
 migrations.append(from_9)
 migrations.append(from_A)
 migrations.append(from_B)
+migrations.append(from_C)
 
 verbose_print = False