// 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

////////////////////////////////////////////////////////////////////
//
// Base class for sparc instructions, and some support functions
//

output header {{

        union CondCodes
        {
            struct
            {
                uint8_t c:1;
                uint8_t v:1;
                uint8_t z:1;
                uint8_t n:1;
            };
            uint32_t bits;
        };

        enum CondTest
        {
            Always=0x8,
            Never=0x0,
            NotEqual=0x9,
            Equal=0x1,
            Greater=0xA,
            LessOrEqual=0x2,
            GreaterOrEqual=0xB,
            Less=0x3,
            GreaterUnsigned=0xC,
            LessOrEqualUnsigned=0x4,
            CarryClear=0xD,
            CarrySet=0x5,
            Positive=0xE,
            Negative=0x6,
            OverflowClear=0xF,
            OverflowSet=0x7
        };

        enum FpCondTest
        {
            FAlways=0x8,
            FNever=0x0,
            FUnordered=0x7,
            FGreater=0x6,
            FUnorderedOrGreater=0x5,
            FLess=0x4,
            FUnorderedOrLess=0x3,
            FLessOrGreater=0x2,
            FNotEqual=0x1,
            FEqual=0x9,
            FUnorderedOrEqual=0xA,
            FGreaterOrEqual=0xB,
            FUnorderedOrGreaterOrEqual=0xC,
            FLessOrEqual=0xD,
            FUnorderedOrLessOrEqual=0xE,
            FOrdered=0xF
        };

        extern const char *CondTestAbbrev[];

        /**
         * Base class for all SPARC static instructions.
         */
        class SparcStaticInst : public StaticInst
        {
          protected:
            // Constructor.
            SparcStaticInst(const char *mnem,
                 ExtMachInst _machInst, OpClass __opClass)
                    : StaticInst(mnem, _machInst, __opClass)
                {
                }

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

            void printReg(std::ostream &os, RegId reg) const;
            void printSrcReg(std::ostream &os, int reg) const;
            void printDestReg(std::ostream &os, int reg) const;

            void printRegArray(std::ostream &os,
                const RegId indexArray[], int num) const;

            void advancePC(SparcISA::PCState &pcState) const;
        };

        bool passesFpCondition(uint32_t fcc, uint32_t condition);

        bool passesCondition(uint32_t codes, uint32_t condition);

        inline int64_t
        sign_ext(uint64_t data, int origWidth)
        {
            int shiftAmount = 64 - origWidth;
            return (((int64_t)data) << shiftAmount) >> shiftAmount;
        }
}};

output decoder {{

        const char *CondTestAbbrev[] =
        {
            "nev", // Never
            "e", // Equal
            "le", // Less or Equal
            "l", // Less
            "leu", // Less or Equal Unsigned
            "c", // Carry set
            "n", // Negative
            "o", // Overflow set
            "a", // Always
            "ne", // Not Equal
            "g", // Greater
            "ge", // Greater or Equal
            "gu", // Greater Unsigned
            "cc", // Carry clear
            "p", // Positive
            "oc" // Overflow Clear
        };
}};

def template ROrImmDecode {{
    {
        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
    }
}};

output header {{
    union DoubleSingle
    {
        double d;
        uint64_t ui;
        uint32_t s[2];
        DoubleSingle(double _d) : d(_d)
        {}
        DoubleSingle(uint64_t _ui) : ui(_ui)
        {}
        DoubleSingle(uint32_t _s0, uint32_t _s1)
        {
            s[0] = _s0;
            s[1] = _s1;
        }
    };
}};

