arch-x86: Clean up x86 integer indexes.
Instead of having a bunch of implicit integer registers which are identified only by number, except in the ISA description where there are operands hard coded to certain numeric offsets into the implicit registers, and having an independent count of those implicit registers, just create a set of named indices for the registers we need. Redefine NUM_INTREGS to be the total number of registers, and NUM_ARCH_INTREGS to be the number of architectural integer registers. Instead of using NUM_INTREGS as a coincidental short hand for the first microop register (since that comes after the architectural ones), and implicitly knowing that that's the zero register, define an INTREG_T0 constant which at least makes it clear what register we're talking about, even if it's not clear that the semantics of that register make it mostly a placeholder. Change-Id: I5fa41169b9619ea68a50d6d5241ff9a07440bceb Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/42523 Reviewed-by: Gabe Black <gabe.black@gmail.com> Maintainer: Gabe Black <gabe.black@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -54,10 +54,10 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
|
||||
//In this special case, we don't use a base. The displacement also
|
||||
//changes, but that's managed by the decoder.
|
||||
if (machInst.sib.base == INTREG_RBP && machInst.modRM.mod == 0)
|
||||
base = NUM_INTREGS;
|
||||
base = INTREG_T0;
|
||||
//In -this- special case, we don't use an index.
|
||||
if (index == INTREG_RSP)
|
||||
index = NUM_INTREGS;
|
||||
index = INTREG_T0;
|
||||
} else {
|
||||
if (machInst.addrSize == 2) {
|
||||
unsigned rm = machInst.modRM.rm;
|
||||
@@ -92,7 +92,7 @@ void EmulEnv::doModRM(const ExtMachInst & machInst)
|
||||
if (machInst.modRM.mod == 0 && machInst.modRM.rm == 5) {
|
||||
//Since we need to use a different encoding of this
|
||||
//instruction anyway, just ignore the base in those cases
|
||||
base = NUM_INTREGS;
|
||||
base = INTREG_T0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@ namespace X86ISA
|
||||
EmulEnv(RegIndex _reg, RegIndex _regm,
|
||||
int _dataSize, int _addressSize, int _stackSize) :
|
||||
reg(_reg), regm(_regm), seg(SEGMENT_REG_DS),
|
||||
scale(0), index(NUM_INTREGS),
|
||||
base(NUM_INTREGS),
|
||||
scale(0), index(INTREG_T0),
|
||||
base(INTREG_T0),
|
||||
dataSize(_dataSize), addressSize(_addressSize),
|
||||
stackSize(_stackSize)
|
||||
{;}
|
||||
|
||||
@@ -185,7 +185,7 @@ InitInterrupt::invoke(ThreadContext *tc, const StaticInstPtr &inst)
|
||||
{
|
||||
DPRINTF(Faults, "Init interrupt.\n");
|
||||
// The otherwise unmodified integer registers should be set to 0.
|
||||
for (int index = 0; index < NUM_INTREGS; index++) {
|
||||
for (int index = 0; index < NUM_ARCH_INTREGS; index++) {
|
||||
tc->setIntReg(index, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ X86StaticInst::printReg(std::ostream &os, RegId reg, int size)
|
||||
ccprintf(os, longFormats[size], "15");
|
||||
break;
|
||||
default:
|
||||
ccprintf(os, microFormats[size], reg_idx - NUM_INTREGS);
|
||||
ccprintf(os, microFormats[size], reg_idx - INTREG_MICRO_BEGIN);
|
||||
}
|
||||
ccprintf(os, suffix);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ ISA::ISA(const X86ISAParams &p) : BaseISA(p), vendorString(p.vendor_string)
|
||||
fatal_if(vendorString.size() != 12,
|
||||
"CPUID vendor string must be 12 characters\n");
|
||||
|
||||
_regClasses.emplace_back(NumIntRegs, NUM_INTREGS);
|
||||
_regClasses.emplace_back(NumIntRegs, INTREG_T0);
|
||||
_regClasses.emplace_back(NumFloatRegs);
|
||||
_regClasses.emplace_back(1); // Not applicable to X86
|
||||
_regClasses.emplace_back(2); // Not applicable to X86
|
||||
|
||||
@@ -78,7 +78,7 @@ let {{
|
||||
|
||||
# Add in symbols for the microcode registers
|
||||
for num in range(16):
|
||||
assembler.symbols["t%d" % num] = gpRegIdx("NUM_INTREGS+%d" % num)
|
||||
assembler.symbols["t%d" % num] = gpRegIdx("INTREG_MICRO(%d)" % num)
|
||||
for num in range(8):
|
||||
assembler.symbols["ufp%d" % num] = \
|
||||
fpRegIdx("FLOATREG_MICROFP(%d)" % num)
|
||||
|
||||
@@ -56,9 +56,6 @@ def operand_types {{
|
||||
let {{
|
||||
def intReg(idx, id):
|
||||
return ('IntReg', 'uqw', idx, 'IsInteger', id)
|
||||
def impIntReg(idx, id):
|
||||
return ('IntReg', 'uqw', 'X86ISA::INTREG_IMPLICIT(%s)' % idx,
|
||||
'IsInteger', id)
|
||||
def floatReg(idx, id):
|
||||
return ('FloatReg', 'df', idx, 'IsFloating', id)
|
||||
def ccReg(idx, id):
|
||||
@@ -93,12 +90,12 @@ def operands {{
|
||||
'Data': intReg('data', 6),
|
||||
'DataLow': intReg('dataLow', 6),
|
||||
'DataHi': intReg('dataHi', 6),
|
||||
'ProdLow': impIntReg(0, 7),
|
||||
'ProdHi': impIntReg(1, 8),
|
||||
'Quotient': impIntReg(2, 9),
|
||||
'Remainder': impIntReg(3, 10),
|
||||
'Divisor': impIntReg(4, 11),
|
||||
'DoubleBits': impIntReg(5, 11),
|
||||
'ProdLow': intReg('X86ISA::INTREG_PRODLOW', 7),
|
||||
'ProdHi': intReg('X86ISA::INTREG_PRODHI', 8),
|
||||
'Quotient': intReg('X86ISA::INTREG_QUOTIENT', 9),
|
||||
'Remainder': intReg('X86ISA::INTREG_REMAINDER', 10),
|
||||
'Divisor': intReg('X86ISA::INTREG_DIVISOR', 11),
|
||||
'DoubleBits': intReg('X86ISA::INTREG_DOUBLEBITS', 11),
|
||||
'Rax': intReg('X86ISA::INTREG_RAX', 12),
|
||||
'Rbx': intReg('X86ISA::INTREG_RBX', 13),
|
||||
'Rcx': intReg('X86ISA::INTREG_RCX', 14),
|
||||
|
||||
@@ -144,7 +144,26 @@ namespace X86ISA
|
||||
INTREG_R15W = INTREG_R15,
|
||||
INTREG_R15B = INTREG_R15,
|
||||
|
||||
NUM_INTREGS
|
||||
NUM_ARCH_INTREGS,
|
||||
|
||||
INTREG_MICRO_BEGIN = NUM_ARCH_INTREGS,
|
||||
INTREG_T0 = INTREG_MICRO_BEGIN,
|
||||
INTREG_MICRO_END = INTREG_MICRO_BEGIN + NumMicroIntRegs,
|
||||
|
||||
// The lower part of the result of multiplication.
|
||||
INTREG_PRODLOW,
|
||||
// The upper part of the result of multiplication.
|
||||
INTREG_PRODHI,
|
||||
// The quotient from division.
|
||||
INTREG_QUOTIENT,
|
||||
// The remainder from division.
|
||||
INTREG_REMAINDER,
|
||||
// The divisor for division.
|
||||
INTREG_DIVISOR,
|
||||
// The register to use for shift doubles.
|
||||
INTREG_DOUBLEBITS,
|
||||
|
||||
NUM_INTREGS,
|
||||
};
|
||||
|
||||
// This needs to be large enough to miss all the other bits of an index.
|
||||
@@ -153,13 +172,7 @@ namespace X86ISA
|
||||
inline static IntRegIndex
|
||||
INTREG_MICRO(int index)
|
||||
{
|
||||
return (IntRegIndex)(NUM_INTREGS + index);
|
||||
}
|
||||
|
||||
inline static IntRegIndex
|
||||
INTREG_IMPLICIT(int index)
|
||||
{
|
||||
return (IntRegIndex)(NUM_INTREGS + NumMicroIntRegs + index);
|
||||
return (IntRegIndex)(INTREG_MICRO_BEGIN + index);
|
||||
}
|
||||
|
||||
inline static IntRegIndex
|
||||
@@ -170,9 +183,7 @@ namespace X86ISA
|
||||
return (IntRegIndex)index;
|
||||
}
|
||||
|
||||
const int NumIntArchRegs = NUM_INTREGS;
|
||||
const int NumIntRegs =
|
||||
NumIntArchRegs + NumMicroIntRegs + NumImplicitIntRegs;
|
||||
const int NumIntRegs = NUM_INTREGS;
|
||||
}
|
||||
|
||||
#endif // __ARCH_X86_INTREGS_HH__
|
||||
|
||||
@@ -46,14 +46,6 @@ namespace X86ISA
|
||||
{
|
||||
const int NumMicroIntRegs = 16;
|
||||
|
||||
const int NumImplicitIntRegs = 6;
|
||||
//1. The lower part of the result of multiplication.
|
||||
//2. The upper part of the result of multiplication.
|
||||
//3. The quotient from division
|
||||
//4. The remainder from division
|
||||
//5. The divisor for division
|
||||
//6. The register to use for shift doubles
|
||||
|
||||
const int NumMMXRegs = 8;
|
||||
const int NumXMMRegs = 16;
|
||||
const int NumMicroFpRegs = 8;
|
||||
|
||||
Reference in New Issue
Block a user