From 4a3f11149d791284a012af71067f6b2199aa165c Mon Sep 17 00:00:00 2001 From: Curtis Dunham Date: Tue, 29 Apr 2014 16:05:02 -0500 Subject: arm: use condition code registers for ARM ISA 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. --- src/arch/arm/ccregs.hh | 85 +++++++++++++++++++++++++++++++++++++++ src/arch/arm/faults.cc | 18 ++++----- src/arch/arm/insts/static_inst.cc | 5 ++- src/arch/arm/intregs.hh | 5 --- src/arch/arm/isa.cc | 14 +++---- src/arch/arm/isa.hh | 6 ++- src/arch/arm/isa/operands.isa | 54 ++++++++++++------------- src/arch/arm/miscregs.hh | 19 --------- src/arch/arm/nativetrace.cc | 12 +++--- src/arch/arm/registers.hh | 14 ++++--- src/arch/arm/utility.cc | 6 +-- src/cpu/o3/O3CPU.py | 2 +- src/cpu/simple_thread.hh | 1 + src/sim/serialize.hh | 2 +- util/cpt_upgrader.py | 28 +++++++++++++ 15 files changed, 184 insertions(+), 87 deletions(-) create mode 100644 src/arch/arm/ccregs.hh diff --git a/src/arch/arm/ccregs.hh b/src/arch/arm/ccregs.hh new file mode 100644 index 000000000..1818d9bce --- /dev/null +++ b/src/arch/arm/ccregs.hh @@ -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__ diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index f8313efd2..6c1992dd6 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -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; diff --git a/src/arch/arm/insts/static_inst.cc b/src/arch/arm/insts/static_inst.cc index 260c29a84..9f878ac4d 100644 --- a/src/arch/arm/insts/static_inst.cc +++ b/src/arch/arm/insts/static_inst.cc @@ -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; } } diff --git a/src/arch/arm/intregs.hh b/src/arch/arm/intregs.hh index f96db30d3..d92f58fc4 100644 --- a/src/arch/arm/intregs.hh +++ b/src/arch/arm/intregs.hh @@ -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, diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc index 38607a9ae..e76ff452d 100644 --- a/src/arch/arm/isa.cc +++ b/src/arch/arm/isa.cc @@ -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: diff --git a/src/arch/arm/isa.hh b/src/arch/arm/isa.hh index c72d5d50f..8341cd76b 100644 --- a/src/arch/arm/isa.hh +++ b/src/arch/arm/isa.hh @@ -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) { diff --git a/src/arch/arm/isa/operands.isa b/src/arch/arm/isa/operands.isa index 7a1213377..018c0956b 100644 --- a/src/arch/arm/isa/operands.isa +++ b/src/arch/arm/isa/operands.isa @@ -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)'), diff --git a/src/arch/arm/miscregs.hh b/src/arch/arm/miscregs.hh index 938df5688..e14722028 100644 --- a/src/arch/arm/miscregs.hh +++ b/src/arch/arm/miscregs.hh @@ -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 diff --git a/src/arch/arm/nativetrace.cc b/src/arch/arm/nativetrace.cc index 9ba3fa84a..20f13e69e 100644 --- a/src/arch/arm/nativetrace.cc +++ b/src/arch/arm/nativetrace.cc @@ -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 diff --git a/src/arch/arm/registers.hh b/src/arch/arm/registers.hh index 09041f306..23fc20450 100644 --- a/src/arch/arm/registers.hh +++ b/src/arch/arm/registers.hh @@ -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; diff --git a/src/arch/arm/utility.cc b/src/arch/arm/utility.cc index b0eec495c..6d51d0591 100644 --- a/src/arch/arm/utility.cc +++ b/src/arch/arm/utility.cc @@ -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)); diff --git a/src/cpu/o3/O3CPU.py b/src/cpu/o3/O3CPU.py index 4d215328e..1b25b2e7b 100644 --- a/src/cpu/o3/O3CPU.py +++ b/src/cpu/o3/O3CPU.py @@ -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 diff --git a/src/cpu/simple_thread.hh b/src/cpu/simple_thread.hh index c5fae4e8e..710a5af78 100644 --- a/src/cpu/simple_thread.hh +++ b/src/cpu/simple_thread.hh @@ -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", diff --git a/src/sim/serialize.hh b/src/sim/serialize.hh index 2bf85bdf5..d3c9bb40b 100644 --- a/src/sim/serialize.hh +++ b/src/sim/serialize.hh @@ -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 void paramOut(std::ostream &os, const std::string &name, const T ¶m); diff --git a/util/cpt_upgrader.py b/util/cpt_upgrader.py index df3604754..66c671025 100755 --- a/util/cpt_upgrader.py +++ b/util/cpt_upgrader.py @@ -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 -- cgit v1.2.3