diff options
Diffstat (limited to 'src/arch/x86/isa/microops')
-rw-r--r-- | src/arch/x86/isa/microops/base.isa | 31 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/debug.isa | 229 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/fpop.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/ldstop.isa | 145 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/limmop.isa | 2 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/microops.isa | 8 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/regop.isa | 323 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/seqop.isa | 251 | ||||
-rw-r--r-- | src/arch/x86/isa/microops/specop.isa | 19 |
9 files changed, 891 insertions, 119 deletions
diff --git a/src/arch/x86/isa/microops/base.isa b/src/arch/x86/isa/microops/base.isa index 75658a26c..f1007bf71 100644 --- a/src/arch/x86/isa/microops/base.isa +++ b/src/arch/x86/isa/microops/base.isa @@ -69,6 +69,29 @@ let {{ let {{ class X86Microop(object): + + generatorNameTemplate = "generate_%s_%d" + + generatorTemplate = ''' + StaticInstPtr + ''' + generatorNameTemplate + '''(StaticInstPtr curMacroop) + { + static const char *macrocodeBlock = romMnemonic; + static const ExtMachInst dummyExtMachInst; + static const EmulEnv dummyEmulEnv(0, 0, 1, 1, 1); + + Macroop * macroop = dynamic_cast<Macroop *>(curMacroop.get()); + const ExtMachInst &machInst = + macroop ? macroop->getExtMachInst() : dummyExtMachInst; + const EmulEnv &env = + macroop ? macroop->getEmulEnv() : dummyEmulEnv; + // env may not be used in the microop's constructor. + RegIndex reg = env.reg; + reg = reg; + using namespace RomLabels; + return %s; + } + ''' def __init__(self, name): self.name = name @@ -91,4 +114,12 @@ let {{ def getAllocator(self, mnemonic, *microFlags): return 'new %s(machInst, %s)' % \ (self.className, mnemonic, self.microFlagsText(microFlags)) + + def getGeneratorDef(self, micropc): + return self.generatorTemplate % \ + (self.className, micropc, \ + self.getAllocator(True, True, False, False)) + + def getGenerator(self, micropc): + return self.generatorNameTemplate % (self.className, micropc) }}; diff --git a/src/arch/x86/isa/microops/debug.isa b/src/arch/x86/isa/microops/debug.isa new file mode 100644 index 000000000..38fee59bb --- /dev/null +++ b/src/arch/x86/isa/microops/debug.isa @@ -0,0 +1,229 @@ +// Copyright (c) 2008 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. Redistributions +// in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. Neither the name of +// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +////////////////////////////////////////////////////////////////////////// +// +// Debug Microops +// +////////////////////////////////////////////////////////////////////////// + +output header {{ + class MicroDebugBase : public X86ISA::X86MicroopBase + { + protected: + std::string message; + uint8_t cc; + + public: + MicroDebugBase(ExtMachInst _machInst, const char * mnem, + const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + std::string _message, uint8_t _cc); + + MicroDebugBase(ExtMachInst _machInst, const char * mnem, + const char * instMnem, std::string _message, uint8_t _cc); + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +}}; + +def template MicroDebugDeclare {{ + class %(class_name)s : public %(base_class)s + { + private: + void buildMe(); + public: + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + std::string _message, uint8_t _cc); + + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + std::string _message, uint8_t _cc); + + %(BasicExecDeclare)s + }; +}}; + +def template MicroDebugExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + %(op_decl)s + %(op_rd)s + if (%(cond_test)s) { + %(func)s("%s\n", message); + } + return NoFault; + } +}}; + +output decoder {{ + inline MicroDebugBase::MicroDebugBase( + ExtMachInst machInst, const char * mnem, const char * instMnem, + std::string _message, uint8_t _cc) : + X86MicroopBase(machInst, mnem, instMnem, + false, false, false, false, No_OpClass), + message(_message), cc(_cc) + { + } + + inline MicroDebugBase::MicroDebugBase( + ExtMachInst machInst, const char * mnem, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + std::string _message, uint8_t _cc) : + X86MicroopBase(machInst, mnem, instMnem, + isMicro, isDelayed, isFirst, isLast, No_OpClass), + message(_message), cc(_cc) + { + } +}}; + +def template MicroDebugConstructor {{ + + inline void %(class_name)s::buildMe() + { + %(constructor)s; + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + std::string _message, uint8_t _cc) : + %(base_class)s(machInst, "%(func)s", instMnem, _message, _cc) + { + buildMe(); + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + std::string _message, uint8_t _cc) : + %(base_class)s(machInst, "%(func)s", instMnem, + isMicro, isDelayed, isFirst, isLast, _message, _cc) + { + buildMe(); + } +}}; + +output decoder {{ + std::string MicroDebugBase::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + response << "\"" << message << "\""; + + return response.str(); + } +}}; + +let {{ + class MicroDebug(X86Microop): + def __init__(self, message, flags=None): + self.message = message + if flags: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.cond = " | ".join(flags) + self.className += "Flags" + else: + self.cond = "0" + + def getAllocator(self, *microFlags): + allocator = '''new %(class_name)s(machInst, macrocodeBlock + %(flags)s, "%(message)s", %(cc)s)''' % { + "class_name" : self.className, + "flags" : self.microFlagsText(microFlags), + "message" : self.message, + "cc" : self.cond} + return allocator + + exec_output = "" + header_output = "" + decoder_output = "" + + def buildDebugMicro(func): + global exec_output, header_output, decoder_output + + iop = InstObjParams(func, "Micro%sFlags" % func.capitalize(), + "MicroDebugBase", + {"code": "", + "func": func, + "cond_test": "checkCondition(ccFlagBits, cc)"}) + exec_output += MicroDebugExecute.subst(iop) + header_output += MicroDebugDeclare.subst(iop) + decoder_output += MicroDebugConstructor.subst(iop) + + iop = InstObjParams(func, "Micro%s" % func.capitalize(), + "MicroDebugBase", + {"code": "", + "func": func, + "cond_test": "true"}) + exec_output += MicroDebugExecute.subst(iop) + header_output += MicroDebugDeclare.subst(iop) + decoder_output += MicroDebugConstructor.subst(iop) + + class MicroDebugChild(MicroDebug): + className = "Micro%s" % func.capitalize() + + global microopClasses + microopClasses[func] = MicroDebugChild + + buildDebugMicro("panic") + buildDebugMicro("fatal") + buildDebugMicro("warn") + buildDebugMicro("warn_once") +}}; diff --git a/src/arch/x86/isa/microops/fpop.isa b/src/arch/x86/isa/microops/fpop.isa index 2919aa277..d4acfdbf4 100644 --- a/src/arch/x86/isa/microops/fpop.isa +++ b/src/arch/x86/isa/microops/fpop.isa @@ -245,7 +245,7 @@ let {{ self.className += "Top" def getAllocator(self, *microFlags): - return '''new %(class_name)s(machInst, mnemonic + return '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(src1)s, %(src2)s, %(dest)s, %(dataSize)s, %(spm)d)''' % { "class_name" : self.className, diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa index cb63e7cd9..af94cf31e 100644 --- a/src/arch/x86/isa/microops/ldstop.isa +++ b/src/arch/x86/isa/microops/ldstop.isa @@ -124,14 +124,16 @@ def template MicroLeaDeclare {{ uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize); + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags); %(class_name)s(ExtMachInst _machInst, const char * instMnem, uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize); + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags); %(BasicExecDeclare)s }; @@ -151,11 +153,13 @@ def template MicroLoadExecute {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); + fault = read(xc, EA, Mem, memFlags); - if(fault == NoFault) - { + if (fault == NoFault) { %(code)s; + } else if (memFlags & Request::PF_EXCLUSIVE) { + // For prefetches, ignore any faults/exceptions. + return NoFault; } if(fault == NoFault) { @@ -178,7 +182,7 @@ def template MicroLoadInitiateAcc {{ %(ea_code)s; DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA); - fault = read(xc, EA, Mem, (%(mem_flags)s) | segment); + fault = read(xc, EA, Mem, memFlags); return fault; } @@ -194,7 +198,7 @@ def template MicroLoadCompleteAcc {{ %(op_decl)s; %(op_rd)s; - Mem = pkt->get<typeof(Mem)>(); + Mem = get(pkt); %(code)s; @@ -225,9 +229,10 @@ def template MicroStoreExecute {{ if(fault == NoFault) { - fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); + fault = write(xc, Mem, EA, memFlags); if(fault == NoFault) { + %(post_code)s; %(op_wb)s; } } @@ -252,20 +257,20 @@ def template MicroStoreInitiateAcc {{ if(fault == NoFault) { - fault = write(xc, Mem, EA, (%(mem_flags)s) | segment); - if(fault == NoFault) - { - %(op_wb)s; - } + write(xc, Mem, EA, memFlags); } return fault; } }}; def template MicroStoreCompleteAcc {{ - Fault %(class_name)s::completeAcc(PacketPtr, %(CPU_exec_context)s * xc, - Trace::InstRecord * traceData) const + Fault %(class_name)s::completeAcc(PacketPtr pkt, + %(CPU_exec_context)s * xc, Trace::InstRecord * traceData) const { + %(op_decl)s; + %(op_rd)s; + %(complete_code)s; + %(op_wb)s; return NoFault; } }}; @@ -295,14 +300,16 @@ def template MicroLdStOpDeclare {{ uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize); + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags); %(class_name)s(ExtMachInst _machInst, const char * instMnem, uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize); + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags); %(BasicExecDeclare)s @@ -324,12 +331,13 @@ def template MicroLdStOpConstructor {{ uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize) : + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, false, false, false, false, _scale, _index, _base, _disp, _segment, _data, - _dataSize, _addressSize, %(op_class)s) + _dataSize, _addressSize, _memFlags, %(op_class)s) { buildMe(); } @@ -340,12 +348,13 @@ def template MicroLdStOpConstructor {{ uint8_t _scale, RegIndex _index, RegIndex _base, uint64_t _disp, uint8_t _segment, RegIndex _data, - uint8_t _dataSize, uint8_t _addressSize) : + uint8_t _dataSize, uint8_t _addressSize, + Request::FlagsType _memFlags) : %(base_class)s(machInst, "%(mnemonic)s", instMnem, isMicro, isDelayed, isFirst, isLast, _scale, _index, _base, _disp, _segment, _data, - _dataSize, _addressSize, %(op_class)s) + _dataSize, _addressSize, _memFlags, %(op_class)s) { buildMe(); } @@ -353,26 +362,35 @@ def template MicroLdStOpConstructor {{ let {{ class LdStOp(X86Microop): - def __init__(self, data, segment, addr, disp, dataSize, addressSize): + def __init__(self, data, segment, addr, disp, + dataSize, addressSize, baseFlags, atCPL0, prefetch): self.data = data [self.scale, self.index, self.base] = addr self.disp = disp self.segment = segment self.dataSize = dataSize self.addressSize = addressSize + self.memFlags = baseFlags + if atCPL0: + self.memFlags += " | (CPL0FlagBit << FlagShift)" + if prefetch: + self.memFlags += " | Request::PF_EXCLUSIVE" + self.memFlags += " | (machInst.legacy.addr ? " + \ + "(AddrSizeFlagBit << FlagShift) : 0)" def getAllocator(self, *microFlags): - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(scale)s, %(index)s, %(base)s, %(disp)s, %(segment)s, %(data)s, - %(dataSize)s, %(addressSize)s)''' % { + %(dataSize)s, %(addressSize)s, %(memFlags)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags), "scale" : self.scale, "index" : self.index, "base" : self.base, "disp" : self.disp, "segment" : self.segment, "data" : self.data, - "dataSize" : self.dataSize, "addressSize" : self.addressSize} + "dataSize" : self.dataSize, "addressSize" : self.addressSize, + "memFlags" : self.memFlags} return allocator }}; @@ -384,9 +402,11 @@ let {{ decoder_output = "" exec_output = "" - calculateEA = "EA = SegBase + scale * Index + Base + disp;" + calculateEA = ''' + EA = bits(SegBase + scale * Index + Base + disp, addressSize * 8 - 1, 0); + ''' - def defineMicroLoadOp(mnemonic, code, mem_flags=0): + def defineMicroLoadOp(mnemonic, code, mem_flags="0"): global header_output global decoder_output global exec_output @@ -397,8 +417,7 @@ let {{ # Build up the all register version of this micro op iop = InstObjParams(name, Name, 'X86ISA::LdStOp', {"code": code, - "ea_code": calculateEA, - "mem_flags": mem_flags}) + "ea_code": calculateEA}) header_output += MicroLdStOpDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLoadExecute.subst(iop) @@ -407,19 +426,24 @@ let {{ class LoadOp(LdStOp): def __init__(self, data, segment, addr, disp = 0, - dataSize="env.dataSize", addressSize="env.addressSize"): - super(LoadOp, self).__init__(data, segment, - addr, disp, dataSize, addressSize) + dataSize="env.dataSize", + addressSize="env.addressSize", + atCPL0=False, prefetch=False): + super(LoadOp, self).__init__(data, segment, addr, + disp, dataSize, addressSize, mem_flags, + atCPL0, prefetch) self.className = Name self.mnemonic = name microopClasses[name] = LoadOp defineMicroLoadOp('Ld', 'Data = merge(Data, Mem, dataSize);') - defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', 'StoreCheck') + defineMicroLoadOp('Ldst', 'Data = merge(Data, Mem, dataSize);', + 'X86ISA::StoreCheck') defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;') - def defineMicroStoreOp(mnemonic, code, mem_flags=0): + def defineMicroStoreOp(mnemonic, code, \ + postCode="", completeCode="", mem_flags="0"): global header_output global decoder_output global exec_output @@ -430,8 +454,9 @@ let {{ # Build up the all register version of this micro op iop = InstObjParams(name, Name, 'X86ISA::LdStOp', {"code": code, - "ea_code": calculateEA, - "mem_flags": mem_flags}) + "post_code": postCode, + "complete_code": completeCode, + "ea_code": calculateEA}) header_output += MicroLdStOpDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroStoreExecute.subst(iop) @@ -440,26 +465,26 @@ let {{ class StoreOp(LdStOp): def __init__(self, data, segment, addr, disp = 0, - dataSize="env.dataSize", addressSize="env.addressSize"): - super(StoreOp, self).__init__(data, segment, - addr, disp, dataSize, addressSize) + dataSize="env.dataSize", + addressSize="env.addressSize", + atCPL0=False): + super(StoreOp, self).__init__(data, segment, addr, + disp, dataSize, addressSize, mem_flags, atCPL0, False) self.className = Name self.mnemonic = name microopClasses[name] = StoreOp - defineMicroStoreOp('St', 'Mem = Data;') + defineMicroStoreOp('St', 'Mem = pick(Data, 2, dataSize);') defineMicroStoreOp('Stfp', 'Mem = FpData.uqw;') - defineMicroStoreOp('Stupd', ''' - Mem = Data; - Base = merge(Base, EA - SegBase, addressSize); - '''); - + defineMicroStoreOp('Stupd', 'Mem = pick(Data, 2, dataSize);', + 'Base = merge(Base, EA - SegBase, addressSize);', + 'Base = merge(Base, pkt->req->getVaddr() - SegBase, addressSize);'); + defineMicroStoreOp('Cda', 'Mem = 0;', mem_flags="Request::NO_ACCESS") iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp', {"code": "Data = merge(Data, EA, dataSize);", - "ea_code": calculateEA, - "mem_flags": 0}) + "ea_code": calculateEA}) header_output += MicroLeaDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLeaExecute.subst(iop) @@ -468,7 +493,7 @@ let {{ def __init__(self, data, segment, addr, disp = 0, dataSize="env.dataSize", addressSize="env.addressSize"): super(LeaOp, self).__init__(data, segment, - addr, disp, dataSize, addressSize) + addr, disp, dataSize, addressSize, "0", False, False) self.className = "Lea" self.mnemonic = "lea" @@ -477,38 +502,28 @@ let {{ iop = InstObjParams("tia", "Tia", 'X86ISA::LdStOp', {"code": "xc->demapPage(EA, 0);", - "ea_code": calculateEA, - "mem_flags": 0}) + "ea_code": calculateEA}) header_output += MicroLeaDeclare.subst(iop) decoder_output += MicroLdStOpConstructor.subst(iop) exec_output += MicroLeaExecute.subst(iop) class TiaOp(LdStOp): def __init__(self, segment, addr, disp = 0, - dataSize="env.dataSize", addressSize="env.addressSize"): + dataSize="env.dataSize", + addressSize="env.addressSize"): super(TiaOp, self).__init__("NUM_INTREGS", segment, - addr, disp, dataSize, addressSize) + addr, disp, dataSize, addressSize, "0", False, False) self.className = "Tia" self.mnemonic = "tia" microopClasses["tia"] = TiaOp - iop = InstObjParams("cda", "Cda", 'X86ISA::LdStOp', - {"code": ''' - Addr paddr; - fault = xc->translateDataWriteAddr(EA, paddr, - dataSize, (1 << segment)); - ''', - "ea_code": calculateEA}) - header_output += MicroLeaDeclare.subst(iop) - decoder_output += MicroLdStOpConstructor.subst(iop) - exec_output += MicroLeaExecute.subst(iop) - class CdaOp(LdStOp): def __init__(self, segment, addr, disp = 0, - dataSize="env.dataSize", addressSize="env.addressSize"): + dataSize="env.dataSize", + addressSize="env.addressSize", atCPL0=False): super(CdaOp, self).__init__("NUM_INTREGS", segment, - addr, disp, dataSize, addressSize) + addr, disp, dataSize, addressSize, "0", atCPL0, False) self.className = "Cda" self.mnemonic = "cda" diff --git a/src/arch/x86/isa/microops/limmop.isa b/src/arch/x86/isa/microops/limmop.isa index 6686444fd..4e75ab8b0 100644 --- a/src/arch/x86/isa/microops/limmop.isa +++ b/src/arch/x86/isa/microops/limmop.isa @@ -154,7 +154,7 @@ let {{ self.dataSize = dataSize def getAllocator(self, *microFlags): - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % { "class_name" : self.className, "mnemonic" : self.mnemonic, diff --git a/src/arch/x86/isa/microops/microops.isa b/src/arch/x86/isa/microops/microops.isa index 53f34d3f2..19266f6d6 100644 --- a/src/arch/x86/isa/microops/microops.isa +++ b/src/arch/x86/isa/microops/microops.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -68,5 +68,11 @@ //Load/store microop definitions ##include "ldstop.isa" +//Control flow microop definitions +##include "seqop.isa" + //Miscellaneous microop definitions ##include "specop.isa" + +//Microops for printing out debug messages through M5 +##include "debug.isa" diff --git a/src/arch/x86/isa/microops/regop.isa b/src/arch/x86/isa/microops/regop.isa index e761f0034..f9bc82119 100644 --- a/src/arch/x86/isa/microops/regop.isa +++ b/src/arch/x86/isa/microops/regop.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -231,6 +231,21 @@ output header {{ void divide(uint64_t dividend, uint64_t divisor, uint64_t "ient, uint64_t &remainder); + + enum SegmentSelectorCheck { + SegNoCheck, SegCSCheck, SegCallGateCheck, SegIntGateCheck, + SegSoftIntGateCheck, SegSSCheck, SegIretCheck, SegIntCSCheck, + SegTRCheck, SegTSSCheck, SegInGDTCheck, SegLDTCheck + }; + + enum LongModeDescriptorType { + LDT64 = 2, + AvailableTSS64 = 9, + BusyTSS64 = 0xb, + CallGate64 = 0xc, + IntGate64 = 0xe, + TrapGate64 = 0xf + }; }}; output decoder {{ @@ -424,7 +439,7 @@ let {{ className = self.className if self.mnemonic == self.base_mnemonic + 'i': className += "Imm" - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(src1)s, %(op2)s, %(dest)s, %(dataSize)s, %(ext)s)''' % { "class_name" : className, @@ -838,19 +853,28 @@ let {{ code = 'RIP = psrc1 + sop2 + CSBase' else_code="RIP = RIP;" - class Br(WrRegOp, CondRegOp): - code = 'nuIP = psrc1 + op2;' - else_code='nuIP = nuIP;' - class Wruflags(WrRegOp): code = 'ccFlagBits = psrc1 ^ op2' + class Wrflags(WrRegOp): + code = ''' + MiscReg newFlags = psrc1 ^ op2; + MiscReg userFlagMask = 0xDD5; + // Get only the user flags + ccFlagBits = newFlags & userFlagMask; + // Get everything else + nccFlagBits = newFlags & ~userFlagMask; + ''' + class Rdip(RdRegOp): code = 'DestReg = RIP - CSBase' class Ruflags(RdRegOp): code = 'DestReg = ccFlagBits' + class Rflags(RdRegOp): + code = 'DestReg = ccFlagBits | nccFlagBits' + class Ruflag(RegOp): code = ''' int flag = bits(ccFlagBits, imm8); @@ -863,6 +887,20 @@ let {{ super(Ruflag, self).__init__(dest, \ "NUM_INTREGS", imm, flags, dataSize) + class Rflag(RegOp): + code = ''' + MiscReg flagMask = 0x3F7FDD5; + MiscReg flags = (nccFlagBits | ccFlagBits) & flagMask; + int flag = bits(flags, imm8); + DestReg = merge(DestReg, flag, dataSize); + ccFlagBits = (flag == 0) ? (ccFlagBits | EZFBit) : + (ccFlagBits & ~EZFBit); + ''' + def __init__(self, dest, imm, flags=None, \ + dataSize="env.dataSize"): + super(Rflag, self).__init__(dest, \ + "NUM_INTREGS", imm, flags, dataSize) + class Sext(RegOp): code = ''' IntReg val = psrc1; @@ -883,17 +921,53 @@ let {{ ''' class Zext(RegOp): - code = 'DestReg = bits(psrc1, op2, 0);' + code = 'DestReg = merge(DestReg, bits(psrc1, op2, 0), dataSize);' + + class Rddr(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Rddr, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + CR4 cr4 = CR4Op; + DR7 dr7 = DR7Op; + if ((cr4.de == 1 && (src1 == 4 || src1 == 5)) || src1 >= 8) { + fault = new InvalidOpcode(); + } else if (dr7.gd) { + fault = new DebugException(); + } else { + DestReg = merge(DestReg, DebugSrc1, dataSize); + } + ''' + + class Wrdr(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Wrdr, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + CR4 cr4 = CR4Op; + DR7 dr7 = DR7Op; + if ((cr4.de == 1 && (dest == 4 || dest == 5)) || dest >= 8) { + fault = new InvalidOpcode(); + } else if ((dest == 6 || dest == 7) && + bits(psrc1, 63, 32) && + machInst.mode.mode == LongMode) { + fault = new GeneralProtection(0); + } else if (dr7.gd) { + fault = new DebugException(); + } else { + DebugDest = psrc1; + } + ''' class Rdcr(RegOp): def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(Rdcr, self).__init__(dest, \ src1, "NUM_INTREGS", flags, dataSize) code = ''' - if (dest == 1 || (dest > 4 && dest < 8) || (dest > 8)) { + if (src1 == 1 || (src1 > 4 && src1 < 8) || (src1 > 8)) { fault = new InvalidOpcode(); } else { - DestReg = ControlSrc1; + DestReg = merge(DestReg, ControlSrc1, dataSize); } ''' @@ -950,7 +1024,7 @@ let {{ ''' # Microops for manipulating segmentation registers - class SegOp(RegOp): + class SegOp(CondRegOp): abstract = True def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): super(SegOp, self).__init__(dest, \ @@ -971,74 +1045,223 @@ let {{ SegSelDest = psrc1; ''' + class WrAttr(SegOp): + code = ''' + SegAttrDest = psrc1; + ''' + class Rdbase(SegOp): code = ''' - DestReg = SegBaseDest; + DestReg = merge(DestReg, SegBaseSrc1, dataSize); ''' class Rdlimit(SegOp): code = ''' - DestReg = SegLimitSrc1; + DestReg = merge(DestReg, SegLimitSrc1, dataSize); + ''' + + class RdAttr(SegOp): + code = ''' + DestReg = merge(DestReg, SegAttrSrc1, dataSize); ''' class Rdsel(SegOp): code = ''' - DestReg = SegSelSrc1; + DestReg = merge(DestReg, SegSelSrc1, dataSize); ''' - class Chks(SegOp): + class Rdval(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Rdval, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) code = ''' - // The selector is in source 1. - SegSelector selector = psrc1; - - // Compute the address of the descriptor and set DestReg to it. - if (selector.ti) { - // A descriptor in the LDT - Addr target = (selector.esi << 3) + LDTRBase; - if (!LDTRSel || (selector.esi << 3) + dataSize > LDTRLimit) - fault = new GeneralProtection(selector & mask(16)); - DestReg = target; - } else { - // A descriptor in the GDT - Addr target = (selector.esi << 3) + GDTRBase; - if ((selector.esi << 3) + dataSize > GDTRLimit) - fault = new GeneralProtection(selector & mask(16)); - DestReg = target; + DestReg = MiscRegSrc1; + ''' + + class Wrval(RegOp): + def __init__(self, dest, src1, flags=None, dataSize="env.dataSize"): + super(Wrval, self).__init__(dest, \ + src1, "NUM_INTREGS", flags, dataSize) + code = ''' + MiscRegDest = SrcReg1; + ''' + + class Chks(RegOp): + def __init__(self, dest, src1, src2=0, + flags=None, dataSize="env.dataSize"): + super(Chks, self).__init__(dest, + src1, src2, flags, dataSize) + code = ''' + // The selector is in source 1 and can be at most 16 bits. + SegSelector selector = DestReg; + SegDescriptor desc = SrcReg1; + HandyM5Reg m5reg = M5Reg; + + switch (imm8) + { + case SegNoCheck: + break; + case SegCSCheck: + panic("CS checks for far calls/jumps not implemented.\\n"); + break; + case SegCallGateCheck: + panic("CS checks for far calls/jumps through call gates" + "not implemented.\\n"); + break; + case SegSoftIntGateCheck: + // Check permissions. + if (desc.dpl < m5reg.cpl) { + fault = new GeneralProtection(selector); + } + // Fall through on purpose + case SegIntGateCheck: + // Make sure the gate's the right type. + if ((m5reg.mode == LongMode && (desc.type & 0xe) != 0xe) || + ((desc.type & 0x6) != 0x6)) { + fault = new GeneralProtection(0); + } + break; + case SegSSCheck: + if (selector.si || selector.ti) { + if (!desc.p) { + fault = new StackFault(selector); + } + } else { + if ((m5reg.submode != SixtyFourBitMode || + m5reg.cpl == 3) || + !(desc.s == 1 && + desc.type.codeOrData == 0 && desc.type.w) || + (desc.dpl != m5reg.cpl) || + (selector.rpl != m5reg.cpl)) { + fault = new GeneralProtection(selector); + } + } + break; + case SegIretCheck: + { + if ((!selector.si && !selector.ti) || + (selector.rpl < m5reg.cpl) || + !(desc.s == 1 && desc.type.codeOrData == 1) || + (!desc.type.c && desc.dpl != selector.rpl) || + (desc.type.c && desc.dpl > selector.rpl)) { + fault = new GeneralProtection(selector); + } else if (!desc.p) { + fault = new SegmentNotPresent(selector); + } + break; + } + case SegIntCSCheck: + if (m5reg.mode == LongMode) { + if (desc.l != 1 || desc.d != 0) { + fault = new GeneralProtection(selector); + } + } else { + panic("Interrupt CS checks not implemented " + "in legacy mode.\\n"); + } + break; + case SegTRCheck: + if (!selector.si || selector.ti) { + fault = new GeneralProtection(selector); + } + break; + case SegTSSCheck: + if (!desc.p) { + fault = new SegmentNotPresent(selector); + } else if (!(desc.type == 0x9 || + (desc.type == 1 && + m5reg.mode != LongMode))) { + fault = new GeneralProtection(selector); + } + break; + case SegInGDTCheck: + if (selector.ti) { + fault = new GeneralProtection(selector); + } + break; + case SegLDTCheck: + if (!desc.p) { + fault = new SegmentNotPresent(selector); + } else if (desc.type != 0x2) { + fault = new GeneralProtection(selector); + } + break; + default: + panic("Undefined segment check type.\\n"); } ''' flag_code = ''' // Check for a NULL selector and set ZF,EZF appropriately. ccFlagBits = ccFlagBits & ~(ext & (ZFBit | EZFBit)); - if (!selector.esi && !selector.ti) + if (!selector.si && !selector.ti) ccFlagBits = ccFlagBits | (ext & (ZFBit | EZFBit)); ''' class Wrdh(RegOp): code = ''' + SegDescriptor desc = SrcReg1; + + uint64_t target = bits(SrcReg2, 31, 0) << 32; + switch(desc.type) { + case LDT64: + case AvailableTSS64: + case BusyTSS64: + replaceBits(target, 23, 0, desc.baseLow); + replaceBits(target, 31, 24, desc.baseHigh); + break; + case CallGate64: + case IntGate64: + case TrapGate64: + replaceBits(target, 15, 0, bits(desc, 15, 0)); + replaceBits(target, 31, 16, bits(desc, 63, 48)); + break; + default: + panic("Wrdh used with wrong descriptor type!\\n"); + } + DestReg = target; + ''' + + class Wrtsc(WrRegOp): + code = ''' + TscOp = psrc1; + ''' + + class Rdtsc(RdRegOp): + code = ''' + DestReg = TscOp; + ''' + class Rdm5reg(RdRegOp): + code = ''' + DestReg = M5Reg; ''' class Wrdl(RegOp): code = ''' SegDescriptor desc = SrcReg1; - SegAttr attr = 0; - attr.dpl = desc.dpl; - attr.defaultSize = desc.d; - if (!desc.s) { - SegBaseDest = SegBaseDest; - SegLimitDest = SegLimitDest; - SegAttrDest = SegAttrDest; - panic("System segment encountered.\\n"); - } else { - if (!desc.p) - panic("Segment not present.\\n"); - if (desc.type.codeOrData) { - attr.readable = desc.type.r; - attr.longMode = desc.l; - } else { - attr.expandDown = desc.type.e; + SegSelector selector = SrcReg2; + if (selector.si || selector.ti) { + SegAttr attr = 0; + attr.dpl = desc.dpl; + attr.defaultSize = desc.d; + if (!desc.s) { + // The expand down bit happens to be set for gates. + if (desc.type.e) { + panic("Gate descriptor encountered.\\n"); + } attr.readable = 1; - attr.writable = desc.type.w; + attr.writable = 1; + } else { + if (!desc.p) + panic("Segment not present.\\n"); + if (desc.type.codeOrData) { + attr.readable = desc.type.r; + attr.longMode = desc.l; + } else { + attr.expandDown = desc.type.e; + attr.readable = 1; + attr.writable = desc.type.w; + } } Addr base = desc.baseLow | (desc.baseHigh << 24); Addr limit = desc.limitLow | (desc.limitHigh << 16); @@ -1047,6 +1270,10 @@ let {{ SegBaseDest = base; SegLimitDest = limit; SegAttrDest = attr; + } else { + SegBaseDest = SegBaseDest; + SegLimitDest = SegLimitDest; + SegAttrDest = SegAttrDest; } ''' }}; diff --git a/src/arch/x86/isa/microops/seqop.isa b/src/arch/x86/isa/microops/seqop.isa new file mode 100644 index 000000000..332519b87 --- /dev/null +++ b/src/arch/x86/isa/microops/seqop.isa @@ -0,0 +1,251 @@ +// Copyright (c) 2008 The Hewlett-Packard Development Company +// All rights reserved. +// +// Redistribution and use of this software in source and binary forms, +// with or without modification, are permitted provided that the +// following conditions are met: +// +// The software must be used only for Non-Commercial Use which means any +// use which is NOT directed to receiving any direct monetary +// compensation for, or commercial advantage from such use. Illustrative +// examples of non-commercial use are academic research, personal study, +// teaching, education and corporate research & development. +// Illustrative examples of commercial use are distributing products for +// commercial advantage and providing services using the software for +// commercial advantage. +// +// If you wish to use this software or functionality therein that may be +// covered by patents for commercial use, please contact: +// Director of Intellectual Property Licensing +// Office of Strategy and Technology +// Hewlett-Packard Company +// 1501 Page Mill Road +// Palo Alto, California 94304 +// +// Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. Redistributions +// in binary form must reproduce the above copyright notice, this list of +// conditions and the following disclaimer in the documentation and/or +// other materials provided with the distribution. Neither the name of +// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. No right of +// sublicense is granted herewith. Derivatives of the software and +// output created using the software may be prepared, but only for +// Non-Commercial Uses. Derivatives of the software may be shared with +// others provided: (i) the others agree to abide by the list of +// conditions herein which includes the Non-Commercial Use restrictions; +// and (ii) such Derivatives of the software include the above copyright +// notice to acknowledge the contribution from this software where +// applicable, this list of conditions and the disclaimer below. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: Gabe Black + +output header {{ + class SeqOpBase : public X86ISA::X86MicroopBase + { + protected: + uint16_t target; + uint8_t cc; + + public: + SeqOpBase(ExtMachInst _machInst, const char * instMnem, + const char * mnemonic, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint16_t _target, uint8_t _cc); + + SeqOpBase(ExtMachInst _machInst, const char * instMnem, + const char * mnemonic, + uint16_t _target, uint8_t _cc); + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; + }; +}}; + +def template SeqOpDeclare {{ + class %(class_name)s : public %(base_class)s + { + private: + void buildMe(); + public: + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint16_t _target, uint8_t _cc); + + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + uint16_t _target, uint8_t _cc); + + %(BasicExecDeclare)s + }; +}}; + +def template SeqOpExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, + Trace::InstRecord *traceData) const + { + %(op_decl)s; + %(op_rd)s; + if (%(cond_test)s) { + %(code)s; + } else { + %(else_code)s; + } + %(op_wb)s; + return NoFault; + } +}}; + +output decoder {{ + inline SeqOpBase::SeqOpBase( + ExtMachInst machInst, const char * mnemonic, const char * instMnem, + uint16_t _target, uint8_t _cc) : + X86MicroopBase(machInst, mnemonic, instMnem, + false, false, false, false, No_OpClass), + target(_target), cc(_cc) + { + } + + inline SeqOpBase::SeqOpBase( + ExtMachInst machInst, const char * mnemonic, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint16_t _target, uint8_t _cc) : + X86MicroopBase(machInst, mnemonic, instMnem, + isMicro, isDelayed, isFirst, isLast, No_OpClass), + target(_target), cc(_cc) + { + } +}}; + +def template SeqOpConstructor {{ + + inline void %(class_name)s::buildMe() + { + %(constructor)s; + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + uint16_t _target, uint8_t _cc) : + %(base_class)s(machInst, "%(mnemonic)s", instMnem, _target, _cc) + { + buildMe(); + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + uint16_t _target, uint8_t _cc) : + %(base_class)s(machInst, "%(mnemonic)s", instMnem, + isMicro, isDelayed, isFirst, isLast, _target, _cc) + { + buildMe(); + } +}}; + +output decoder {{ + std::string SeqOpBase::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + ccprintf(response, "%#x", target); + + return response.str(); + } +}}; + +let {{ + class SeqOp(X86Microop): + def __init__(self, target, flags=None): + self.target = target + if flags: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.cond = " | ".join(flags) + self.className += "Flags" + else: + self.cond = "0" + + def getAllocator(self, *microFlags): + allocator = '''new %(class_name)s(machInst, macrocodeBlock + %(flags)s, %(target)s, %(cc)s)''' % { + "class_name" : self.className, + "flags" : self.microFlagsText(microFlags), + "target" : self.target, + "cc" : self.cond} + return allocator + + class Br(SeqOp): + className = "MicroBranch" + + def getAllocator(self, *microFlags): + (is_micro, is_delayed, is_first, is_last) = microFlags + is_last = False + is_delayed = True + microFlags = (is_micro, is_delayed, is_first, is_last) + return super(Br, self).getAllocator(*microFlags) + + class Eret(SeqOp): + target = "normalMicroPC(0)" + className = "Eret" + + def __init__(self, flags=None): + if flags: + if not isinstance(flags, (list, tuple)): + raise Exception, "flags must be a list or tuple of flags" + self.cond = " | ".join(flags) + self.className += "Flags" + else: + self.cond = "0" + + def getAllocator(self, *microFlags): + (is_micro, is_delayed, is_first, is_last) = microFlags + is_last = True + is_delayed = False + microFlags = (is_micro, is_delayed, is_first, is_last) + return super(Eret, self).getAllocator(*microFlags) + + iop = InstObjParams("br", "MicroBranchFlags", "SeqOpBase", + {"code": "nuIP = target", + "else_code": "nuIP = nuIP", + "cond_test": "checkCondition(ccFlagBits, cc)"}) + exec_output += SeqOpExecute.subst(iop) + header_output += SeqOpDeclare.subst(iop) + decoder_output += SeqOpConstructor.subst(iop) + iop = InstObjParams("br", "MicroBranch", "SeqOpBase", + {"code": "nuIP = target", + "else_code": "nuIP = nuIP", + "cond_test": "true"}) + exec_output += SeqOpExecute.subst(iop) + header_output += SeqOpDeclare.subst(iop) + decoder_output += SeqOpConstructor.subst(iop) + microopClasses["br"] = Br + + iop = InstObjParams("eret", "EretFlags", "SeqOpBase", + {"code": "", "else_code": "", + "cond_test": "checkCondition(ccFlagBits, cc)"}) + exec_output += SeqOpExecute.subst(iop) + header_output += SeqOpDeclare.subst(iop) + decoder_output += SeqOpConstructor.subst(iop) + iop = InstObjParams("eret", "Eret", "SeqOpBase", + {"code": "", "else_code": "", + "cond_test": "true"}) + exec_output += SeqOpExecute.subst(iop) + header_output += SeqOpDeclare.subst(iop) + decoder_output += SeqOpConstructor.subst(iop) + microopClasses["eret"] = Eret +}}; diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index 6bcc7ff91..c6e172ef1 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -1,4 +1,4 @@ -// Copyright (c) 2007 The Hewlett-Packard Development Company +// Copyright (c) 2007-2008 The Hewlett-Packard Development Company // All rights reserved. // // Redistribution and use of this software in source and binary forms, @@ -95,6 +95,9 @@ output header {{ } %(BasicExecDeclare)s + + std::string generateDisassembly(Addr pc, + const SymbolTable *symtab) const; }; }}; @@ -201,6 +204,16 @@ output decoder {{ return response.str(); } + + std::string MicroHalt::generateDisassembly(Addr pc, + const SymbolTable *symtab) const + { + std::stringstream response; + + printMnemonic(response, instMnem, mnemonic); + + return response.str(); + } }}; let {{ @@ -217,7 +230,7 @@ let {{ self.cond = "0" def getAllocator(self, *microFlags): - allocator = '''new %(class_name)s(machInst, mnemonic + allocator = '''new %(class_name)s(machInst, macrocodeBlock %(flags)s, %(fault)s, %(cc)s)''' % { "class_name" : self.className, "flags" : self.microFlagsText(microFlags), @@ -244,7 +257,7 @@ let {{ pass def getAllocator(self, *microFlags): - return "new MicroHalt(machInst, mnemonic %s)" % \ + return "new MicroHalt(machInst, macrocodeBlock %s)" % \ self.microFlagsText(microFlags) microopClasses["halt"] = Halt |