blob: 34c2685fe775ab9317a50306b50a699e97c17cde [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 "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
};
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 RegId(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 int
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