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:
@@ -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)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user