let {{
    def filterDoubles(code):
        assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
        for opName in ("Frd", "Frs1", "Frs2", "Frd_N"):
            next_pos = 0
            operandsREString = (r'''
            (?<!\w)             # neg. lookbehind assertion: prevent partial matches
            ((%s)(?:_([^\W_]+))?)   # match: operand with optional '.' then suffix
            (?!\w)             # neg. lookahead assertion: prevent partial matches
            ''' % opName)
            operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
            is_src = False
            is_dest = False
            extension = None
            foundOne = False
            while 1:
                match = operandsRE.search(code, next_pos)
                if not match:
                    break
                foundOne = True
                op = match.groups()
                (op_full, op_base, op_ext) = op
                is_dest_local = (assignRE.match(code, match.end()) != None)
                is_dest = is_dest or is_dest_local
                is_src = is_src or not is_dest_local
                if extension and extension != op_ext:
                    raise Exception, "Inconsistent extensions in double filter."
                extension = op_ext
                next_pos = match.end()
            if foundOne:
                # Get rid of any unwanted extension
                code = operandsRE.sub(op_base, code)
                is_int = False
                member = "d"
                if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
                    is_int = True
                    member = "ui"
                if is_src:
                    code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
                        (opName, opName, opName, member)) + code
                if is_dest:
                    code += '''
                        %s_low = DoubleSingle(%s).s[1];
                        %s_high = DoubleSingle(%s).s[0];''' % \
                             (opName, opName, opName, opName)
                if is_int:
                    code = ("uint64_t %s;" % opName) + code
                else:
                    code = ("double %s;" % opName) + code
        return code
}};

let {{
    def splitOutImm(code):
        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?')
        rOrImmMatch = matcher.search(code)
        if (rOrImmMatch == None):
            return (False, code, '', '', '')
        rString = rOrImmMatch.group("rNum")
        if (rOrImmMatch.group("typeQual") != None):
            rString += rOrImmMatch.group("typeQual")
        iString = rOrImmMatch.group("iNum")
        orig_code = code
        code = matcher.sub('Rs' + rString, orig_code)
        imm_code = matcher.sub('imm', orig_code)
        return (True, code, imm_code, rString, iString)
}};

