blob: 5489ef84204872ea63764b0beb6301cad86d4731 [file] [log] [blame]
/*
* Copyright (c) 2010-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.
*
* Copyright (c) 2009 The Regents of The University of Michigan
* All rights reserved.
*
* 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.
*/
#include <cassert>
#ifndef __ARCH_ARM_REGS_INT_HH__
#define __ARCH_ARM_REGS_INT_HH__
#include "arch/arm/types.hh"
#include "base/logging.hh"
#include "cpu/reg_class.hh"
#include "debug/IntRegs.hh"
#include "sim/core.hh"
namespace gem5
{
namespace ArmISA
{
BitUnion32(PackedIntReg)
Bitfield<31, 16> uh1;
Bitfield<15, 0> uh0;
SignedBitfield<31, 16> sh1;
SignedBitfield<15, 0> sh0;
Bitfield<31, 0> uw;
SignedBitfield<31, 0> sw;
EndBitUnion(PackedIntReg)
namespace int_reg
{
enum : RegIndex
{
/* All the unique register indices. */
_R0Idx,
_R1Idx,
_R2Idx,
_R3Idx,
_R4Idx,
_R5Idx,
_R6Idx,
_R7Idx,
_R8Idx,
_R9Idx,
_R10Idx,
_R11Idx,
_R12Idx,
_R13Idx,
_R14Idx,
_R15Idx,
_R13SvcIdx,
_R14SvcIdx,
_R13MonIdx,
_R14MonIdx,
_R13HypIdx,
_R13AbtIdx,
_R14AbtIdx,
_R13UndIdx,
_R14UndIdx,
_R13IrqIdx,
_R14IrqIdx,
_R8FiqIdx,
_R9FiqIdx,
_R10FiqIdx,
_R11FiqIdx,
_R12FiqIdx,
_R13FiqIdx,
_R14FiqIdx,
_ZeroIdx,
_Ureg0Idx,
_Ureg1Idx,
_Ureg2Idx,
_Sp0Idx,
_Sp1Idx,
_Sp2Idx,
_Sp3Idx,
NumRegs,
_SpxIdx = NumRegs,
NumArchRegs = 32,
_X0Idx = 0,
_X1Idx,
_X2Idx,
_X3Idx,
_X4Idx,
_X5Idx,
_X6Idx,
_X7Idx,
_X8Idx,
_X9Idx,
_X10Idx,
_X11Idx,
_X12Idx,
_X13Idx,
_X14Idx,
_X15Idx,
_X16Idx,
_X17Idx,
_X18Idx,
_X19Idx,
_X20Idx,
_X21Idx,
_X22Idx,
_X23Idx,
_X24Idx,
_X25Idx,
_X26Idx,
_X27Idx,
_X28Idx,
_X29Idx,
_X30Idx,
_X31Idx
};
} // namespace int_reg
class IntRegClassOps : public RegClassOps
{
RegId flatten(const BaseISA &isa, const RegId &id) const override;
};
inline constexpr IntRegClassOps intRegClassOps;
inline constexpr RegClass intRegClass =
RegClass(IntRegClass, IntRegClassName, int_reg::NumRegs, debug::IntRegs).
ops(intRegClassOps).
needsFlattening();
inline constexpr RegClass flatIntRegClass =
RegClass(IntRegClass, IntRegClassName, int_reg::NumRegs, debug::IntRegs);
namespace int_reg
{
inline constexpr RegId
/* All the unique register indices. */
R0 = intRegClass[_R0Idx],
R1 = intRegClass[_R1Idx],
R2 = intRegClass[_R2Idx],
R3 = intRegClass[_R3Idx],
R4 = intRegClass[_R4Idx],
R5 = intRegClass[_R5Idx],
R6 = intRegClass[_R6Idx],
R7 = intRegClass[_R7Idx],
R8 = intRegClass[_R8Idx],
R9 = intRegClass[_R9Idx],
R10 = intRegClass[_R10Idx],
R11 = intRegClass[_R11Idx],
R12 = intRegClass[_R12Idx],
R13 = intRegClass[_R13Idx],
R14 = intRegClass[_R14Idx],
R15 = intRegClass[_R15Idx],
R13Svc = intRegClass[_R13SvcIdx],
R14Svc = intRegClass[_R14SvcIdx],
R13Mon = intRegClass[_R13MonIdx],
R14Mon = intRegClass[_R14MonIdx],
R13Hyp = intRegClass[_R13HypIdx],
R13Abt = intRegClass[_R13AbtIdx],
R14Abt = intRegClass[_R14AbtIdx],
R13Und = intRegClass[_R13UndIdx],
R14Und = intRegClass[_R14UndIdx],
R13Irq = intRegClass[_R13IrqIdx],
R14Irq = intRegClass[_R14IrqIdx],
R8Fiq = intRegClass[_R8FiqIdx],
R9Fiq = intRegClass[_R9FiqIdx],
R10Fiq = intRegClass[_R10FiqIdx],
R11Fiq = intRegClass[_R11FiqIdx],
R12Fiq = intRegClass[_R12FiqIdx],
R13Fiq = intRegClass[_R13FiqIdx],
R14Fiq = intRegClass[_R14FiqIdx],
Zero = intRegClass[_ZeroIdx],
Ureg0 = intRegClass[_Ureg0Idx],
Ureg1 = intRegClass[_Ureg1Idx],
Ureg2 = intRegClass[_Ureg2Idx],
Sp0 = intRegClass[_Sp0Idx],
Sp1 = intRegClass[_Sp1Idx],
Sp2 = intRegClass[_Sp2Idx],
Sp3 = intRegClass[_Sp3Idx],
Spx = intRegClass[_SpxIdx],
X0 = intRegClass[_X0Idx],
X1 = intRegClass[_X1Idx],
X2 = intRegClass[_X2Idx],
X3 = intRegClass[_X3Idx],
X4 = intRegClass[_X4Idx],
X5 = intRegClass[_X5Idx],
X6 = intRegClass[_X6Idx],
X7 = intRegClass[_X7Idx],
X8 = intRegClass[_X8Idx],
X9 = intRegClass[_X9Idx],
X10 = intRegClass[_X10Idx],
X11 = intRegClass[_X11Idx],
X12 = intRegClass[_X12Idx],
X13 = intRegClass[_X13Idx],
X14 = intRegClass[_X14Idx],
X15 = intRegClass[_X15Idx],
X16 = intRegClass[_X16Idx],
X17 = intRegClass[_X17Idx],
X18 = intRegClass[_X18Idx],
X19 = intRegClass[_X19Idx],
X20 = intRegClass[_X20Idx],
X21 = intRegClass[_X21Idx],
X22 = intRegClass[_X22Idx],
X23 = intRegClass[_X23Idx],
X24 = intRegClass[_X24Idx],
X25 = intRegClass[_X25Idx],
X26 = intRegClass[_X26Idx],
X27 = intRegClass[_X27Idx],
X28 = intRegClass[_X28Idx],
X29 = intRegClass[_X29Idx],
X30 = intRegClass[_X30Idx],
X31 = intRegClass[_X31Idx];
inline constexpr auto
&Sp = R13,
&Lr = R14,
&Pc = R15,
&SpSvc = R13Svc,
&LRSvc = R14Svc,
&SPMon = R13Mon,
&LRMon = R14Mon,
&SPHyp = R13Hyp,
&SPAbt = R13Abt,
&LRAbt = R14Abt,
&SPUnd = R13Und,
&LRUnd = R14Und,
&SPIrq = R13Irq,
&LRIrq = R14Irq,
&SPFiq = R13Fiq,
&LRFiq = R14Fiq,
/* USR mode */
&R0Usr = R0,
&R1Usr = R1,
&R2Usr = R2,
&R3Usr = R3,
&R4Usr = R4,
&R5Usr = R5,
&R6Usr = R6,
&R7Usr = R7,
&R8Usr = R8,
&R9Usr = R9,
&R10Usr = R10,
&R11Usr = R11,
&R12Usr = R12,
&R13Usr = R13,
&SPUsr = Sp,
&R14Usr = R14,
&LRUsr = Lr,
&R15Usr = R15,
&PcUsr = Pc,
/* SVC mode */
&R0Svc = R0,
&R1Svc = R1,
&R2Svc = R2,
&R3Svc = R3,
&R4Svc = R4,
&R5Svc = R5,
&R6Svc = R6,
&R7Svc = R7,
&R8Svc = R8,
&R9Svc = R9,
&R10Svc = R10,
&R11Svc = R11,
&R12Svc = R12,
&PcSvc = Pc,
&R15Svc = R15,
/* MON mode */
&R0Mon = R0,
&R1Mon = R1,
&R2Mon = R2,
&R3Mon = R3,
&R4Mon = R4,
&R5Mon = R5,
&R6Mon = R6,
&R7Mon = R7,
&R8Mon = R8,
&R9Mon = R9,
&R10Mon = R10,
&R11Mon = R11,
&R12Mon = R12,
&PcMon = Pc,
&R15Mon = R15,
/* ABT mode */
&R0Abt = R0,
&R1Abt = R1,
&R2Abt = R2,
&R3Abt = R3,
&R4Abt = R4,
&R5Abt = R5,
&R6Abt = R6,
&R7Abt = R7,
&R8Abt = R8,
&R9Abt = R9,
&R10Abt = R10,
&R11Abt = R11,
&R12Abt = R12,
&PcAbt = Pc,
&R15Abt = R15,
/* HYP mode */
&R0Hyp = R0,
&R1Hyp = R1,
&R2Hyp = R2,
&R3Hyp = R3,
&R4Hyp = R4,
&R5Hyp = R5,
&R6Hyp = R6,
&R7Hyp = R7,
&R8Hyp = R8,
&R9Hyp = R9,
&R10Hyp = R10,
&R11Hyp = R11,
&R12Hyp = R12,
&LRHyp = Lr,
&R14Hyp = R14,
&PcHyp = Pc,
&R15Hyp = R15,
/* UND mode */
&R0Und = R0,
&R1Und = R1,
&R2Und = R2,
&R3Und = R3,
&R4Und = R4,
&R5Und = R5,
&R6Und = R6,
&R7Und = R7,
&R8Und = R8,
&R9Und = R9,
&R10Und = R10,
&R11Und = R11,
&R12Und = R12,
&PcUnd = Pc,
&R15Und = R15,
/* IRQ mode */
&R0Irq = R0,
&R1Irq = R1,
&R2Irq = R2,
&R3Irq = R3,
&R4Irq = R4,
&R5Irq = R5,
&R6Irq = R6,
&R7Irq = R7,
&R8Irq = R8,
&R9Irq = R9,
&R10Irq = R10,
&R11Irq = R11,
&R12Irq = R12,
&PcIrq = Pc,
&R15Irq = R15,
/* FIQ mode */
&R0Fiq = R0,
&R1Fiq = R1,
&R2Fiq = R2,
&R3Fiq = R3,
&R4Fiq = R4,
&R5Fiq = R5,
&R6Fiq = R6,
&R7Fiq = R7,
&PcFiq = Pc,
&R15Fiq = R15;
typedef const RegId RegMap[NumArchRegs];
const RegMap Reg64Map = {
R0, R1, R2, R3, R4, R5, R6, R7,
R8Usr, R9Usr, R10Usr, R11Usr, R12Usr, R13Usr, R14Usr, R13Hyp,
R14Irq, R13Irq, R14Svc, R13Svc, R14Abt, R13Abt, R14Und, R13Und,
R8Fiq, R9Fiq, R10Fiq, R11Fiq, R12Fiq, R13Fiq, R14Fiq, Zero
};
static inline RegId
x(unsigned index)
{
assert(index < NumArchRegs);
return intRegClass[_X0Idx + index];
}
const RegMap RegUsrMap = {
R0Usr, R1Usr, R2Usr, R3Usr, R4Usr, R5Usr, R6Usr, R7Usr,
R8Usr, R9Usr, R10Usr, R11Usr, R12Usr, R13Usr, R14Usr, R15Usr,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero
};
static inline const RegId &
usr(unsigned index)
{
assert(index < NumArchRegs);
return RegUsrMap[index];
}
const RegMap RegHypMap = {
R0Hyp, R1Hyp, R2Hyp, R3Hyp, R4Hyp, R5Hyp, R6Hyp, R7Hyp,
R8Hyp, R9Hyp, R10Hyp, R11Hyp, R12Hyp, R13Hyp, R14Hyp, R15Hyp,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero
};
static inline const RegId &
hyp(unsigned index)
{
assert(index < NumArchRegs);
return RegHypMap[index];
}
const RegMap RegSvcMap = {
R0Svc, R1Svc, R2Svc, R3Svc, R4Svc, R5Svc, R6Svc, R7Svc,
R8Svc, R9Svc, R10Svc, R11Svc, R12Svc, R13Svc, R14Svc, R15Svc,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero
};
static inline const RegId &
svc(unsigned index)
{
assert(index < NumArchRegs);
return RegSvcMap[index];
}
const RegMap RegMonMap = {
R0Mon, R1Mon, R2Mon, R3Mon, R4Mon, R5Mon, R6Mon, R7Mon,
R8Mon, R9Mon, R10Mon, R11Mon, R12Mon, R13Mon, R14Mon, R15Mon,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero
};
static inline const RegId &
mon(unsigned index)
{
assert(index < NumArchRegs);
return RegMonMap[index];
}
const RegMap RegAbtMap = {
R0Abt, R1Abt, R2Abt, R3Abt, R4Abt, R5Abt, R6Abt, R7Abt,
R8Abt, R9Abt, R10Abt, R11Abt, R12Abt, R13Abt, R14Abt, R15Abt,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero
};
static inline const RegId &
abt(unsigned index)
{
assert(index < NumArchRegs);
return RegAbtMap[index];
}
const RegMap RegUndMap = {
R0Und, R1Und, R2Und, R3Und, R4Und, R5Und, R6Und, R7Und,
R8Und, R9Und, R10Und, R11Und, R12Und, R13Und, R14Und, R15Und,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero
};
static inline const RegId &
und(unsigned index)
{
assert(index < NumArchRegs);
return RegUndMap[index];
}
const RegMap RegIrqMap = {
R0Irq, R1Irq, R2Irq, R3Irq, R4Irq, R5Irq, R6Irq, R7Irq,
R8Irq, R9Irq, R10Irq, R11Irq, R12Irq, R13Irq, R14Irq, R15Irq,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero
};
static inline const RegId &
irq(unsigned index)
{
assert(index < NumArchRegs);
return RegIrqMap[index];
}
const RegMap RegFiqMap = {
R0Fiq, R1Fiq, R2Fiq, R3Fiq, R4Fiq, R5Fiq, R6Fiq, R7Fiq,
R8Fiq, R9Fiq, R10Fiq, R11Fiq, R12Fiq, R13Fiq, R14Fiq, R15Fiq,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero
};
static inline const RegId &
fiq(unsigned index)
{
assert(index < NumArchRegs);
return RegFiqMap[index];
}
static const unsigned regsPerMode = NumRegs;
static inline int
regInMode(OperatingMode mode, int reg)
{
assert(reg < NumArchRegs);
return mode * regsPerMode + reg;
}
} // namespace int_reg
static inline const RegId &
flattenIntRegModeIndex(int reg)
{
int mode = reg / int_reg::regsPerMode;
reg = reg % int_reg::regsPerMode;
switch (mode) {
case MODE_USER:
case MODE_SYSTEM:
return int_reg::usr(reg);
case MODE_FIQ:
return int_reg::fiq(reg);
case MODE_IRQ:
return int_reg::irq(reg);
case MODE_SVC:
return int_reg::svc(reg);
case MODE_MON:
return int_reg::mon(reg);
case MODE_ABORT:
return int_reg::abt(reg);
case MODE_HYP:
return int_reg::hyp(reg);
case MODE_UNDEFINED:
return int_reg::und(reg);
default:
panic("%d: Flattening into an unknown mode: reg:%#x mode:%#x\n",
curTick(), reg, mode);
}
}
static inline RegIndex
makeSP(RegIndex reg)
{
if (reg == int_reg::X31)
reg = int_reg::Spx;
return reg;
}
static inline bool
couldBeSP(RegIndex reg)
{
return (reg == int_reg::X31 || reg == int_reg::Spx);
}
static inline bool
isSP(RegIndex reg)
{
return reg == int_reg::Spx;
}
static inline bool
couldBeZero(RegIndex reg)
{
return (reg == int_reg::X31 || reg == int_reg::Zero);
}
static inline bool
isZero(RegIndex reg)
{
return reg == int_reg::Zero;
}
static inline RegIndex
makeZero(RegIndex reg)
{
if (reg == int_reg::X31)
reg = int_reg::Zero;
return reg;
}
// Semantically meaningful register indices
inline constexpr size_t NumArgumentRegs = 4;
inline constexpr size_t NumArgumentRegs64 = 8;
inline constexpr auto
&ReturnValueReg = int_reg::X0,
&ReturnValueReg1 = int_reg::X1,
&ArgumentReg0 = int_reg::X0,
&ArgumentReg1 = int_reg::X1,
&ArgumentReg2 = int_reg::X2,
&FramePointerReg = int_reg::X11,
&StackPointerReg = int_reg::Sp,
&ReturnAddressReg = int_reg::Lr,
&SyscallNumReg = ReturnValueReg,
&SyscallPseudoReturnReg = ReturnValueReg,
&SyscallSuccessReg = ReturnValueReg;
} // namespace ArmISA
} // namespace gem5
#endif