summaryrefslogtreecommitdiff
path: root/src/arch/x86/isa/microops/regop.isa
diff options
context:
space:
mode:
Diffstat (limited to 'src/arch/x86/isa/microops/regop.isa')
-rw-r--r--src/arch/x86/isa/microops/regop.isa234
1 files changed, 189 insertions, 45 deletions
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index a99194c5e..7c5b6df01 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):
@@ -274,11 +356,20 @@ let {{
decoder_output = ""
exec_output = ""
- def defineMicroRegOp(mnemonic, code):
+ def setUpMicroRegOp(name, Name, base, code, child):
global header_output
global decoder_output
global exec_output
global microopClasses
+
+ iop = InstObjParams(name, Name, base, {"code" : code})
+ header_output += MicroRegOpDeclare.subst(iop)
+ decoder_output += MicroRegOpConstructor.subst(iop)
+ exec_output += MicroRegOpExecute.subst(iop)
+
+ microopClasses[name] = child
+
+ def defineMicroRegOp(mnemonic, code):
Name = mnemonic
name = mnemonic.lower()
@@ -289,34 +380,23 @@ let {{
regCode = matcher.sub("SrcReg2", code)
immCode = matcher.sub("imm8", code)
- # Build up the all register version of this micro op
- iop = InstObjParams(name, Name, 'X86MicroopBase', {"code" : regCode})
- header_output += MicroRegOpDeclare.subst(iop)
- decoder_output += MicroRegOpConstructor.subst(iop)
- exec_output += MicroRegOpExecute.subst(iop)
-
+ # Build the all register version of this micro op
class RegOpChild(RegOp):
def __init__(self, dest, src1, src2):
super(RegOpChild, self).__init__(dest, src1, src2)
self.className = Name
self.mnemonic = name
- microopClasses[name] = RegOpChild
-
- # Build up the immediate version of this micro op
- iop = InstObjParams(name + "i", Name,
- 'X86MicroopBase', {"code" : immCode})
- header_output += MicroRegOpImmDeclare.subst(iop)
- decoder_output += MicroRegOpImmConstructor.subst(iop)
- exec_output += MicroRegOpImmExecute.subst(iop)
+ setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild);
- class RegOpImmChild(RegOpImm):
- def __init__(self, dest, src1, imm):
- super(RegOpImmChild, self).__init__(dest, src1, imm)
+ # Build the immediate version of this micro op
+ class RegOpChildImm(RegOpImm):
+ def __init__(self, dest, src1, src2):
+ super(RegOpChildImm, self).__init__(dest, src1, src2)
self.className = Name + "Imm"
self.mnemonic = name + "i"
- microopClasses[name + "i"] = RegOpImmChild
+ setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm);
defineMicroRegOp('Add', 'DestReg = merge(DestReg, SrcReg1 + op2, dataSize)') #Needs to set OF,CF,SF
defineMicroRegOp('Or', 'DestReg = merge(DestReg, SrcReg1 | op2, dataSize)')
@@ -328,4 +408,68 @@ let {{
defineMicroRegOp('Cmp', 'DestReg = merge(DestReg, DestReg - op2, dataSize)') #Needs to set OF,CF,SF and not DestReg
defineMicroRegOp('Mov', 'DestReg = merge(SrcReg1, op2, dataSize)')
+ # This has it's own function because Wr ops have implicit destinations
+ def defineMicroRegOpWr(mnemonic, code):
+ Name = mnemonic
+ name = mnemonic.lower()
+
+ # Find op2 in each of the instruction definitions. Create two versions
+ # of the code, one with an integer operand, and one with an immediate
+ # operand.
+ matcher = re.compile("op2(?P<typeQual>\\.\\w+)?")
+ regCode = matcher.sub("SrcReg2", code)
+ immCode = matcher.sub("imm8", code)
+
+ # Build the all register version of this micro op
+ class RegOpChild(RegOp):
+ def __init__(self, src1, src2):
+ super(RegOpChild, self).__init__("NUM_INTREGS", src1, src2)
+ self.className = Name
+ self.mnemonic = name
+
+ setUpMicroRegOp(name, Name, "RegOp", regCode, RegOpChild);
+
+ # Build the immediate version of this micro op
+ class RegOpChildImm(RegOpImm):
+ def __init__(self, src1, src2):
+ super(RegOpChildImm, self).__init__("NUM_INTREGS", src1, src2)
+ self.className = Name + "Imm"
+ self.mnemonic = name + "i"
+
+ setUpMicroRegOp(name + "i", Name + "Imm", "RegOpImm", immCode, RegOpChildImm);
+
+ defineMicroRegOpWr('Wrip', 'RIP = SrcReg1 + op2')
+
+ # This has it's own function because Rd ops don't always have two parameters
+ def defineMicroRegOpRd(mnemonic, code):
+ Name = mnemonic
+ name = mnemonic.lower()
+
+ class RegOpChild(RegOp):
+ def __init__(self, dest, src1 = "NUM_INTREGS"):
+ super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS")
+ self.className = Name
+ self.mnemonic = name
+
+ setUpMicroRegOp(name, Name, "RegOp", code, RegOpChild);
+
+ defineMicroRegOpRd('Rdip', 'DestReg = RIP')
+
+ def defineMicroRegOpImm(mnemonic, code):
+ Name = mnemonic
+ name = mnemonic.lower()
+
+ class RegOpChild(RegOpImm):
+ def __init__(self, dest, src1, src2):
+ super(RegOpChild, self).__init__(dest, src1, src2)
+ self.className = Name
+ self.mnemonic = name
+
+ setUpMicroRegOp(name, Name, "RegOpImm", code, RegOpChild);
+
+ defineMicroRegOpImm('Sext', '''
+ IntReg val = SrcReg1;
+ int sign_bit = bits(val, imm8-1, imm8-1);
+ val = sign_bit ? (val | ~mask(imm8)) : val;
+ DestReg = merge(DestReg, val, dataSize);''')
}};