output decoder {{

        inline void printMnemonic(std::ostream &os, const char * mnemonic)
        {
            ccprintf(os, "\t%s   ", mnemonic);
        }

        void SparcStaticInst::printRegArray(std::ostream &os,
            const RegId indexArray[], int num) const
        {
            if (num <= 0)
                return;
            printReg(os, indexArray[0]);
            for (int x = 1; x < num; x++) {
                os << ", ";
                printReg(os, indexArray[x]);
            }
        }

        void
        SparcStaticInst::advancePC(SparcISA::PCState &pcState) const
        {
            pcState.advance();
        }

        void
        SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
        {
            if (_numSrcRegs > reg)
                printReg(os, _srcRegIdx[reg]);
        }

        void
        SparcStaticInst::printDestReg(std::ostream &os, int reg) const
        {
            if (_numDestRegs > reg)
                printReg(os, _destRegIdx[reg]);
        }

        void
        SparcStaticInst::printReg(std::ostream &os, RegId reg) const
        {
            const int MaxGlobal = 8;
            const int MaxOutput = 16;
            const int MaxLocal = 24;
            const int MaxInput = 32;
            const int MaxMicroReg = 40;
            RegIndex reg_idx = reg.index();
            if (reg.isIntReg()) {
                // If we used a register from the next or previous window,
                // take out the offset.
                while (reg_idx >= MaxMicroReg)
                    reg_idx -= MaxMicroReg;
                if (reg_idx == FramePointerReg)
                    ccprintf(os, "%%fp");
                else if (reg_idx == StackPointerReg)
                    ccprintf(os, "%%sp");
                else if (reg_idx < MaxGlobal)
                    ccprintf(os, "%%g%d", reg_idx);
                else if (reg_idx < MaxOutput)
                    ccprintf(os, "%%o%d", reg_idx - MaxGlobal);
                else if (reg_idx < MaxLocal)
                    ccprintf(os, "%%l%d", reg_idx - MaxOutput);
                else if (reg_idx < MaxInput)
                    ccprintf(os, "%%i%d", reg_idx - MaxLocal);
                else if (reg_idx < MaxMicroReg)
                    ccprintf(os, "%%u%d", reg_idx - MaxInput);
                // The fake int regs that are really control regs
                else {
                    switch (reg_idx - MaxMicroReg) {
                      case 1:
                        ccprintf(os, "%%y");
                        break;
                      case 2:
                        ccprintf(os, "%%ccr");
                        break;
                      case 3:
                        ccprintf(os, "%%cansave");
                        break;
                      case 4:
                        ccprintf(os, "%%canrestore");
                        break;
                      case 5:
                        ccprintf(os, "%%cleanwin");
                        break;
                      case 6:
                        ccprintf(os, "%%otherwin");
                        break;
                      case 7:
                        ccprintf(os, "%%wstate");
                        break;
                    }
                }
            } else if (reg.isFloatReg()) {
                ccprintf(os, "%%f%d", reg_idx);
            } else {
                switch (reg_idx) {
                  case MISCREG_ASI:
                    ccprintf(os, "%%asi");
                    break;
                  case MISCREG_FPRS:
                    ccprintf(os, "%%fprs");
                    break;
                  case MISCREG_PCR:
                    ccprintf(os, "%%pcr");
                    break;
                  case MISCREG_PIC:
                    ccprintf(os, "%%pic");
                    break;
                  case MISCREG_GSR:
                    ccprintf(os, "%%gsr");
                    break;
                  case MISCREG_SOFTINT:
                    ccprintf(os, "%%softint");
                    break;
                  case MISCREG_SOFTINT_SET:
                    ccprintf(os, "%%softint_set");
                    break;
                  case MISCREG_SOFTINT_CLR:
                    ccprintf(os, "%%softint_clr");
                    break;
                  case MISCREG_TICK_CMPR:
                    ccprintf(os, "%%tick_cmpr");
                    break;
                  case MISCREG_STICK:
                    ccprintf(os, "%%stick");
                    break;
                  case MISCREG_STICK_CMPR:
                    ccprintf(os, "%%stick_cmpr");
                    break;
                  case MISCREG_TPC:
                    ccprintf(os, "%%tpc");
                    break;
                  case MISCREG_TNPC:
                    ccprintf(os, "%%tnpc");
                    break;
                  case MISCREG_TSTATE:
                    ccprintf(os, "%%tstate");
                    break;
                  case MISCREG_TT:
                    ccprintf(os, "%%tt");
                    break;
                  case MISCREG_TICK:
                    ccprintf(os, "%%tick");
                    break;
                  case MISCREG_TBA:
                    ccprintf(os, "%%tba");
                    break;
                  case MISCREG_PSTATE:
                    ccprintf(os, "%%pstate");
                    break;
                  case MISCREG_TL:
                    ccprintf(os, "%%tl");
                    break;
                  case MISCREG_PIL:
                    ccprintf(os, "%%pil");
                    break;
                  case MISCREG_CWP:
                    ccprintf(os, "%%cwp");
                    break;
                  case MISCREG_GL:
                    ccprintf(os, "%%gl");
                    break;
                  case MISCREG_HPSTATE:
                    ccprintf(os, "%%hpstate");
                    break;
                  case MISCREG_HTSTATE:
                    ccprintf(os, "%%htstate");
                    break;
                  case MISCREG_HINTP:
                    ccprintf(os, "%%hintp");
                    break;
                  case MISCREG_HTBA:
                    ccprintf(os, "%%htba");
                    break;
                  case MISCREG_HSTICK_CMPR:
                    ccprintf(os, "%%hstick_cmpr");
                    break;
                  case MISCREG_HVER:
                    ccprintf(os, "%%hver");
                    break;
                  case MISCREG_STRAND_STS_REG:
                    ccprintf(os, "%%strand_sts_reg");
                    break;
                  case MISCREG_FSR:
                    ccprintf(os, "%%fsr");
                    break;
                  default:
                    ccprintf(os, "%%ctrl%d", reg_idx);
                }
            }
        }

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

            printMnemonic(ss, mnemonic);

            // just print the first two source regs... if there's
            // a third one, it's a read-modify-write dest (Rc),
            // e.g. for CMOVxx
            if (_numSrcRegs > 0)
                printReg(ss, _srcRegIdx[0]);
            if (_numSrcRegs > 1) {
                ss << ",";
                printReg(ss, _srcRegIdx[1]);
            }

            // just print the first dest... if there's a second one,
            // it's generally implicit
            if (_numDestRegs > 0) {
                if (_numSrcRegs > 0)
                    ss << ",";
                printReg(ss, _destRegIdx[0]);
            }

            return ss.str();
        }

        bool
        passesFpCondition(uint32_t fcc, uint32_t condition)
        {
            bool u = (fcc == 3);
            bool g = (fcc == 2);
            bool l = (fcc == 1);
            bool e = (fcc == 0);
            switch (condition) {
              case FAlways:
                return 1;
              case FNever:
                return 0;
              case FUnordered:
                return u;
              case FGreater:
                return g;
              case FUnorderedOrGreater:
                return u || g;
              case FLess:
                return l;
              case FUnorderedOrLess:
                return u || l;
              case FLessOrGreater:
                return l || g;
              case FNotEqual:
                return l || g || u;
              case FEqual:
                return e;
              case FUnorderedOrEqual:
                return u || e;
              case FGreaterOrEqual:
                return g || e;
              case FUnorderedOrGreaterOrEqual:
                return u || g || e;
              case FLessOrEqual:
                return l || e;
              case FUnorderedOrLessOrEqual:
                return u || l || e;
              case FOrdered:
                return e || l || g;
            }
            panic("Tried testing condition nonexistant "
                    "condition code %d", condition);
        }

        bool
        passesCondition(uint32_t codes, uint32_t condition)
        {
            CondCodes condCodes;
            condCodes.bits =  0;
            condCodes.c = codes & 0x1 ? 1 : 0;
            condCodes.v = codes & 0x2 ? 1 : 0;
            condCodes.z = codes & 0x4 ? 1 : 0;
            condCodes.n = codes & 0x8 ? 1 : 0;

            switch (condition) {
              case Always:
                return true;
              case Never:
                return false;
              case NotEqual:
                return !condCodes.z;
              case Equal:
                return condCodes.z;
              case Greater:
                return !(condCodes.z | (condCodes.n ^ condCodes.v));
              case LessOrEqual:
                return condCodes.z | (condCodes.n ^ condCodes.v);
              case GreaterOrEqual:
                return !(condCodes.n ^ condCodes.v);
              case Less:
                return (condCodes.n ^ condCodes.v);
              case GreaterUnsigned:
                return !(condCodes.c | condCodes.z);
              case LessOrEqualUnsigned:
                return (condCodes.c | condCodes.z);
              case CarryClear:
                return !condCodes.c;
              case CarrySet:
                return condCodes.c;
              case Positive:
                return !condCodes.n;
              case Negative:
                return condCodes.n;
              case OverflowClear:
                return !condCodes.v;
              case OverflowSet:
                return condCodes.v;
            }
            panic("Tried testing condition nonexistant "
                    "condition code %d", condition);
        }
}};

output exec {{
    /// Check "FP enabled" machine status bit.  Called when executing any FP
    /// instruction.
    /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
    /// if not.  Non-full-system mode: always returns NoFault.
    static inline Fault
    checkFpEnableFault(CPU_EXEC_CONTEXT *xc)
    {
        if (FullSystem) {
            PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE);
            if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) {
                return NoFault;
            } else {
                return std::make_shared<FpDisabled>();
            }
        } else {
            return NoFault;
        }
    }
    static inline Fault
    checkVecEnableFault(CPU_EXEC_CONTEXT *xc)
    {
        return std::make_shared<VecDisabled>();
    }
}};


