// Copyright (c) 2008 The Hewlett-Packard Development Company
// All rights reserved.
//
// The license below extends only to copyright in the software and shall
// not be construed as granting a license to any other intellectual
// property including but not limited to intellectual property relating
// to a hardware implementation of the functionality of the software
// licensed hereunder.  You may use the software subject to the license
// terms below provided that you ensure that this notice is replicated
// unmodified and in its entirety in all distributions of the software,
// modified or unmodified, in source code or in binary form.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met: redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer;
// redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution;
// neither the name of the copyright holders nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Authors: Gabe Black

//////////////////////////////////////////////////////////////////////////
//
// Debug Microops
//
//////////////////////////////////////////////////////////////////////////

output header {{
    class MicroDebug : public X86ISA::X86MicroopBase
    {
      protected:
        std::shared_ptr<GenericISA::M5DebugFault> fault;

      public:
        MicroDebug(ExtMachInst _machInst, const char *mnem,
                const char *instMnem, uint64_t setFlags,
                GenericISA::M5DebugFault *_fault);

        Fault
        execute(ExecContext *xc, Trace::InstRecord *traceData) const
        {
            return fault;
        }

        std::string
        generateDisassembly(Addr pc, const SymbolTable *symtab) const
        {
            std::stringstream response;

            printMnemonic(response, instMnem, mnemonic);
            response << "\"" << fault->message() << "\"";

            return response.str();
        }
    };

    class MicroDebugFlags : public MicroDebug
    {
      protected:
        uint8_t cc;

      public:
        MicroDebugFlags(ExtMachInst _machInst, const char *mnem,
                const char *instMnem, uint64_t setFlags,
                GenericISA::M5DebugFault *_fault, uint8_t _cc);

        Fault execute(ExecContext *, Trace::InstRecord *) const;
    };
}};

output decoder {{
    MicroDebug::MicroDebug(ExtMachInst _machInst, const char *mnem,
            const char *instMnem, uint64_t setFlags,
            GenericISA::M5DebugFault *_fault) :
        X86ISA::X86MicroopBase(_machInst, mnem, instMnem,
                               setFlags, No_OpClass),
        fault(_fault)
    {}
}};

def template MicroDebugFlagsExecute {{
        Fault
        %(class_name)s::execute(ExecContext *xc,
                Trace::InstRecord *traceData) const
        {
            %(op_decl)s
            %(op_rd)s
            if (%(cond_test)s) {
                return %(base_class)s::execute(xc, traceData);
            } else {
                return NoFault;
            }
        }
}};

def template MicroDebugFlagsConstructor {{
    %(class_name)s::%(class_name)s(
            ExtMachInst machInst, const char *mnem,
            const char *instMnem, uint64_t setFlags,
            GenericISA::M5DebugFault *_fault, uint8_t _cc) :
        %(base_class)s(machInst, mnem, instMnem, setFlags, _fault),
        cc(_cc)
    {
        %(constructor)s;
    }
}};

let {{
    iop = InstObjParams("", "MicroDebugFlags", "MicroDebug",
            {"code": "",
             "cond_test": "checkCondition(ccFlagBits | cfofBits | \
                                              dfBit | ecfBit | ezfBit, cc)"})
    exec_output = MicroDebugFlagsExecute.subst(iop)
    decoder_output = MicroDebugFlagsConstructor.subst(iop)
}};

let {{
    class MicroDebug(X86Microop):
        def __init__(self, name, fault, message, once, flags):
            self.name = name
            self.fault = fault
            self.message = message
            self.once = once
            self.flags = flags
            if flags and not isinstance(flags, (list, tuple)):
                raise Exception, "flags must be a list or tuple of flags"

            self.className = "MicroDebugFlags" if flags else "MicroDebug"

        def getAllocator(self, microFlags):
            if self.once:
                fault_allocator_template = \
                    "new %(fault_type)s(%(token)s, %(message)s)"
            else:
                fault_allocator_template = \
                    "new %(fault_type)s(%(message)s)"
            fault_allocator = fault_allocator_template % {
                "fault_type": self.fault,
                "token": "std::string(\"%s\")" % self.message,
                "message": "\"%s\"" % self.message
            }

            args = ["machInst", "\"%s\"" % self.name, "macrocodeBlock",
                self.microFlagsText(microFlags), fault_allocator]

            if self.flags:
                args.append(" | ".join(self.flags))

            return "new " + self.className + "(" + ", ".join(args) + ")"

    def buildDebugMicro(name, with_once=False):
        global microopClasses

        fault_class = "GenericISA::M5" + name.capitalize() + "Fault"

        class MicroDebugChild(MicroDebug):
            def __init__(self, message, flags=None):
                super(MicroDebugChild, self).__init__(
                        name, fault_class, message, False, flags)

        microopClasses[name] = MicroDebugChild

        if with_once:
            fault_once_class = \
                "GenericISA::M5" + name.capitalize() + "OnceFault"
            name_once = name + "_once"

            class MicroDebugOnceChild(MicroDebug):
                def __init__(self, message, flags=None):
                    super(MicroDebugOnceChild, self).__init__(
                            name_once, fault_once_class, message, True, flags)

            microopClasses[name_once] = MicroDebugOnceChild

    buildDebugMicro("panic")
    buildDebugMicro("fatal")
    buildDebugMicro("hack", True)
    buildDebugMicro("inform", True)
    buildDebugMicro("warn", True)
}};
