summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86/isa/base.isa58
-rw-r--r--src/arch/x86/isa/microops/limmop.isa18
-rw-r--r--src/arch/x86/isa/microops/regop.isa138
-rw-r--r--src/arch/x86/isa_traits.hh4
4 files changed, 187 insertions, 31 deletions
diff --git a/src/arch/x86/isa/base.isa b/src/arch/x86/isa/base.isa
index eba24f709..d9bd87f2d 100644
--- a/src/arch/x86/isa/base.isa
+++ b/src/arch/x86/isa/base.isa
@@ -95,6 +95,14 @@ output header {{
/**
* Base class for all X86 static instructions.
*/
+ BitUnion64(X86IntReg)
+ Bitfield<63,0> R;
+ Bitfield<31,0> E;
+ Bitfield<15,0> X;
+ Bitfield<15,8> H;
+ Bitfield<7, 0> L;
+ EndBitUnion(X86IntReg)
+
class X86StaticInst : public StaticInst
{
protected:
@@ -114,10 +122,50 @@ output header {{
inline uint64_t merge(uint64_t into, uint64_t val, int size) const
{
- //FIXME This needs to be significantly more sophisticated
+ X86IntReg reg;
+ reg = into;
+ //FIXME This needs to be handle high bytes as well
+ switch(size)
+ {
+ case 1:
+ reg.L = val;
+ break;
+ case 2:
+ reg.X = val;
+ break;
+ case 4:
+ //XXX Check if this should be zeroed or sign extended
+ reg = 0;
+ reg.E = val;
+ break;
+ case 8:
+ reg.R = val;
+ break;
+ default:
+ panic("Tried to merge with unrecognized size %d.\n", size);
+ }
return val;
}
+ inline uint64_t pick(uint64_t from, int size)
+ {
+ X86IntReg reg;
+ reg = from;
+ switch(size)
+ {
+ case 1:
+ return reg.L;
+ case 2:
+ return reg.E;
+ case 4:
+ return reg.X;
+ case 8:
+ return reg.R;
+ default:
+ panic("Tried to pick with unrecognized size %d.\n", size);
+ }
+ }
+
};
}};
@@ -128,6 +176,12 @@ output decoder {{
ccprintf(os, "\t%s ", mnemonic);
}
+ inline void printMnemonic(std::ostream &os,
+ const char * instMnemonic, const char * mnemonic)
+ {
+ ccprintf(os, "\t%s : %s ", instMnemonic, mnemonic);
+ }
+
void
X86StaticInst::printSrcReg(std::ostream &os, int reg) const
{
@@ -197,6 +251,8 @@ output decoder {{
case INTREG_R15W:
ccprintf(os, "r15");
break;
+ default:
+ ccprintf(os, "t%d", reg - NUM_INTREGS);
}
} else if (reg < Ctrl_Base_DepTag) {
ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa
index c76c074b1..141d7523f 100644
--- a/src/arch/x86/isa/microops/limmop.isa
+++ b/src/arch/x86/isa/microops/limmop.isa
@@ -79,6 +79,9 @@ def template MicroLimmOpDeclare {{
const uint64_t imm;
void buildMe();
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+
public:
%(class_name)s(ExtMachInst _machInst,
const char * instMnem,
@@ -93,6 +96,20 @@ def template MicroLimmOpDeclare {{
};
}};
+def template MicroLimmOpDisassembly {{
+ std::string %(class_name)s::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ printReg(response, dest);
+ response << ", ";
+ ccprintf(response, "%#x", imm);
+ return response.str();
+ }
+}};
+
def template MicroLimmOpConstructor {{
inline void %(class_name)s::buildMe()
@@ -148,5 +165,6 @@ let {{
{"code" : "DestReg = imm;"})
header_output += MicroLimmOpDeclare.subst(iop)
decoder_output += MicroLimmOpConstructor.subst(iop)
+ decoder_output += MicroLimmOpDisassembly.subst(iop)
exec_output += MicroLimmOpExecute.subst(iop)
}};
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index a99194c5e..d5fb25cb5 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -59,6 +59,100 @@
//
//////////////////////////////////////////////////////////////////////////
+output header {{
+ /**
+ * Base classes for RegOps which provides a generateDisassembly method.
+ */
+ class RegOp : public X86MicroopBase
+ {
+ protected:
+ const RegIndex src1;
+ const RegIndex src2;
+ const RegIndex dest;
+ const bool setStatus;
+ const uint8_t dataSize;
+ const uint8_t ext;
+
+ // Constructor
+ RegOp(ExtMachInst _machInst,
+ const char *mnem, const char *_instMnem,
+ bool isMicro, bool isDelayed,
+ bool isFirst, bool isLast,
+ RegIndex _src1, RegIndex _src2, RegIndex _dest,
+ bool _setStatus, uint8_t _dataSize, uint8_t _ext,
+ OpClass __opClass) :
+ X86MicroopBase(_machInst, mnem, _instMnem,
+ isMicro, isDelayed, isFirst, isLast,
+ __opClass),
+ src1(_src1), src2(_src2), dest(_dest),
+ setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+
+ class RegOpImm : public X86MicroopBase
+ {
+ protected:
+ const RegIndex src1;
+ const uint8_t imm8;
+ const RegIndex dest;
+ const bool setStatus;
+ const uint8_t dataSize;
+ const uint8_t ext;
+
+ // Constructor
+ RegOpImm(ExtMachInst _machInst,
+ const char * mnem, const char *_instMnem,
+ bool isMicro, bool isDelayed,
+ bool isFirst, bool isLast,
+ RegIndex _src1, uint8_t _imm8, RegIndex _dest,
+ bool _setStatus, uint8_t _dataSize, uint8_t _ext,
+ OpClass __opClass) :
+ X86MicroopBase(_machInst, mnem, _instMnem,
+ isMicro, isDelayed, isFirst, isLast,
+ __opClass),
+ src1(_src1), imm8(_imm8), dest(_dest),
+ setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+ {
+ }
+
+ std::string generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const;
+ };
+}};
+
+output decoder {{
+ std::string RegOp::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ printReg(response, dest);
+ response << ", ";
+ printReg(response, src1);
+ response << ", ";
+ printReg(response, src2);
+ return response.str();
+ }
+
+ std::string RegOpImm::generateDisassembly(Addr pc,
+ const SymbolTable *symtab) const
+ {
+ std::stringstream response;
+
+ printMnemonic(response, instMnem, mnemonic);
+ printReg(response, dest);
+ response << ", ";
+ printReg(response, src1);
+ ccprintf(response, ", %#x", imm8);
+ return response.str();
+ }
+}};
+
def template MicroRegOpExecute {{
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
Trace::InstRecord *traceData) const
@@ -101,12 +195,6 @@ def template MicroRegOpDeclare {{
class %(class_name)s : public %(base_class)s
{
protected:
- const RegIndex src1;
- const RegIndex src2;
- const RegIndex dest;
- const bool setStatus;
- const uint8_t dataSize;
- const uint8_t ext;
void buildMe();
public:
@@ -130,12 +218,6 @@ def template MicroRegOpImmDeclare {{
class %(class_name)sImm : public %(base_class)s
{
protected:
- const RegIndex src1;
- const uint8_t imm8;
- const RegIndex dest;
- const bool setStatus;
- const uint8_t dataSize;
- const uint8_t ext;
void buildMe();
public:
@@ -166,9 +248,9 @@ def template MicroRegOpConstructor {{
RegIndex _src1, RegIndex _src2, RegIndex _dest,
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
- false, false, false, false, %(op_class)s),
- src1(_src1), src2(_src2), dest(_dest),
- setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+ false, false, false, false,
+ _src1, _src2, _dest, _setStatus, _dataSize, _ext,
+ %(op_class)s)
{
buildMe();
}
@@ -179,9 +261,9 @@ def template MicroRegOpConstructor {{
RegIndex _src1, RegIndex _src2, RegIndex _dest,
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
- isMicro, isDelayed, isFirst, isLast, %(op_class)s),
- src1(_src1), src2(_src2), dest(_dest),
- setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+ isMicro, isDelayed, isFirst, isLast,
+ _src1, _src2, _dest, _setStatus, _dataSize, _ext,
+ %(op_class)s)
{
buildMe();
}
@@ -199,9 +281,9 @@ def template MicroRegOpImmConstructor {{
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
- false, false, false, false, %(op_class)s),
- src1(_src1), imm8(_imm8), dest(_dest),
- setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+ false, false, false, false,
+ _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
+ %(op_class)s)
{
buildMe();
}
@@ -212,9 +294,9 @@ def template MicroRegOpImmConstructor {{
RegIndex _src1, uint8_t _imm8, RegIndex _dest,
bool _setStatus, uint8_t _dataSize, uint8_t _ext) :
%(base_class)s(machInst, "%(mnemonic)s", instMnem,
- isMicro, isDelayed, isFirst, isLast, %(op_class)s),
- src1(_src1), imm8(_imm8), dest(_dest),
- setStatus(_setStatus), dataSize(_dataSize), ext(_ext)
+ isMicro, isDelayed, isFirst, isLast,
+ _src1, _imm8, _dest, _setStatus, _dataSize, _ext,
+ %(op_class)s)
{
buildMe();
}
@@ -227,7 +309,7 @@ let {{
self.src1 = src1
self.src2 = src2
self.setStatus = False
- self.dataSize = 1
+ self.dataSize = "env.dataSize"
self.ext = 0
def getAllocator(self, *microFlags):
@@ -249,7 +331,7 @@ let {{
self.src1 = src1
self.imm8 = imm8
self.setStatus = False
- self.dataSize = 1
+ self.dataSize = "env.dataSize"
self.ext = 0
def getAllocator(self, *microFlags):
@@ -290,7 +372,7 @@ let {{
immCode = matcher.sub("imm8", code)
# Build up the all register version of this micro op
- iop = InstObjParams(name, Name, 'X86MicroopBase', {"code" : regCode})
+ iop = InstObjParams(name, Name, 'RegOp', {"code" : regCode})
header_output += MicroRegOpDeclare.subst(iop)
decoder_output += MicroRegOpConstructor.subst(iop)
exec_output += MicroRegOpExecute.subst(iop)
@@ -305,7 +387,7 @@ let {{
# Build up the immediate version of this micro op
iop = InstObjParams(name + "i", Name,
- 'X86MicroopBase', {"code" : immCode})
+ 'RegOpImm', {"code" : immCode})
header_output += MicroRegOpImmDeclare.subst(iop)
decoder_output += MicroRegOpImmConstructor.subst(iop)
exec_output += MicroRegOpImmExecute.subst(iop)
diff --git a/src/arch/x86/isa_traits.hh b/src/arch/x86/isa_traits.hh
index 5a625f741..7aba6248a 100644
--- a/src/arch/x86/isa_traits.hh
+++ b/src/arch/x86/isa_traits.hh
@@ -81,8 +81,8 @@ namespace X86ISA
// These enumerate all the registers for dependence tracking.
enum DependenceTags {
- //The number of microcode registers needs to be added to this
- FP_Base_DepTag = 16,
+ //There are 16 microcode registers at the moment
+ FP_Base_DepTag = 32,
Ctrl_Base_DepTag =
FP_Base_DepTag +
//mmx/x87 registers