summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
authorNathanael Premillieu <nathanael.premillieu@arm.com>2017-04-05 12:46:06 -0500
committerAndreas Sandberg <andreas.sandberg@arm.com>2017-07-05 14:43:49 +0000
commit5e8287d2e2eaf058495442ea9e32fafc343a0b53 (patch)
tree7d0891b8984926f8e404d6ca8247f45695f9fc9b /src/arch/x86
parent864f87f9c56a66dceeca0f4e9470fbaa3001b627 (diff)
downloadgem5-5e8287d2e2eaf058495442ea9e32fafc343a0b53.tar.xz
arch, cpu: Architectural Register structural indexing
Replace the unified register mapping with a structure associating a class and an index. It is now much easier to know which class of register the index is referring to. Also, when adding a new class there is no need to modify existing ones. Change-Id: I55b3ac80763702aa2cd3ed2cbff0a75ef7620373 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> [ Fix RISCV build issues ] Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-on: https://gem5-review.googlesource.com/2700
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/insts/microfpop.hh2
-rw-r--r--src/arch/x86/insts/microldstop.hh14
-rw-r--r--src/arch/x86/insts/micromediaop.hh4
-rw-r--r--src/arch/x86/insts/microregop.hh4
-rw-r--r--src/arch/x86/insts/static_inst.cc48
-rw-r--r--src/arch/x86/insts/static_inst.hh32
-rw-r--r--src/arch/x86/isa/microops/limmop.isa2
-rw-r--r--src/arch/x86/isa/specialize.isa25
-rw-r--r--src/arch/x86/registers.hh2
9 files changed, 81 insertions, 52 deletions
diff --git a/src/arch/x86/insts/microfpop.hh b/src/arch/x86/insts/microfpop.hh
index 15638e6b4..04ec285d4 100644
--- a/src/arch/x86/insts/microfpop.hh
+++ b/src/arch/x86/insts/microfpop.hh
@@ -66,7 +66,7 @@ namespace X86ISA
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
__opClass),
- src1(_src1.idx), src2(_src2.idx), dest(_dest.idx),
+ src1(_src1.regIdx), src2(_src2.regIdx), dest(_dest.regIdx),
dataSize(_dataSize), spm(_spm)
{}
/*
diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh
index c36fbacfd..e12a51c4c 100644
--- a/src/arch/x86/insts/microldstop.hh
+++ b/src/arch/x86/insts/microldstop.hh
@@ -75,12 +75,12 @@ namespace X86ISA
Request::FlagsType _memFlags,
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, setFlags, __opClass),
- scale(_scale), index(_index.idx), base(_base.idx),
- disp(_disp), segment(_segment.idx),
+ scale(_scale), index(_index.regIdx), base(_base.regIdx),
+ disp(_disp), segment(_segment.regIdx),
dataSize(_dataSize), addressSize(_addressSize),
- memFlags(_memFlags | _segment.idx)
+ memFlags(_memFlags | _segment.regIdx)
{
- assert(_segment.idx < NUM_SEGMENTREGS);
+ assert(_segment.regIdx < NUM_SEGMENTREGS);
foldOBit =
(dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
foldABit =
@@ -110,7 +110,7 @@ namespace X86ISA
_scale, _index, _base, _disp, _segment,
_dataSize, _addressSize, _memFlags,
__opClass),
- data(_data.idx)
+ data(_data.regIdx)
{
}
@@ -143,8 +143,8 @@ namespace X86ISA
_scale, _index, _base, _disp, _segment,
_dataSize, _addressSize, _memFlags,
__opClass),
- dataLow(_dataLow.idx),
- dataHi(_dataHi.idx)
+ dataLow(_dataLow.regIdx),
+ dataHi(_dataHi.regIdx)
{
}
diff --git a/src/arch/x86/insts/micromediaop.hh b/src/arch/x86/insts/micromediaop.hh
index 1259b6982..547780108 100644
--- a/src/arch/x86/insts/micromediaop.hh
+++ b/src/arch/x86/insts/micromediaop.hh
@@ -59,7 +59,7 @@ namespace X86ISA
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
__opClass),
- src1(_src1.idx), dest(_dest.idx),
+ src1(_src1.regIdx), dest(_dest.regIdx),
srcSize(_srcSize), destSize(_destSize), ext(_ext)
{}
@@ -102,7 +102,7 @@ namespace X86ISA
MediaOpBase(_machInst, mnem, _instMnem, setFlags,
_src1, _dest, _srcSize, _destSize, _ext,
__opClass),
- src2(_src2.idx)
+ src2(_src2.regIdx)
{}
std::string generateDisassembly(Addr pc,
diff --git a/src/arch/x86/insts/microregop.hh b/src/arch/x86/insts/microregop.hh
index 1f4eb3981..1accc3555 100644
--- a/src/arch/x86/insts/microregop.hh
+++ b/src/arch/x86/insts/microregop.hh
@@ -64,7 +64,7 @@ namespace X86ISA
OpClass __opClass) :
X86MicroopBase(_machInst, mnem, _instMnem, setFlags,
__opClass),
- src1(_src1.idx), dest(_dest.idx),
+ src1(_src1.regIdx), dest(_dest.regIdx),
dataSize(_dataSize), ext(_ext)
{
foldOBit = (dataSize == 1 && !_machInst.rex.present) ? 1 << 6 : 0;
@@ -90,7 +90,7 @@ namespace X86ISA
RegOpBase(_machInst, mnem, _instMnem, setFlags,
_src1, _dest, _dataSize, _ext,
__opClass),
- src2(_src2.idx)
+ src2(_src2.regIdx)
{
}
diff --git a/src/arch/x86/insts/static_inst.cc b/src/arch/x86/insts/static_inst.cc
index ff425f6bf..b9c5486ed 100644
--- a/src/arch/x86/insts/static_inst.cc
+++ b/src/arch/x86/insts/static_inst.cc
@@ -120,7 +120,7 @@ namespace X86ISA
}
void
- X86StaticInst::printReg(std::ostream &os, int reg, int size) const
+ X86StaticInst::printReg(std::ostream &os, RegId reg, int size) const
{
assert(size == 1 || size == 2 || size == 4 || size == 8);
static const char * abcdFormats[9] =
@@ -132,20 +132,20 @@ namespace X86ISA
static const char * microFormats[9] =
{"", "t%db", "t%dw", "", "t%dd", "", "", "", "t%d"};
- RegIndex rel_reg;
+ RegIndex reg_idx = reg.regIdx;
- switch (regIdxToClass(reg, &rel_reg)) {
+ switch (reg.regClass) {
case IntRegClass: {
const char * suffix = "";
- bool fold = rel_reg & IntFoldBit;
- rel_reg &= ~IntFoldBit;
+ bool fold = reg_idx & IntFoldBit;
+ reg_idx &= ~IntFoldBit;
if (fold)
suffix = "h";
- else if (rel_reg < 8 && size == 1)
+ else if (reg_idx < 8 && size == 1)
suffix = "l";
- switch (rel_reg) {
+ switch (reg_idx) {
case INTREG_RAX:
ccprintf(os, abcdFormats[size], "a");
break;
@@ -195,41 +195,41 @@ namespace X86ISA
ccprintf(os, longFormats[size], "15");
break;
default:
- ccprintf(os, microFormats[size], rel_reg - NUM_INTREGS);
+ ccprintf(os, microFormats[size], reg_idx - NUM_INTREGS);
}
ccprintf(os, suffix);
break;
}
case FloatRegClass: {
- if (rel_reg < NumMMXRegs) {
- ccprintf(os, "%%mmx%d", rel_reg);
+ if (reg_idx < NumMMXRegs) {
+ ccprintf(os, "%%mmx%d", reg_idx);
return;
}
- rel_reg -= NumMMXRegs;
- if (rel_reg < NumXMMRegs * 2) {
- ccprintf(os, "%%xmm%d_%s", rel_reg / 2,
- (rel_reg % 2) ? "high": "low");
+ reg_idx -= NumMMXRegs;
+ if (reg_idx < NumXMMRegs * 2) {
+ ccprintf(os, "%%xmm%d_%s", reg_idx / 2,
+ (reg_idx % 2) ? "high": "low");
return;
}
- rel_reg -= NumXMMRegs * 2;
- if (rel_reg < NumMicroFpRegs) {
- ccprintf(os, "%%ufp%d", rel_reg);
+ reg_idx -= NumXMMRegs * 2;
+ if (reg_idx < NumMicroFpRegs) {
+ ccprintf(os, "%%ufp%d", reg_idx);
return;
}
- rel_reg -= NumMicroFpRegs;
- ccprintf(os, "%%st(%d)", rel_reg);
+ reg_idx -= NumMicroFpRegs;
+ ccprintf(os, "%%st(%d)", reg_idx);
break;
}
case CCRegClass:
- ccprintf(os, "%%cc%d", rel_reg);
+ ccprintf(os, "%%cc%d", reg_idx);
break;
case MiscRegClass:
- switch (rel_reg) {
+ switch (reg_idx) {
default:
- ccprintf(os, "%%ctrl%d", rel_reg);
+ ccprintf(os, "%%ctrl%d", reg_idx);
}
break;
}
@@ -250,14 +250,14 @@ namespace X86ISA
{
if (scale != 1)
ccprintf(os, "%d*", scale);
- printReg(os, index, addressSize);
+ printReg(os, InstRegIndex(index), addressSize);
someAddr = true;
}
if (base != ZeroReg)
{
if (someAddr)
os << " + ";
- printReg(os, base, addressSize);
+ printReg(os, InstRegIndex(base), addressSize);
someAddr = true;
}
}
diff --git a/src/arch/x86/insts/static_inst.hh b/src/arch/x86/insts/static_inst.hh
index d06470a3e..0cea0e132 100644
--- a/src/arch/x86/insts/static_inst.hh
+++ b/src/arch/x86/insts/static_inst.hh
@@ -51,11 +51,27 @@ namespace X86ISA
* wrapper struct for these lets take advantage of the compiler's type
* checking.
*/
- struct InstRegIndex
+ struct InstRegIndex : public RegId
{
- RegIndex idx;
- explicit InstRegIndex(RegIndex _idx) : idx(_idx)
- {}
+ 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;
+ }
+ }
};
/**
@@ -81,7 +97,7 @@ namespace X86ISA
void printSegment(std::ostream &os, int segment) const;
- void printReg(std::ostream &os, int reg, int size) const;
+ void printReg(std::ostream &os, RegId reg, int size) const;
void printSrcReg(std::ostream &os, int reg, int size) const;
void printDestReg(std::ostream &os, int reg, int size) const;
void printMem(std::ostream &os, uint8_t segment,
@@ -91,7 +107,7 @@ namespace X86ISA
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
{
X86IntReg reg = into;
- if (_destRegIdx[0] & IntFoldBit)
+ if (_destRegIdx[0].regIdx & IntFoldBit)
{
reg.H = val;
return reg;
@@ -122,7 +138,7 @@ namespace X86ISA
{
X86IntReg reg = from;
DPRINTF(X86, "Picking with size %d\n", size);
- if (_srcRegIdx[idx] & IntFoldBit)
+ if (_srcRegIdx[idx].regIdx & IntFoldBit)
return reg.H;
switch(size)
{
@@ -143,7 +159,7 @@ namespace X86ISA
{
X86IntReg reg = from;
DPRINTF(X86, "Picking with size %d\n", size);
- if (_srcRegIdx[idx] & IntFoldBit)
+ if (_srcRegIdx[idx].regIdx & IntFoldBit)
return reg.SH;
switch(size)
{
diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa
index cd282f67a..8a832f5d5 100644
--- a/src/arch/x86/isa/microops/limmop.isa
+++ b/src/arch/x86/isa/microops/limmop.isa
@@ -95,7 +95,7 @@ def template MicroLimmOpConstructor {{
InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
setFlags, %(op_class)s),
- dest(_dest.idx), imm(_imm), dataSize(_dataSize)
+ dest(_dest.regIdx), imm(_imm), dataSize(_dataSize)
{
foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0;
%(constructor)s;
diff --git a/src/arch/x86/isa/specialize.isa b/src/arch/x86/isa/specialize.isa
index 5a21c0944..84e5f6b02 100644
--- a/src/arch/x86/isa/specialize.isa
+++ b/src/arch/x86/isa/specialize.isa
@@ -143,13 +143,19 @@ let {{
regString = "INTREG_R%s" % opType.reg
env.addReg(regString)
env.addToDisassembly(
- "printReg(out, %s, regSize);\n" % regString)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ regString)
+
Name += "_R"
+
elif opType.tag == "B":
# This refers to registers whose index is encoded as part of the opcode
env.addToDisassembly(
- "printReg(out, %s, regSize);\n" % InstRegIndex)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ InstRegIndex)
+
Name += "_R"
+
env.addReg(InstRegIndex)
elif opType.tag == "M":
# This refers to memory. The macroop constructor sets up modrm
@@ -182,8 +188,11 @@ let {{
# Use the "reg" field of the ModRM byte to select the register
env.addReg(ModRMRegIndex)
env.addToDisassembly(
- "printReg(out, %s, regSize);\n" % ModRMRegIndex)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ ModRMRegIndex)
+
if opType.tag == "P":
+
Name += "_MMX"
elif opType.tag == "V":
Name += "_XMM"
@@ -195,8 +204,11 @@ let {{
regEnv = copy.copy(env)
regEnv.addReg(ModRMRMIndex)
regEnv.addToDisassembly(
- "printReg(out, %s, regSize);\n" % ModRMRMIndex)
+ "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
@@ -222,8 +234,11 @@ let {{
# Non register modrm settings should cause an error
env.addReg(ModRMRMIndex)
env.addToDisassembly(
- "printReg(out, %s, regSize);\n" % ModRMRMIndex)
+ "printReg(out, InstRegIndex(%s), regSize);\n" %
+ ModRMRMIndex)
+
if opType.tag == "PR":
+
Name += "_MMX"
elif opType.tag == "VR":
Name += "_XMM"
diff --git a/src/arch/x86/registers.hh b/src/arch/x86/registers.hh
index c28336dc9..d23731977 100644
--- a/src/arch/x86/registers.hh
+++ b/src/arch/x86/registers.hh
@@ -105,8 +105,6 @@ typedef union
MiscReg ctrlReg;
} AnyReg;
-typedef uint16_t RegIndex;
-
} // namespace X86ISA
#endif // __ARCH_X86_REGFILE_HH__