specop.isa revision 10184:bbfa3152bdea
12929Sktlim@umich.edu// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
22929Sktlim@umich.edu// Copyright (c) 2011 Mark D. Hill and David A. Wood
32932Sktlim@umich.edu// All rights reserved.
42929Sktlim@umich.edu//
52929Sktlim@umich.edu// The license below extends only to copyright in the software and shall
62929Sktlim@umich.edu// not be construed as granting a license to any other intellectual
72929Sktlim@umich.edu// property including but not limited to intellectual property relating
82929Sktlim@umich.edu// to a hardware implementation of the functionality of the software
92929Sktlim@umich.edu// licensed hereunder.  You may use the software subject to the license
102929Sktlim@umich.edu// terms below provided that you ensure that this notice is replicated
112929Sktlim@umich.edu// unmodified and in its entirety in all distributions of the software,
122929Sktlim@umich.edu// modified or unmodified, in source code or in binary form.
132929Sktlim@umich.edu//
142929Sktlim@umich.edu// Redistribution and use in source and binary forms, with or without
152929Sktlim@umich.edu// modification, are permitted provided that the following conditions are
162929Sktlim@umich.edu// met: redistributions of source code must retain the above copyright
172929Sktlim@umich.edu// notice, this list of conditions and the following disclaimer;
182929Sktlim@umich.edu// redistributions in binary form must reproduce the above copyright
192929Sktlim@umich.edu// notice, this list of conditions and the following disclaimer in the
202929Sktlim@umich.edu// documentation and/or other materials provided with the distribution;
212929Sktlim@umich.edu// neither the name of the copyright holders nor the names of its
222929Sktlim@umich.edu// contributors may be used to endorse or promote products derived from
232929Sktlim@umich.edu// this software without specific prior written permission.
242929Sktlim@umich.edu//
252929Sktlim@umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262929Sktlim@umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272929Sktlim@umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282932Sktlim@umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292932Sktlim@umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302932Sktlim@umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312929Sktlim@umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
326007Ssteve.reinhardt@amd.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332929Sktlim@umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342929Sktlim@umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352929Sktlim@umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362929Sktlim@umich.edu//
372929Sktlim@umich.edu// Authors: Gabe Black
382929Sktlim@umich.edu
392929Sktlim@umich.edu//////////////////////////////////////////////////////////////////////////
402929Sktlim@umich.edu//
412929Sktlim@umich.edu// Fault Microop
422929Sktlim@umich.edu//
432929Sktlim@umich.edu//////////////////////////////////////////////////////////////////////////
442929Sktlim@umich.edu
452929Sktlim@umich.eduoutput header {{
462929Sktlim@umich.edu    class MicroFaultBase : public X86ISA::X86MicroopBase
476007Ssteve.reinhardt@amd.com    {
486007Ssteve.reinhardt@amd.com      protected:
496007Ssteve.reinhardt@amd.com        Fault fault;
506007Ssteve.reinhardt@amd.com        uint8_t cc;
516007Ssteve.reinhardt@amd.com
526007Ssteve.reinhardt@amd.com      public:
536007Ssteve.reinhardt@amd.com        MicroFaultBase(ExtMachInst _machInst, const char * instMnem,
546007Ssteve.reinhardt@amd.com                uint64_t setFlags, Fault _fault, uint8_t _cc);
556007Ssteve.reinhardt@amd.com
566007Ssteve.reinhardt@amd.com        std::string generateDisassembly(Addr pc,
576007Ssteve.reinhardt@amd.com                const SymbolTable *symtab) const;
586007Ssteve.reinhardt@amd.com    };
596007Ssteve.reinhardt@amd.com
606007Ssteve.reinhardt@amd.com    class MicroHalt : public X86ISA::X86MicroopBase
616007Ssteve.reinhardt@amd.com    {
626007Ssteve.reinhardt@amd.com      public:
636007Ssteve.reinhardt@amd.com        MicroHalt(ExtMachInst _machInst, const char * instMnem,
646007Ssteve.reinhardt@amd.com                uint64_t setFlags) :
656007Ssteve.reinhardt@amd.com            X86MicroopBase(_machInst, "halt", instMnem,
666007Ssteve.reinhardt@amd.com                           setFlags | (ULL(1) << StaticInst::IsNonSpeculative),
676007Ssteve.reinhardt@amd.com                           No_OpClass)
686007Ssteve.reinhardt@amd.com        {
696007Ssteve.reinhardt@amd.com        }
706007Ssteve.reinhardt@amd.com
716007Ssteve.reinhardt@amd.com        %(BasicExecDeclare)s
726007Ssteve.reinhardt@amd.com
736007Ssteve.reinhardt@amd.com        std::string generateDisassembly(Addr pc,
746007Ssteve.reinhardt@amd.com                const SymbolTable *symtab) const;
756007Ssteve.reinhardt@amd.com    };
762929Sktlim@umich.edu}};
772929Sktlim@umich.edu
782929Sktlim@umich.edudef template MicroFaultDeclare {{
796007Ssteve.reinhardt@amd.com    class %(class_name)s : public %(base_class)s
806007Ssteve.reinhardt@amd.com    {
816007Ssteve.reinhardt@amd.com      public:
826007Ssteve.reinhardt@amd.com        %(class_name)s(ExtMachInst _machInst, const char * instMnem,
836007Ssteve.reinhardt@amd.com                uint64_t setFlags, Fault _fault, uint8_t _cc);
846007Ssteve.reinhardt@amd.com
852929Sktlim@umich.edu        %(BasicExecDeclare)s
862929Sktlim@umich.edu    };
872929Sktlim@umich.edu}};
882929Sktlim@umich.edu
892929Sktlim@umich.edudef template MicroFaultExecute {{
906011Ssteve.reinhardt@amd.com        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
916007Ssteve.reinhardt@amd.com                Trace::InstRecord *traceData) const
926007Ssteve.reinhardt@amd.com        {
936007Ssteve.reinhardt@amd.com            %(op_decl)s;
946007Ssteve.reinhardt@amd.com            %(op_rd)s;
956007Ssteve.reinhardt@amd.com            if (%(cond_test)s) {
966007Ssteve.reinhardt@amd.com                //Return the fault we were constructed with
976007Ssteve.reinhardt@amd.com                return fault;
986007Ssteve.reinhardt@amd.com            } else {
996007Ssteve.reinhardt@amd.com                return NoFault;
1006007Ssteve.reinhardt@amd.com            }
1016007Ssteve.reinhardt@amd.com        }
1026007Ssteve.reinhardt@amd.com}};
1036007Ssteve.reinhardt@amd.com
1046007Ssteve.reinhardt@amd.comoutput exec {{
1056011Ssteve.reinhardt@amd.com    Fault
1066007Ssteve.reinhardt@amd.com    MicroHalt::execute(%(CPU_exec_context)s *xc,
1076007Ssteve.reinhardt@amd.com            Trace::InstRecord * traceData) const
1086007Ssteve.reinhardt@amd.com    {
1096007Ssteve.reinhardt@amd.com        xc->tcBase()->suspend();
1106007Ssteve.reinhardt@amd.com        return NoFault;
1116007Ssteve.reinhardt@amd.com    }
1126007Ssteve.reinhardt@amd.com}};
1136011Ssteve.reinhardt@amd.com
1146007Ssteve.reinhardt@amd.comoutput decoder {{
1156007Ssteve.reinhardt@amd.com    MicroFaultBase::MicroFaultBase(
1166007Ssteve.reinhardt@amd.com            ExtMachInst machInst, const char * instMnem,
1176007Ssteve.reinhardt@amd.com            uint64_t setFlags, Fault _fault, uint8_t _cc) :
1186007Ssteve.reinhardt@amd.com        X86MicroopBase(machInst, "fault", instMnem, setFlags, No_OpClass),
1196007Ssteve.reinhardt@amd.com                fault(_fault), cc(_cc)
1206007Ssteve.reinhardt@amd.com    {
1216011Ssteve.reinhardt@amd.com    }
1226007Ssteve.reinhardt@amd.com}};
1236007Ssteve.reinhardt@amd.com
1246007Ssteve.reinhardt@amd.comdef template MicroFaultConstructor {{
1256007Ssteve.reinhardt@amd.com    %(class_name)s::%(class_name)s(
1266007Ssteve.reinhardt@amd.com            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
1276008Ssteve.reinhardt@amd.com            Fault _fault, uint8_t _cc) :
1286007Ssteve.reinhardt@amd.com        %(base_class)s(machInst, instMnem, setFlags, _fault, _cc)
1296008Ssteve.reinhardt@amd.com    {
1306008Ssteve.reinhardt@amd.com        %(constructor)s;
1316008Ssteve.reinhardt@amd.com    }
1326008Ssteve.reinhardt@amd.com}};
1336008Ssteve.reinhardt@amd.com
1346008Ssteve.reinhardt@amd.comoutput decoder {{
1356008Ssteve.reinhardt@amd.com    std::string MicroFaultBase::generateDisassembly(Addr pc,
1366007Ssteve.reinhardt@amd.com            const SymbolTable *symtab) const
1376007Ssteve.reinhardt@amd.com    {
1386007Ssteve.reinhardt@amd.com        std::stringstream response;
1396007Ssteve.reinhardt@amd.com
1406007Ssteve.reinhardt@amd.com        printMnemonic(response, instMnem, mnemonic);
1412929Sktlim@umich.edu        if(fault)
1422929Sktlim@umich.edu            response << fault->name();
1432929Sktlim@umich.edu        else
1442929Sktlim@umich.edu            response << "No Fault";
1456007Ssteve.reinhardt@amd.com
1466007Ssteve.reinhardt@amd.com        return response.str();
1472929Sktlim@umich.edu    }
1482929Sktlim@umich.edu
1492929Sktlim@umich.edu    std::string MicroHalt::generateDisassembly(Addr pc,
1502929Sktlim@umich.edu            const SymbolTable *symtab) const
1516007Ssteve.reinhardt@amd.com    {
1526007Ssteve.reinhardt@amd.com        std::stringstream response;
1532929Sktlim@umich.edu
1542929Sktlim@umich.edu        printMnemonic(response, instMnem, mnemonic);
1556007Ssteve.reinhardt@amd.com
1562929Sktlim@umich.edu        return response.str();
1572929Sktlim@umich.edu    }
1582929Sktlim@umich.edu}};
1592929Sktlim@umich.edu
1602929Sktlim@umich.edulet {{
1612929Sktlim@umich.edu    class Fault(X86Microop):
1622929Sktlim@umich.edu        className = "MicroFault"
1634937Sstever@gmail.com        def __init__(self, fault, flags=None):
1644937Sstever@gmail.com            self.fault = fault
1654937Sstever@gmail.com            if flags:
1664937Sstever@gmail.com                if not isinstance(flags, (list, tuple)):
1674937Sstever@gmail.com                    raise Exception, "flags must be a list or tuple of flags"
1684937Sstever@gmail.com                self.cond = " | ".join(flags)
1694937Sstever@gmail.com                self.className += "Flags"
1704937Sstever@gmail.com            else:
1714937Sstever@gmail.com                self.cond = "0"
1725773Snate@binkert.org
1734937Sstever@gmail.com        def getAllocator(self, microFlags):
1744937Sstever@gmail.com            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
1754937Sstever@gmail.com                    %(flags)s, %(fault)s, %(cc)s)''' % {
1762929Sktlim@umich.edu                "class_name" : self.className,
1772929Sktlim@umich.edu                "flags" : self.microFlagsText(microFlags),
1782929Sktlim@umich.edu                "fault" : self.fault,
1795773Snate@binkert.org                "cc" : self.cond}
1802929Sktlim@umich.edu            return allocator
1812929Sktlim@umich.edu
1822929Sktlim@umich.edu    iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase",
1832929Sktlim@umich.edu            {"code": "",
1842929Sktlim@umich.edu             "cond_test": "checkCondition(ccFlagBits | cfofBits | dfBit | \
1852929Sktlim@umich.edu                                          ecfBit | ezfBit, cc)"})
1864937Sstever@gmail.com    exec_output = MicroFaultExecute.subst(iop)
1874937Sstever@gmail.com    header_output = MicroFaultDeclare.subst(iop)
1884937Sstever@gmail.com    decoder_output = MicroFaultConstructor.subst(iop)
1894937Sstever@gmail.com    iop = InstObjParams("fault", "MicroFault", "MicroFaultBase",
1904937Sstever@gmail.com            {"code": "",
1914937Sstever@gmail.com             "cond_test": "true"})
1924937Sstever@gmail.com    exec_output += MicroFaultExecute.subst(iop)
1934937Sstever@gmail.com    header_output += MicroFaultDeclare.subst(iop)
1944937Sstever@gmail.com    decoder_output += MicroFaultConstructor.subst(iop)
1954937Sstever@gmail.com    microopClasses["fault"] = Fault
1964937Sstever@gmail.com
1974937Sstever@gmail.com    class Halt(X86Microop):
1984937Sstever@gmail.com        className = "MicroHalt"
1994937Sstever@gmail.com        def __init__(self):
2004937Sstever@gmail.com            pass
2012929Sktlim@umich.edu
2022929Sktlim@umich.edu        def getAllocator(self, microFlags):
2032929Sktlim@umich.edu            return "new MicroHalt(machInst, macrocodeBlock, %s)" % \
2042929Sktlim@umich.edu                    self.microFlagsText(microFlags)
2052929Sktlim@umich.edu
2062929Sktlim@umich.edu    microopClasses["halt"] = Halt
2072929Sktlim@umich.edu}};
2086011Ssteve.reinhardt@amd.com
2092929Sktlim@umich.edudef template MicroFenceOpDeclare {{
2102929Sktlim@umich.edu    class %(class_name)s : public X86ISA::X86MicroopBase
2112929Sktlim@umich.edu    {
2122929Sktlim@umich.edu      public:
2132929Sktlim@umich.edu        %(class_name)s(ExtMachInst _machInst,
2142929Sktlim@umich.edu                const char * instMnem,
2152929Sktlim@umich.edu                uint64_t setFlags);
2162929Sktlim@umich.edu
2172997Sstever@eecs.umich.edu        %(BasicExecDeclare)s
2182997Sstever@eecs.umich.edu    };
2192929Sktlim@umich.edu}};
2202997Sstever@eecs.umich.edu
2212997Sstever@eecs.umich.edudef template MicroFenceOpConstructor {{
2222929Sktlim@umich.edu    %(class_name)s::%(class_name)s(
2232997Sstever@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags) :
2242997Sstever@eecs.umich.edu        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
2252997Sstever@eecs.umich.edu                setFlags, %(op_class)s)
2262929Sktlim@umich.edu    {
2272997Sstever@eecs.umich.edu        %(constructor)s;
2282997Sstever@eecs.umich.edu    }
2292997Sstever@eecs.umich.edu}};
2302997Sstever@eecs.umich.edu
2315773Snate@binkert.orglet {{
2325773Snate@binkert.org    class MfenceOp(X86Microop):
2332997Sstever@eecs.umich.edu        def __init__(self):
2342997Sstever@eecs.umich.edu            self.className = "Mfence"
2356007Ssteve.reinhardt@amd.com            self.mnemonic = "mfence"
2366007Ssteve.reinhardt@amd.com            self.instFlags = "| (1ULL << StaticInst::IsMemBarrier)"
2372997Sstever@eecs.umich.edu
2382929Sktlim@umich.edu        def getAllocator(self, microFlags):
2392997Sstever@eecs.umich.edu            allocString = '''
2402997Sstever@eecs.umich.edu                    (StaticInstPtr)(new %(class_name)s(machInst,
2412997Sstever@eecs.umich.edu                        macrocodeBlock, %(flags)s))
2422997Sstever@eecs.umich.edu            '''
2432997Sstever@eecs.umich.edu            allocator = allocString % {
2442997Sstever@eecs.umich.edu                "class_name" : self.className,
2452997Sstever@eecs.umich.edu                "mnemonic" : self.mnemonic,
2462929Sktlim@umich.edu                "flags" : self.microFlagsText(microFlags) + self.instFlags}
2472997Sstever@eecs.umich.edu            return allocator
2482929Sktlim@umich.edu
2492929Sktlim@umich.edu    microopClasses["mfence"] = MfenceOp
2503005Sstever@eecs.umich.edu}};
2513005Sstever@eecs.umich.edu
2523005Sstever@eecs.umich.edulet {{
2533005Sstever@eecs.umich.edu    # Build up the all register version of this micro op
2546025Snate@binkert.org    iop = InstObjParams("mfence", "Mfence", 'X86MicroopBase',
2556025Snate@binkert.org            {"code" : ""})
2566025Snate@binkert.org    header_output += MicroFenceOpDeclare.subst(iop)
2576025Snate@binkert.org    decoder_output += MicroFenceOpConstructor.subst(iop)
2586025Snate@binkert.org    exec_output += BasicExecute.subst(iop)
2596025Snate@binkert.org}};
2604130Ssaidi@eecs.umich.edu