debug.isa revision 14277
111012Sandreas.sandberg@arm.com// Copyright (c) 2008 The Hewlett-Packard Development Company
211897Ssudhanshu.jha@arm.com// All rights reserved.
311012Sandreas.sandberg@arm.com//
411012Sandreas.sandberg@arm.com// The license below extends only to copyright in the software and shall
511012Sandreas.sandberg@arm.com// not be construed as granting a license to any other intellectual
611012Sandreas.sandberg@arm.com// property including but not limited to intellectual property relating
711012Sandreas.sandberg@arm.com// to a hardware implementation of the functionality of the software
811012Sandreas.sandberg@arm.com// licensed hereunder.  You may use the software subject to the license
911012Sandreas.sandberg@arm.com// terms below provided that you ensure that this notice is replicated
1011012Sandreas.sandberg@arm.com// unmodified and in its entirety in all distributions of the software,
1111012Sandreas.sandberg@arm.com// modified or unmodified, in source code or in binary form.
1211012Sandreas.sandberg@arm.com//
1311012Sandreas.sandberg@arm.com// Redistribution and use in source and binary forms, with or without
1411012Sandreas.sandberg@arm.com// modification, are permitted provided that the following conditions are
1511012Sandreas.sandberg@arm.com// met: redistributions of source code must retain the above copyright
1611012Sandreas.sandberg@arm.com// notice, this list of conditions and the following disclaimer;
1711012Sandreas.sandberg@arm.com// redistributions in binary form must reproduce the above copyright
1811012Sandreas.sandberg@arm.com// notice, this list of conditions and the following disclaimer in the
1911012Sandreas.sandberg@arm.com// documentation and/or other materials provided with the distribution;
2011012Sandreas.sandberg@arm.com// neither the name of the copyright holders nor the names of its
2111012Sandreas.sandberg@arm.com// contributors may be used to endorse or promote products derived from
2211012Sandreas.sandberg@arm.com// this software without specific prior written permission.
2311012Sandreas.sandberg@arm.com//
2411012Sandreas.sandberg@arm.com// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2511012Sandreas.sandberg@arm.com// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2611012Sandreas.sandberg@arm.com// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2711012Sandreas.sandberg@arm.com// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2811012Sandreas.sandberg@arm.com// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2911012Sandreas.sandberg@arm.com// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3011012Sandreas.sandberg@arm.com// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3111012Sandreas.sandberg@arm.com// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3211012Sandreas.sandberg@arm.com// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3311012Sandreas.sandberg@arm.com// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3411012Sandreas.sandberg@arm.com// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3511012Sandreas.sandberg@arm.com//
3611012Sandreas.sandberg@arm.com// Authors: Gabe Black
3711012Sandreas.sandberg@arm.com
3811012Sandreas.sandberg@arm.com//////////////////////////////////////////////////////////////////////////
3911012Sandreas.sandberg@arm.com//
4011012Sandreas.sandberg@arm.com// Debug Microops
4111012Sandreas.sandberg@arm.com//
4211012Sandreas.sandberg@arm.com//////////////////////////////////////////////////////////////////////////
4311012Sandreas.sandberg@arm.com
4411012Sandreas.sandberg@arm.comoutput header {{
4511012Sandreas.sandberg@arm.com    class MicroDebug : public X86ISA::X86MicroopBase
4611012Sandreas.sandberg@arm.com    {
4711012Sandreas.sandberg@arm.com      protected:
4811012Sandreas.sandberg@arm.com        std::shared_ptr<GenericISA::M5DebugFault> fault;
4911012Sandreas.sandberg@arm.com
5011012Sandreas.sandberg@arm.com      public:
5111012Sandreas.sandberg@arm.com        MicroDebug(ExtMachInst _machInst, const char *mnem,
5211012Sandreas.sandberg@arm.com                const char *instMnem, uint64_t setFlags,
5311012Sandreas.sandberg@arm.com                GenericISA::M5DebugFault *_fault);
5411012Sandreas.sandberg@arm.com
5511012Sandreas.sandberg@arm.com        Fault
5611012Sandreas.sandberg@arm.com        execute(ExecContext *xc, Trace::InstRecord *traceData) const
5711012Sandreas.sandberg@arm.com        {
5811012Sandreas.sandberg@arm.com            return fault;
5911012Sandreas.sandberg@arm.com        }
6011012Sandreas.sandberg@arm.com
6111012Sandreas.sandberg@arm.com        std::string
6211012Sandreas.sandberg@arm.com        generateDisassembly(Addr pc, const SymbolTable *symtab) const
6311012Sandreas.sandberg@arm.com        {
6411012Sandreas.sandberg@arm.com            std::stringstream response;
6511012Sandreas.sandberg@arm.com
6611012Sandreas.sandberg@arm.com            printMnemonic(response, instMnem, mnemonic);
6711012Sandreas.sandberg@arm.com            response << "\"" << fault->message() << "\"";
6811012Sandreas.sandberg@arm.com
6911012Sandreas.sandberg@arm.com            return response.str();
7011012Sandreas.sandberg@arm.com        }
7111012Sandreas.sandberg@arm.com    };
7211012Sandreas.sandberg@arm.com
7311012Sandreas.sandberg@arm.com    class MicroDebugFlags : public MicroDebug
7411012Sandreas.sandberg@arm.com    {
7511012Sandreas.sandberg@arm.com      protected:
7611012Sandreas.sandberg@arm.com        uint8_t cc;
7711012Sandreas.sandberg@arm.com
7811012Sandreas.sandberg@arm.com      public:
7911012Sandreas.sandberg@arm.com        MicroDebugFlags(ExtMachInst _machInst, const char *mnem,
8011012Sandreas.sandberg@arm.com                const char *instMnem, uint64_t setFlags,
8111012Sandreas.sandberg@arm.com                GenericISA::M5DebugFault *_fault, uint8_t _cc);
8211012Sandreas.sandberg@arm.com
8311012Sandreas.sandberg@arm.com        Fault execute(ExecContext *, Trace::InstRecord *) const;
8411012Sandreas.sandberg@arm.com    };
8511012Sandreas.sandberg@arm.com}};
8611012Sandreas.sandberg@arm.com
8711012Sandreas.sandberg@arm.comoutput decoder {{
8811012Sandreas.sandberg@arm.com    MicroDebug::MicroDebug(ExtMachInst _machInst, const char *mnem,
8911012Sandreas.sandberg@arm.com            const char *instMnem, uint64_t setFlags,
9011012Sandreas.sandberg@arm.com            GenericISA::M5DebugFault *_fault) :
9111012Sandreas.sandberg@arm.com        X86ISA::X86MicroopBase(_machInst, mnem, instMnem,
9211012Sandreas.sandberg@arm.com                               setFlags, No_OpClass),
9311012Sandreas.sandberg@arm.com        fault(_fault)
9411012Sandreas.sandberg@arm.com    {}
9511012Sandreas.sandberg@arm.com}};
9611012Sandreas.sandberg@arm.com
9711012Sandreas.sandberg@arm.comdef template MicroDebugFlagsExecute {{
9811012Sandreas.sandberg@arm.com        Fault
9911012Sandreas.sandberg@arm.com        %(class_name)s::execute(ExecContext *xc,
10011012Sandreas.sandberg@arm.com                Trace::InstRecord *traceData) const
10111012Sandreas.sandberg@arm.com        {
10211012Sandreas.sandberg@arm.com            %(op_decl)s
10311012Sandreas.sandberg@arm.com            %(op_rd)s
10411012Sandreas.sandberg@arm.com            if (%(cond_test)s) {
10511012Sandreas.sandberg@arm.com                return %(base_class)s::execute(xc, traceData);
10611012Sandreas.sandberg@arm.com            } else {
10711012Sandreas.sandberg@arm.com                return NoFault;
10811012Sandreas.sandberg@arm.com            }
10911012Sandreas.sandberg@arm.com        }
11011012Sandreas.sandberg@arm.com}};
11111012Sandreas.sandberg@arm.com
11211012Sandreas.sandberg@arm.comdef template MicroDebugFlagsConstructor {{
11311012Sandreas.sandberg@arm.com    %(class_name)s::%(class_name)s(
11411012Sandreas.sandberg@arm.com            ExtMachInst machInst, const char *mnem,
11511012Sandreas.sandberg@arm.com            const char *instMnem, uint64_t setFlags,
11611012Sandreas.sandberg@arm.com            GenericISA::M5DebugFault *_fault, uint8_t _cc) :
11711012Sandreas.sandberg@arm.com        %(base_class)s(machInst, mnem, instMnem, setFlags, _fault),
11811012Sandreas.sandberg@arm.com        cc(_cc)
11911012Sandreas.sandberg@arm.com    {
12011012Sandreas.sandberg@arm.com        %(constructor)s;
12111012Sandreas.sandberg@arm.com    }
12211012Sandreas.sandberg@arm.com}};
12311012Sandreas.sandberg@arm.com
12411012Sandreas.sandberg@arm.comlet {{
12511012Sandreas.sandberg@arm.com    iop = InstObjParams("", "MicroDebugFlags", "MicroDebug",
12611012Sandreas.sandberg@arm.com            {"code": "",
12711012Sandreas.sandberg@arm.com             "cond_test": "checkCondition(ccFlagBits | cfofBits | \
12811012Sandreas.sandberg@arm.com                                              dfBit | ecfBit | ezfBit, cc)"})
12911012Sandreas.sandberg@arm.com    exec_output = MicroDebugFlagsExecute.subst(iop)
13011012Sandreas.sandberg@arm.com    decoder_output = MicroDebugFlagsConstructor.subst(iop)
13111012Sandreas.sandberg@arm.com}};
13211012Sandreas.sandberg@arm.com
13311012Sandreas.sandberg@arm.comlet {{
13411012Sandreas.sandberg@arm.com    class MicroDebug(X86Microop):
13511012Sandreas.sandberg@arm.com        def __init__(self, name, fault, message, once, flags):
13611012Sandreas.sandberg@arm.com            self.name = name
13711012Sandreas.sandberg@arm.com            self.fault = fault
13811012Sandreas.sandberg@arm.com            self.message = message
13911897Ssudhanshu.jha@arm.com            self.once = once
14011897Ssudhanshu.jha@arm.com            self.flags = flags
14111897Ssudhanshu.jha@arm.com            if flags and not isinstance(flags, (list, tuple)):
14211897Ssudhanshu.jha@arm.com                raise Exception, "flags must be a list or tuple of flags"
14311012Sandreas.sandberg@arm.com
14411012Sandreas.sandberg@arm.com            self.className = "MicroDebugFlags" if flags else "MicroDebug"
14511012Sandreas.sandberg@arm.com
14611012Sandreas.sandberg@arm.com        def getAllocator(self, microFlags):
14711012Sandreas.sandberg@arm.com            if self.once:
14811012Sandreas.sandberg@arm.com                fault_allocator_template = \
14911012Sandreas.sandberg@arm.com                    "new %(fault_type)s(%(token)s, %(message)s)"
15011012Sandreas.sandberg@arm.com            else:
15111012Sandreas.sandberg@arm.com                fault_allocator_template = \
15211012Sandreas.sandberg@arm.com                    "new %(fault_type)s(%(message)s)"
15311897Ssudhanshu.jha@arm.com            fault_allocator = fault_allocator_template % {
15411897Ssudhanshu.jha@arm.com                "fault_type": self.fault,
15511897Ssudhanshu.jha@arm.com                "token": "std::string(\"%s\")" % self.message,
15611897Ssudhanshu.jha@arm.com                "message": "\"%s\"" % self.message
15711897Ssudhanshu.jha@arm.com            }
15811012Sandreas.sandberg@arm.com
15911012Sandreas.sandberg@arm.com            args = ["machInst", "\"%s\"" % self.name, "macrocodeBlock",
16011012Sandreas.sandberg@arm.com                self.microFlagsText(microFlags), fault_allocator]
16111897Ssudhanshu.jha@arm.com
16211012Sandreas.sandberg@arm.com            if self.flags:
16311012Sandreas.sandberg@arm.com                args.append(" | ".join(self.flags))
16411012Sandreas.sandberg@arm.com
16511012Sandreas.sandberg@arm.com            return "new " + self.className + "(" + ", ".join(args) + ")"
16611012Sandreas.sandberg@arm.com
16711012Sandreas.sandberg@arm.com    def buildDebugMicro(name, with_once=False):
16811012Sandreas.sandberg@arm.com        global microopClasses
16911012Sandreas.sandberg@arm.com
17011012Sandreas.sandberg@arm.com        fault_class = "GenericISA::M5" + name.capitalize() + "Fault"
17111012Sandreas.sandberg@arm.com
17211012Sandreas.sandberg@arm.com        class MicroDebugChild(MicroDebug):
17311012Sandreas.sandberg@arm.com            def __init__(self, message, flags=None):
17411012Sandreas.sandberg@arm.com                super(MicroDebugChild, self).__init__(
17511012Sandreas.sandberg@arm.com                        name, fault_class, message, False, flags)
17611012Sandreas.sandberg@arm.com
17711012Sandreas.sandberg@arm.com        microopClasses[name] = MicroDebugChild
17811012Sandreas.sandberg@arm.com
17911012Sandreas.sandberg@arm.com        if with_once:
18011012Sandreas.sandberg@arm.com            fault_once_class = \
18111012Sandreas.sandberg@arm.com                "GenericISA::M5" + name.capitalize() + "OnceFault"
18211012Sandreas.sandberg@arm.com            name_once = name + "_once"
18311012Sandreas.sandberg@arm.com
18411012Sandreas.sandberg@arm.com            class MicroDebugOnceChild(MicroDebug):
18511012Sandreas.sandberg@arm.com                def __init__(self, message, flags=None):
18611012Sandreas.sandberg@arm.com                    super(MicroDebugOnceChild, self).__init__(
18711012Sandreas.sandberg@arm.com                            name_once, fault_once_class, message, True, flags)
18811012Sandreas.sandberg@arm.com
18911012Sandreas.sandberg@arm.com            microopClasses[name_once] = MicroDebugOnceChild
19011012Sandreas.sandberg@arm.com
19111012Sandreas.sandberg@arm.com    buildDebugMicro("panic")
19211012Sandreas.sandberg@arm.com    buildDebugMicro("fatal")
19311012Sandreas.sandberg@arm.com    buildDebugMicro("hack", True)
19411012Sandreas.sandberg@arm.com    buildDebugMicro("inform", True)
19511012Sandreas.sandberg@arm.com    buildDebugMicro("warn", True)
19611012Sandreas.sandberg@arm.com}};
19711012Sandreas.sandberg@arm.com