specop.isa revision 12236:126ac9da6050
13170Sstever@eecs.umich.edu// Copyright (c) 2007-2008 The Hewlett-Packard Development Company
29383SAli.Saidi@ARM.com// Copyright (c) 2011 Mark D. Hill and David A. Wood
39383SAli.Saidi@ARM.com// All rights reserved.
49383SAli.Saidi@ARM.com//
59383SAli.Saidi@ARM.com// The license below extends only to copyright in the software and shall
69383SAli.Saidi@ARM.com// not be construed as granting a license to any other intellectual
79383SAli.Saidi@ARM.com// property including but not limited to intellectual property relating
89383SAli.Saidi@ARM.com// to a hardware implementation of the functionality of the software
99383SAli.Saidi@ARM.com// licensed hereunder.  You may use the software subject to the license
109383SAli.Saidi@ARM.com// terms below provided that you ensure that this notice is replicated
119383SAli.Saidi@ARM.com// unmodified and in its entirety in all distributions of the software,
129383SAli.Saidi@ARM.com// modified or unmodified, in source code or in binary form.
139383SAli.Saidi@ARM.com//
143170Sstever@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
153170Sstever@eecs.umich.edu// modification, are permitted provided that the following conditions are
163170Sstever@eecs.umich.edu// met: redistributions of source code must retain the above copyright
173170Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
183170Sstever@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
193170Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
203170Sstever@eecs.umich.edu// documentation and/or other materials provided with the distribution;
213170Sstever@eecs.umich.edu// neither the name of the copyright holders nor the names of its
223170Sstever@eecs.umich.edu// contributors may be used to endorse or promote products derived from
233170Sstever@eecs.umich.edu// this software without specific prior written permission.
243170Sstever@eecs.umich.edu//
253170Sstever@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
263170Sstever@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
273170Sstever@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
283170Sstever@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
293170Sstever@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
303170Sstever@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
313170Sstever@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
323170Sstever@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
333170Sstever@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
343170Sstever@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
353170Sstever@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
363170Sstever@eecs.umich.edu//
373170Sstever@eecs.umich.edu// Authors: Gabe Black
383170Sstever@eecs.umich.edu
393170Sstever@eecs.umich.edu//////////////////////////////////////////////////////////////////////////
403170Sstever@eecs.umich.edu//
413170Sstever@eecs.umich.edu// Fault Microop
423170Sstever@eecs.umich.edu//
433170Sstever@eecs.umich.edu//////////////////////////////////////////////////////////////////////////
443170Sstever@eecs.umich.edu
453170Sstever@eecs.umich.eduoutput header {{
463170Sstever@eecs.umich.edu    class MicroFaultBase : public X86ISA::X86MicroopBase
473170Sstever@eecs.umich.edu    {
483170Sstever@eecs.umich.edu      protected:
493170Sstever@eecs.umich.edu        Fault fault;
504027Sstever@eecs.umich.edu        uint8_t cc;
514027Sstever@eecs.umich.edu
524027Sstever@eecs.umich.edu      public:
534027Sstever@eecs.umich.edu        MicroFaultBase(ExtMachInst _machInst, const char * instMnem,
544027Sstever@eecs.umich.edu                uint64_t setFlags, Fault _fault, uint8_t _cc);
554027Sstever@eecs.umich.edu
564027Sstever@eecs.umich.edu        std::string generateDisassembly(Addr pc,
574027Sstever@eecs.umich.edu                const SymbolTable *symtab) const;
583170Sstever@eecs.umich.edu    };
593170Sstever@eecs.umich.edu
606330Sgblack@eecs.umich.edu    class MicroHalt : public X86ISA::X86MicroopBase
6112334Sgabeblack@google.com    {
629383SAli.Saidi@ARM.com      public:
633170Sstever@eecs.umich.edu        MicroHalt(ExtMachInst _machInst, const char * instMnem,
643170Sstever@eecs.umich.edu                uint64_t setFlags) :
655569Snate@binkert.org            X86MicroopBase(_machInst, "halt", instMnem,
663170Sstever@eecs.umich.edu                           setFlags | (ULL(1) << StaticInst::IsNonSpeculative) |
673170Sstever@eecs.umich.edu                           (ULL(1) << StaticInst::IsQuiesce),
683170Sstever@eecs.umich.edu                           No_OpClass)
699383SAli.Saidi@ARM.com        {
709383SAli.Saidi@ARM.com        }
719383SAli.Saidi@ARM.com
729383SAli.Saidi@ARM.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
739383SAli.Saidi@ARM.com
749383SAli.Saidi@ARM.com        std::string generateDisassembly(Addr pc,
759383SAli.Saidi@ARM.com                const SymbolTable *symtab) const;
769383SAli.Saidi@ARM.com    };
779383SAli.Saidi@ARM.com}};
789383SAli.Saidi@ARM.com
7910574Sandreas.hansson@arm.comdef template MicroFaultDeclare {{
809383SAli.Saidi@ARM.com    class %(class_name)s : public %(base_class)s
819383SAli.Saidi@ARM.com    {
829383SAli.Saidi@ARM.com      public:
839383SAli.Saidi@ARM.com        %(class_name)s(ExtMachInst _machInst, const char * instMnem,
849383SAli.Saidi@ARM.com                uint64_t setFlags, Fault _fault, uint8_t _cc);
859383SAli.Saidi@ARM.com
869383SAli.Saidi@ARM.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
879383SAli.Saidi@ARM.com    };
8812749Sgiacomo.travaglini@arm.com}};
893170Sstever@eecs.umich.edu
907783SGiacomo.Gabrielli@arm.comdef template MicroFaultExecute {{
917783SGiacomo.Gabrielli@arm.com        Fault %(class_name)s::execute(ExecContext *xc,
923170Sstever@eecs.umich.edu                Trace::InstRecord *traceData) const
933170Sstever@eecs.umich.edu        {
9410030SAli.Saidi@ARM.com            %(op_decl)s;
9510030SAli.Saidi@ARM.com            %(op_rd)s;
9610030SAli.Saidi@ARM.com            if (%(cond_test)s) {
9710030SAli.Saidi@ARM.com                //Return the fault we were constructed with
9810030SAli.Saidi@ARM.com                return fault;
993170Sstever@eecs.umich.edu            } else {
1003170Sstever@eecs.umich.edu                return NoFault;
1013170Sstever@eecs.umich.edu            }
10212749Sgiacomo.travaglini@arm.com        }
1033170Sstever@eecs.umich.edu}};
1043170Sstever@eecs.umich.edu
1053170Sstever@eecs.umich.eduoutput exec {{
1063170Sstever@eecs.umich.edu    Fault
1074040Ssaidi@eecs.umich.edu    MicroHalt::execute(ExecContext *xc, Trace::InstRecord * traceData) const
1083170Sstever@eecs.umich.edu    {
1093170Sstever@eecs.umich.edu        xc->tcBase()->suspend();
1107783SGiacomo.Gabrielli@arm.com        return NoFault;
1117783SGiacomo.Gabrielli@arm.com    }
1123170Sstever@eecs.umich.edu}};
1133170Sstever@eecs.umich.edu
1143170Sstever@eecs.umich.eduoutput decoder {{
1154040Ssaidi@eecs.umich.edu    MicroFaultBase::MicroFaultBase(
1167783SGiacomo.Gabrielli@arm.com            ExtMachInst machInst, const char * instMnem,
1173170Sstever@eecs.umich.edu            uint64_t setFlags, Fault _fault, uint8_t _cc) :
1183170Sstever@eecs.umich.edu        X86MicroopBase(machInst, "fault", instMnem, setFlags, No_OpClass),
1193170Sstever@eecs.umich.edu                fault(_fault), cc(_cc)
1203170Sstever@eecs.umich.edu    {
1213170Sstever@eecs.umich.edu    }
1223170Sstever@eecs.umich.edu}};
1233170Sstever@eecs.umich.edu
1243170Sstever@eecs.umich.edudef template MicroFaultConstructor {{
1255714Shsul@eecs.umich.edu    %(class_name)s::%(class_name)s(
1263170Sstever@eecs.umich.edu            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
1275714Shsul@eecs.umich.edu            Fault _fault, uint8_t _cc) :
1283170Sstever@eecs.umich.edu        %(base_class)s(machInst, instMnem, setFlags, _fault, _cc)
1293170Sstever@eecs.umich.edu    {
1303170Sstever@eecs.umich.edu        %(constructor)s;
1313170Sstever@eecs.umich.edu    }
1323170Sstever@eecs.umich.edu}};
1333170Sstever@eecs.umich.edu
1343170Sstever@eecs.umich.eduoutput decoder {{
1353170Sstever@eecs.umich.edu    std::string MicroFaultBase::generateDisassembly(Addr pc,
1363170Sstever@eecs.umich.edu            const SymbolTable *symtab) const
1373170Sstever@eecs.umich.edu    {
13812218Snikos.nikoleris@arm.com        std::stringstream response;
13912218Snikos.nikoleris@arm.com
14012218Snikos.nikoleris@arm.com        printMnemonic(response, instMnem, mnemonic);
14112218Snikos.nikoleris@arm.com        if(fault)
14212218Snikos.nikoleris@arm.com            response << fault->name();
14312218Snikos.nikoleris@arm.com        else
14412218Snikos.nikoleris@arm.com            response << "No Fault";
1453170Sstever@eecs.umich.edu
1463170Sstever@eecs.umich.edu        return response.str();
1475569Snate@binkert.org    }
148
149    std::string MicroHalt::generateDisassembly(Addr pc,
150            const SymbolTable *symtab) const
151    {
152        std::stringstream response;
153
154        printMnemonic(response, instMnem, mnemonic);
155
156        return response.str();
157    }
158}};
159
160let {{
161    class Fault(X86Microop):
162        className = "MicroFault"
163        def __init__(self, fault, flags=None):
164            self.fault = fault
165            if flags:
166                if not isinstance(flags, (list, tuple)):
167                    raise Exception, "flags must be a list or tuple of flags"
168                self.cond = " | ".join(flags)
169                self.className += "Flags"
170            else:
171                self.cond = "0"
172
173        def getAllocator(self, microFlags):
174            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
175                    %(flags)s, %(fault)s, %(cc)s)''' % {
176                "class_name" : self.className,
177                "flags" : self.microFlagsText(microFlags),
178                "fault" : self.fault,
179                "cc" : self.cond}
180            return allocator
181
182    iop = InstObjParams("fault", "MicroFaultFlags", "MicroFaultBase",
183            {"code": "",
184             "cond_test": "checkCondition(ccFlagBits | cfofBits | dfBit | \
185                                          ecfBit | ezfBit, cc)"})
186    exec_output = MicroFaultExecute.subst(iop)
187    header_output = MicroFaultDeclare.subst(iop)
188    decoder_output = MicroFaultConstructor.subst(iop)
189    iop = InstObjParams("fault", "MicroFault", "MicroFaultBase",
190            {"code": "",
191             "cond_test": "true"})
192    exec_output += MicroFaultExecute.subst(iop)
193    header_output += MicroFaultDeclare.subst(iop)
194    decoder_output += MicroFaultConstructor.subst(iop)
195    microopClasses["fault"] = Fault
196
197    class Halt(X86Microop):
198        className = "MicroHalt"
199        def __init__(self):
200            pass
201
202        def getAllocator(self, microFlags):
203            return "new MicroHalt(machInst, macrocodeBlock, %s)" % \
204                    self.microFlagsText(microFlags)
205
206    microopClasses["halt"] = Halt
207}};
208
209def template MicroFenceOpDeclare {{
210    class %(class_name)s : public X86ISA::X86MicroopBase
211    {
212      public:
213        %(class_name)s(ExtMachInst _machInst,
214                const char * instMnem,
215                uint64_t setFlags);
216
217        Fault execute(ExecContext *, Trace::InstRecord *) const;
218    };
219}};
220
221def template MicroFenceOpConstructor {{
222    %(class_name)s::%(class_name)s(
223            ExtMachInst machInst, const char * instMnem, uint64_t setFlags) :
224        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
225                setFlags, %(op_class)s)
226    {
227        %(constructor)s;
228    }
229}};
230
231let {{
232    class MfenceOp(X86Microop):
233        def __init__(self):
234            self.className = "Mfence"
235            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