summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe Black <gblack@eecs.umich.edu>2007-06-19 22:40:10 +0000
committerGabe Black <gblack@eecs.umich.edu>2007-06-19 22:40:10 +0000
commitd2ccf5e50917701a4eab9f1848c8d524ccf0c7cc (patch)
tree19cfdd9b70857361f756ff8f86fa70b3ef87a4b9
parentcc796de96201754b3e3a38996090ed633307aa8c (diff)
downloadgem5-d2ccf5e50917701a4eab9f1848c8d524ccf0c7cc.tar.xz
More faithfulness to what instructions should work in what modes, and added the MOVSXD instruction.
--HG-- extra : convert_revision : 38b9bf6cd4bdec6355b1158967c7d3562715cacd
-rw-r--r--src/arch/x86/isa/decoder/one_byte_opcodes.isa51
-rw-r--r--src/arch/x86/isa/insts/data_transfer/move.py9
-rw-r--r--src/arch/x86/isa/microops/regop.isa94
3 files changed, 83 insertions, 71 deletions
diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 78270e782..c3f95137a 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -172,25 +172,33 @@
default: aas();
}
}
- 0x08: decode OPCODE_OP_BOTTOM3 {
- 0x0: inc_eAX();
- 0x1: inc_eCX();
- 0x2: inc_eDX();
- 0x3: inc_eBX();
- 0x4: inc_eSP();
- 0x5: inc_eBP();
- 0x6: inc_eSI();
- 0x7: inc_eDI();
+ 0x08: decode MODE_SUBMODE {
+ 0x0: M5InternalError::error (
+ {{"Tried to execute an REX prefix!"}});
+ default: decode OPCODE_OP_BOTTOM3 {
+ 0x0: inc_eAX();
+ 0x1: inc_eCX();
+ 0x2: inc_eDX();
+ 0x3: inc_eBX();
+ 0x4: inc_eSP();
+ 0x5: inc_eBP();
+ 0x6: inc_eSI();
+ 0x7: inc_eDI();
+ }
}
- 0x09: decode OPCODE_OP_BOTTOM3 {
- 0x0: dec_eAX();
- 0x1: dec_eCX();
- 0x2: dec_eDX();
- 0x3: dec_eBX();
- 0x4: dec_eSP();
- 0x5: dec_eBP();
- 0x6: dec_eSI();
- 0x7: dec_eDI();
+ 0x09: decode MODE_SUBMODE {
+ 0x0: M5InternalError::error (
+ {{"Tried to execute an REX prefix!"}});
+ default: decode OPCODE_OP_BOTTOM3 {
+ 0x0: dec_eAX();
+ 0x1: dec_eCX();
+ 0x2: dec_eDX();
+ 0x3: dec_eBX();
+ 0x4: dec_eSP();
+ 0x5: dec_eBP();
+ 0x6: dec_eSI();
+ 0x7: dec_eDI();
+ }
}
format Inst {
0x0A: decode OPCODE_OP_BOTTOM3 {
@@ -227,7 +235,10 @@
0x0: This_should_be_an_illegal_instruction();
default: bound_Gv_Ma();
}
- 0x3: arpl_Ew_Gw();
+ 0x3: decode MODE_SUBMODE {
+ 0x0: Inst::MOVSXD(Gv,Ed);
+ default: arpl_Ew_Gw();
+ }
0x4: M5InternalError::error(
{{"Tried to execute the FS segment override prefix!"}});
0x5: M5InternalError::error(
@@ -301,7 +312,7 @@
0x7: group10_Ev(); //Make sure this is Ev
}
0x12: decode OPCODE_OP_BOTTOM3 {
- 0x0: nop_or_pause(); //Check for repe prefix
+ default: nop_or_pause(); //Check for repe prefix
0x1: xchg_rCX_rAX();
0x2: xchg_rDX_rAX();
0x3: xchg_rVX_rAX();
diff --git a/src/arch/x86/isa/insts/data_transfer/move.py b/src/arch/x86/isa/insts/data_transfer/move.py
index ff4af0af4..1464e6379 100644
--- a/src/arch/x86/isa/insts/data_transfer/move.py
+++ b/src/arch/x86/isa/insts/data_transfer/move.py
@@ -74,6 +74,15 @@ def macroop MOV_M_I {
limm "env.reg", "IMMEDIATE"
#Do a store to put the register operand into memory
};
+
+def macroop MOVSXD_R_R {
+ sext "env.reg", "env.regm", "env.dataSize"
+};
+
+def macroop MOVSXD_R_M {
+ #Do a load to fill the register operand from memory
+ sext "env.reg", "env.regm", "env.dataSize"
+};
'''
#let {{
# class MOV(Inst):
diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa
index 6f86892c3..7c5b6df01 100644
--- a/src/arch/x86/isa/microops/regop.isa
+++ b/src/arch/x86/isa/microops/regop.isa
@@ -356,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()
@@ -371,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, 'RegOp', {"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,
- 'RegOpImm', {"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)')
@@ -412,10 +410,6 @@ let {{
# This has it's own function because Wr ops have implicit destinations
def defineMicroRegOpWr(mnemonic, code):
- global header_output
- global decoder_output
- global exec_output
- global microopClasses
Name = mnemonic
name = mnemonic.lower()
@@ -426,58 +420,56 @@ 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, 'RegOp', {"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, src1, src2):
super(RegOpChild, self).__init__("NUM_INTREGS", 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,
- 'RegOpImm', {"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, src1, imm):
- super(RegOpImmChild, self).__init__("NUM_INTREGS", src1, imm)
+ # 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"
- microopClasses[name + "i"] = RegOpImmChild
+ 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):
- global header_output
- global decoder_output
- global exec_output
- global microopClasses
Name = mnemonic
name = mnemonic.lower()
- iop = InstObjParams(name, Name, 'RegOp', {"code" : code})
- header_output += MicroRegOpDeclare.subst(iop)
- decoder_output += MicroRegOpConstructor.subst(iop)
- exec_output += MicroRegOpExecute.subst(iop)
-
class RegOpChild(RegOp):
def __init__(self, dest, src1 = "NUM_INTREGS"):
super(RegOpChild, self).__init__(dest, src1, "NUM_INTREGS")
self.className = Name
self.mnemonic = name
- microopClasses[name] = RegOpChild
+ 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);''')
}};