// Copyright (c) 2007 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

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

def template MicroLimmOpExecute {{
        Fault %(class_name)s::execute(ExecContext *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;

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

      public:
        %(class_name)s(ExtMachInst _machInst,
                const char * instMnem,
                uint64_t setFlags, InstRegIndex _dest,
                uint64_t _imm, uint8_t _dataSize);

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

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 {{
    %(class_name)s::%(class_name)s(
            ExtMachInst machInst, const char * instMnem, uint64_t setFlags,
            InstRegIndex _dest, uint64_t _imm, uint8_t _dataSize) :
        %(base_class)s(machInst, "%(mnemonic)s", instMnem,
                setFlags, %(op_class)s),
                dest(_dest.index()), imm(_imm), dataSize(_dataSize)
    {
        foldOBit = (dataSize == 1 && !machInst.rex.present) ? 1 << 6 : 0;
        %(constructor)s;
    }
}};

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):
            allocString = '''
                (%(dataSize)s >= 4) ?
                    (StaticInstPtr)(new %(class_name)sBig(machInst,
                        macrocodeBlock, %(flags)s, %(dest)s, %(imm)s,
                        %(dataSize)s)) :
                    (StaticInstPtr)(new %(class_name)s(machInst,
                        macrocodeBlock, %(flags)s, %(dest)s, %(imm)s,
                        %(dataSize)s))
            '''
            allocator = allocString % {
                "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

    class LfpimmOp(X86Microop):
        def __init__(self, dest, imm, dataSize="env.dataSize"):
            self.className = "Lfpimm"
            self.mnemonic = "lfpimm"
            self.dest = dest
            if isinstance(imm, (int, long)):
                imm = "ULL(%d)" % imm
            elif isinstance(imm, float):
                imm = "getDoubleBits(%.16f)" % imm
            self.imm = imm
            self.dataSize = dataSize

        def getAllocator(self, microFlags):
            allocator = '''new %(class_name)s(machInst, macrocodeBlock,
                    %(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["lfpimm"] = LfpimmOp
}};

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

    iop = InstObjParams("lfpimm", "Lfpimm", 'X86MicroopBase',
            {"code" : "FpDestReg_uqw = imm"})
    header_output += MicroLimmOpDeclare.subst(iop)
    decoder_output += MicroLimmOpConstructor.subst(iop)
    decoder_output += MicroLimmOpDisassembly.subst(iop)
    exec_output += MicroLimmOpExecute.subst(iop)
}};
