specop.isa revision 10341:0b4d10f53c2d
13388Sgblack@eecs.umich.edu// Copyright (c) 2007-2008 The Hewlett-Packard Development Company 23388Sgblack@eecs.umich.edu// Copyright (c) 2011 Mark D. Hill and David A. Wood 33388Sgblack@eecs.umich.edu// All rights reserved. 43388Sgblack@eecs.umich.edu// 53388Sgblack@eecs.umich.edu// The license below extends only to copyright in the software and shall 63388Sgblack@eecs.umich.edu// not be construed as granting a license to any other intellectual 73388Sgblack@eecs.umich.edu// property including but not limited to intellectual property relating 83388Sgblack@eecs.umich.edu// to a hardware implementation of the functionality of the software 93388Sgblack@eecs.umich.edu// licensed hereunder. You may use the software subject to the license 103388Sgblack@eecs.umich.edu// terms below provided that you ensure that this notice is replicated 113388Sgblack@eecs.umich.edu// unmodified and in its entirety in all distributions of the software, 123388Sgblack@eecs.umich.edu// modified or unmodified, in source code or in binary form. 133388Sgblack@eecs.umich.edu// 143388Sgblack@eecs.umich.edu// Redistribution and use in source and binary forms, with or without 153388Sgblack@eecs.umich.edu// modification, are permitted provided that the following conditions are 163388Sgblack@eecs.umich.edu// met: redistributions of source code must retain the above copyright 173388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer; 183388Sgblack@eecs.umich.edu// redistributions in binary form must reproduce the above copyright 193388Sgblack@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the 203388Sgblack@eecs.umich.edu// documentation and/or other materials provided with the distribution; 213388Sgblack@eecs.umich.edu// neither the name of the copyright holders nor the names of its 223388Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from 233388Sgblack@eecs.umich.edu// this software without specific prior written permission. 243388Sgblack@eecs.umich.edu// 253388Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 263388Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 273388Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 283388Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 293388Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 303270SN/A// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 313270SN/A// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 323270SN/A// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 333270SN/A// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 343270SN/A// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 353270SN/A// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 363270SN/A// 373270SN/A// Authors: Gabe Black 383270SN/A 393270SN/A////////////////////////////////////////////////////////////////////////// 403270SN/A// 413270SN/A// Fault Microop 423270SN/A// 433270SN/A////////////////////////////////////////////////////////////////////////// 443388Sgblack@eecs.umich.edu 453388Sgblack@eecs.umich.eduoutput header {{ 463270SN/A class MicroFaultBase : public X86ISA::X86MicroopBase 473270SN/A { 483270SN/A protected: 493270SN/A Fault fault; 503270SN/A uint8_t cc; 513270SN/A 523270SN/A public: 533270SN/A MicroFaultBase(ExtMachInst _machInst, const char * instMnem, 543388Sgblack@eecs.umich.edu uint64_t setFlags, Fault _fault, uint8_t _cc); 553388Sgblack@eecs.umich.edu 563270SN/A std::string generateDisassembly(Addr pc, 573270SN/A const SymbolTable *symtab) const; 583270SN/A }; 593270SN/A 603270SN/A class MicroHalt : public X86ISA::X86MicroopBase 613270SN/A { 623270SN/A public: 633270SN/A MicroHalt(ExtMachInst _machInst, const char * instMnem, 643270SN/A uint64_t setFlags) : 653270SN/A X86MicroopBase(_machInst, "halt", instMnem, 663270SN/A setFlags | (ULL(1) << StaticInst::IsNonSpeculative) | 673270SN/A (ULL(1) << StaticInst::IsQuiesce), 683270SN/A No_OpClass) 693270SN/A { 703270SN/A } 713270SN/A 723270SN/A %(BasicExecDeclare)s 733270SN/A 743270SN/A std::string generateDisassembly(Addr pc, 753270SN/A const SymbolTable *symtab) const; 763270SN/A }; 773270SN/A}}; 783270SN/A 793270SN/Adef template MicroFaultDeclare {{ 803270SN/A class %(class_name)s : public %(base_class)s 813270SN/A { 823270SN/A public: 833270SN/A %(class_name)s(ExtMachInst _machInst, const char * instMnem, 843270SN/A uint64_t setFlags, Fault _fault, uint8_t _cc); 853270SN/A 863270SN/A %(BasicExecDeclare)s 873270SN/A }; 883270SN/A}}; 893270SN/A 903270SN/Adef template MicroFaultExecute {{ 913270SN/A Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc, 923270SN/A Trace::InstRecord *traceData) const 933270SN/A { 943270SN/A %(op_decl)s; 953280SN/A %(op_rd)s; 963270SN/A if (%(cond_test)s) { 973270SN/A //Return the fault we were constructed with 983270SN/A return fault; 993270SN/A } else { 1003270SN/A return NoFault; 1013270SN/A } 1023270SN/A } 1033270SN/A}}; 1043270SN/A 1053270SN/Aoutput exec {{ 1063270SN/A Fault 1073270SN/A MicroHalt::execute(CPU_EXEC_CONTEXT *xc, 1083270SN/A Trace::InstRecord * traceData) const 1093270SN/A { 1103270SN/A xc->tcBase()->suspend(); 1113270SN/A return NoFault; 1123270SN/A } 1133270SN/A}}; 1143270SN/A 1153270SN/Aoutput decoder {{ 1163270SN/A MicroFaultBase::MicroFaultBase( 1173270SN/A ExtMachInst machInst, const char * instMnem, 1183270SN/A uint64_t setFlags, Fault _fault, uint8_t _cc) : 1193270SN/A X86MicroopBase(machInst, "fault", instMnem, setFlags, No_OpClass), 1203270SN/A fault(_fault), cc(_cc) 1213270SN/A { 1223280SN/A } 1233270SN/A}}; 1243270SN/A 1253270SN/Adef template MicroFaultConstructor {{ 1263270SN/A %(class_name)s::%(class_name)s( 1273270SN/A ExtMachInst machInst, const char * instMnem, uint64_t setFlags, 1283270SN/A Fault _fault, uint8_t _cc) : 1293270SN/A %(base_class)s(machInst, instMnem, setFlags, _fault, _cc) 1303270SN/A { 1313270SN/A %(constructor)s; 1323379SN/A } 1333270SN/A}}; 1343270SN/A 1353270SN/Aoutput decoder {{ 1363379SN/A std::string MicroFaultBase::generateDisassembly(Addr pc, 1373270SN/A const SymbolTable *symtab) const 1383270SN/A { 1393270SN/A std::stringstream response; 1403270SN/A 1413270SN/A printMnemonic(response, instMnem, mnemonic); 1423270SN/A if(fault) 1433270SN/A response << fault->name(); 1443270SN/A else 1453270SN/A response << "No Fault"; 1463270SN/A 1473270SN/A return response.str(); 1483270SN/A } 1493270SN/A 1503270SN/A std::string MicroHalt::generateDisassembly(Addr pc, 1513270SN/A const SymbolTable *symtab) const 1523270SN/A { 1533270SN/A std::stringstream response; 1543270SN/A 1553270SN/A printMnemonic(response, instMnem, mnemonic); 1563270SN/A 1573270SN/A return response.str(); 1583270SN/A } 1593270SN/A}}; 1603280SN/A 1613270SN/Alet {{ 1623274SN/A class Fault(X86Microop): 1633270SN/A className = "MicroFault" 1643270SN/A def __init__(self, fault, flags=None): 1653274SN/A self.fault = fault 1663270SN/A if flags: 1673280SN/A if not isinstance(flags, (list, tuple)): 1683270SN/A raise Exception, "flags must be a list or tuple of flags" 1693270SN/A self.cond = " | ".join(flags) 1703270SN/A self.className += "Flags" 1713270SN/A else: 1723270SN/A self.cond = "0" 1733274SN/A 1743270SN/A def getAllocator(self, microFlags): 1753280SN/A allocator = '''new %(class_name)s(machInst, macrocodeBlock, 1763270SN/A %(flags)s, %(fault)s, %(cc)s)''' % { 1773270SN/A "class_name" : self.className, 1783270SN/A "flags" : self.microFlagsText(microFlags), 1793270SN/A "fault" : self.fault, 1803270SN/A "cc" : self.cond} 1813274SN/A return allocator 1823270SN/A 1833280SN/A iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase", 1843270SN/A {"code": "", 1853270SN/A "cond_test": "checkCondition(ccFlagBits | cfofBits | dfBit | \ 1863270SN/A ecfBit | ezfBit, cc)"}) 1873270SN/A exec_output = MicroFaultExecute.subst(iop) 1883270SN/A header_output = MicroFaultDeclare.subst(iop) 1893274SN/A decoder_output = MicroFaultConstructor.subst(iop) 1903270SN/A iop = InstObjParams("fault", "MicroFault", "MicroFaultBase", 1913280SN/A {"code": "", 1923270SN/A "cond_test": "true"}) 1933270SN/A exec_output += MicroFaultExecute.subst(iop) 1943270SN/A header_output += MicroFaultDeclare.subst(iop) 1953270SN/A decoder_output += MicroFaultConstructor.subst(iop) 1963270SN/A microopClasses["fault"] = Fault 1973274SN/A 1983270SN/A class Halt(X86Microop): 1993280SN/A className = "MicroHalt" 2003270SN/A def __init__(self): 2013270SN/A pass 2023270SN/A 2033270SN/A def getAllocator(self, microFlags): 2043270SN/A return "new MicroHalt(machInst, macrocodeBlock, %s)" % \ 2053274SN/A self.microFlagsText(microFlags) 2063270SN/A 2073280SN/A microopClasses["halt"] = Halt 2083270SN/A}}; 2093270SN/A 2103270SN/Adef template MicroFenceOpDeclare {{ 2113270SN/A class %(class_name)s : public X86ISA::X86MicroopBase 2123270SN/A { 2133274SN/A public: 2143270SN/A %(class_name)s(ExtMachInst _machInst, 2153280SN/A const char * instMnem, 2163270SN/A uint64_t setFlags); 2173270SN/A 2183270SN/A %(BasicExecDeclare)s 2193270SN/A }; 2203270SN/A}}; 2213274SN/A 2223270SN/Adef template MicroFenceOpConstructor {{ 2233280SN/A %(class_name)s::%(class_name)s( 2243270SN/A ExtMachInst machInst, const char * instMnem, uint64_t setFlags) : 2253270SN/A %(base_class)s(machInst, "%(mnemonic)s", instMnem, 2263270SN/A setFlags, %(op_class)s) 2273270SN/A { 2283270SN/A %(constructor)s; 2293270SN/A } 2303270SN/A}}; 2313280SN/A 2323388Sgblack@eecs.umich.edulet {{ 2333270SN/A class MfenceOp(X86Microop): 2343270SN/A def __init__(self): 2353274SN/A self.className = "Mfence" 2363274SN/A self.mnemonic = "mfence" 2373274SN/A self.instFlags = "| (1ULL << StaticInst::IsMemBarrier)" 2383274SN/A 2393274SN/A def getAllocator(self, microFlags): 2403274SN/A allocString = ''' 2413274SN/A (StaticInstPtr)(new %(class_name)s(machInst, 2423274SN/A macrocodeBlock, %(flags)s)) 2433270SN/A ''' 2443270SN/A allocator = allocString % { 2453270SN/A "class_name" : self.className, 2463280SN/A "mnemonic" : self.mnemonic, 2473280SN/A "flags" : self.microFlagsText(microFlags) + self.instFlags} 2483280SN/A return allocator 2493280SN/A 2503280SN/A microopClasses["mfence"] = MfenceOp 2513280SN/A}}; 2523280SN/A 2533280SN/Alet {{ 2543280SN/A # Build up the all register version of this micro op 2553280SN/A iop = InstObjParams("mfence", "Mfence", 'X86MicroopBase', 2563280SN/A {"code" : ""}) 2573280SN/A header_output += MicroFenceOpDeclare.subst(iop) 2583270SN/A decoder_output += MicroFenceOpConstructor.subst(iop) 2593280SN/A exec_output += BasicExecute.subst(iop) 2603280SN/A}}; 2613270SN/A