base.isa revision 2561
110448Snilay@cs.wisc.edu////////////////////////////////////////////////////////////////////
210448Snilay@cs.wisc.edu//
310448Snilay@cs.wisc.edu// Base class for sparc instructions, and some support functions
410448Snilay@cs.wisc.edu//
510448Snilay@cs.wisc.edu
610448Snilay@cs.wisc.eduoutput header {{
710448Snilay@cs.wisc.edu
810448Snilay@cs.wisc.edu        union CondCodes
910448Snilay@cs.wisc.edu        {
1010448Snilay@cs.wisc.edu            struct
1110448Snilay@cs.wisc.edu            {
1210448Snilay@cs.wisc.edu                uint8_t c:1;
1310448Snilay@cs.wisc.edu                uint8_t v:1;
1410448Snilay@cs.wisc.edu                uint8_t z:1;
1510448Snilay@cs.wisc.edu                uint8_t n:1;
1610448Snilay@cs.wisc.edu            };
1710448Snilay@cs.wisc.edu            uint32_t bits;
1810448Snilay@cs.wisc.edu        };
1910448Snilay@cs.wisc.edu
2010448Snilay@cs.wisc.edu        enum CondTest
2110448Snilay@cs.wisc.edu        {
2210447Snilay@cs.wisc.edu            Always=0x8,
2310447Snilay@cs.wisc.edu            Never=0x0,
2410447Snilay@cs.wisc.edu            NotEqual=0x9,
2510447Snilay@cs.wisc.edu            Equal=0x1,
2610447Snilay@cs.wisc.edu            Greater=0xA,
2710447Snilay@cs.wisc.edu            LessOrEqual=0x2,
2810447Snilay@cs.wisc.edu            GreaterOrEqual=0xB,
2910447Snilay@cs.wisc.edu            Less=0x3,
3010447Snilay@cs.wisc.edu            GreaterUnsigned=0xC,
3110447Snilay@cs.wisc.edu            LessOrEqualUnsigned=0x4,
3210447Snilay@cs.wisc.edu            CarryClear=0xD,
3310447Snilay@cs.wisc.edu            CarrySet=0x5,
3410447Snilay@cs.wisc.edu            Positive=0xE,
3510447Snilay@cs.wisc.edu            Negative=0x6,
3610447Snilay@cs.wisc.edu            OverflowClear=0xF,
3710447Snilay@cs.wisc.edu            OverflowSet=0x7
3810447Snilay@cs.wisc.edu        };
3910447Snilay@cs.wisc.edu
4010447Snilay@cs.wisc.edu        extern char * CondTestAbbrev[];
4110447Snilay@cs.wisc.edu
4210447Snilay@cs.wisc.edu        /**
4310447Snilay@cs.wisc.edu         * Base class for all SPARC static instructions.
4410447Snilay@cs.wisc.edu         */
4510447Snilay@cs.wisc.edu        class SparcStaticInst : public StaticInst
4610447Snilay@cs.wisc.edu        {
4710447Snilay@cs.wisc.edu          protected:
4810447Snilay@cs.wisc.edu            // Constructor.
4910447Snilay@cs.wisc.edu            SparcStaticInst(const char *mnem,
5010447Snilay@cs.wisc.edu                 MachInst _machInst, OpClass __opClass)
5110447Snilay@cs.wisc.edu                    : StaticInst(mnem, _machInst, __opClass)
5210447Snilay@cs.wisc.edu                {
5310447Snilay@cs.wisc.edu                }
5410447Snilay@cs.wisc.edu
5510447Snilay@cs.wisc.edu            std::string generateDisassembly(Addr pc,
5610447Snilay@cs.wisc.edu                const SymbolTable *symtab) const;
5710447Snilay@cs.wisc.edu
5810447Snilay@cs.wisc.edu            void printReg(std::ostream &os, int reg) const;
5910447Snilay@cs.wisc.edu        };
6010447Snilay@cs.wisc.edu
6110447Snilay@cs.wisc.edu        bool passesCondition(uint32_t codes, uint32_t condition);
6210447Snilay@cs.wisc.edu
6310447Snilay@cs.wisc.edu        inline int64_t sign_ext(uint64_t data, int origWidth)
6410447Snilay@cs.wisc.edu        {
6510447Snilay@cs.wisc.edu            int shiftAmount = 64 - origWidth;
6610447Snilay@cs.wisc.edu            return (((int64_t)data) << shiftAmount) >> shiftAmount;
6710447Snilay@cs.wisc.edu        }
6810447Snilay@cs.wisc.edu}};
6910447Snilay@cs.wisc.edu
7010447Snilay@cs.wisc.eduoutput decoder {{
7110447Snilay@cs.wisc.edu
7210447Snilay@cs.wisc.edu        char * CondTestAbbrev[] =
7310447Snilay@cs.wisc.edu        {
7410447Snilay@cs.wisc.edu            "nev", //Never
7510447Snilay@cs.wisc.edu            "e", //Equal
7610447Snilay@cs.wisc.edu            "le", //Less or Equal
7710447Snilay@cs.wisc.edu            "l", //Less
7810447Snilay@cs.wisc.edu            "leu", //Less or Equal Unsigned
7910447Snilay@cs.wisc.edu            "c", //Carry set
8010447Snilay@cs.wisc.edu            "n", //Negative
8110447Snilay@cs.wisc.edu            "o", //Overflow set
8210447Snilay@cs.wisc.edu            "a", //Always
8310447Snilay@cs.wisc.edu            "ne", //Not Equal
8410447Snilay@cs.wisc.edu            "g", //Greater
8510447Snilay@cs.wisc.edu            "ge", //Greater or Equal
8610447Snilay@cs.wisc.edu            "gu", //Greater Unsigned
8710447Snilay@cs.wisc.edu            "cc", //Carry clear
8810447Snilay@cs.wisc.edu            "p", //Positive
8910447Snilay@cs.wisc.edu            "oc" //Overflow Clear
9010447Snilay@cs.wisc.edu        };
9110447Snilay@cs.wisc.edu}};
9210447Snilay@cs.wisc.edu
9310447Snilay@cs.wisc.edudef template ROrImmDecode {{
9410447Snilay@cs.wisc.edu    {
9510447Snilay@cs.wisc.edu        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
9610447Snilay@cs.wisc.edu                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
9710447Snilay@cs.wisc.edu    }
9810447Snilay@cs.wisc.edu}};
9910447Snilay@cs.wisc.edu
10010447Snilay@cs.wisc.edulet {{
10110447Snilay@cs.wisc.edu    def splitOutImm(code):
10210447Snilay@cs.wisc.edu        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)')
10310447Snilay@cs.wisc.edu        rOrImmMatch = matcher.search(code)
10410447Snilay@cs.wisc.edu        if (rOrImmMatch == None):
10510447Snilay@cs.wisc.edu            return (False, code, '', '', '')
10610447Snilay@cs.wisc.edu        rString = rOrImmMatch.group("rNum")
10710447Snilay@cs.wisc.edu        iString = rOrImmMatch.group("iNum")
10810447Snilay@cs.wisc.edu        orig_code = code
10910447Snilay@cs.wisc.edu        code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code)
11010447Snilay@cs.wisc.edu        imm_code = matcher.sub('imm', orig_code)
11110447Snilay@cs.wisc.edu        return (True, code, imm_code, rString, iString)
11210447Snilay@cs.wisc.edu}};
11310447Snilay@cs.wisc.edu
11410447Snilay@cs.wisc.eduoutput decoder {{
11510447Snilay@cs.wisc.edu
11610447Snilay@cs.wisc.edu        inline void printMnemonic(std::ostream &os, const char * mnemonic)
11710447Snilay@cs.wisc.edu        {
11810447Snilay@cs.wisc.edu            ccprintf(os, "\t%s   ", mnemonic);
11910447Snilay@cs.wisc.edu        }
12010447Snilay@cs.wisc.edu
12110447Snilay@cs.wisc.edu        void
12210447Snilay@cs.wisc.edu        SparcStaticInst::printReg(std::ostream &os, int reg) const
12310447Snilay@cs.wisc.edu        {
12410447Snilay@cs.wisc.edu            const int MaxGlobal = 8;
12510447Snilay@cs.wisc.edu            const int MaxOutput = 16;
12610447Snilay@cs.wisc.edu            const int MaxLocal = 24;
12710447Snilay@cs.wisc.edu            const int MaxInput = 32;
12810447Snilay@cs.wisc.edu            if (reg == FramePointerReg)
12910447Snilay@cs.wisc.edu                ccprintf(os, "%%fp");
13010447Snilay@cs.wisc.edu            else if (reg == StackPointerReg)
13110447Snilay@cs.wisc.edu                ccprintf(os, "%%sp");
13210447Snilay@cs.wisc.edu            else if(reg < MaxGlobal)
13310447Snilay@cs.wisc.edu                ccprintf(os, "%%g%d", reg);
13410447Snilay@cs.wisc.edu            else if(reg < MaxOutput)
13510447Snilay@cs.wisc.edu                ccprintf(os, "%%o%d", reg - MaxGlobal);
13610447Snilay@cs.wisc.edu            else if(reg < MaxLocal)
13710447Snilay@cs.wisc.edu                ccprintf(os, "%%l%d", reg - MaxOutput);
13810447Snilay@cs.wisc.edu            else if(reg < MaxInput)
13910447Snilay@cs.wisc.edu                ccprintf(os, "%%i%d", reg - MaxLocal);
14010447Snilay@cs.wisc.edu            else {
14110447Snilay@cs.wisc.edu                ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
14210447Snilay@cs.wisc.edu            }
14310447Snilay@cs.wisc.edu        }
14410447Snilay@cs.wisc.edu
14510447Snilay@cs.wisc.edu        std::string SparcStaticInst::generateDisassembly(Addr pc,
14610447Snilay@cs.wisc.edu            const SymbolTable *symtab) const
14710447Snilay@cs.wisc.edu        {
14810447Snilay@cs.wisc.edu            std::stringstream ss;
14910447Snilay@cs.wisc.edu
15010447Snilay@cs.wisc.edu            printMnemonic(ss, mnemonic);
15110447Snilay@cs.wisc.edu
15210447Snilay@cs.wisc.edu            // just print the first two source regs... if there's
15310447Snilay@cs.wisc.edu            // a third one, it's a read-modify-write dest (Rc),
15410447Snilay@cs.wisc.edu            // e.g. for CMOVxx
15510447Snilay@cs.wisc.edu            if(_numSrcRegs > 0)
15610447Snilay@cs.wisc.edu            {
15710447Snilay@cs.wisc.edu                printReg(ss, _srcRegIdx[0]);
15810447Snilay@cs.wisc.edu            }
15910447Snilay@cs.wisc.edu            if(_numSrcRegs > 1)
16010447Snilay@cs.wisc.edu            {
16110447Snilay@cs.wisc.edu                ss << ",";
16210447Snilay@cs.wisc.edu                printReg(ss, _srcRegIdx[1]);
16310447Snilay@cs.wisc.edu            }
16410447Snilay@cs.wisc.edu
16510447Snilay@cs.wisc.edu            // just print the first dest... if there's a second one,
16610447Snilay@cs.wisc.edu            // it's generally implicit
16710447Snilay@cs.wisc.edu            if(_numDestRegs > 0)
16810447Snilay@cs.wisc.edu            {
16910447Snilay@cs.wisc.edu                if(_numSrcRegs > 0)
17010447Snilay@cs.wisc.edu                    ss << ",";
17110447Snilay@cs.wisc.edu                    printReg(ss, _destRegIdx[0]);
17210447Snilay@cs.wisc.edu            }
17310447Snilay@cs.wisc.edu
17410447Snilay@cs.wisc.edu            return ss.str();
17510447Snilay@cs.wisc.edu        }
17610447Snilay@cs.wisc.edu
17710447Snilay@cs.wisc.edu        bool passesCondition(uint32_t codes, uint32_t condition)
17810447Snilay@cs.wisc.edu        {
17910447Snilay@cs.wisc.edu            CondCodes condCodes;
18010447Snilay@cs.wisc.edu            condCodes.bits = codes;
18110447Snilay@cs.wisc.edu            switch(condition)
18210447Snilay@cs.wisc.edu            {
18310447Snilay@cs.wisc.edu              case Always:
18410447Snilay@cs.wisc.edu                return true;
18510447Snilay@cs.wisc.edu              case Never:
18610447Snilay@cs.wisc.edu                return false;
18710447Snilay@cs.wisc.edu              case NotEqual:
18810447Snilay@cs.wisc.edu                return !condCodes.z;
18910447Snilay@cs.wisc.edu              case Equal:
19010447Snilay@cs.wisc.edu                return condCodes.z;
19110447Snilay@cs.wisc.edu              case Greater:
19210447Snilay@cs.wisc.edu                return !(condCodes.z | (condCodes.n ^ condCodes.v));
19310447Snilay@cs.wisc.edu              case LessOrEqual:
19410447Snilay@cs.wisc.edu                return condCodes.z | (condCodes.n ^ condCodes.v);
19510447Snilay@cs.wisc.edu              case GreaterOrEqual:
19610447Snilay@cs.wisc.edu                return !(condCodes.n ^ condCodes.v);
19710447Snilay@cs.wisc.edu              case Less:
19810447Snilay@cs.wisc.edu                return (condCodes.n ^ condCodes.v);
19910447Snilay@cs.wisc.edu              case GreaterUnsigned:
20010447Snilay@cs.wisc.edu                return !(condCodes.c | condCodes.z);
20110447Snilay@cs.wisc.edu              case LessOrEqualUnsigned:
20210447Snilay@cs.wisc.edu                return (condCodes.c | condCodes.z);
20310447Snilay@cs.wisc.edu              case CarryClear:
20410447Snilay@cs.wisc.edu                return !condCodes.c;
20510447Snilay@cs.wisc.edu              case CarrySet:
20610447Snilay@cs.wisc.edu                return condCodes.c;
20710447Snilay@cs.wisc.edu              case Positive:
20810447Snilay@cs.wisc.edu                return !condCodes.n;
20910447Snilay@cs.wisc.edu              case Negative:
21010447Snilay@cs.wisc.edu                return condCodes.n;
21110447Snilay@cs.wisc.edu              case OverflowClear:
21210447Snilay@cs.wisc.edu                return !condCodes.v;
21310447Snilay@cs.wisc.edu              case OverflowSet:
21410447Snilay@cs.wisc.edu                return condCodes.v;
21510447Snilay@cs.wisc.edu            }
21610447Snilay@cs.wisc.edu            panic("Tried testing condition nonexistant "
21710447Snilay@cs.wisc.edu                    "condition code %d", condition);
21810447Snilay@cs.wisc.edu        }
21910447Snilay@cs.wisc.edu}};
22010447Snilay@cs.wisc.edu
22110447Snilay@cs.wisc.edu