blob: d92f58fc435f5935a638540c089c77a88d3aedaf [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.
*
* Authors: Gabe Black
*/
#include <cassert>
#ifndef __ARCH_ARM_INTREGS_HH__
#define __ARCH_ARM_INTREGS_HH__
#include "arch/arm/types.hh"
namespace ArmISA
{
enum IntRegIndex
{
/* All the unique register indices. */
INTREG_R0,
INTREG_R1,
INTREG_R2,
INTREG_R3,
INTREG_R4,
INTREG_R5,
INTREG_R6,
INTREG_R7,
INTREG_R8,
INTREG_R9,
INTREG_R10,
INTREG_R11,
INTREG_R12,
INTREG_R13,
INTREG_SP = INTREG_R13,
INTREG_R14,
INTREG_LR = INTREG_R14,
INTREG_R15,
INTREG_PC = INTREG_R15,
INTREG_R13_SVC,
INTREG_SP_SVC = INTREG_R13_SVC,
INTREG_R14_SVC,
INTREG_LR_SVC = INTREG_R14_SVC,
INTREG_R13_MON,
INTREG_SP_MON = INTREG_R13_MON,
INTREG_R14_MON,
INTREG_LR_MON = INTREG_R14_MON,
INTREG_R13_HYP,
INTREG_SP_HYP = INTREG_R13_HYP,
INTREG_R13_ABT,
INTREG_SP_ABT = INTREG_R13_ABT,
INTREG_R14_ABT,
INTREG_LR_ABT = INTREG_R14_ABT,
INTREG_R13_UND,
INTREG_SP_UND = INTREG_R13_UND,
INTREG_R14_UND,
INTREG_LR_UND = INTREG_R14_UND,
INTREG_R13_IRQ,
INTREG_SP_IRQ = INTREG_R13_IRQ,
INTREG_R14_IRQ,
INTREG_LR_IRQ = INTREG_R14_IRQ,
INTREG_R8_FIQ,
INTREG_R9_FIQ,
INTREG_R10_FIQ,
INTREG_R11_FIQ,
INTREG_R12_FIQ,
INTREG_R13_FIQ,
INTREG_SP_FIQ = INTREG_R13_FIQ,
INTREG_R14_FIQ,
INTREG_LR_FIQ = INTREG_R14_FIQ,
INTREG_ZERO,
INTREG_UREG0,
INTREG_UREG1,
INTREG_UREG2,
INTREG_DUMMY, // Dummy reg used to throw away int reg results
INTREG_SP0,
INTREG_SP1,
INTREG_SP2,
INTREG_SP3,
NUM_INTREGS,
NUM_ARCH_INTREGS = 32,
/* AArch64 registers */
INTREG_X0 = 0,
INTREG_X1,
INTREG_X2,
INTREG_X3,
INTREG_X4,
INTREG_X5,
INTREG_X6,
INTREG_X7,
INTREG_X8,
INTREG_X9,
INTREG_X10,
INTREG_X11,
INTREG_X12,
INTREG_X13,
INTREG_X14,
INTREG_X15,
INTREG_X16,
INTREG_X17,
INTREG_X18,
INTREG_X19,
INTREG_X20,
INTREG_X21,
INTREG_X22,
INTREG_X23,
INTREG_X24,
INTREG_X25,
INTREG_X26,
INTREG_X27,
INTREG_X28,
INTREG_X29,
INTREG_X30,
INTREG_X31,
INTREG_SPX = NUM_INTREGS,
/* All the aliased indexes. */
/* USR mode */
INTREG_R0_USR = INTREG_R0,
INTREG_R1_USR = INTREG_R1,
INTREG_R2_USR = INTREG_R2,
INTREG_R3_USR = INTREG_R3,
INTREG_R4_USR = INTREG_R4,
INTREG_R5_USR = INTREG_R5,
INTREG_R6_USR = INTREG_R6,
INTREG_R7_USR = INTREG_R7,
INTREG_R8_USR = INTREG_R8,
INTREG_R9_USR = INTREG_R9,
INTREG_R10_USR = INTREG_R10,
INTREG_R11_USR = INTREG_R11,
INTREG_R12_USR = INTREG_R12,
INTREG_R13_USR = INTREG_R13,
INTREG_SP_USR = INTREG_SP,
INTREG_R14_USR = INTREG_R14,
INTREG_LR_USR = INTREG_LR,
INTREG_R15_USR = INTREG_R15,
INTREG_PC_USR = INTREG_PC,
/* SVC mode */
INTREG_R0_SVC = INTREG_R0,
INTREG_R1_SVC = INTREG_R1,
INTREG_R2_SVC = INTREG_R2,
INTREG_R3_SVC = INTREG_R3,
INTREG_R4_SVC = INTREG_R4,
INTREG_R5_SVC = INTREG_R5,
INTREG_R6_SVC = INTREG_R6,
INTREG_R7_SVC = INTREG_R7,
INTREG_R8_SVC = INTREG_R8,
INTREG_R9_SVC = INTREG_R9,
INTREG_R10_SVC = INTREG_R10,
INTREG_R11_SVC = INTREG_R11,
INTREG_R12_SVC = INTREG_R12,
INTREG_PC_SVC = INTREG_PC,
INTREG_R15_SVC = INTREG_R15,
/* MON mode */
INTREG_R0_MON = INTREG_R0,
INTREG_R1_MON = INTREG_R1,
INTREG_R2_MON = INTREG_R2,
INTREG_R3_MON = INTREG_R3,
INTREG_R4_MON = INTREG_R4,
INTREG_R5_MON = INTREG_R5,
INTREG_R6_MON = INTREG_R6,
INTREG_R7_MON = INTREG_R7,
INTREG_R8_MON = INTREG_R8,
INTREG_R9_MON = INTREG_R9,
INTREG_R10_MON = INTREG_R10,
INTREG_R11_MON = INTREG_R11,
INTREG_R12_MON = INTREG_R12,
INTREG_PC_MON = INTREG_PC,
INTREG_R15_MON = INTREG_R15,
/* ABT mode */
INTREG_R0_ABT = INTREG_R0,
INTREG_R1_ABT = INTREG_R1,
INTREG_R2_ABT = INTREG_R2,
INTREG_R3_ABT = INTREG_R3,
INTREG_R4_ABT = INTREG_R4,
INTREG_R5_ABT = INTREG_R5,
INTREG_R6_ABT = INTREG_R6,
INTREG_R7_ABT = INTREG_R7,
INTREG_R8_ABT = INTREG_R8,
INTREG_R9_ABT = INTREG_R9,
INTREG_R10_ABT = INTREG_R10,
INTREG_R11_ABT = INTREG_R11,
INTREG_R12_ABT = INTREG_R12,
INTREG_PC_ABT = INTREG_PC,
INTREG_R15_ABT = INTREG_R15,
/* HYP mode */
INTREG_R0_HYP = INTREG_R0,
INTREG_R1_HYP = INTREG_R1,
INTREG_R2_HYP = INTREG_R2,
INTREG_R3_HYP = INTREG_R3,
INTREG_R4_HYP = INTREG_R4,
INTREG_R5_HYP = INTREG_R5,
INTREG_R6_HYP = INTREG_R6,
INTREG_R7_HYP = INTREG_R7,
INTREG_R8_HYP = INTREG_R8,
INTREG_R9_HYP = INTREG_R9,
INTREG_R10_HYP = INTREG_R10,
INTREG_R11_HYP = INTREG_R11,
INTREG_R12_HYP = INTREG_R12,
INTREG_LR_HYP = INTREG_LR,
INTREG_R14_HYP = INTREG_R14,
INTREG_PC_HYP = INTREG_PC,
INTREG_R15_HYP = INTREG_R15,
/* UND mode */
INTREG_R0_UND = INTREG_R0,
INTREG_R1_UND = INTREG_R1,
INTREG_R2_UND = INTREG_R2,
INTREG_R3_UND = INTREG_R3,
INTREG_R4_UND = INTREG_R4,
INTREG_R5_UND = INTREG_R5,
INTREG_R6_UND = INTREG_R6,
INTREG_R7_UND = INTREG_R7,
INTREG_R8_UND = INTREG_R8,
INTREG_R9_UND = INTREG_R9,
INTREG_R10_UND = INTREG_R10,
INTREG_R11_UND = INTREG_R11,
INTREG_R12_UND = INTREG_R12,
INTREG_PC_UND = INTREG_PC,
INTREG_R15_UND = INTREG_R15,
/* IRQ mode */
INTREG_R0_IRQ = INTREG_R0,
INTREG_R1_IRQ = INTREG_R1,
INTREG_R2_IRQ = INTREG_R2,
INTREG_R3_IRQ = INTREG_R3,
INTREG_R4_IRQ = INTREG_R4,
INTREG_R5_IRQ = INTREG_R5,
INTREG_R6_IRQ = INTREG_R6,
INTREG_R7_IRQ = INTREG_R7,
INTREG_R8_IRQ = INTREG_R8,
INTREG_R9_IRQ = INTREG_R9,
INTREG_R10_IRQ = INTREG_R10,
INTREG_R11_IRQ = INTREG_R11,
INTREG_R12_IRQ = INTREG_R12,
INTREG_PC_IRQ = INTREG_PC,
INTREG_R15_IRQ = INTREG_R15,
/* FIQ mode */
INTREG_R0_FIQ = INTREG_R0,
INTREG_R1_FIQ = INTREG_R1,
INTREG_R2_FIQ = INTREG_R2,
INTREG_R3_FIQ = INTREG_R3,
INTREG_R4_FIQ = INTREG_R4,
INTREG_R5_FIQ = INTREG_R5,
INTREG_R6_FIQ = INTREG_R6,
INTREG_R7_FIQ = INTREG_R7,
INTREG_PC_FIQ = INTREG_PC,
INTREG_R15_FIQ = INTREG_R15
};
typedef IntRegIndex IntRegMap[NUM_ARCH_INTREGS];
const IntRegMap IntReg64Map = {
INTREG_R0, INTREG_R1, INTREG_R2, INTREG_R3,
INTREG_R4, INTREG_R5, INTREG_R6, INTREG_R7,
INTREG_R8_USR, INTREG_R9_USR, INTREG_R10_USR, INTREG_R11_USR,
INTREG_R12_USR, INTREG_R13_USR, INTREG_R14_USR, INTREG_R13_HYP,
INTREG_R14_IRQ, INTREG_R13_IRQ, INTREG_R14_SVC, INTREG_R13_SVC,
INTREG_R14_ABT, INTREG_R13_ABT, INTREG_R14_UND, INTREG_R13_UND,
INTREG_R8_FIQ, INTREG_R9_FIQ, INTREG_R10_FIQ, INTREG_R11_FIQ,
INTREG_R12_FIQ, INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_ZERO
};
const IntRegMap IntRegUsrMap = {
INTREG_R0_USR, INTREG_R1_USR, INTREG_R2_USR, INTREG_R3_USR,
INTREG_R4_USR, INTREG_R5_USR, INTREG_R6_USR, INTREG_R7_USR,
INTREG_R8_USR, INTREG_R9_USR, INTREG_R10_USR, INTREG_R11_USR,
INTREG_R12_USR, INTREG_R13_USR, INTREG_R14_USR, INTREG_R15_USR,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO
};
static inline IntRegIndex
INTREG_USR(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return IntRegUsrMap[index];
}
const IntRegMap IntRegHypMap = {
INTREG_R0_HYP, INTREG_R1_HYP, INTREG_R2_HYP, INTREG_R3_HYP,
INTREG_R4_HYP, INTREG_R5_HYP, INTREG_R6_HYP, INTREG_R7_HYP,
INTREG_R8_HYP, INTREG_R9_HYP, INTREG_R10_HYP, INTREG_R11_HYP,
INTREG_R12_HYP, INTREG_R13_HYP, INTREG_R14_HYP, INTREG_R15_HYP,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO
};
static inline IntRegIndex
INTREG_HYP(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return IntRegHypMap[index];
}
const IntRegMap IntRegSvcMap = {
INTREG_R0_SVC, INTREG_R1_SVC, INTREG_R2_SVC, INTREG_R3_SVC,
INTREG_R4_SVC, INTREG_R5_SVC, INTREG_R6_SVC, INTREG_R7_SVC,
INTREG_R8_SVC, INTREG_R9_SVC, INTREG_R10_SVC, INTREG_R11_SVC,
INTREG_R12_SVC, INTREG_R13_SVC, INTREG_R14_SVC, INTREG_R15_SVC,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO
};
static inline IntRegIndex
INTREG_SVC(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return IntRegSvcMap[index];
}
const IntRegMap IntRegMonMap = {
INTREG_R0_MON, INTREG_R1_MON, INTREG_R2_MON, INTREG_R3_MON,
INTREG_R4_MON, INTREG_R5_MON, INTREG_R6_MON, INTREG_R7_MON,
INTREG_R8_MON, INTREG_R9_MON, INTREG_R10_MON, INTREG_R11_MON,
INTREG_R12_MON, INTREG_R13_MON, INTREG_R14_MON, INTREG_R15_MON,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO
};
static inline IntRegIndex
INTREG_MON(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return IntRegMonMap[index];
}
const IntRegMap IntRegAbtMap = {
INTREG_R0_ABT, INTREG_R1_ABT, INTREG_R2_ABT, INTREG_R3_ABT,
INTREG_R4_ABT, INTREG_R5_ABT, INTREG_R6_ABT, INTREG_R7_ABT,
INTREG_R8_ABT, INTREG_R9_ABT, INTREG_R10_ABT, INTREG_R11_ABT,
INTREG_R12_ABT, INTREG_R13_ABT, INTREG_R14_ABT, INTREG_R15_ABT,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO
};
static inline IntRegIndex
INTREG_ABT(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return IntRegAbtMap[index];
}
const IntRegMap IntRegUndMap = {
INTREG_R0_UND, INTREG_R1_UND, INTREG_R2_UND, INTREG_R3_UND,
INTREG_R4_UND, INTREG_R5_UND, INTREG_R6_UND, INTREG_R7_UND,
INTREG_R8_UND, INTREG_R9_UND, INTREG_R10_UND, INTREG_R11_UND,
INTREG_R12_UND, INTREG_R13_UND, INTREG_R14_UND, INTREG_R15_UND,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO
};
static inline IntRegIndex
INTREG_UND(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return IntRegUndMap[index];
}
const IntRegMap IntRegIrqMap = {
INTREG_R0_IRQ, INTREG_R1_IRQ, INTREG_R2_IRQ, INTREG_R3_IRQ,
INTREG_R4_IRQ, INTREG_R5_IRQ, INTREG_R6_IRQ, INTREG_R7_IRQ,
INTREG_R8_IRQ, INTREG_R9_IRQ, INTREG_R10_IRQ, INTREG_R11_IRQ,
INTREG_R12_IRQ, INTREG_R13_IRQ, INTREG_R14_IRQ, INTREG_R15_IRQ,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO
};
static inline IntRegIndex
INTREG_IRQ(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return IntRegIrqMap[index];
}
const IntRegMap IntRegFiqMap = {
INTREG_R0_FIQ, INTREG_R1_FIQ, INTREG_R2_FIQ, INTREG_R3_FIQ,
INTREG_R4_FIQ, INTREG_R5_FIQ, INTREG_R6_FIQ, INTREG_R7_FIQ,
INTREG_R8_FIQ, INTREG_R9_FIQ, INTREG_R10_FIQ, INTREG_R11_FIQ,
INTREG_R12_FIQ, INTREG_R13_FIQ, INTREG_R14_FIQ, INTREG_R15_FIQ,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO,
INTREG_ZERO, INTREG_ZERO, INTREG_ZERO, INTREG_ZERO
};
static inline IntRegIndex
INTREG_FIQ(unsigned index)
{
assert(index < NUM_ARCH_INTREGS);
return IntRegFiqMap[index];
}
static const unsigned intRegsPerMode = NUM_INTREGS;
static inline int
intRegInMode(OperatingMode mode, int reg)
{
assert(reg < NUM_ARCH_INTREGS);
return mode * intRegsPerMode + reg;
}
static inline int
flattenIntRegModeIndex(int reg)
{
int mode = reg / intRegsPerMode;
reg = reg % intRegsPerMode;
switch (mode) {
case MODE_USER:
case MODE_SYSTEM:
return INTREG_USR(reg);
case MODE_FIQ:
return INTREG_FIQ(reg);
case MODE_IRQ:
return INTREG_IRQ(reg);
case MODE_SVC:
return INTREG_SVC(reg);
case MODE_MON:
return INTREG_MON(reg);
case MODE_ABORT:
return INTREG_ABT(reg);
case MODE_HYP:
return INTREG_HYP(reg);
case MODE_UNDEFINED:
return INTREG_UND(reg);
default:
panic("%d: Flattening into an unknown mode: reg:%#x mode:%#x\n",
curTick(), reg, mode);
}
}
static inline IntRegIndex
makeSP(IntRegIndex reg)
{
if (reg == INTREG_X31)
reg = INTREG_SPX;
return reg;
}
static inline IntRegIndex
makeZero(IntRegIndex reg)
{
if (reg == INTREG_X31)
reg = INTREG_ZERO;
return reg;
}
static inline bool
isSP(IntRegIndex reg)
{
return reg == INTREG_SPX;
}
}
#endif