base.isa revision 4344
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
902561SN/A        extern 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;
1142030SN/A        };
1152030SN/A
1164004Sgblack@eecs.umich.edu        bool passesFpCondition(uint32_t fcc, uint32_t condition);
1174004Sgblack@eecs.umich.edu
1182482SN/A        bool passesCondition(uint32_t codes, uint32_t condition);
1192516SN/A
1202516SN/A        inline int64_t sign_ext(uint64_t data, int origWidth)
1212516SN/A        {
1222526SN/A            int shiftAmount = 64 - origWidth;
1232516SN/A            return (((int64_t)data) << shiftAmount) >> shiftAmount;
1242516SN/A        }
1252482SN/A}};
1262482SN/A
1272561SN/Aoutput decoder {{
1282561SN/A
1292561SN/A        char * CondTestAbbrev[] =
1302561SN/A        {
1312561SN/A            "nev", //Never
1322561SN/A            "e", //Equal
1332561SN/A            "le", //Less or Equal
1342561SN/A            "l", //Less
1352561SN/A            "leu", //Less or Equal Unsigned
1362561SN/A            "c", //Carry set
1372561SN/A            "n", //Negative
1382561SN/A            "o", //Overflow set
1392561SN/A            "a", //Always
1402561SN/A            "ne", //Not Equal
1412561SN/A            "g", //Greater
1422561SN/A            "ge", //Greater or Equal
1432561SN/A            "gu", //Greater Unsigned
1442561SN/A            "cc", //Carry clear
1452561SN/A            "p", //Positive
1462561SN/A            "oc" //Overflow Clear
1472561SN/A        };
1482561SN/A}};
1492561SN/A
1502482SN/Adef template ROrImmDecode {{
1512482SN/A    {
1522482SN/A        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
1532482SN/A                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
1542482SN/A    }
1552482SN/A}};
1562482SN/A
1572482SN/Alet {{
1582482SN/A    def splitOutImm(code):
1592614SN/A        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
1602482SN/A        rOrImmMatch = matcher.search(code)
1612482SN/A        if (rOrImmMatch == None):
1622516SN/A            return (False, code, '', '', '')
1632516SN/A        rString = rOrImmMatch.group("rNum")
1642614SN/A        if (rOrImmMatch.group("typeQual") != None):
1652614SN/A            rString += rOrImmMatch.group("typeQual")
1662516SN/A        iString = rOrImmMatch.group("iNum")
1672482SN/A        orig_code = code
1682614SN/A        code = matcher.sub('Rs' + rString, orig_code)
1692482SN/A        imm_code = matcher.sub('imm', orig_code)
1702516SN/A        return (True, code, imm_code, rString, iString)
1712030SN/A}};
1722030SN/A
1732030SN/Aoutput decoder {{
1742030SN/A
1752516SN/A        inline void printMnemonic(std::ostream &os, const char * mnemonic)
1762516SN/A        {
1772516SN/A            ccprintf(os, "\t%s   ", mnemonic);
1782516SN/A        }
1792516SN/A
1802944Sgblack@eecs.umich.edu        void SparcStaticInst::printRegArray(std::ostream &os,
1812944Sgblack@eecs.umich.edu            const RegIndex indexArray[], int num) const
1822944Sgblack@eecs.umich.edu        {
1832944Sgblack@eecs.umich.edu            if(num <= 0)
1842944Sgblack@eecs.umich.edu                return;
1852944Sgblack@eecs.umich.edu            printReg(os, indexArray[0]);
1862944Sgblack@eecs.umich.edu            for(int x = 1; x < num; x++)
1872944Sgblack@eecs.umich.edu            {
1882944Sgblack@eecs.umich.edu                os << ", ";
1892944Sgblack@eecs.umich.edu                printReg(os, indexArray[x]);
1902944Sgblack@eecs.umich.edu            }
1912944Sgblack@eecs.umich.edu        }
1922944Sgblack@eecs.umich.edu
1932469SN/A        void
1942944Sgblack@eecs.umich.edu        SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
1952944Sgblack@eecs.umich.edu        {
1962944Sgblack@eecs.umich.edu            if(_numSrcRegs > reg)
1972944Sgblack@eecs.umich.edu                printReg(os, _srcRegIdx[reg]);
1982944Sgblack@eecs.umich.edu        }
1992944Sgblack@eecs.umich.edu
2002944Sgblack@eecs.umich.edu        void
2012944Sgblack@eecs.umich.edu        SparcStaticInst::printDestReg(std::ostream &os, int reg) const
2022944Sgblack@eecs.umich.edu        {
2032944Sgblack@eecs.umich.edu            if(_numDestRegs > reg)
2042944Sgblack@eecs.umich.edu                printReg(os, _destRegIdx[reg]);
2052944Sgblack@eecs.umich.edu        }
2062944Sgblack@eecs.umich.edu
2072944Sgblack@eecs.umich.edu        void
2082951Sgblack@eecs.umich.edu        SparcStaticInst::printReg(std::ostream &os, int reg) const
2092469SN/A        {
2102516SN/A            const int MaxGlobal = 8;
2112516SN/A            const int MaxOutput = 16;
2122516SN/A            const int MaxLocal = 24;
2132516SN/A            const int MaxInput = 32;
2143978Sgblack@eecs.umich.edu            const int MaxMicroReg = 40;
2153978Sgblack@eecs.umich.edu            if (reg < FP_Base_DepTag) {
2163978Sgblack@eecs.umich.edu                //If we used a register from the next or previous window,
2173978Sgblack@eecs.umich.edu                //take out the offset.
2183978Sgblack@eecs.umich.edu                while (reg >= MaxMicroReg)
2193978Sgblack@eecs.umich.edu                    reg -= MaxMicroReg;
2203978Sgblack@eecs.umich.edu                if (reg == FramePointerReg)
2213978Sgblack@eecs.umich.edu                    ccprintf(os, "%%fp");
2223978Sgblack@eecs.umich.edu                else if (reg == StackPointerReg)
2233978Sgblack@eecs.umich.edu                    ccprintf(os, "%%sp");
2243978Sgblack@eecs.umich.edu                else if(reg < MaxGlobal)
2253978Sgblack@eecs.umich.edu                    ccprintf(os, "%%g%d", reg);
2263978Sgblack@eecs.umich.edu                else if(reg < MaxOutput)
2273978Sgblack@eecs.umich.edu                    ccprintf(os, "%%o%d", reg - MaxGlobal);
2283978Sgblack@eecs.umich.edu                else if(reg < MaxLocal)
2293978Sgblack@eecs.umich.edu                    ccprintf(os, "%%l%d", reg - MaxOutput);
2303978Sgblack@eecs.umich.edu                else if(reg < MaxInput)
2313978Sgblack@eecs.umich.edu                    ccprintf(os, "%%i%d", reg - MaxLocal);
2323978Sgblack@eecs.umich.edu                else if(reg < MaxMicroReg)
2333978Sgblack@eecs.umich.edu                    ccprintf(os, "%%u%d", reg - MaxInput);
2343978Sgblack@eecs.umich.edu                //The fake int regs that are really control regs
2353978Sgblack@eecs.umich.edu                else {
2363978Sgblack@eecs.umich.edu                    switch (reg - MaxMicroReg) {
2373978Sgblack@eecs.umich.edu                      case 1:
2383978Sgblack@eecs.umich.edu                        ccprintf(os, "%%y");
2393978Sgblack@eecs.umich.edu                        break;
2403978Sgblack@eecs.umich.edu                      case 2:
2413978Sgblack@eecs.umich.edu                        ccprintf(os, "%%ccr");
2423978Sgblack@eecs.umich.edu                        break;
2433978Sgblack@eecs.umich.edu                      case 3:
2443978Sgblack@eecs.umich.edu                        ccprintf(os, "%%cansave");
2453978Sgblack@eecs.umich.edu                        break;
2463978Sgblack@eecs.umich.edu                      case 4:
2473978Sgblack@eecs.umich.edu                        ccprintf(os, "%%canrestore");
2483978Sgblack@eecs.umich.edu                        break;
2493978Sgblack@eecs.umich.edu                      case 5:
2503978Sgblack@eecs.umich.edu                        ccprintf(os, "%%cleanwin");
2513978Sgblack@eecs.umich.edu                        break;
2523978Sgblack@eecs.umich.edu                      case 6:
2533978Sgblack@eecs.umich.edu                        ccprintf(os, "%%otherwin");
2543978Sgblack@eecs.umich.edu                        break;
2553978Sgblack@eecs.umich.edu                      case 7:
2563978Sgblack@eecs.umich.edu                        ccprintf(os, "%%wstate");
2573978Sgblack@eecs.umich.edu                        break;
2583978Sgblack@eecs.umich.edu                    }
2593978Sgblack@eecs.umich.edu                }
2603978Sgblack@eecs.umich.edu            } else if (reg < Ctrl_Base_DepTag) {
2613978Sgblack@eecs.umich.edu                ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
2623978Sgblack@eecs.umich.edu            } else {
2633978Sgblack@eecs.umich.edu                switch (reg - Ctrl_Base_DepTag) {
2643978Sgblack@eecs.umich.edu                  case MISCREG_ASI:
2653978Sgblack@eecs.umich.edu                    ccprintf(os, "%%asi");
2663978Sgblack@eecs.umich.edu                    break;
2673978Sgblack@eecs.umich.edu                  case MISCREG_FPRS:
2683978Sgblack@eecs.umich.edu                    ccprintf(os, "%%fprs");
2693978Sgblack@eecs.umich.edu                    break;
2703978Sgblack@eecs.umich.edu                  case MISCREG_PCR:
2713978Sgblack@eecs.umich.edu                    ccprintf(os, "%%pcr");
2723978Sgblack@eecs.umich.edu                    break;
2733978Sgblack@eecs.umich.edu                  case MISCREG_PIC:
2743978Sgblack@eecs.umich.edu                    ccprintf(os, "%%pic");
2753978Sgblack@eecs.umich.edu                    break;
2763978Sgblack@eecs.umich.edu                  case MISCREG_GSR:
2773978Sgblack@eecs.umich.edu                    ccprintf(os, "%%gsr");
2783978Sgblack@eecs.umich.edu                    break;
2793978Sgblack@eecs.umich.edu                  case MISCREG_SOFTINT:
2803978Sgblack@eecs.umich.edu                    ccprintf(os, "%%softint");
2813978Sgblack@eecs.umich.edu                    break;
2823978Sgblack@eecs.umich.edu                  case MISCREG_SOFTINT_SET:
2833978Sgblack@eecs.umich.edu                    ccprintf(os, "%%softint_set");
2843978Sgblack@eecs.umich.edu                    break;
2853978Sgblack@eecs.umich.edu                  case MISCREG_SOFTINT_CLR:
2863978Sgblack@eecs.umich.edu                    ccprintf(os, "%%softint_clr");
2873978Sgblack@eecs.umich.edu                    break;
2883978Sgblack@eecs.umich.edu                  case MISCREG_TICK_CMPR:
2893978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tick_cmpr");
2903978Sgblack@eecs.umich.edu                    break;
2913978Sgblack@eecs.umich.edu                  case MISCREG_STICK:
2923978Sgblack@eecs.umich.edu                    ccprintf(os, "%%stick");
2933978Sgblack@eecs.umich.edu                    break;
2943978Sgblack@eecs.umich.edu                  case MISCREG_STICK_CMPR:
2953978Sgblack@eecs.umich.edu                    ccprintf(os, "%%stick_cmpr");
2963978Sgblack@eecs.umich.edu                    break;
2973978Sgblack@eecs.umich.edu                  case MISCREG_TPC:
2983978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tpc");
2993978Sgblack@eecs.umich.edu                    break;
3003978Sgblack@eecs.umich.edu                  case MISCREG_TNPC:
3013978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tnpc");
3023978Sgblack@eecs.umich.edu                    break;
3033978Sgblack@eecs.umich.edu                  case MISCREG_TSTATE:
3043978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tstate");
3053978Sgblack@eecs.umich.edu                    break;
3063978Sgblack@eecs.umich.edu                  case MISCREG_TT:
3073978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tt");
3083978Sgblack@eecs.umich.edu                    break;
3093978Sgblack@eecs.umich.edu                  case MISCREG_TICK:
3103978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tick");
3113978Sgblack@eecs.umich.edu                    break;
3123978Sgblack@eecs.umich.edu                  case MISCREG_TBA:
3133978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tba");
3143978Sgblack@eecs.umich.edu                    break;
3153978Sgblack@eecs.umich.edu                  case MISCREG_PSTATE:
3163978Sgblack@eecs.umich.edu                    ccprintf(os, "%%pstate");
3173978Sgblack@eecs.umich.edu                    break;
3183978Sgblack@eecs.umich.edu                  case MISCREG_TL:
3193978Sgblack@eecs.umich.edu                    ccprintf(os, "%%tl");
3203978Sgblack@eecs.umich.edu                    break;
3213978Sgblack@eecs.umich.edu                  case MISCREG_PIL:
3223978Sgblack@eecs.umich.edu                    ccprintf(os, "%%pil");
3233978Sgblack@eecs.umich.edu                    break;
3243978Sgblack@eecs.umich.edu                  case MISCREG_CWP:
3253978Sgblack@eecs.umich.edu                    ccprintf(os, "%%cwp");
3263978Sgblack@eecs.umich.edu                    break;
3273978Sgblack@eecs.umich.edu                  case MISCREG_GL:
3283978Sgblack@eecs.umich.edu                    ccprintf(os, "%%gl");
3293978Sgblack@eecs.umich.edu                    break;
3303978Sgblack@eecs.umich.edu                  case MISCREG_HPSTATE:
3313978Sgblack@eecs.umich.edu                    ccprintf(os, "%%hpstate");
3323978Sgblack@eecs.umich.edu                    break;
3333978Sgblack@eecs.umich.edu                  case MISCREG_HTSTATE:
3343978Sgblack@eecs.umich.edu                    ccprintf(os, "%%htstate");
3353978Sgblack@eecs.umich.edu                    break;
3363978Sgblack@eecs.umich.edu                  case MISCREG_HINTP:
3373978Sgblack@eecs.umich.edu                    ccprintf(os, "%%hintp");
3383978Sgblack@eecs.umich.edu                    break;
3393978Sgblack@eecs.umich.edu                  case MISCREG_HTBA:
3403978Sgblack@eecs.umich.edu                    ccprintf(os, "%%htba");
3413978Sgblack@eecs.umich.edu                    break;
3423978Sgblack@eecs.umich.edu                  case MISCREG_HSTICK_CMPR:
3433978Sgblack@eecs.umich.edu                    ccprintf(os, "%%hstick_cmpr");
3443978Sgblack@eecs.umich.edu                    break;
3453978Sgblack@eecs.umich.edu                  case MISCREG_HVER:
3463978Sgblack@eecs.umich.edu                    ccprintf(os, "%%hver");
3473978Sgblack@eecs.umich.edu                    break;
3483978Sgblack@eecs.umich.edu                  case MISCREG_STRAND_STS_REG:
3493978Sgblack@eecs.umich.edu                    ccprintf(os, "%%strand_sts_reg");
3503978Sgblack@eecs.umich.edu                    break;
3513978Sgblack@eecs.umich.edu                  case MISCREG_FSR:
3523978Sgblack@eecs.umich.edu                    ccprintf(os, "%%fsr");
3533978Sgblack@eecs.umich.edu                    break;
3543978Sgblack@eecs.umich.edu                  default:
3553978Sgblack@eecs.umich.edu                    ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
3563978Sgblack@eecs.umich.edu                }
3572469SN/A            }
3582469SN/A        }
3592469SN/A
3602224SN/A        std::string SparcStaticInst::generateDisassembly(Addr pc,
3612224SN/A            const SymbolTable *symtab) const
3622030SN/A        {
3632224SN/A            std::stringstream ss;
3642030SN/A
3652516SN/A            printMnemonic(ss, mnemonic);
3662030SN/A
3672224SN/A            // just print the first two source regs... if there's
3682224SN/A            // a third one, it's a read-modify-write dest (Rc),
3692224SN/A            // e.g. for CMOVxx
3702224SN/A            if(_numSrcRegs > 0)
3712224SN/A            {
3722224SN/A                printReg(ss, _srcRegIdx[0]);
3732224SN/A            }
3742224SN/A            if(_numSrcRegs > 1)
3752224SN/A            {
3762224SN/A                ss << ",";
3772224SN/A                printReg(ss, _srcRegIdx[1]);
3782224SN/A            }
3792224SN/A
3802224SN/A            // just print the first dest... if there's a second one,
3812224SN/A            // it's generally implicit
3822224SN/A            if(_numDestRegs > 0)
3832224SN/A            {
3842030SN/A                if(_numSrcRegs > 0)
3852224SN/A                    ss << ",";
3862224SN/A                    printReg(ss, _destRegIdx[0]);
3872224SN/A            }
3882030SN/A
3892224SN/A            return ss.str();
3902030SN/A        }
3912030SN/A
3924004Sgblack@eecs.umich.edu        bool passesFpCondition(uint32_t fcc, uint32_t condition)
3934004Sgblack@eecs.umich.edu        {
3944004Sgblack@eecs.umich.edu            bool u = (fcc == 3);
3954004Sgblack@eecs.umich.edu            bool g = (fcc == 2);
3964004Sgblack@eecs.umich.edu            bool l = (fcc == 1);
3974004Sgblack@eecs.umich.edu            bool e = (fcc == 0);
3984004Sgblack@eecs.umich.edu            switch(condition)
3994004Sgblack@eecs.umich.edu            {
4004004Sgblack@eecs.umich.edu              case FAlways:
4014004Sgblack@eecs.umich.edu                return 1;
4024004Sgblack@eecs.umich.edu              case FNever:
4034004Sgblack@eecs.umich.edu                return 0;
4044004Sgblack@eecs.umich.edu              case FUnordered:
4054004Sgblack@eecs.umich.edu                return u;
4064004Sgblack@eecs.umich.edu              case FGreater:
4074004Sgblack@eecs.umich.edu                return g;
4084004Sgblack@eecs.umich.edu              case FUnorderedOrGreater:
4094004Sgblack@eecs.umich.edu                return u || g;
4104004Sgblack@eecs.umich.edu              case FLess:
4114004Sgblack@eecs.umich.edu                return l;
4124004Sgblack@eecs.umich.edu              case FUnorderedOrLess:
4134004Sgblack@eecs.umich.edu                return u || l;
4144004Sgblack@eecs.umich.edu              case FLessOrGreater:
4154004Sgblack@eecs.umich.edu                return l || g;
4164004Sgblack@eecs.umich.edu              case FNotEqual:
4174004Sgblack@eecs.umich.edu                return l || g || u;
4184004Sgblack@eecs.umich.edu              case FEqual:
4194004Sgblack@eecs.umich.edu                return e;
4204004Sgblack@eecs.umich.edu              case FUnorderedOrEqual:
4214004Sgblack@eecs.umich.edu                return u || e;
4224004Sgblack@eecs.umich.edu              case FGreaterOrEqual:
4234004Sgblack@eecs.umich.edu                return g || e;
4244004Sgblack@eecs.umich.edu              case FUnorderedOrGreaterOrEqual:
4254004Sgblack@eecs.umich.edu                return u || g || e;
4264004Sgblack@eecs.umich.edu              case FLessOrEqual:
4274004Sgblack@eecs.umich.edu                return l || e;
4284004Sgblack@eecs.umich.edu              case FUnorderedOrLessOrEqual:
4294004Sgblack@eecs.umich.edu                return u || l || e;
4304004Sgblack@eecs.umich.edu              case FOrdered:
4314004Sgblack@eecs.umich.edu                return e || l || g;
4324004Sgblack@eecs.umich.edu            }
4334004Sgblack@eecs.umich.edu            panic("Tried testing condition nonexistant "
4344004Sgblack@eecs.umich.edu                    "condition code %d", condition);
4354004Sgblack@eecs.umich.edu        }
4364004Sgblack@eecs.umich.edu
4372482SN/A        bool passesCondition(uint32_t codes, uint32_t condition)
4382030SN/A        {
4392482SN/A            CondCodes condCodes;
4403603Ssaidi@eecs.umich.edu            condCodes.bits =  0;
4413603Ssaidi@eecs.umich.edu            condCodes.c = codes & 0x1 ? 1 : 0;
4423603Ssaidi@eecs.umich.edu            condCodes.v = codes & 0x2 ? 1 : 0;
4433603Ssaidi@eecs.umich.edu            condCodes.z = codes & 0x4 ? 1 : 0;
4443603Ssaidi@eecs.umich.edu            condCodes.n = codes & 0x8 ? 1 : 0;
4453603Ssaidi@eecs.umich.edu
4462224SN/A            switch(condition)
4472224SN/A            {
4482224SN/A              case Always:
4492224SN/A                return true;
4502224SN/A              case Never:
4512224SN/A                return false;
4522224SN/A              case NotEqual:
4532482SN/A                return !condCodes.z;
4542224SN/A              case Equal:
4552482SN/A                return condCodes.z;
4562224SN/A              case Greater:
4572482SN/A                return !(condCodes.z | (condCodes.n ^ condCodes.v));
4582224SN/A              case LessOrEqual:
4592482SN/A                return condCodes.z | (condCodes.n ^ condCodes.v);
4602224SN/A              case GreaterOrEqual:
4612482SN/A                return !(condCodes.n ^ condCodes.v);
4622224SN/A              case Less:
4632482SN/A                return (condCodes.n ^ condCodes.v);
4642224SN/A              case GreaterUnsigned:
4652482SN/A                return !(condCodes.c | condCodes.z);
4662224SN/A              case LessOrEqualUnsigned:
4672482SN/A                return (condCodes.c | condCodes.z);
4682224SN/A              case CarryClear:
4692482SN/A                return !condCodes.c;
4702224SN/A              case CarrySet:
4712482SN/A                return condCodes.c;
4722224SN/A              case Positive:
4732482SN/A                return !condCodes.n;
4742224SN/A              case Negative:
4752482SN/A                return condCodes.n;
4762224SN/A              case OverflowClear:
4772482SN/A                return !condCodes.v;
4782224SN/A              case OverflowSet:
4792482SN/A                return condCodes.v;
4802224SN/A            }
4812469SN/A            panic("Tried testing condition nonexistant "
4822469SN/A                    "condition code %d", condition);
4832030SN/A        }
4842030SN/A}};
4852030SN/A
4863931Ssaidi@eecs.umich.eduoutput exec {{
4873931Ssaidi@eecs.umich.edu    /// Check "FP enabled" machine status bit.  Called when executing any FP
4883931Ssaidi@eecs.umich.edu    /// instruction in full-system mode.
4893931Ssaidi@eecs.umich.edu    /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
4903931Ssaidi@eecs.umich.edu    /// if not.  Non-full-system mode: always returns NoFault.
4913931Ssaidi@eecs.umich.edu#if FULL_SYSTEM
4923931Ssaidi@eecs.umich.edu    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
4933931Ssaidi@eecs.umich.edu    {
4943931Ssaidi@eecs.umich.edu        Fault fault = NoFault;	// dummy... this ipr access should not fault
4954172Ssaidi@eecs.umich.edu        if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef &&
4964172Ssaidi@eecs.umich.edu            xc->readMiscReg(MISCREG_FPRS) & 0x4)
4973931Ssaidi@eecs.umich.edu            return NoFault;
4983931Ssaidi@eecs.umich.edu        else
4993931Ssaidi@eecs.umich.edu            return new FpDisabled;
5003931Ssaidi@eecs.umich.edu    }
5013931Ssaidi@eecs.umich.edu#else
5023931Ssaidi@eecs.umich.edu    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
5033931Ssaidi@eecs.umich.edu    {
5043931Ssaidi@eecs.umich.edu        return NoFault;
5053931Ssaidi@eecs.umich.edu    }
5063931Ssaidi@eecs.umich.edu#endif
5073931Ssaidi@eecs.umich.edu}};
5083931Ssaidi@eecs.umich.edu
5093931Ssaidi@eecs.umich.edu
510