From d2ccf5e50917701a4eab9f1848c8d524ccf0c7cc Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Tue, 19 Jun 2007 22:40:10 +0000 Subject: [PATCH] More faithfulness to what instructions should work in what modes, and added the MOVSXD instruction. --HG-- extra : convert_revision : 38b9bf6cd4bdec6355b1158967c7d3562715cacd --- src/arch/x86/isa/decoder/one_byte_opcodes.isa | 51 ++++++---- src/arch/x86/isa/insts/data_transfer/move.py | 9 ++ src/arch/x86/isa/microops/regop.isa | 94 +++++++++---------- 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);''') }}; -- 2.30.2