From 33dbd8a76698fefeb3a0c3f735da22c044b8a872 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 18 Oct 2007 22:40:18 -0700 Subject: X86: Make the "fault" microop predicated. --HG-- extra : convert_revision : 48dae1f3c680636833c137fe6b95b37ae84e188c --- src/arch/x86/isa/formats/string.isa | 2 +- src/arch/x86/isa/microops/specop.isa | 118 ++++++++++++++++++++++++++++------- 2 files changed, 96 insertions(+), 24 deletions(-) (limited to 'src/arch') diff --git a/src/arch/x86/isa/formats/string.isa b/src/arch/x86/isa/formats/string.isa index b1d3c4bbe..cb3ebc496 100644 --- a/src/arch/x86/isa/formats/string.isa +++ b/src/arch/x86/isa/formats/string.isa @@ -103,7 +103,7 @@ def format StringInst(*opTypeSet) {{ %s } else if (LEGACY_REPNE) { // The repne prefix is illegal - return new MicroFault(machInst, "illprefix", new InvalidOpcode); + return new MicroFault(machInst, "illprefix", new InvalidOpcode, 0); } else { %s } diff --git a/src/arch/x86/isa/microops/specop.isa b/src/arch/x86/isa/microops/specop.isa index 5c9e8dda9..ca4a6dc57 100644 --- a/src/arch/x86/isa/microops/specop.isa +++ b/src/arch/x86/isa/microops/specop.isa @@ -60,57 +60,106 @@ ////////////////////////////////////////////////////////////////////////// output header {{ - class MicroFault : public X86ISA::X86MicroopBase + class MicroFaultBase : public X86ISA::X86MicroopBase { protected: Fault fault; - void buildMe(); + uint8_t cc; public: - MicroFault(ExtMachInst _machInst, const char * instMnem, + MicroFaultBase(ExtMachInst _machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - Fault _fault); - - MicroFault(ExtMachInst _machInst, const char * instMnem, - Fault _fault); + Fault _fault, uint8_t _cc); - %(BasicExecDeclare)s + MicroFaultBase(ExtMachInst _machInst, const char * instMnem, + Fault _fault, uint8_t _cc); std::string generateDisassembly(Addr pc, const SymbolTable *symtab) const; }; }}; -output decoder {{ - Fault MicroFault::execute(%(CPU_exec_context)s *xc, +def template MicroFaultDeclare {{ + 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, + Fault _fault, uint8_t _cc); + + %(class_name)s(ExtMachInst _machInst, const char * instMnem, + Fault _fault, uint8_t _cc); + + %(BasicExecDeclare)s + }; +}}; + +def template MicroFaultExecute {{ + Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { - //Return the fault we were constructed with - return fault; + %(op_decl)s; + %(op_rd)s; + if (%(cond_test)s) { + //Return the fault we were constructed with + return fault; + } else { + return NoFault; + } } }}; output decoder {{ - inline MicroFault::MicroFault( - ExtMachInst machInst, const char * instMnem, Fault _fault) : + inline MicroFaultBase::MicroFaultBase( + ExtMachInst machInst, const char * instMnem, + Fault _fault, uint8_t _cc) : X86MicroopBase(machInst, "fault", instMnem, - false, false, false, false, No_OpClass), fault(_fault) + false, false, false, false, No_OpClass), + fault(_fault), cc(_cc) { } - inline MicroFault::MicroFault( + inline MicroFaultBase::MicroFaultBase( ExtMachInst machInst, const char * instMnem, bool isMicro, bool isDelayed, bool isFirst, bool isLast, - Fault _fault) : + Fault _fault, uint8_t _cc) : X86MicroopBase(machInst, "fault", instMnem, isMicro, isDelayed, isFirst, isLast, No_OpClass), - fault(_fault) + fault(_fault), cc(_cc) { } }}; +def template MicroFaultConstructor {{ + + inline void %(class_name)s::buildMe() + { + %(constructor)s; + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + Fault _fault, uint8_t _cc) : + %(base_class)s(machInst, instMnem, _fault, _cc) + { + buildMe(); + } + + inline %(class_name)s::%(class_name)s( + ExtMachInst machInst, const char * instMnem, + bool isMicro, bool isDelayed, bool isFirst, bool isLast, + Fault _fault, uint8_t _cc) : + %(base_class)s(machInst, instMnem, + isMicro, isDelayed, isFirst, isLast, _fault, _cc) + { + buildMe(); + } +}}; + output decoder {{ - std::string MicroFault::generateDisassembly(Addr pc, + std::string MicroFaultBase::generateDisassembly(Addr pc, const SymbolTable *symtab) const { std::stringstream response; @@ -127,14 +176,37 @@ output decoder {{ let {{ class Fault(X86Microop): - def __init__(self, fault): + className = "MicroFault" + def __init__(self, fault, flags=None): self.fault = fault + 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 MicroFault(machInst, mnemonic - %(flags)s, %(fault)s)''' % { + allocator = '''new %(class_name)s(machInst, mnemonic + %(flags)s, %(fault)s, %(cc)s)''' % { + "class_name" : self.className, "flags" : self.microFlagsText(microFlags), - "fault" : self.fault} + "fault" : self.fault, + "cc" : self.cond} return allocator + + iop = InstObjParams("fault", "MicroFault", "MicroFaultBase", + {"code": "", + "cond_test": "checkCondition(ccFlagBits, cc)"}) + exec_output = MicroFaultExecute.subst(iop) + header_output = MicroFaultDeclare.subst(iop) + decoder_output = MicroFaultConstructor.subst(iop) + iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase", + {"code": "", + "cond_test": "true"}) + exec_output += MicroFaultExecute.subst(iop) + header_output += MicroFaultDeclare.subst(iop) + decoder_output += MicroFaultConstructor.subst(iop) microopClasses["fault"] = Fault }}; -- cgit v1.2.3