// Copyright (c) 2006-2007 The Regents of The University of Michigan
// All rights reserved.
//
// 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: Ali Saidi
//          Gabe Black
//          Steve Reinhardt

////////////////////////////////////////////////////////////////////
//
// Integer operate instructions
//

output header {{
        /**
         * Base class for integer operations.
         */
        class IntOp : public SparcStaticInst
        {
          protected:
            // Constructor
            IntOp(const char *mnem, ExtMachInst _machInst,
                    OpClass __opClass) :
                SparcStaticInst(mnem, _machInst, __opClass)
            {
            }

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

            virtual bool printPseudoOps(std::ostream &os, Addr pc,
                    const SymbolTable *symtab) const;
        };

        /**
         * Base class for immediate integer operations.
         */
        class IntOpImm : public IntOp
        {
          protected:
            // Constructor
            IntOpImm(const char *mnem, ExtMachInst _machInst,
                    OpClass __opClass) :
                IntOp(mnem, _machInst, __opClass)
            {
            }

            int64_t imm;

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

            virtual bool printPseudoOps(std::ostream &os, Addr pc,
                    const SymbolTable *symtab) const;
        };

        /**
         * Base class for 10 bit immediate integer operations.
         */
        class IntOpImm10 : public IntOpImm
        {
          protected:
            // Constructor
            IntOpImm10(const char *mnem, ExtMachInst _machInst,
                    OpClass __opClass) :
                IntOpImm(mnem, _machInst, __opClass)
            {
                imm = sext<10>(SIMM10);
            }
        };

        /**
         * Base class for 11 bit immediate integer operations.
         */
        class IntOpImm11 : public IntOpImm
        {
          protected:
            // Constructor
            IntOpImm11(const char *mnem, ExtMachInst _machInst,
                    OpClass __opClass) :
                IntOpImm(mnem, _machInst, __opClass)
            {
                imm = sext<11>(SIMM11);
            }
        };

        /**
         * Base class for 13 bit immediate integer operations.
         */
        class IntOpImm13 : public IntOpImm
        {
          protected:
            // Constructor
            IntOpImm13(const char *mnem, ExtMachInst _machInst,
                    OpClass __opClass) :
                IntOpImm(mnem, _machInst, __opClass)
            {
                imm = sext<13>(SIMM13);
            }
        };

        /**
         * Base class for sethi.
         */
        class SetHi : public IntOpImm
        {
          protected:
            // Constructor
            SetHi(const char *mnem, ExtMachInst _machInst,
                    OpClass __opClass) :
                IntOpImm(mnem, _machInst, __opClass)
            {
                imm = (IMM22 & 0x3FFFFF) << 10;
            }

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

def template SetHiDecode {{
    {
        if (RD == 0 && IMM22 == 0)
            return (SparcStaticInst *)(new Nop("nop", machInst, No_OpClass));
        else
            return (SparcStaticInst *)(new %(class_name)s(machInst));
    }
}};

output decoder {{

        bool
        IntOp::printPseudoOps(std::ostream &os, Addr pc,
                const SymbolTable *symbab) const
        {
            if (!std::strcmp(mnemonic, "or") && _srcRegIdx[0] == 0) {
                printMnemonic(os, "mov");
                printSrcReg(os, 1);
                ccprintf(os, ", ");
                printDestReg(os, 0);
                return true;
            }
            return false;
        }

        bool
        IntOpImm::printPseudoOps(std::ostream &os, Addr pc,
                const SymbolTable *symbab) const
        {
            if (!std::strcmp(mnemonic, "or")) {
                if (_numSrcRegs > 0 && _srcRegIdx[0] == 0) {
                    if (imm == 0) {
                        printMnemonic(os, "clr");
                    } else {
                        printMnemonic(os, "mov");
                        ccprintf(os, " 0x%x, ", imm);
                    }
                    printDestReg(os, 0);
                    return true;
                } else if (imm == 0) {
                    printMnemonic(os, "mov");
                    printSrcReg(os, 0);
                    ccprintf(os, ", ");
                    printDestReg(os, 0);
                    return true;
                }
            }
            return false;
        }

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

            if (printPseudoOps(response, pc, symtab))
                return response.str();
            printMnemonic(response, mnemonic);
            printRegArray(response, _srcRegIdx, _numSrcRegs);
            if (_numDestRegs && _numSrcRegs)
                response << ", ";
            printDestReg(response, 0);
            return response.str();
        }

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

            if (printPseudoOps(response, pc, symtab))
                return response.str();
            printMnemonic(response, mnemonic);
            printRegArray(response, _srcRegIdx, _numSrcRegs);
            if (_numSrcRegs > 0)
                response << ", ";
            ccprintf(response, "0x%x", imm);
            if (_numDestRegs > 0)
                response << ", ";
            printDestReg(response, 0);
            return response.str();
        }

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

            printMnemonic(response, mnemonic);
            ccprintf(response, "%%hi(0x%x), ", imm);
            printDestReg(response, 0);
            return response.str();
        }
}};

