specop.isa revision 10184
114184Sgabeblack@google.com// Copyright (c) 2007-2008 The Hewlett-Packard Development Company 214184Sgabeblack@google.com// Copyright (c) 2011 Mark D. Hill and David A. Wood 314184Sgabeblack@google.com// All rights reserved. 414184Sgabeblack@google.com// 514184Sgabeblack@google.com// The license below extends only to copyright in the software and shall 614184Sgabeblack@google.com// not be construed as granting a license to any other intellectual 714184Sgabeblack@google.com// property including but not limited to intellectual property relating 814184Sgabeblack@google.com// to a hardware implementation of the functionality of the software 914184Sgabeblack@google.com// licensed hereunder. You may use the software subject to the license 1014184Sgabeblack@google.com// terms below provided that you ensure that this notice is replicated 1114184Sgabeblack@google.com// unmodified and in its entirety in all distributions of the software, 1214184Sgabeblack@google.com// modified or unmodified, in source code or in binary form. 1314184Sgabeblack@google.com// 1414184Sgabeblack@google.com// Redistribution and use in source and binary forms, with or without 1514184Sgabeblack@google.com// modification, are permitted provided that the following conditions are 1614184Sgabeblack@google.com// met: redistributions of source code must retain the above copyright 1714184Sgabeblack@google.com// notice, this list of conditions and the following disclaimer; 1814184Sgabeblack@google.com// redistributions in binary form must reproduce the above copyright 1914184Sgabeblack@google.com// notice, this list of conditions and the following disclaimer in the 2014184Sgabeblack@google.com// documentation and/or other materials provided with the distribution; 2114184Sgabeblack@google.com// neither the name of the copyright holders nor the names of its 2214184Sgabeblack@google.com// contributors may be used to endorse or promote products derived from 2314184Sgabeblack@google.com// this software without specific prior written permission. 2414184Sgabeblack@google.com// 2514184Sgabeblack@google.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2614184Sgabeblack@google.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2714184Sgabeblack@google.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2814184Sgabeblack@google.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2914184Sgabeblack@google.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3014184Sgabeblack@google.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3114184Sgabeblack@google.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3214184Sgabeblack@google.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3314184Sgabeblack@google.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3414184Sgabeblack@google.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3514184Sgabeblack@google.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3614184Sgabeblack@google.com// 3714184Sgabeblack@google.com// Authors: Gabe Black 3814184Sgabeblack@google.com 3914184Sgabeblack@google.com////////////////////////////////////////////////////////////////////////// 4014184Sgabeblack@google.com// 4114184Sgabeblack@google.com// Fault Microop 4214184Sgabeblack@google.com// 4314184Sgabeblack@google.com////////////////////////////////////////////////////////////////////////// 4414184Sgabeblack@google.com 4514184Sgabeblack@google.comoutput header {{ 4614184Sgabeblack@google.com class MicroFaultBase : public X86ISA::X86MicroopBase 4714184Sgabeblack@google.com { 4814184Sgabeblack@google.com protected: 4914184Sgabeblack@google.com Fault fault; 5014184Sgabeblack@google.com uint8_t cc; 5114184Sgabeblack@google.com 5214184Sgabeblack@google.com public: 5314184Sgabeblack@google.com MicroFaultBase(ExtMachInst _machInst, const char * instMnem, 5414184Sgabeblack@google.com uint64_t setFlags, Fault _fault, uint8_t _cc); 5514184Sgabeblack@google.com 5614184Sgabeblack@google.com std::string generateDisassembly(Addr pc, 5714184Sgabeblack@google.com const SymbolTable *symtab) const; 5814184Sgabeblack@google.com }; 5914184Sgabeblack@google.com 6014184Sgabeblack@google.com class MicroHalt : public X86ISA::X86MicroopBase 6114184Sgabeblack@google.com { 6214184Sgabeblack@google.com public: 6314184Sgabeblack@google.com MicroHalt(ExtMachInst _machInst, const char * instMnem, 6414184Sgabeblack@google.com uint64_t setFlags) : 6514184Sgabeblack@google.com X86MicroopBase(_machInst, "halt", instMnem, 6614184Sgabeblack@google.com setFlags | (ULL(1) << StaticInst::IsNonSpeculative), 6714184Sgabeblack@google.com No_OpClass) 6814184Sgabeblack@google.com { 6914184Sgabeblack@google.com } 7014184Sgabeblack@google.com 7114184Sgabeblack@google.com %(BasicExecDeclare)s 7214184Sgabeblack@google.com 7314184Sgabeblack@google.com std::string generateDisassembly(Addr pc, 7414184Sgabeblack@google.com const SymbolTable *symtab) const; 7514184Sgabeblack@google.com }; 7614184Sgabeblack@google.com}}; 7714184Sgabeblack@google.com 7814184Sgabeblack@google.comdef template MicroFaultDeclare {{ 7914184Sgabeblack@google.com class %(class_name)s : public %(base_class)s 8014184Sgabeblack@google.com { 8114184Sgabeblack@google.com public: 8214184Sgabeblack@google.com %(class_name)s(ExtMachInst _machInst, const char * instMnem, 8314184Sgabeblack@google.com uint64_t setFlags, Fault _fault, uint8_t _cc); 8414184Sgabeblack@google.com 8514184Sgabeblack@google.com %(BasicExecDeclare)s 8614184Sgabeblack@google.com }; 8714184Sgabeblack@google.com}}; 8814184Sgabeblack@google.com 8914184Sgabeblack@google.comdef template MicroFaultExecute {{ 9014184Sgabeblack@google.com Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, 9114184Sgabeblack@google.com Trace::InstRecord *traceData) const 9214184Sgabeblack@google.com { 9314184Sgabeblack@google.com %(op_decl)s; 9414184Sgabeblack@google.com %(op_rd)s; 9514184Sgabeblack@google.com if (%(cond_test)s) { 9614184Sgabeblack@google.com //Return the fault we were constructed with 9714184Sgabeblack@google.com return fault; 9814184Sgabeblack@google.com } else { 9914184Sgabeblack@google.com return NoFault; 10014184Sgabeblack@google.com } 10114184Sgabeblack@google.com } 10214184Sgabeblack@google.com}}; 10314184Sgabeblack@google.com 10414184Sgabeblack@google.comoutput exec {{ 10514184Sgabeblack@google.com Fault 10614184Sgabeblack@google.com MicroHalt::execute(%(CPU_exec_context)s *xc, 10714184Sgabeblack@google.com Trace::InstRecord * traceData) const 10814184Sgabeblack@google.com { 10914184Sgabeblack@google.com xc->tcBase()->suspend(); 11014184Sgabeblack@google.com return NoFault; 11114184Sgabeblack@google.com } 11214184Sgabeblack@google.com}}; 11314184Sgabeblack@google.com 11414184Sgabeblack@google.comoutput decoder {{ 11514184Sgabeblack@google.com MicroFaultBase::MicroFaultBase( 11614184Sgabeblack@google.com ExtMachInst machInst, const char * instMnem, 11714184Sgabeblack@google.com uint64_t setFlags, Fault _fault, uint8_t _cc) : 11814184Sgabeblack@google.com X86MicroopBase(machInst, "fault", instMnem, setFlags, No_OpClass), 11914184Sgabeblack@google.com fault(_fault), cc(_cc) 12014184Sgabeblack@google.com { 12114184Sgabeblack@google.com } 12214184Sgabeblack@google.com}}; 12314184Sgabeblack@google.com 12414184Sgabeblack@google.comdef template MicroFaultConstructor {{ 12514184Sgabeblack@google.com %(class_name)s::%(class_name)s( 12614184Sgabeblack@google.com ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 12714184Sgabeblack@google.com Fault _fault, uint8_t _cc) : 12814184Sgabeblack@google.com %(base_class)s(machInst, instMnem, setFlags, _fault, _cc) 12914184Sgabeblack@google.com { 13014184Sgabeblack@google.com %(constructor)s; 13114184Sgabeblack@google.com } 13214184Sgabeblack@google.com}}; 13314184Sgabeblack@google.com 13414184Sgabeblack@google.comoutput decoder {{ 13514184Sgabeblack@google.com std::string MicroFaultBase::generateDisassembly(Addr pc, 13614184Sgabeblack@google.com const SymbolTable *symtab) const 13714184Sgabeblack@google.com { 13814184Sgabeblack@google.com std::stringstream response; 13914184Sgabeblack@google.com 14014184Sgabeblack@google.com printMnemonic(response, instMnem, mnemonic); 14114184Sgabeblack@google.com if(fault) 14214184Sgabeblack@google.com response << fault->name(); 14314184Sgabeblack@google.com else 14414184Sgabeblack@google.com response << "No Fault"; 14514184Sgabeblack@google.com 14614184Sgabeblack@google.com return response.str(); 14714184Sgabeblack@google.com } 14814184Sgabeblack@google.com 14914184Sgabeblack@google.com std::string MicroHalt::generateDisassembly(Addr pc, 15014184Sgabeblack@google.com const SymbolTable *symtab) const 15114184Sgabeblack@google.com { 15214184Sgabeblack@google.com std::stringstream response; 15314184Sgabeblack@google.com 15414184Sgabeblack@google.com printMnemonic(response, instMnem, mnemonic); 15514184Sgabeblack@google.com 15614184Sgabeblack@google.com return response.str(); 15714184Sgabeblack@google.com } 15814184Sgabeblack@google.com}}; 15914184Sgabeblack@google.com 16014184Sgabeblack@google.comlet {{ 16114184Sgabeblack@google.com class Fault(X86Microop): 16214184Sgabeblack@google.com className = "MicroFault" 16314184Sgabeblack@google.com def __init__(self, fault, flags=None): 16414184Sgabeblack@google.com self.fault = fault 16514184Sgabeblack@google.com if flags: 16614184Sgabeblack@google.com if not isinstance(flags, (list, tuple)): 16714184Sgabeblack@google.com raise Exception, "flags must be a list or tuple of flags" 16814184Sgabeblack@google.com self.cond = " | ".join(flags) 16914184Sgabeblack@google.com self.className += "Flags" 17014184Sgabeblack@google.com else: 17114184Sgabeblack@google.com self.cond = "0" 17214184Sgabeblack@google.com 17314184Sgabeblack@google.com def getAllocator(self, microFlags): 17414184Sgabeblack@google.com allocator = '''new %(class_name)s(machInst, macrocodeBlock, 17514184Sgabeblack@google.com %(flags)s, %(fault)s, %(cc)s)''' % { 17614184Sgabeblack@google.com "class_name" : self.className, 17714184Sgabeblack@google.com "flags" : self.microFlagsText(microFlags), 17814184Sgabeblack@google.com "fault" : self.fault, 17914184Sgabeblack@google.com "cc" : self.cond} 18014184Sgabeblack@google.com return allocator 18114184Sgabeblack@google.com 18214184Sgabeblack@google.com iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase", 18314184Sgabeblack@google.com {"code": "", 18414184Sgabeblack@google.com "cond_test": "checkCondition(ccFlagBits | cfofBits | dfBit | \ 18514184Sgabeblack@google.com ecfBit | ezfBit, cc)"}) 18614184Sgabeblack@google.com exec_output = MicroFaultExecute.subst(iop) 18714184Sgabeblack@google.com header_output = MicroFaultDeclare.subst(iop) 18814184Sgabeblack@google.com decoder_output = MicroFaultConstructor.subst(iop) 18914184Sgabeblack@google.com iop = InstObjParams("fault", "MicroFault", "MicroFaultBase", 19014184Sgabeblack@google.com {"code": "", 19114184Sgabeblack@google.com "cond_test": "true"}) 19214184Sgabeblack@google.com exec_output += MicroFaultExecute.subst(iop) 19314184Sgabeblack@google.com header_output += MicroFaultDeclare.subst(iop) 19414184Sgabeblack@google.com decoder_output += MicroFaultConstructor.subst(iop) 19514184Sgabeblack@google.com microopClasses["fault"] = Fault 19614184Sgabeblack@google.com 19714184Sgabeblack@google.com class Halt(X86Microop): 19814184Sgabeblack@google.com className = "MicroHalt" 19914184Sgabeblack@google.com def __init__(self): 20014184Sgabeblack@google.com pass 20114184Sgabeblack@google.com 20214184Sgabeblack@google.com def getAllocator(self, microFlags): 20314184Sgabeblack@google.com return "new MicroHalt(machInst, macrocodeBlock, %s)" % \ 20414184Sgabeblack@google.com self.microFlagsText(microFlags) 20514184Sgabeblack@google.com 20614184Sgabeblack@google.com microopClasses["halt"] = Halt 20714184Sgabeblack@google.com}}; 20814184Sgabeblack@google.com 20914184Sgabeblack@google.comdef template MicroFenceOpDeclare {{ 21014184Sgabeblack@google.com class %(class_name)s : public X86ISA::X86MicroopBase 21114184Sgabeblack@google.com { 21214184Sgabeblack@google.com public: 21314184Sgabeblack@google.com %(class_name)s(ExtMachInst _machInst, 21414184Sgabeblack@google.com const char * instMnem, 21514184Sgabeblack@google.com uint64_t setFlags); 21614184Sgabeblack@google.com 21714184Sgabeblack@google.com %(BasicExecDeclare)s 21814184Sgabeblack@google.com }; 21914184Sgabeblack@google.com}}; 22014184Sgabeblack@google.com 22114184Sgabeblack@google.comdef template MicroFenceOpConstructor {{ 22214184Sgabeblack@google.com %(class_name)s::%(class_name)s( 22314184Sgabeblack@google.com ExtMachInst machInst, const char * instMnem, uint64_t setFlags) : 22414184Sgabeblack@google.com %(base_class)s(machInst, "%(mnemonic)s", instMnem, 22514184Sgabeblack@google.com setFlags, %(op_class)s) 22614184Sgabeblack@google.com { 22714184Sgabeblack@google.com %(constructor)s; 22814184Sgabeblack@google.com } 22914184Sgabeblack@google.com}}; 23014184Sgabeblack@google.com 23114184Sgabeblack@google.comlet {{ 23214184Sgabeblack@google.com class MfenceOp(X86Microop): 23314184Sgabeblack@google.com def __init__(self): 23414184Sgabeblack@google.com self.className = "Mfence" 23514184Sgabeblack@google.com self.mnemonic = "mfence" 236 self.instFlags = "| (1ULL << StaticInst::IsMemBarrier)" 237 238 def getAllocator(self, microFlags): 239 allocString = ''' 240 (StaticInstPtr)(new %(class_name)s(machInst, 241 macrocodeBlock, %(flags)s)) 242 ''' 243 allocator = allocString % { 244 "class_name" : self.className, 245 "mnemonic" : self.mnemonic, 246 "flags" : self.microFlagsText(microFlags) + self.instFlags} 247 return allocator 248 249 microopClasses["mfence"] = MfenceOp 250}}; 251 252let {{ 253 # Build up the all register version of this micro op 254 iop = InstObjParams("mfence", "Mfence", 'X86MicroopBase', 255 {"code" : ""}) 256 header_output += MicroFenceOpDeclare.subst(iop) 257 decoder_output += MicroFenceOpConstructor.subst(iop) 258 exec_output += BasicExecute.subst(iop) 259}}; 260