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