def template IntOpExecute {{
        Fault %(class_name)s::execute(CPU_EXEC_CONTEXT *xc,
                Trace::InstRecord *traceData) const
        {
            Fault fault = NoFault;

            %(op_decl)s;
            %(op_rd)s;
            %(code)s;

            // Write the resulting state to the execution context
            if (fault == NoFault) {
                %(cc_code)s;
                %(op_wb)s;
            }
            return fault;
        }
}};

let {{
    def doIntFormat(code, ccCode, name, Name, opt_flags):
        (usesImm, code, immCode,
         rString, iString) = splitOutImm(code)
        iop = InstObjParams(name, Name, 'IntOp',
                {"code": code, "cc_code": ccCode},
                opt_flags)
        header_output = BasicDeclare.subst(iop)
        decoder_output = BasicConstructor.subst(iop)
        exec_output = IntOpExecute.subst(iop)
        if usesImm:
            imm_iop = InstObjParams(name, Name + 'Imm', 'IntOpImm' + iString,
                    {"code": immCode, "cc_code": ccCode}, opt_flags)
            header_output += BasicDeclare.subst(imm_iop)
            decoder_output += BasicConstructor.subst(imm_iop)
            exec_output += IntOpExecute.subst(imm_iop)
            decode_block = ROrImmDecode.subst(iop)
        else:
            decode_block = BasicDecode.subst(iop)
        return (header_output, decoder_output, exec_output, decode_block)

    calcCcCode = '''
        uint16_t _ic, _iv, _iz, _in, _xc, _xv, _xz, _xn;

        _in = (Rd >> 31) & 1;
        _iz = ((Rd & 0xFFFFFFFF) == 0);
        _xn = (Rd >> 63) & 1;
        _xz = (Rd == 0);
        _iv = %(iv)s & 1;
        _ic = %(ic)s & 1;
        _xv = %(xv)s & 1;
        _xc = %(xc)s & 1;

        Ccr =  _ic << 0 | _iv << 1 | _iz << 2 | _in << 3 |
               _xc << 4 | _xv << 5 | _xz << 6 | _xn << 7;


        DPRINTF(Sparc, "in = %%d\\n", _in);
        DPRINTF(Sparc, "iz = %%d\\n", _iz);
        DPRINTF(Sparc, "xn = %%d\\n", _xn);
        DPRINTF(Sparc, "xz = %%d\\n", _xz);
        DPRINTF(Sparc, "iv = %%d\\n", _iv);
        DPRINTF(Sparc, "ic = %%d\\n", _ic);
        DPRINTF(Sparc, "xv = %%d\\n", _xv);
        DPRINTF(Sparc, "xc = %%d\\n", _xc);
        '''

    default_ic = "findCarry(32, res, op1, op2)"
    default_iv = "findOverflow(32, res, op1, op2)"
    default_xc = "findCarry(64, res, op1, op2)"
    default_xv = "findOverflow(64, res, op1, op2)"
    default_sub_ic = "!findCarry(32, res, op1, ~op2)"
    default_sub_iv = "findOverflow(32, res, op1, ~op2)"
    default_sub_xc = "!findCarry(64, res, op1, ~op2)"
    default_sub_xv = "findOverflow(64, res, op1, ~op2)"
}};

// Primary format for integer operate instructions:
def format IntOp(code, *opt_flags) {{
    ccCode = ''
    (header_output,
     decoder_output,
     exec_output,
     decode_block) = doIntFormat(code, ccCode,
                                 name, Name, opt_flags)
}};

// Primary format for integer operate instructions:
def format IntOpCc(code, ic=default_ic, iv=default_iv,
                         xc=default_xc, xv=default_xv,
                         sub=False, *opt_flags) {{

    if sub == "False":
        (def_ic, def_iv, def_xc, def_xv) = \
            (default_ic, default_iv, default_xc, default_xv)
    else:
        (def_ic, def_iv, def_xc, def_xv) = \
            (default_sub_ic, default_sub_iv, default_sub_xc, default_sub_xv)
    if ic == "default_ic":
        ic = def_ic
    if iv == "default_iv":
        iv = def_iv
    if xc == "default_xc":
        xc = def_xc
    if xv == "default_xv":
        xv = def_xv
    ccCode = calcCcCode % vars()
    (header_output,
     decoder_output,
     exec_output,
     decode_block) = doIntFormat(code, ccCode,
                                 name, Name, opt_flags)
}};

// Primary format for integer operate instructions:
def format IntOpCcRes(code, ic=0, iv=0, xc=0, xv=0, *opt_flags) {{
    ccCode = calcCcCode % {"ic" : ic, "iv" : iv, "xc" : xc, "xv" : xv}
    (header_output,
     decoder_output,
     exec_output,
     decode_block) = doIntFormat(code, ccCode,
                                 name, Name, opt_flags)
}};

def format SetHi(code, *opt_flags) {{
    iop = InstObjParams(name, Name, 'SetHi',
            {"code": code, "cc_code": ''}, opt_flags)
    header_output = BasicDeclare.subst(iop)
    decoder_output = BasicConstructor.subst(iop)
    exec_output = IntOpExecute.subst(iop)
    decode_block = SetHiDecode.subst(iop)
}};

