15425Sgblack@eecs.umich.edu// Copyright (c) 2008 The Hewlett-Packard Development Company
25425Sgblack@eecs.umich.edu// All rights reserved.
35425Sgblack@eecs.umich.edu//
47087Snate@binkert.org// The license below extends only to copyright in the software and shall
57087Snate@binkert.org// not be construed as granting a license to any other intellectual
67087Snate@binkert.org// property including but not limited to intellectual property relating
77087Snate@binkert.org// to a hardware implementation of the functionality of the software
87087Snate@binkert.org// licensed hereunder.  You may use the software subject to the license
97087Snate@binkert.org// terms below provided that you ensure that this notice is replicated
107087Snate@binkert.org// unmodified and in its entirety in all distributions of the software,
117087Snate@binkert.org// modified or unmodified, in source code or in binary form.
125425Sgblack@eecs.umich.edu//
137087Snate@binkert.org// Redistribution and use in source and binary forms, with or without
147087Snate@binkert.org// modification, are permitted provided that the following conditions are
157087Snate@binkert.org// met: redistributions of source code must retain the above copyright
167087Snate@binkert.org// notice, this list of conditions and the following disclaimer;
177087Snate@binkert.org// redistributions in binary form must reproduce the above copyright
187087Snate@binkert.org// notice, this list of conditions and the following disclaimer in the
197087Snate@binkert.org// documentation and/or other materials provided with the distribution;
207087Snate@binkert.org// neither the name of the copyright holders nor the names of its
215425Sgblack@eecs.umich.edu// contributors may be used to endorse or promote products derived from
227087Snate@binkert.org// this software without specific prior written permission.
235425Sgblack@eecs.umich.edu//
245425Sgblack@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
255425Sgblack@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
265425Sgblack@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
275425Sgblack@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
285425Sgblack@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
295425Sgblack@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
305425Sgblack@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
315425Sgblack@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
325425Sgblack@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
335425Sgblack@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
345425Sgblack@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
355425Sgblack@eecs.umich.edu//
365425Sgblack@eecs.umich.edu// Authors: Gabe Black
375425Sgblack@eecs.umich.edu
385425Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////////////
395425Sgblack@eecs.umich.edu//
405425Sgblack@eecs.umich.edu// Debug Microops
415425Sgblack@eecs.umich.edu//
425425Sgblack@eecs.umich.edu//////////////////////////////////////////////////////////////////////////
435425Sgblack@eecs.umich.edu
445425Sgblack@eecs.umich.eduoutput header {{
4514277Sgabeblack@google.com    class MicroDebug : public X86ISA::X86MicroopBase
465425Sgblack@eecs.umich.edu    {
475425Sgblack@eecs.umich.edu      protected:
4814277Sgabeblack@google.com        std::shared_ptr<GenericISA::M5DebugFault> fault;
495425Sgblack@eecs.umich.edu
505425Sgblack@eecs.umich.edu      public:
5114277Sgabeblack@google.com        MicroDebug(ExtMachInst _machInst, const char *mnem,
5214277Sgabeblack@google.com                const char *instMnem, uint64_t setFlags,
5314277Sgabeblack@google.com                GenericISA::M5DebugFault *_fault);
5414277Sgabeblack@google.com
5514277Sgabeblack@google.com        Fault
5614277Sgabeblack@google.com        execute(ExecContext *xc, Trace::InstRecord *traceData) const
5714277Sgabeblack@google.com        {
5814277Sgabeblack@google.com            return fault;
5914277Sgabeblack@google.com        }
605425Sgblack@eecs.umich.edu
617965Sgblack@eecs.umich.edu        std::string
627965Sgblack@eecs.umich.edu        generateDisassembly(Addr pc, const SymbolTable *symtab) const
637965Sgblack@eecs.umich.edu        {
647965Sgblack@eecs.umich.edu            std::stringstream response;
657965Sgblack@eecs.umich.edu
667965Sgblack@eecs.umich.edu            printMnemonic(response, instMnem, mnemonic);
6714277Sgabeblack@google.com            response << "\"" << fault->message() << "\"";
687965Sgblack@eecs.umich.edu
697965Sgblack@eecs.umich.edu            return response.str();
707965Sgblack@eecs.umich.edu        }
715425Sgblack@eecs.umich.edu    };
725425Sgblack@eecs.umich.edu
7314277Sgabeblack@google.com    class MicroDebugFlags : public MicroDebug
745425Sgblack@eecs.umich.edu    {
7514277Sgabeblack@google.com      protected:
7614277Sgabeblack@google.com        uint8_t cc;
7714277Sgabeblack@google.com
785425Sgblack@eecs.umich.edu      public:
7914277Sgabeblack@google.com        MicroDebugFlags(ExtMachInst _machInst, const char *mnem,
8014277Sgabeblack@google.com                const char *instMnem, uint64_t setFlags,
8114277Sgabeblack@google.com                GenericISA::M5DebugFault *_fault, uint8_t _cc);
825425Sgblack@eecs.umich.edu
8312236Sgabeblack@google.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
845425Sgblack@eecs.umich.edu    };
855425Sgblack@eecs.umich.edu}};
865425Sgblack@eecs.umich.edu
8714277Sgabeblack@google.comoutput decoder {{
8814277Sgabeblack@google.com    MicroDebug::MicroDebug(ExtMachInst _machInst, const char *mnem,
8914277Sgabeblack@google.com            const char *instMnem, uint64_t setFlags,
9014277Sgabeblack@google.com            GenericISA::M5DebugFault *_fault) :
9114277Sgabeblack@google.com        X86ISA::X86MicroopBase(_machInst, mnem, instMnem,
9214277Sgabeblack@google.com                               setFlags, No_OpClass),
9314277Sgabeblack@google.com        fault(_fault)
9414277Sgabeblack@google.com    {}
9514277Sgabeblack@google.com}};
9614277Sgabeblack@google.com
9714277Sgabeblack@google.comdef template MicroDebugFlagsExecute {{
987965Sgblack@eecs.umich.edu        Fault
9912234Sgabeblack@google.com        %(class_name)s::execute(ExecContext *xc,
1005425Sgblack@eecs.umich.edu                Trace::InstRecord *traceData) const
1015425Sgblack@eecs.umich.edu        {
1025425Sgblack@eecs.umich.edu            %(op_decl)s
1035425Sgblack@eecs.umich.edu            %(op_rd)s
1045425Sgblack@eecs.umich.edu            if (%(cond_test)s) {
10514277Sgabeblack@google.com                return %(base_class)s::execute(xc, traceData);
1067965Sgblack@eecs.umich.edu            } else {
1077965Sgblack@eecs.umich.edu                return NoFault;
1085425Sgblack@eecs.umich.edu            }
1095425Sgblack@eecs.umich.edu        }
1105425Sgblack@eecs.umich.edu}};
1115425Sgblack@eecs.umich.edu
11214277Sgabeblack@google.comdef template MicroDebugFlagsConstructor {{
1137975Sgblack@eecs.umich.edu    %(class_name)s::%(class_name)s(
11414277Sgabeblack@google.com            ExtMachInst machInst, const char *mnem,
11514277Sgabeblack@google.com            const char *instMnem, uint64_t setFlags,
11614277Sgabeblack@google.com            GenericISA::M5DebugFault *_fault, uint8_t _cc) :
11714277Sgabeblack@google.com        %(base_class)s(machInst, mnem, instMnem, setFlags, _fault),
11814277Sgabeblack@google.com        cc(_cc)
1195425Sgblack@eecs.umich.edu    {
1207626Sgblack@eecs.umich.edu        %(constructor)s;
1215425Sgblack@eecs.umich.edu    }
1225425Sgblack@eecs.umich.edu}};
1235425Sgblack@eecs.umich.edu
1245425Sgblack@eecs.umich.edulet {{
12514277Sgabeblack@google.com    iop = InstObjParams("", "MicroDebugFlags", "MicroDebug",
12614277Sgabeblack@google.com            {"code": "",
12714277Sgabeblack@google.com             "cond_test": "checkCondition(ccFlagBits | cfofBits | \
12814277Sgabeblack@google.com                                              dfBit | ecfBit | ezfBit, cc)"})
12914277Sgabeblack@google.com    exec_output = MicroDebugFlagsExecute.subst(iop)
13014277Sgabeblack@google.com    decoder_output = MicroDebugFlagsConstructor.subst(iop)
13114277Sgabeblack@google.com}};
13214277Sgabeblack@google.com
13314277Sgabeblack@google.comlet {{
1345425Sgblack@eecs.umich.edu    class MicroDebug(X86Microop):
13514277Sgabeblack@google.com        def __init__(self, name, fault, message, once, flags):
13614277Sgabeblack@google.com            self.name = name
13714277Sgabeblack@google.com            self.fault = fault
1385425Sgblack@eecs.umich.edu            self.message = message
13914277Sgabeblack@google.com            self.once = once
14014277Sgabeblack@google.com            self.flags = flags
14114277Sgabeblack@google.com            if flags and not isinstance(flags, (list, tuple)):
14214277Sgabeblack@google.com                raise Exception, "flags must be a list or tuple of flags"
14314277Sgabeblack@google.com
14414277Sgabeblack@google.com            self.className = "MicroDebugFlags" if flags else "MicroDebug"
1455425Sgblack@eecs.umich.edu
1467620Sgblack@eecs.umich.edu        def getAllocator(self, microFlags):
14714277Sgabeblack@google.com            if self.once:
14814277Sgabeblack@google.com                fault_allocator_template = \
14914277Sgabeblack@google.com                    "new %(fault_type)s(%(token)s, %(message)s)"
15014277Sgabeblack@google.com            else:
15114277Sgabeblack@google.com                fault_allocator_template = \
15214277Sgabeblack@google.com                    "new %(fault_type)s(%(message)s)"
15314277Sgabeblack@google.com            fault_allocator = fault_allocator_template % {
15414277Sgabeblack@google.com                "fault_type": self.fault,
15514277Sgabeblack@google.com                "token": "std::string(\"%s\")" % self.message,
15614277Sgabeblack@google.com                "message": "\"%s\"" % self.message
15714277Sgabeblack@google.com            }
1585425Sgblack@eecs.umich.edu
15914277Sgabeblack@google.com            args = ["machInst", "\"%s\"" % self.name, "macrocodeBlock",
16014277Sgabeblack@google.com                self.microFlagsText(microFlags), fault_allocator]
1615425Sgblack@eecs.umich.edu
16214277Sgabeblack@google.com            if self.flags:
16314277Sgabeblack@google.com                args.append(" | ".join(self.flags))
1645425Sgblack@eecs.umich.edu
16514277Sgabeblack@google.com            return "new " + self.className + "(" + ", ".join(args) + ")"
1665425Sgblack@eecs.umich.edu
16714277Sgabeblack@google.com    def buildDebugMicro(name, with_once=False):
16814277Sgabeblack@google.com        global microopClasses
16914277Sgabeblack@google.com
17014277Sgabeblack@google.com        fault_class = "GenericISA::M5" + name.capitalize() + "Fault"
1715425Sgblack@eecs.umich.edu
1725425Sgblack@eecs.umich.edu        class MicroDebugChild(MicroDebug):
17314277Sgabeblack@google.com            def __init__(self, message, flags=None):
17414277Sgabeblack@google.com                super(MicroDebugChild, self).__init__(
17514277Sgabeblack@google.com                        name, fault_class, message, False, flags)
1765425Sgblack@eecs.umich.edu
17714277Sgabeblack@google.com        microopClasses[name] = MicroDebugChild
1785425Sgblack@eecs.umich.edu
17914277Sgabeblack@google.com        if with_once:
18014277Sgabeblack@google.com            fault_once_class = \
18114277Sgabeblack@google.com                "GenericISA::M5" + name.capitalize() + "OnceFault"
18214277Sgabeblack@google.com            name_once = name + "_once"
18314277Sgabeblack@google.com
18414277Sgabeblack@google.com            class MicroDebugOnceChild(MicroDebug):
18514277Sgabeblack@google.com                def __init__(self, message, flags=None):
18614277Sgabeblack@google.com                    super(MicroDebugOnceChild, self).__init__(
18714277Sgabeblack@google.com                            name_once, fault_once_class, message, True, flags)
18814277Sgabeblack@google.com
18914277Sgabeblack@google.com            microopClasses[name_once] = MicroDebugOnceChild
19014277Sgabeblack@google.com
19114277Sgabeblack@google.com    buildDebugMicro("panic")
19214277Sgabeblack@google.com    buildDebugMicro("fatal")
19314277Sgabeblack@google.com    buildDebugMicro("hack", True)
19414277Sgabeblack@google.com    buildDebugMicro("inform", True)
19514277Sgabeblack@google.com    buildDebugMicro("warn", True)
1965425Sgblack@eecs.umich.edu}};
197