arch-x86: Eliminate the DependenceTags in registers.hh.

These were a weird holdover from when register indices were all squished
into a single scalar value, offset based on the register type. When that
change happened, the person who made it misunderstood what the
InstRegIndex type was for, and decided to build RegId into it for some
reason. The only purpose of InstRegIndex is to make sure everybody
agrees that the value being passed around is going to be used as a
register index and not a literal value, or vice versa. There is no type
associated with it as far as floating point, integer, or misc registers.
That gets applied at a different step, and actually can't be part of
InstRegIndex since the same base class may need to hold register indices
that are going to be treated as integer or floating point depending on
the subclass using them.

Also, since the values of the various constants in the DepdenceTags enum
where never actually added into register indices in the first place, the
code in the InstRegIndex constructor would never do anything. All
registers would be arbitrarily sorted into Int, FP, etc, and then when
they actually went to be used the category would be thrown away.

Change-Id: I8c4e8d6e9cdb53e298c00ad2f56e8c7304e51e96
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40339
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:
Gabe Black
2021-02-01 18:25:33 -08:00
parent b8d52fee57
commit a1b4ce84f7
6 changed files with 42 additions and 67 deletions

View File

@@ -90,7 +90,7 @@ class LdStOp : public InstOperands<MemOp, FoldedDataOp, AddrOp>
InstOperands<MemOp, FoldedDataOp, AddrOp>(
mach_inst, mnem, inst_mnem, set_flags, op_class,
_data, { _scale, _index, _base, _disp, _segment },
data_size, address_size, mem_flags | _segment.index())
data_size, address_size, mem_flags | _segment.index)
{}
};
@@ -109,7 +109,7 @@ class LdStFpOp : public InstOperands<MemOp, FloatDataOp, AddrOp>
InstOperands<MemOp, FloatDataOp, AddrOp>(
mach_inst, mnem, inst_mnem, set_flags, op_class,
_data, { _scale, _index, _base, _disp, _segment },
data_size, address_size, mem_flags | _segment.index())
data_size, address_size, mem_flags | _segment.index)
{}
};
@@ -127,7 +127,7 @@ class MemNoDataOp : public InstOperands<MemOp, AddrOp>
InstOperands<MemOp, AddrOp>(
mach_inst, mnem, inst_mnem, set_flags, op_class,
{ _scale, _index, _base, _disp, _segment },
data_size, address_size, mem_flags | _segment.index())
data_size, address_size, mem_flags | _segment.index)
{}
};
@@ -149,7 +149,7 @@ class LdStSplitOp :
InstOperands<MemOp, FoldedDataLowOp, FoldedDataHiOp, AddrOp>(
mach_inst, mnem, inst_mnem, set_flags, op_class,
data_low, data_hi, { _scale, _index, _base, _disp, _segment },
data_size, address_size, mem_flags | _segment.index())
data_size, address_size, mem_flags | _segment.index)
{}
};

View File

