base.isa revision 9918
13931Ssaidi@eecs.umich.edu// Copyright (c) 2006-2007 The Regents of The University of Michigan
22632Sstever@eecs.umich.edu// All rights reserved.
32632Sstever@eecs.umich.edu//
42632Sstever@eecs.umich.edu// Redistribution and use in source and binary forms, with or without
52632Sstever@eecs.umich.edu// modification, are permitted provided that the following conditions are
62632Sstever@eecs.umich.edu// met: redistributions of source code must retain the above copyright
72632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer;
82632Sstever@eecs.umich.edu// redistributions in binary form must reproduce the above copyright
92632Sstever@eecs.umich.edu// notice, this list of conditions and the following disclaimer in the
102632Sstever@eecs.umich.edu// documentation and/or other materials provided with the distribution;
112632Sstever@eecs.umich.edu// neither the name of the copyright holders nor the names of its
122632Sstever@eecs.umich.edu// contributors may be used to endorse or promote products derived from
132632Sstever@eecs.umich.edu// this software without specific prior written permission.
142632Sstever@eecs.umich.edu//
152632Sstever@eecs.umich.edu// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162632Sstever@eecs.umich.edu// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172632Sstever@eecs.umich.edu// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182632Sstever@eecs.umich.edu// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
192632Sstever@eecs.umich.edu// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
202632Sstever@eecs.umich.edu// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
212632Sstever@eecs.umich.edu// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
222632Sstever@eecs.umich.edu// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
232632Sstever@eecs.umich.edu// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
242632Sstever@eecs.umich.edu// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
252632Sstever@eecs.umich.edu// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262632Sstever@eecs.umich.edu//
272632Sstever@eecs.umich.edu// Authors: Ali Saidi
282632Sstever@eecs.umich.edu//          Gabe Black
292632Sstever@eecs.umich.edu//          Steve Reinhardt
302632Sstever@eecs.umich.edu
312030SN/A////////////////////////////////////////////////////////////////////
322030SN/A//
332030SN/A// Base class for sparc instructions, and some support functions
342030SN/A//
352030SN/A
362030SN/Aoutput header {{
372224SN/A
382482SN/A        union CondCodes
392224SN/A        {
402482SN/A            struct
412482SN/A            {
422482SN/A                uint8_t c:1;
432482SN/A                uint8_t v:1;
442482SN/A                uint8_t z:1;
452482SN/A                uint8_t n:1;
462482SN/A            };
472482SN/A            uint32_t bits;
482458SN/A        };
492224SN/A
502482SN/A        enum CondTest
512224SN/A        {
522224SN/A            Always=0x8,
532224SN/A            Never=0x0,
542224SN/A            NotEqual=0x9,
552224SN/A            Equal=0x1,
562224SN/A            Greater=0xA,
572224SN/A            LessOrEqual=0x2,
582224SN/A            GreaterOrEqual=0xB,
592224SN/A            Less=0x3,
602224SN/A            GreaterUnsigned=0xC,
612224SN/A            LessOrEqualUnsigned=0x4,
622224SN/A            CarryClear=0xD,
632224SN/A            CarrySet=0x5,
642224SN/A            Positive=0xE,
652224SN/A            Negative=0x6,
662224SN/A            OverflowClear=0xF,
672224SN/A            OverflowSet=0x7
682458SN/A        };
692224SN/A
704004Sgblack@eecs.umich.edu        enum FpCondTest
714004Sgblack@eecs.umich.edu        {
724004Sgblack@eecs.umich.edu            FAlways=0x8,
734004Sgblack@eecs.umich.edu            FNever=0x0,
744004Sgblack@eecs.umich.edu            FUnordered=0x7,
754004Sgblack@eecs.umich.edu            FGreater=0x6,
764004Sgblack@eecs.umich.edu            FUnorderedOrGreater=0x5,
774004Sgblack@eecs.umich.edu            FLess=0x4,
784004Sgblack@eecs.umich.edu            FUnorderedOrLess=0x3,
794004Sgblack@eecs.umich.edu            FLessOrGreater=0x2,
804004Sgblack@eecs.umich.edu            FNotEqual=0x1,
814004Sgblack@eecs.umich.edu            FEqual=0x9,
824004Sgblack@eecs.umich.edu            FUnorderedOrEqual=0xA,
834004Sgblack@eecs.umich.edu            FGreaterOrEqual=0xB,
844004Sgblack@eecs.umich.edu            FUnorderedOrGreaterOrEqual=0xC,
854004Sgblack@eecs.umich.edu            FLessOrEqual=0xD,
864004Sgblack@eecs.umich.edu            FUnorderedOrLessOrEqual=0xE,
874004Sgblack@eecs.umich.edu            FOrdered=0xF
884004Sgblack@eecs.umich.edu        };
894004Sgblack@eecs.umich.edu
905202Sstever@gmail.com        extern const char *CondTestAbbrev[];
912561SN/A
922030SN/A        /**
932030SN/A         * Base class for all SPARC static instructions.
942030SN/A         */
952224SN/A        class SparcStaticInst : public StaticInst
962030SN/A        {
972224SN/A          protected:
982224SN/A            // Constructor.
992224SN/A            SparcStaticInst(const char *mnem,
1003278Sgblack@eecs.umich.edu                 ExtMachInst _machInst, OpClass __opClass)
1012224SN/A                    : StaticInst(mnem, _machInst, __opClass)
1022030SN/A                {
1032030SN/A                }
1042030SN/A
1052224SN/A            std::string generateDisassembly(Addr pc,
1062224SN/A                const SymbolTable *symtab) const;
1072469SN/A
1082951Sgblack@eecs.umich.edu            void printReg(std::ostream &os, int reg) const;
1092944Sgblack@eecs.umich.edu            void printSrcReg(std::ostream &os, int reg) const;
1102944Sgblack@eecs.umich.edu            void printDestReg(std::ostream &os, int reg) const;
1112944Sgblack@eecs.umich.edu
1122944Sgblack@eecs.umich.edu            void printRegArray(std::ostream &os,
1132944Sgblack@eecs.umich.edu                const RegIndex indexArray[], int num) const;
1147720Sgblack@eecs.umich.edu
1157720Sgblack@eecs.umich.edu            void advancePC(SparcISA::PCState &pcState) const;
1162030SN/A        };
1172030SN/A
1184004Sgblack@eecs.umich.edu        bool passesFpCondition(uint32_t fcc, uint32_t condition);
1194004Sgblack@eecs.umich.edu
1202482SN/A        bool passesCondition(uint32_t codes, uint32_t condition);
1212516SN/A
1227741Sgblack@eecs.umich.edu        inline int64_t
1237741Sgblack@eecs.umich.edu        sign_ext(uint64_t data, int origWidth)
1242516SN/A        {
1252526SN/A            int shiftAmount = 64 - origWidth;
1262516SN/A            return (((int64_t)data) << shiftAmount) >> shiftAmount;
1272516SN/A        }
1282482SN/A}};
1292482SN/A
1302561SN/Aoutput decoder {{
1312561SN/A
1325202Sstever@gmail.com        const char *CondTestAbbrev[] =
1332561SN/A        {
1347741Sgblack@eecs.umich.edu            "nev", // Never
1357741Sgblack@eecs.umich.edu            "e", // Equal
1367741Sgblack@eecs.umich.edu            "le", // Less or Equal
1377741Sgblack@eecs.umich.edu            "l", // Less
1387741Sgblack@eecs.umich.edu            "leu", // Less or Equal Unsigned
1397741Sgblack@eecs.umich.edu            "c", // Carry set
1407741Sgblack@eecs.umich.edu            "n", // Negative
1417741Sgblack@eecs.umich.edu            "o", // Overflow set
1427741Sgblack@eecs.umich.edu            "a", // Always
1437741Sgblack@eecs.umich.edu            "ne", // Not Equal
1447741Sgblack@eecs.umich.edu            "g", // Greater
1457741Sgblack@eecs.umich.edu            "ge", // Greater or Equal
1467741Sgblack@eecs.umich.edu            "gu", // Greater Unsigned
1477741Sgblack@eecs.umich.edu            "cc", // Carry clear
1487741Sgblack@eecs.umich.edu            "p", // Positive
1497741Sgblack@eecs.umich.edu            "oc" // Overflow Clear
1502561SN/A        };
1512561SN/A}};
1522561SN/A
1532482SN/Adef template ROrImmDecode {{
1542482SN/A    {
1552482SN/A        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
1562482SN/A                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
1572482SN/A    }
1582482SN/A}};
1592482SN/A
1604362Sgblack@eecs.umich.eduoutput header {{
1614362Sgblack@eecs.umich.edu    union DoubleSingle
1624362Sgblack@eecs.umich.edu    {
1634362Sgblack@eecs.umich.edu        double d;
1644362Sgblack@eecs.umich.edu        uint64_t ui;
1654362Sgblack@eecs.umich.edu        uint32_t s[2];
1664362Sgblack@eecs.umich.edu        DoubleSingle(double _d) : d(_d)
1674362Sgblack@eecs.umich.edu        {}
1684362Sgblack@eecs.umich.edu        DoubleSingle(uint64_t _ui) : ui(_ui)
1694362Sgblack@eecs.umich.edu        {}
1704362Sgblack@eecs.umich.edu        DoubleSingle(uint32_t _s0, uint32_t _s1)
1714362Sgblack@eecs.umich.edu        {
1724362Sgblack@eecs.umich.edu            s[0] = _s0;
1734362Sgblack@eecs.umich.edu            s[1] = _s1;
1744362Sgblack@eecs.umich.edu        }
1754362Sgblack@eecs.umich.edu    };
1764362Sgblack@eecs.umich.edu}};
1774362Sgblack@eecs.umich.edu
1784362Sgblack@eecs.umich.edulet {{
1794362Sgblack@eecs.umich.edu    def filterDoubles(code):
1804362Sgblack@eecs.umich.edu        assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
1814362Sgblack@eecs.umich.edu        for opName in ("Frd", "Frs1", "Frs2", "Frd_N"):
1824362Sgblack@eecs.umich.edu            next_pos = 0
1834362Sgblack@eecs.umich.edu            operandsREString = (r'''
1848588Sgblack@eecs.umich.edu            (?<!\w)             # neg. lookbehind assertion: prevent partial matches
1858588Sgblack@eecs.umich.edu            ((%s)(?:_([^\W_]+))?)   # match: operand with optional '.' then suffix
1868588Sgblack@eecs.umich.edu            (?!\w)             # neg. lookahead assertion: prevent partial matches
1874362Sgblack@eecs.umich.edu            ''' % opName)
1884362Sgblack@eecs.umich.edu            operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
1894362Sgblack@eecs.umich.edu            is_src = False
1904362Sgblack@eecs.umich.edu            is_dest = False
1914362Sgblack@eecs.umich.edu            extension = None
1924362Sgblack@eecs.umich.edu            foundOne = False
1934362Sgblack@eecs.umich.edu            while 1:
1944362Sgblack@eecs.umich.edu                match = operandsRE.search(code, next_pos)
1954362Sgblack@eecs.umich.edu                if not match:
1964362Sgblack@eecs.umich.edu                    break
1974362Sgblack@eecs.umich.edu                foundOne = True
1984362Sgblack@eecs.umich.edu                op = match.groups()
1994362Sgblack@eecs.umich.edu                (op_full, op_base, op_ext) = op
2004362Sgblack@eecs.umich.edu                is_dest_local = (assignRE.match(code, match.end()) != None)
2014362Sgblack@eecs.umich.edu                is_dest = is_dest or is_dest_local
2024362Sgblack@eecs.umich.edu                is_src = is_src or not is_dest_local
2034362Sgblack@eecs.umich.edu                if extension and extension != op_ext:
2044362Sgblack@eecs.umich.edu                    raise Exception, "Inconsistent extensions in double filter."
2054362Sgblack@eecs.umich.edu                extension = op_ext
2064362Sgblack@eecs.umich.edu                next_pos = match.end()
2074362Sgblack@eecs.umich.edu            if foundOne:
2084362Sgblack@eecs.umich.edu                # Get rid of any unwanted extension
2094362Sgblack@eecs.umich.edu                code = operandsRE.sub(op_base, code)
2104362Sgblack@eecs.umich.edu                is_int = False
2114362Sgblack@eecs.umich.edu                member = "d"
2124362Sgblack@eecs.umich.edu                if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
2134362Sgblack@eecs.umich.edu                    is_int = True
2144362Sgblack@eecs.umich.edu                    member = "ui"
2154362Sgblack@eecs.umich.edu                if is_src:
2164362Sgblack@eecs.umich.edu                    code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
2174362Sgblack@eecs.umich.edu                        (opName, opName, opName, member)) + code
2184362Sgblack@eecs.umich.edu                if is_dest:
2194362Sgblack@eecs.umich.edu                    code += '''
2204362Sgblack@eecs.umich.edu                        %s_low = DoubleSingle(%s).s[1];
2214362Sgblack@eecs.umich.edu                        %s_high = DoubleSingle(%s).s[0];''' % \
2224362Sgblack@eecs.umich.edu                             (opName, opName, opName, opName)
2234362Sgblack@eecs.umich.edu                if is_int:
2244362Sgblack@eecs.umich.edu                    code = ("uint64_t %s;" % opName) + code
2254362Sgblack@eecs.umich.edu                else:
2264362Sgblack@eecs.umich.edu                    code = ("double %s;" % opName) + code
2274362Sgblack@eecs.umich.edu        return code
2284362Sgblack@eecs.umich.edu}};
2294362Sgblack@eecs.umich.edu
2302482SN/Alet {{
2312482SN/A    def splitOutImm(code):
2328588Sgblack@eecs.umich.edu        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>_[^\W_]+)?')
2332482SN/A        rOrImmMatch = matcher.search(code)
2342482SN/A        if (rOrImmMatch == None):
2352516SN/A            return (False, code, '', '', '')
2362516SN/A        rString = rOrImmMatch.group("rNum")
2372614SN/A        if (rOrImmMatch.group("typeQual") != None):
2382614SN/A            rString += rOrImmMatch.group("typeQual")
2392516SN/A        iString = rOrImmMatch.group("iNum")
2402482SN/A        orig_code = code
2412614SN/A        code = matcher.sub('Rs' + rString, orig_code)
2422482SN/A        imm_code = matcher.sub('imm', orig_code)
2432516SN/A        return (True, code, imm_code, rString, iString)
2442030SN/A}};
2452030SN/A
2462030SN/Aoutput decoder {{
2472030SN/A
2482516SN/A        inline void printMnemonic(std::ostream &os, const char * mnemonic)
2492516SN/A        {
2502516SN/A            ccprintf(os, "\t%s   ", mnemonic);
2512516SN/A        }
2522516SN/A
2532944Sgblack@eecs.umich.edu        void SparcStaticInst::printRegArray(std::ostream &os,
2542944Sgblack@eecs.umich.edu            const RegIndex indexArray[], int num) const
2552944Sgblack@eecs.umich.edu        {
2567741Sgblack@eecs.umich.edu            if (num <= 0)
2572944Sgblack@eecs.umich.edu                return;
2582944Sgblack@eecs.umich.edu            printReg(os, indexArray[0]);
2597741Sgblack@eecs.umich.edu            for (int x = 1; x < num; x++) {
2602944Sgblack@eecs.umich.edu                os << ", ";
2612944Sgblack@eecs.umich.edu                printReg(os, indexArray[x]);
2622944Sgblack@eecs.umich.edu            }
2632944Sgblack@eecs.umich.edu        }
2642944Sgblack@eecs.umich.edu
2652469SN/A        void
2667720Sgblack@eecs.umich.edu        SparcStaticInst::advancePC(SparcISA::PCState &pcState) const
2677720Sgblack@eecs.umich.edu        {
2687720Sgblack@eecs.umich.edu            pcState.advance();
2697720Sgblack@eecs.umich.edu        }
2707720Sgblack@eecs.umich.edu
2717720Sgblack@eecs.umich.edu        void
2722944Sgblack@eecs.umich.edu        SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
2732944Sgblack@eecs.umich.edu        {
2747741Sgblack@eecs.umich.edu            if (_numSrcRegs > reg)
2752944Sgblack@eecs.umich.edu                printReg(os, _srcRegIdx[reg]);
2762944Sgblack@eecs.umich.edu        }
2772944Sgblack@eecs.umich.edu
2782944Sgblack@eecs.umich.edu        void
2792944Sgblack@eecs.umich.edu        SparcStaticInst::printDestReg(std::ostream &os, int reg) const
2802944Sgblack@eecs.umich.edu        {
2817741Sgblack@eecs.umich.edu            if (_numDestRegs > reg)
2822944Sgblack@eecs.umich.edu                printReg(os, _destRegIdx[reg]);
2832944Sgblack@eecs.umich.edu        }
2842944Sgblack@eecs.umich.edu
2852944Sgblack@eecs.umich.edu        void
2862951Sgblack@eecs.umich.edu        SparcStaticInst::printReg(std::ostream &os, int reg) const
2872469SN/A        {
2882516SN/A            const int MaxGlobal = 8;
2892516SN/A            const int MaxOutput = 16;
2902516SN/A            const int MaxLocal = 24;
2912516SN/A            const int MaxInput = 32;
2923978Sgblack@eecs.umich.edu            const int MaxMicroReg = 40;
2939918Ssteve.reinhardt@amd.com            if (reg < FP_Reg_Base) {
2947741Sgblack@eecs.umich.edu                // If we used a register from the next or previous window,
2957741Sgblack@eecs.umich.edu                // take out the offset.
2963978Sgblack@eecs.umich.edu                while (reg >= MaxMicroReg)
2973978Sgblack@eecs.umich.edu                    reg -= MaxMicroReg;
2983978Sgblack@eecs.umich.edu                if (reg == FramePointerReg)
2993978Sgblack@eecs.umich.edu                    ccprintf(os, "%%fp");
3003978Sgblack@eecs.umich.edu                else if (reg == StackPointerReg)
3013978Sgblack@eecs.umich.edu                    ccprintf(os, "%%sp");
3027741Sgblack@eecs.umich.edu                else if (reg < MaxGlobal)
3033978Sgblack@eecs.umich.edu                    ccprintf(os, "%%g%d", reg);
3047741Sgblack@eecs.umich.edu                else if (reg < MaxOutput)
3053978Sgblack@eecs.umich.edu                    ccprintf(os, "%%o%d", reg - MaxGlobal);
3067741Sgblack@eecs.umich.edu                else if (reg < MaxLocal)
3073978Sgblack@eecs.umich.edu                    ccprintf(os, "%%l%d", reg - MaxOutput);
3087741Sgblack@eecs.umich.edu                else if (reg < MaxInput)
3093978Sgblack@eecs.umich.edu                    ccprintf(os, "%%i%d", reg - MaxLocal);
3107741Sgblack@eecs.umich.edu                else if (reg < MaxMicroReg)
3113978Sgblack@eecs.umich.edu                    ccprintf(os, "%%u%d", reg - MaxInput);
3127741Sgblack@eecs.umich.edu                // The fake int regs that are really control regs
3133978Sgblack@eecs.umich.edu                else {
3143978Sgblack@eecs.umich.edu                    switch (reg - MaxMicroReg) {
3153978Sgblack@eecs.umich.edu                      case 1:
3163978Sgblack@eecs.umich.edu                        ccprintf(os, "%%y");
3173978Sgblack@eecs.umich.edu                        break;
3183978Sgblack@eecs.umich.edu                      case 2:
3193978Sgblack@eecs.umich.edu                        ccprintf(os, "%%ccr");
3203978Sgblack@eecs.umich.edu                        break;
3213978Sgblack@eecs.umich.edu                      case 3:
3223978Sgblack@eecs.umich.edu                        ccprintf(os, "%%cansave");
3233978Sgblack@eecs.umich.edu                        break;
3243978Sgblack@eecs.umich.edu                      case 4:
3253978Sgblack@eecs.umich.edu                        ccprintf(os, "%%canrestore");
3263978Sgblack@eecs.umich.edu                        break;
3273978Sgblack@eecs.umich.edu                      case 5:
3283978Sgblack@eecs.umich.edu                        ccprintf(os, "%%cleanwin");
3293978Sgblack@eecs.umich.edu                        break;
3303978Sgblack@eecs.umich.edu                      case 6:
3313978Sgblack@eecs.umich.edu                        ccprintf(os, "%%otherwin");
3323978Sgblack@eecs.umich.edu                        break;
3333978Sgblack@eecs.umich.edu                      case 7:
3343978Sgblack@eecs.umich.edu                        ccprintf(os, "%%wstate");
3353978Sgblack@eecs.umich.edu                        break;
3363978Sgblack@eecs.umich.edu                    }
3373978Sgblack@eecs.umich.edu                }
3389918Ssteve.reinhardt@amd.com            } else if (reg < Misc_Reg_Base) {
3399918Ssteve.reinhardt@amd.com                ccprintf(os, "%%f%d", reg - FP_Reg_Base);
3403978Sgblack@eecs.umich.edu            } else {
3419918Ssteve.reinhardt@amd.com                switch (reg - Misc_Reg_Base) {
3423978Sgblack@eecs.umich.edu                  case MISCREG_ASI:
3433978Sgblack@eecs.umich.edu                    ccprintf(os, "%%asi");
3443978Sgblack@eecs.umich.edu                    break;
3453978Sgblack@eecs.umich.edu                  case MISCREG_FPRS:
3463978Sgblack@eecs.umich.edu                    ccprintf(os, "%%fprs");
3473978Sgblack@eecs.umich.edu                    break;
3483978Sgblack@eecs.umich.edu                  case MISCREG_PCR:
3493978Sgblack@eecs.umich.edu                    ccprintf(os, "%%pcr");
3503978Sgblack@eecs.umich.edu                    break;
3513978Sgblack@eecs.umich.edu                  case MISCREG_PIC:
3523978Sgblack@eecs.umich.edu                    ccprintf(os, "%%pic");
3533978Sgblack@eecs.umich.edu                    break;
3543978Sgblack@eecs.umich.edu                  case MISCREG_GSR:
3553978Sgblack@eecs.umich.edu                    ccprintf(os, "%%gsr");
3563978Sgblack@eecs.umich.edu                    break;
3573978Sgblack@eecs.umich.edu                  case MISCREG_SOFTINT:
3583978Sgblack@eecs.umich.edu                    ccprintf(os, "%%softint");
3593978Sgblack@eecs.umich.edu                    break;
3603978Sgblack@eecs.umich.edu                  case MISCREG_SOFTINT_SET:
3613978Sgblack@eecs.umich.edu                    ccprintf(os, "%%softint_set");
3623978Sgblack@eecs.umich.edu                    break;
3633978Sgblack@eecs.umich.edu                  case MISCREG_SOFTINT_CLR:
3643978Sgblack@eecs.umich.edu                    ccprintf(os, "%%softint_clr");
3653978Sgblack@eecs.umich.edu                    break;
3663978Sgblack@eecs.umich.edu                  case MISCREG_TICK_CMPR:
3673978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tick_cmpr");
3683978Sgblack@eecs.umich.edu                    break;
3693978Sgblack@eecs.umich.edu                  case MISCREG_STICK:
3703978Sgblack@eecs.umich.edu                    ccprintf(os, "%%stick");
3713978Sgblack@eecs.umich.edu                    break;
3723978Sgblack@eecs.umich.edu                  case MISCREG_STICK_CMPR:
3733978Sgblack@eecs.umich.edu                    ccprintf(os, "%%stick_cmpr");
3743978Sgblack@eecs.umich.edu                    break;
3753978Sgblack@eecs.umich.edu                  case MISCREG_TPC:
3763978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tpc");
3773978Sgblack@eecs.umich.edu                    break;
3783978Sgblack@eecs.umich.edu                  case MISCREG_TNPC:
3793978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tnpc");
3803978Sgblack@eecs.umich.edu                    break;
3813978Sgblack@eecs.umich.edu                  case MISCREG_TSTATE:
3823978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tstate");
3833978Sgblack@eecs.umich.edu                    break;
3843978Sgblack@eecs.umich.edu                  case MISCREG_TT:
3853978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tt");
3863978Sgblack@eecs.umich.edu                    break;
3873978Sgblack@eecs.umich.edu                  case MISCREG_TICK:
3883978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tick");
3893978Sgblack@eecs.umich.edu                    break;
3903978Sgblack@eecs.umich.edu                  case MISCREG_TBA:
3913978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tba");
3923978Sgblack@eecs.umich.edu                    break;
3933978Sgblack@eecs.umich.edu                  case MISCREG_PSTATE:
3943978Sgblack@eecs.umich.edu                    ccprintf(os, "%%pstate");
3953978Sgblack@eecs.umich.edu                    break;
3963978Sgblack@eecs.umich.edu                  case MISCREG_TL:
3973978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tl");
3983978Sgblack@eecs.umich.edu                    break;
3993978Sgblack@eecs.umich.edu                  case MISCREG_PIL:
4003978Sgblack@eecs.umich.edu                    ccprintf(os, "%%pil");
4013978Sgblack@eecs.umich.edu                    break;
4023978Sgblack@eecs.umich.edu                  case MISCREG_CWP:
4033978Sgblack@eecs.umich.edu                    ccprintf(os, "%%cwp");
4043978Sgblack@eecs.umich.edu                    break;
4053978Sgblack@eecs.umich.edu                  case MISCREG_GL:
4063978Sgblack@eecs.umich.edu                    ccprintf(os, "%%gl");
4073978Sgblack@eecs.umich.edu                    break;
4083978Sgblack@eecs.umich.edu                  case MISCREG_HPSTATE:
4093978Sgblack@eecs.umich.edu                    ccprintf(os, "%%hpstate");
4103978Sgblack@eecs.umich.edu                    break;
4113978Sgblack@eecs.umich.edu                  case MISCREG_HTSTATE:
4123978Sgblack@eecs.umich.edu                    ccprintf(os, "%%htstate");
4133978Sgblack@eecs.umich.edu                    break;
4143978Sgblack@eecs.umich.edu                  case MISCREG_HINTP:
4153978Sgblack@eecs.umich.edu                    ccprintf(os, "%%hintp");
4163978Sgblack@eecs.umich.edu                    break;
4173978Sgblack@eecs.umich.edu                  case MISCREG_HTBA:
4183978Sgblack@eecs.umich.edu                    ccprintf(os, "%%htba");
4193978Sgblack@eecs.umich.edu                    break;
4203978Sgblack@eecs.umich.edu                  case MISCREG_HSTICK_CMPR:
4213978Sgblack@eecs.umich.edu                    ccprintf(os, "%%hstick_cmpr");
4223978Sgblack@eecs.umich.edu                    break;
4233978Sgblack@eecs.umich.edu                  case MISCREG_HVER:
4243978Sgblack@eecs.umich.edu                    ccprintf(os, "%%hver");
4253978Sgblack@eecs.umich.edu                    break;
4263978Sgblack@eecs.umich.edu                  case MISCREG_STRAND_STS_REG:
4273978Sgblack@eecs.umich.edu                    ccprintf(os, "%%strand_sts_reg");
4283978Sgblack@eecs.umich.edu                    break;
4293978Sgblack@eecs.umich.edu                  case MISCREG_FSR:
4303978Sgblack@eecs.umich.edu                    ccprintf(os, "%%fsr");
4313978Sgblack@eecs.umich.edu                    break;
4323978Sgblack@eecs.umich.edu                  default:
4339918Ssteve.reinhardt@amd.com                    ccprintf(os, "%%ctrl%d", reg - Misc_Reg_Base);
4343978Sgblack@eecs.umich.edu                }
4352469SN/A            }
4362469SN/A        }
4372469SN/A
4387741Sgblack@eecs.umich.edu        std::string
4397741Sgblack@eecs.umich.edu        SparcStaticInst::generateDisassembly(Addr pc,
4407741Sgblack@eecs.umich.edu                const SymbolTable *symtab) const
4412030SN/A        {
4422224SN/A            std::stringstream ss;
4432030SN/A
4442516SN/A            printMnemonic(ss, mnemonic);
4452030SN/A
4462224SN/A            // just print the first two source regs... if there's
4472224SN/A            // a third one, it's a read-modify-write dest (Rc),
4482224SN/A            // e.g. for CMOVxx
4497741Sgblack@eecs.umich.edu            if (_numSrcRegs > 0)
4502224SN/A                printReg(ss, _srcRegIdx[0]);
4517741Sgblack@eecs.umich.edu            if (_numSrcRegs > 1) {
4522224SN/A                ss << ",";
4532224SN/A                printReg(ss, _srcRegIdx[1]);
4542224SN/A            }
4552224SN/A
4562224SN/A            // just print the first dest... if there's a second one,
4572224SN/A            // it's generally implicit
4587741Sgblack@eecs.umich.edu            if (_numDestRegs > 0) {
4597741Sgblack@eecs.umich.edu                if (_numSrcRegs > 0)
4602224SN/A                    ss << ",";
4612224SN/A                    printReg(ss, _destRegIdx[0]);
4622224SN/A            }
4632030SN/A
4642224SN/A            return ss.str();
4652030SN/A        }
4662030SN/A
4677741Sgblack@eecs.umich.edu        bool
4687741Sgblack@eecs.umich.edu        passesFpCondition(uint32_t fcc, uint32_t condition)
4694004Sgblack@eecs.umich.edu        {
4704004Sgblack@eecs.umich.edu            bool u = (fcc == 3);
4714004Sgblack@eecs.umich.edu            bool g = (fcc == 2);
4724004Sgblack@eecs.umich.edu            bool l = (fcc == 1);
4734004Sgblack@eecs.umich.edu            bool e = (fcc == 0);
4747741Sgblack@eecs.umich.edu            switch (condition) {
4754004Sgblack@eecs.umich.edu              case FAlways:
4764004Sgblack@eecs.umich.edu                return 1;
4774004Sgblack@eecs.umich.edu              case FNever:
4784004Sgblack@eecs.umich.edu                return 0;
4794004Sgblack@eecs.umich.edu              case FUnordered:
4804004Sgblack@eecs.umich.edu                return u;
4814004Sgblack@eecs.umich.edu              case FGreater:
4824004Sgblack@eecs.umich.edu                return g;
4834004Sgblack@eecs.umich.edu              case FUnorderedOrGreater:
4844004Sgblack@eecs.umich.edu                return u || g;
4854004Sgblack@eecs.umich.edu              case FLess:
4864004Sgblack@eecs.umich.edu                return l;
4874004Sgblack@eecs.umich.edu              case FUnorderedOrLess:
4884004Sgblack@eecs.umich.edu                return u || l;
4894004Sgblack@eecs.umich.edu              case FLessOrGreater:
4904004Sgblack@eecs.umich.edu                return l || g;
4914004Sgblack@eecs.umich.edu              case FNotEqual:
4924004Sgblack@eecs.umich.edu                return l || g || u;
4934004Sgblack@eecs.umich.edu              case FEqual:
4944004Sgblack@eecs.umich.edu                return e;
4954004Sgblack@eecs.umich.edu              case FUnorderedOrEqual:
4964004Sgblack@eecs.umich.edu                return u || e;
4974004Sgblack@eecs.umich.edu              case FGreaterOrEqual:
4984004Sgblack@eecs.umich.edu                return g || e;
4994004Sgblack@eecs.umich.edu              case FUnorderedOrGreaterOrEqual:
5004004Sgblack@eecs.umich.edu                return u || g || e;
5014004Sgblack@eecs.umich.edu              case FLessOrEqual:
5024004Sgblack@eecs.umich.edu                return l || e;
5034004Sgblack@eecs.umich.edu              case FUnorderedOrLessOrEqual:
5044004Sgblack@eecs.umich.edu                return u || l || e;
5054004Sgblack@eecs.umich.edu              case FOrdered:
5064004Sgblack@eecs.umich.edu                return e || l || g;
5074004Sgblack@eecs.umich.edu            }
5084004Sgblack@eecs.umich.edu            panic("Tried testing condition nonexistant "
5094004Sgblack@eecs.umich.edu                    "condition code %d", condition);
5104004Sgblack@eecs.umich.edu        }
5114004Sgblack@eecs.umich.edu
5127741Sgblack@eecs.umich.edu        bool
5137741Sgblack@eecs.umich.edu        passesCondition(uint32_t codes, uint32_t condition)
5142030SN/A        {
5152482SN/A            CondCodes condCodes;
5163603Ssaidi@eecs.umich.edu            condCodes.bits =  0;
5173603Ssaidi@eecs.umich.edu            condCodes.c = codes & 0x1 ? 1 : 0;
5183603Ssaidi@eecs.umich.edu            condCodes.v = codes & 0x2 ? 1 : 0;
5193603Ssaidi@eecs.umich.edu            condCodes.z = codes & 0x4 ? 1 : 0;
5203603Ssaidi@eecs.umich.edu            condCodes.n = codes & 0x8 ? 1 : 0;
5213603Ssaidi@eecs.umich.edu
5227741Sgblack@eecs.umich.edu            switch (condition) {
5232224SN/A              case Always:
5242224SN/A                return true;
5252224SN/A              case Never:
5262224SN/A                return false;
5272224SN/A              case NotEqual:
5282482SN/A                return !condCodes.z;
5292224SN/A              case Equal:
5302482SN/A                return condCodes.z;
5312224SN/A              case Greater:
5322482SN/A                return !(condCodes.z | (condCodes.n ^ condCodes.v));
5332224SN/A              case LessOrEqual:
5342482SN/A                return condCodes.z | (condCodes.n ^ condCodes.v);
5352224SN/A              case GreaterOrEqual:
5362482SN/A                return !(condCodes.n ^ condCodes.v);
5372224SN/A              case Less:
5382482SN/A                return (condCodes.n ^ condCodes.v);
5392224SN/A              case GreaterUnsigned:
5402482SN/A                return !(condCodes.c | condCodes.z);
5412224SN/A              case LessOrEqualUnsigned:
5422482SN/A                return (condCodes.c | condCodes.z);
5432224SN/A              case CarryClear:
5442482SN/A                return !condCodes.c;
5452224SN/A              case CarrySet:
5462482SN/A                return condCodes.c;
5472224SN/A              case Positive:
5482482SN/A                return !condCodes.n;
5492224SN/A              case Negative:
5502482SN/A                return condCodes.n;
5512224SN/A              case OverflowClear:
5522482SN/A                return !condCodes.v;
5532224SN/A              case OverflowSet:
5542482SN/A                return condCodes.v;
5552224SN/A            }
5562469SN/A            panic("Tried testing condition nonexistant "
5572469SN/A                    "condition code %d", condition);
5582030SN/A        }
5592030SN/A}};
5602030SN/A
5613931Ssaidi@eecs.umich.eduoutput exec {{
5623931Ssaidi@eecs.umich.edu    /// Check "FP enabled" machine status bit.  Called when executing any FP
5638565Sgblack@eecs.umich.edu    /// instruction.
5643931Ssaidi@eecs.umich.edu    /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
5653931Ssaidi@eecs.umich.edu    /// if not.  Non-full-system mode: always returns NoFault.
5668565Sgblack@eecs.umich.edu    static inline Fault
5677741Sgblack@eecs.umich.edu    checkFpEnableFault(%(CPU_exec_context)s *xc)
5683931Ssaidi@eecs.umich.edu    {
5698738Sgblack@eecs.umich.edu        if (FullSystem) {
5708829Sgblack@eecs.umich.edu            PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE);
5718829Sgblack@eecs.umich.edu            if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) {
5728565Sgblack@eecs.umich.edu                return NoFault;
5738565Sgblack@eecs.umich.edu            } else {
5748565Sgblack@eecs.umich.edu                return new FpDisabled;
5758565Sgblack@eecs.umich.edu            }
5768565Sgblack@eecs.umich.edu        } else {
5773931Ssaidi@eecs.umich.edu            return NoFault;
5787741Sgblack@eecs.umich.edu        }
5793931Ssaidi@eecs.umich.edu    }
5803931Ssaidi@eecs.umich.edu}};
5813931Ssaidi@eecs.umich.edu
5823931Ssaidi@eecs.umich.edu
583