// Copyright (c) 2007 The Hewlett-Packard Development Company
// All rights reserved.
//
// Redistribution and use of this software in source and binary forms,
// with or without modification, are permitted provided that the
// following conditions are met:
//
// The software must be used only for Non-Commercial Use which means any
// use which is NOT directed to receiving any direct monetary
// compensation for, or commercial advantage from such use.  Illustrative
// examples of non-commercial use are academic research, personal study,
// teaching, education and corporate research & development.
// Illustrative examples of commercial use are distributing products for
// commercial advantage and providing services using the software for
// commercial advantage.
//
// If you wish to use this software or functionality therein that may be
// covered by patents for commercial use, please contact:
//     Director of Intellectual Property Licensing
//     Office of Strategy and Technology
//     Hewlett-Packard Company
//     1501 Page Mill Road
//     Palo Alto, California  94304
//
// 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 HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.  No right of
// sublicense is granted herewith.  Derivatives of the software and
// output created using the software may be prepared, but only for
// Non-Commercial Uses.  Derivatives of the software may be shared with
// others provided: (i) the others agree to abide by the list of
// conditions herein which includes the Non-Commercial Use restrictions;
// and (ii) such Derivatives of the software include the above copyright
// notice to acknowledge the contribution from this software where
// applicable, this list of conditions and the disclaimer below.
//
// 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

//////////////////////////////////////////////////////////////////////////
//
// LIMMOp Microop templates
//
//////////////////////////////////////////////////////////////////////////

def template MicroLimmOpExecute {{
        Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
                Trace::InstRecord *traceData) const
        {
            %(op_decl)s;
            %(op_rd)s;
            %(code)s;
            %(op_wb)s;
            return NoFault;
        }
}};

def template MicroLimmOpDeclare {{
    class %(class_name)s : public X86ISA::X86MicroopBase
    {
      protected:
        const RegIndex dest;
        const uint64_t imm;
        const uint8_t dataSize;
        RegIndex foldOBit;
        void buildMe();

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

      public:
        %(class_name)s(ExtMachInst _machInst,
                const char * instMnem,
                bool isMicro, bool isDelayed, bool isFirst, bool isLast,
                RegIndex _dest, uint64_t _imm, uint8_t _dataSize);

        %(class_name)s(ExtMachInst _machInst,
                const char * instMnem,
                RegIndex _dest, uint64_t _imm, uint8_t _dataSize);

        %(BasicExecDeclare)s
    };
}};

def template MicroLimmOpDisassembly {{
    std::string %(class_name)s::generateDisassembly(Addr pc,
            const SymbolTable *symtab) const
    {
        std::stringstream response;

        printMnemonic(response, instMnem, mnemonic);
        printDestReg(response, 0, dataSize);
        response << ", ";
        ccprintf(response, "%#x", imm);
        return response.str();
    }
}};

def template MicroLimmOpConstructor {{

    inline void %(class_name)s::buildMe()
    {
        foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0;
        %(constructor)s;
    }

    inline %(class_name)s::%(class_name)s(
            ExtMachInst machInst, const char * instMnem,
            RegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
                false, false, false, false, %(op_class)s),
                dest(_dest), imm(_imm), dataSize(_dataSize)
    {
        buildMe();
    }

    inline %(class_name)s::%(class_name)s(
            ExtMachInst machInst, const char * instMnem,
            bool isMicro, bool isDelayed, bool isFirst, bool isLast,
            RegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
                isMicro, isDelayed, isFirst, isLast, %(op_class)s),
                dest(_dest), imm(_imm), dataSize(_dataSize)
    {
        buildMe();
    }
}};

let {{
    class LimmOp(X86Microop):
        def __init__(self, dest, imm, dataSize="env.dataSize"):
            self.className = "Limm"
            self.mnemonic = "limm"
            self.dest = dest
            if isinstance(imm, (int, long)):
                imm = "ULL(%d)" % imm
            self.imm = imm
            self.dataSize = dataSize

        def getAllocator(self, *microFlags):
            allocator = '''new %(class_name)s(machInst, mnemonic
                    %(flags)s, %(dest)s, %(imm)s, %(dataSize)s)''' % {
                "class_name" : self.className,
                "mnemonic" : self.mnemonic,
                "flags" : self.microFlagsText(microFlags),
                "dest" : self.dest, "imm" : self.imm,
                "dataSize" : self.dataSize}
            return allocator

    microopClasses["limm"] = LimmOp
}};

let {{
    # Build up the all register version of this micro op
    iop = InstObjParams("limm", "Limm", 'X86MicroopBase',
            {"code" : "DestReg = merge(DestReg, imm, dataSize);"})
    header_output += MicroLimmOpDeclare.subst(iop)
    decoder_output += MicroLimmOpConstructor.subst(iop)
    decoder_output += MicroLimmOpDisassembly.subst(iop)
    exec_output += MicroLimmOpExecute.subst(iop)
}};
