base.isa revision 3931
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
702561SN/A        extern char * CondTestAbbrev[];
712561SN/A
722030SN/A        /**
732030SN/A         * Base class for all SPARC static instructions.
742030SN/A         */
752224SN/A        class SparcStaticInst : public StaticInst
762030SN/A        {
772224SN/A          protected:
782224SN/A            // Constructor.
792224SN/A            SparcStaticInst(const char *mnem,
803278Sgblack@eecs.umich.edu                 ExtMachInst _machInst, OpClass __opClass)
812224SN/A                    : StaticInst(mnem, _machInst, __opClass)
822030SN/A                {
832030SN/A                }
842030SN/A
852224SN/A            std::string generateDisassembly(Addr pc,
862224SN/A                const SymbolTable *symtab) const;
872469SN/A
882951Sgblack@eecs.umich.edu            void printReg(std::ostream &os, int reg) const;
892944Sgblack@eecs.umich.edu            void printSrcReg(std::ostream &os, int reg) const;
902944Sgblack@eecs.umich.edu            void printDestReg(std::ostream &os, int reg) const;
912944Sgblack@eecs.umich.edu
922944Sgblack@eecs.umich.edu            void printRegArray(std::ostream &os,
932944Sgblack@eecs.umich.edu                const RegIndex indexArray[], int num) const;
942030SN/A        };
952030SN/A
962482SN/A        bool passesCondition(uint32_t codes, uint32_t condition);
972516SN/A
982516SN/A        inline int64_t sign_ext(uint64_t data, int origWidth)
992516SN/A        {
1002526SN/A            int shiftAmount = 64 - origWidth;
1012516SN/A            return (((int64_t)data) << shiftAmount) >> shiftAmount;
1022516SN/A        }
1032482SN/A}};
1042482SN/A
1052561SN/Aoutput decoder {{
1062561SN/A
1072561SN/A        char * CondTestAbbrev[] =
1082561SN/A        {
1092561SN/A            "nev", //Never
1102561SN/A            "e", //Equal
1112561SN/A            "le", //Less or Equal
1122561SN/A            "l", //Less
1132561SN/A            "leu", //Less or Equal Unsigned
1142561SN/A            "c", //Carry set
1152561SN/A            "n", //Negative
1162561SN/A            "o", //Overflow set
1172561SN/A            "a", //Always
1182561SN/A            "ne", //Not Equal
1192561SN/A            "g", //Greater
1202561SN/A            "ge", //Greater or Equal
1212561SN/A            "gu", //Greater Unsigned
1222561SN/A            "cc", //Carry clear
1232561SN/A            "p", //Positive
1242561SN/A            "oc" //Overflow Clear
1252561SN/A        };
1262561SN/A}};
1272561SN/A
1282482SN/Adef template ROrImmDecode {{
1292482SN/A    {
1302482SN/A        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
1312482SN/A                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
1322482SN/A    }
1332482SN/A}};
1342482SN/A
1352482SN/Alet {{
1362482SN/A    def splitOutImm(code):
1372614SN/A        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
1382482SN/A        rOrImmMatch = matcher.search(code)
1392482SN/A        if (rOrImmMatch == None):
1402516SN/A            return (False, code, '', '', '')
1412516SN/A        rString = rOrImmMatch.group("rNum")
1422614SN/A        if (rOrImmMatch.group("typeQual") != None):
1432614SN/A            rString += rOrImmMatch.group("typeQual")
1442516SN/A        iString = rOrImmMatch.group("iNum")
1452482SN/A        orig_code = code
1462614SN/A        code = matcher.sub('Rs' + rString, orig_code)
1472482SN/A        imm_code = matcher.sub('imm', orig_code)
1482516SN/A        return (True, code, imm_code, rString, iString)
1492030SN/A}};
1502030SN/A
1512030SN/Aoutput decoder {{
1522030SN/A
1532516SN/A        inline void printMnemonic(std::ostream &os, const char * mnemonic)
1542516SN/A        {
1552516SN/A            ccprintf(os, "\t%s   ", mnemonic);
1562516SN/A        }
1572516SN/A
1582944Sgblack@eecs.umich.edu        void SparcStaticInst::printRegArray(std::ostream &os,
1592944Sgblack@eecs.umich.edu            const RegIndex indexArray[], int num) const
1602944Sgblack@eecs.umich.edu        {
1612944Sgblack@eecs.umich.edu            if(num <= 0)
1622944Sgblack@eecs.umich.edu                return;
1632944Sgblack@eecs.umich.edu            printReg(os, indexArray[0]);
1642944Sgblack@eecs.umich.edu            for(int x = 1; x < num; x++)
1652944Sgblack@eecs.umich.edu            {
1662944Sgblack@eecs.umich.edu                os << ", ";
1672944Sgblack@eecs.umich.edu                printReg(os, indexArray[x]);
1682944Sgblack@eecs.umich.edu            }
1692944Sgblack@eecs.umich.edu        }
1702944Sgblack@eecs.umich.edu
1712469SN/A        void
1722944Sgblack@eecs.umich.edu        SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
1732944Sgblack@eecs.umich.edu        {
1742944Sgblack@eecs.umich.edu            if(_numSrcRegs > reg)
1752944Sgblack@eecs.umich.edu                printReg(os, _srcRegIdx[reg]);
1762944Sgblack@eecs.umich.edu        }
1772944Sgblack@eecs.umich.edu
1782944Sgblack@eecs.umich.edu        void
1792944Sgblack@eecs.umich.edu        SparcStaticInst::printDestReg(std::ostream &os, int reg) const
1802944Sgblack@eecs.umich.edu        {
1812944Sgblack@eecs.umich.edu            if(_numDestRegs > reg)
1822944Sgblack@eecs.umich.edu                printReg(os, _destRegIdx[reg]);
1832944Sgblack@eecs.umich.edu        }
1842944Sgblack@eecs.umich.edu
1852944Sgblack@eecs.umich.edu        void
1862951Sgblack@eecs.umich.edu        SparcStaticInst::printReg(std::ostream &os, int reg) const
1872469SN/A        {
1882516SN/A            const int MaxGlobal = 8;
1892516SN/A            const int MaxOutput = 16;
1902516SN/A            const int MaxLocal = 24;
1912516SN/A            const int MaxInput = 32;
1923597Sgblack@eecs.umich.edu            const int MaxMicroReg = 33;
1932516SN/A            if (reg == FramePointerReg)
1942516SN/A                ccprintf(os, "%%fp");
1952516SN/A            else if (reg == StackPointerReg)
1962516SN/A                ccprintf(os, "%%sp");
1972516SN/A            else if(reg < MaxGlobal)
1982516SN/A                ccprintf(os, "%%g%d", reg);
1992516SN/A            else if(reg < MaxOutput)
2002516SN/A                ccprintf(os, "%%o%d", reg - MaxGlobal);
2012516SN/A            else if(reg < MaxLocal)
2022516SN/A                ccprintf(os, "%%l%d", reg - MaxOutput);
2032516SN/A            else if(reg < MaxInput)
2042516SN/A                ccprintf(os, "%%i%d", reg - MaxLocal);
2053597Sgblack@eecs.umich.edu            else if(reg < MaxMicroReg)
2063597Sgblack@eecs.umich.edu                ccprintf(os, "%%u%d", reg - MaxInput);
2072469SN/A            else {
2083753Sgblack@eecs.umich.edu                ccprintf(os, "%%f%d", reg - MaxMicroReg);
2092469SN/A            }
2102469SN/A        }
2112469SN/A
2122224SN/A        std::string SparcStaticInst::generateDisassembly(Addr pc,
2132224SN/A            const SymbolTable *symtab) const
2142030SN/A        {
2152224SN/A            std::stringstream ss;
2162030SN/A
2172516SN/A            printMnemonic(ss, mnemonic);
2182030SN/A
2192224SN/A            // just print the first two source regs... if there's
2202224SN/A            // a third one, it's a read-modify-write dest (Rc),
2212224SN/A            // e.g. for CMOVxx
2222224SN/A            if(_numSrcRegs > 0)
2232224SN/A            {
2242224SN/A                printReg(ss, _srcRegIdx[0]);
2252224SN/A            }
2262224SN/A            if(_numSrcRegs > 1)
2272224SN/A            {
2282224SN/A                ss << ",";
2292224SN/A                printReg(ss, _srcRegIdx[1]);
2302224SN/A            }
2312224SN/A
2322224SN/A            // just print the first dest... if there's a second one,
2332224SN/A            // it's generally implicit
2342224SN/A            if(_numDestRegs > 0)
2352224SN/A            {
2362030SN/A                if(_numSrcRegs > 0)
2372224SN/A                    ss << ",";
2382224SN/A                    printReg(ss, _destRegIdx[0]);
2392224SN/A            }
2402030SN/A
2412224SN/A            return ss.str();
2422030SN/A        }
2432030SN/A
2442482SN/A        bool passesCondition(uint32_t codes, uint32_t condition)
2452030SN/A        {
2462482SN/A            CondCodes condCodes;
2473603Ssaidi@eecs.umich.edu            condCodes.bits =  0;
2483603Ssaidi@eecs.umich.edu            condCodes.c = codes & 0x1 ? 1 : 0;
2493603Ssaidi@eecs.umich.edu            condCodes.v = codes & 0x2 ? 1 : 0;
2503603Ssaidi@eecs.umich.edu            condCodes.z = codes & 0x4 ? 1 : 0;
2513603Ssaidi@eecs.umich.edu            condCodes.n = codes & 0x8 ? 1 : 0;
2523603Ssaidi@eecs.umich.edu
2532224SN/A            switch(condition)
2542224SN/A            {
2552224SN/A              case Always:
2562224SN/A                return true;
2572224SN/A              case Never:
2582224SN/A                return false;
2592224SN/A              case NotEqual:
2602482SN/A                return !condCodes.z;
2612224SN/A              case Equal:
2622482SN/A                return condCodes.z;
2632224SN/A              case Greater:
2642482SN/A                return !(condCodes.z | (condCodes.n ^ condCodes.v));
2652224SN/A              case LessOrEqual:
2662482SN/A                return condCodes.z | (condCodes.n ^ condCodes.v);
2672224SN/A              case GreaterOrEqual:
2682482SN/A                return !(condCodes.n ^ condCodes.v);
2692224SN/A              case Less:
2702482SN/A                return (condCodes.n ^ condCodes.v);
2712224SN/A              case GreaterUnsigned:
2722482SN/A                return !(condCodes.c | condCodes.z);
2732224SN/A              case LessOrEqualUnsigned:
2742482SN/A                return (condCodes.c | condCodes.z);
2752224SN/A              case CarryClear:
2762482SN/A                return !condCodes.c;
2772224SN/A              case CarrySet:
2782482SN/A                return condCodes.c;
2792224SN/A              case Positive:
2802482SN/A                return !condCodes.n;
2812224SN/A              case Negative:
2822482SN/A                return condCodes.n;
2832224SN/A              case OverflowClear:
2842482SN/A                return !condCodes.v;
2852224SN/A              case OverflowSet:
2862482SN/A                return condCodes.v;
2872224SN/A            }
2882469SN/A            panic("Tried testing condition nonexistant "
2892469SN/A                    "condition code %d", condition);
2902030SN/A        }
2912030SN/A}};
2922030SN/A
2933931Ssaidi@eecs.umich.eduoutput exec {{
2943931Ssaidi@eecs.umich.edu    /// Check "FP enabled" machine status bit.  Called when executing any FP
2953931Ssaidi@eecs.umich.edu    /// instruction in full-system mode.
2963931Ssaidi@eecs.umich.edu    /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
2973931Ssaidi@eecs.umich.edu    /// if not.  Non-full-system mode: always returns NoFault.
2983931Ssaidi@eecs.umich.edu#if FULL_SYSTEM
2993931Ssaidi@eecs.umich.edu    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
3003931Ssaidi@eecs.umich.edu    {
3013931Ssaidi@eecs.umich.edu        Fault fault = NoFault;	// dummy... this ipr access should not fault
3023931Ssaidi@eecs.umich.edu        if (xc->readMiscRegWithEffect(MISCREG_PSTATE) & PSTATE::pef &&
3033931Ssaidi@eecs.umich.edu            xc->readMiscRegWithEffect(MISCREG_FPRS) & 0x4)
3043931Ssaidi@eecs.umich.edu            return NoFault;
3053931Ssaidi@eecs.umich.edu        else
3063931Ssaidi@eecs.umich.edu            return new FpDisabled;
3073931Ssaidi@eecs.umich.edu    }
3083931Ssaidi@eecs.umich.edu#else
3093931Ssaidi@eecs.umich.edu    inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
3103931Ssaidi@eecs.umich.edu    {
3113931Ssaidi@eecs.umich.edu        return NoFault;
3123931Ssaidi@eecs.umich.edu    }
3133931Ssaidi@eecs.umich.edu#endif
3143931Ssaidi@eecs.umich.edu}};
3153931Ssaidi@eecs.umich.edu
3163931Ssaidi@eecs.umich.edu
317