From 6c125779372ecc7c9482f6e79bd4c5c0c99ad7ec Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Mon, 18 Jun 2007 14:15:00 +0000 Subject: Add in incomplete pick and merge functions which read and write pieces of registers, and fill out microcode disassembly. --HG-- extra : convert_revision : 56332b3999a9079b1bd305ee2826abdf593367e1 --- src/arch/x86/isa/base.isa | 58 ++++++++++++++- src/arch/x86/isa/microops/limmop.isa | 18 +++++ src/arch/x86/isa/microops/regop.isa | 138 ++++++++++++++++++++++++++++------- src/arch/x86/isa_traits.hh | 4 +- 4 files changed, 187 insertions(+), 31 deletions(-) (limited to 'src') 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 -- cgit v1.2.3