@@ -108,7 +108,7 @@ struct IntOp : public Base
{
template <class InstType>
IntOp(InstType *inst, typename Base::ArgType idx) :
Base(idx.index(), inst->dataSize)
Base(idx.index, inst->dataSize)
{}
void
@@ -124,7 +124,7 @@ struct FoldedOp : public Base
{
template <class InstType>
FoldedOp(InstType *inst, typename Base::ArgType idx) :
Base(INTREG_FOLDED(idx.index(), inst->foldOBit), inst->dataSize)
Base(INTREG_FOLDED(idx.index, inst->foldOBit), inst->dataSize)
{}
void
@@ -139,7 +139,7 @@ template <class Base>
struct CrOp : public Base
{
template <class InstType>
CrOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {}
CrOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index, 0) {}
void
print(std::ostream &os) const
@@ -152,7 +152,7 @@ template <class Base>
struct DbgOp : public Base
{
template <class InstType>
DbgOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {}
DbgOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index, 0) {}
void
print(std::ostream &os) const
@@ -166,7 +166,7 @@ template <class Base>
struct SegOp : public Base
{
template <class InstType>
SegOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index(), 0) {}
SegOp(InstType *inst, typename Base::ArgType idx) : Base(idx.index, 0) {}
void
print(std::ostream &os) const
@@ -180,7 +180,7 @@ struct MiscOp : public Base
{
template <class InstType>
MiscOp(InstType *inst, typename Base::ArgType idx) :
Base(idx.index(), inst->dataSize)
Base(idx.index, inst->dataSize)
{}
void
@@ -196,7 +196,7 @@ struct FloatOp : public Base
{
template <class InstType>
FloatOp(InstType *inst, typename Base::ArgType idx) :
Base(idx.index(), inst->dataSize)
Base(idx.index, inst->dataSize)
{}
void
@@ -316,9 +316,9 @@ struct AddrOp
template <class InstType>
AddrOp(InstType *inst, const ArgType &args) : scale(args.scale),
index(INTREG_FOLDED(args.index.index(), inst->foldABit)),
base(INTREG_FOLDED(args.base.index(), inst->foldABit)),
disp(args.disp), segment(args.segment.index()),
index(INTREG_FOLDED(args.index.index, inst->foldABit)),
base(INTREG_FOLDED(args.base.index, inst->foldABit)),
disp(args.disp), segment(args.segment.index),
size(inst->addressSize)
{
assert(segment < NUM_SEGMENTREGS);

View File

@@ -243,13 +243,13 @@ X86StaticInst::printMem(std::ostream &os, uint8_t segment,
if (scale != 0 && index != NUM_INTREGS) {
if (scale != 1)
ccprintf(os, "%d*", scale);
printReg(os, InstRegIndex(index), addressSize);
printReg(os, RegId(IntRegClass, index), addressSize);
someAddr = true;
}
if (base != NUM_INTREGS) {
if (someAddr)
os << " + ";
printReg(os, InstRegIndex(base), addressSize);
printReg(os, RegId(IntRegClass, base), addressSize);
someAddr = true;
}
}

View File

@@ -50,29 +50,10 @@ namespace X86ISA
* wrapper struct for these lets take advantage of the compiler's type
* checking.
*/
struct InstRegIndex : public RegId
struct InstRegIndex
{
explicit InstRegIndex(RegIndex _idx) :
RegId(computeRegClass(_idx), _idx) {}
private:
// TODO: As X86 register index definition is highly built on the
// unified space concept, it is easier for the moment to rely on
// an helper function to compute the RegClass. It would be nice
// to fix those definition and get rid of this.
RegClass
computeRegClass(RegIndex _idx)
{
if (_idx < FP_Reg_Base) {
return IntRegClass;
} else if (_idx < CC_Reg_Base) {
return FloatRegClass;
} else if (_idx < Misc_Reg_Base) {
return CCRegClass;
} else {
return MiscRegClass;
}
}
RegIndex index;
explicit InstRegIndex(RegIndex idx) : index(idx) {}
};
/**

View File

@@ -142,16 +142,17 @@ let {{
regString = "INTREG_R%s" % opType.reg
env.addReg(regString)
env.addToDisassembly(
"printReg(out, InstRegIndex(%s), regSize);\n" %
regString)
"printReg(out, RegId(IntRegClass, %s), regSize);\n" %
regString)
Name += "_R"
elif opType.tag == "B":
# This refers to registers whose index is encoded as part of the opcode
# This refers to registers whose index is encoded as part of
# the opcode.
env.addToDisassembly(
"printReg(out, InstRegIndex(%s), regSize);\n" %
InstRegIndex)
"printReg(out, RegId(IntRegClass, %s), regSize);\n" %
InstRegIndex)
Name += "_R"
@@ -187,36 +188,40 @@ let {{
elif opType.tag in ("G", "P", "T", "V"):
# Use the "reg" field of the ModRM byte to select the register
env.addReg(ModRMRegIndex)
env.addToDisassembly(
"printReg(out, InstRegIndex(%s), regSize);\n" %
ModRMRegIndex)
if opType.tag == "P":
regFormat = 'ccprintf(out, "MMX%%d", %s);\n'
Name += "_MMX"
elif opType.tag == "V":
regFormat = 'ccprintf(out, "XMM%%d", %s);\n'
Name += "_XMM"
else:
regFormat = \
"printReg(out, RegId(IntRegClass, %s), regSize);\n"
Name += "_R"
env.addToDisassembly(regFormat % ModRMRegIndex)
elif opType.tag in ("E", "Q", "W"):
# This might refer to memory or to a register. We need to
# divide it up farther.
regEnv = copy.copy(env)
regEnv.addReg(ModRMRMIndex)
regEnv.addToDisassembly(
"printReg(out, InstRegIndex(%s), regSize);\n" %
ModRMRMIndex)
# This refers to memory. The macroop constructor should set up
# modrm addressing.
memEnv = copy.copy(env)
memEnv.doModRM = True
regSuffix = "_R"
if opType.tag == "Q":
regFormat = 'ccprintf(out, "MMX%%d", %s);\n'
regSuffix = "_MMX"
elif opType.tag == "W":
regFormat = 'ccprintf(out, "XMM%%d", %s);\n'
regSuffix = "_XMM"
else:
regFormat = \
"printReg(out, RegId(IntRegClass, %s), regSize);\n"
regSuffix = "_R"
env.addToDisassembly(regFormat % ModRMRegIndex)
return doSplitDecode("MODRM_MOD",
{"3" : (specializeInst, Name + regSuffix,
copy.copy(opTypes), regEnv)},
@@ -233,17 +238,18 @@ let {{
elif opType.tag in ("PR", "R", "VR"):
# Non register modrm settings should cause an error
env.addReg(ModRMRMIndex)
env.addToDisassembly(
"printReg(out, InstRegIndex(%s), regSize);\n" %
ModRMRMIndex)
if opType.tag == "PR":
regFormat = 'ccprintf(out, "MMX%%d", %s);\n'
Name += "_MMX"
elif opType.tag == "VR":
regFormat = 'ccprintf(out, "XMM%%d", %s);\n'
Name += "_XMM"
else:
regFormat = \
"printReg(out, RegId(IntRegClass, %s), regSize);\n"
Name += "_R"
env.addToDisassembly(regFormat % ModRMRegIndex)
elif opType.tag in ("X", "Y"):
# This type of memory addressing is for string instructions.
# They'll use the right index and segment internally.

View File

@@ -49,18 +49,6 @@
namespace X86ISA
{
// These enumerate all the registers for dependence tracking.
enum DependenceTags
{
// FP_Reg_Base must be large enough to be bigger than any integer
// register index which has the IntFoldBit (1 << 6) set. To be safe
// we just start at (1 << 7) == 128.
FP_Reg_Base = 128,
CC_Reg_Base = FP_Reg_Base + NumFloatRegs,
Misc_Reg_Base = CC_Reg_Base + NUM_CCREGS,
Max_Reg_Index = Misc_Reg_Base + NUM_MISCREGS
};
// Not applicable to x86
using VecElem = ::DummyVecElem;
using VecRegContainer = ::DummyVecRegContainer;