base.isa revision 2516
110086Snilay@cs.wisc.edu////////////////////////////////////////////////////////////////////
210086Snilay@cs.wisc.edu//
310086Snilay@cs.wisc.edu// Base class for sparc instructions, and some support functions
410086Snilay@cs.wisc.edu//
510086Snilay@cs.wisc.edu
610086Snilay@cs.wisc.eduoutput header {{
710086Snilay@cs.wisc.edu
810086Snilay@cs.wisc.edu        union CondCodes
910086Snilay@cs.wisc.edu        {
1010086Snilay@cs.wisc.edu            struct
1110086Snilay@cs.wisc.edu            {
1210086Snilay@cs.wisc.edu                uint8_t c:1;
1310086Snilay@cs.wisc.edu                uint8_t v:1;
1410086Snilay@cs.wisc.edu                uint8_t z:1;
1510086Snilay@cs.wisc.edu                uint8_t n:1;
1610086Snilay@cs.wisc.edu            };
1710086Snilay@cs.wisc.edu            uint32_t bits;
1810086Snilay@cs.wisc.edu        };
1910086Snilay@cs.wisc.edu
2010086Snilay@cs.wisc.edu        enum CondTest
2110086Snilay@cs.wisc.edu        {
2210086Snilay@cs.wisc.edu            Always=0x8,
2310086Snilay@cs.wisc.edu            Never=0x0,
2410086Snilay@cs.wisc.edu            NotEqual=0x9,
2510086Snilay@cs.wisc.edu            Equal=0x1,
2610086Snilay@cs.wisc.edu            Greater=0xA,
2710086Snilay@cs.wisc.edu            LessOrEqual=0x2,
2810086Snilay@cs.wisc.edu            GreaterOrEqual=0xB,
2911793Sbrandon.potter@amd.com            Less=0x3,
3011793Sbrandon.potter@amd.com            GreaterUnsigned=0xC,
318092Snilay@cs.wisc.edu            LessOrEqualUnsigned=0x4,
328092Snilay@cs.wisc.edu            CarryClear=0xD,
338092Snilay@cs.wisc.edu            CarrySet=0x5,
348092Snilay@cs.wisc.edu            Positive=0xE,
358174Snilay@cs.wisc.edu            Negative=0x6,
368174Snilay@cs.wisc.edu            OverflowClear=0xF,
378092Snilay@cs.wisc.edu            OverflowSet=0x7
388174Snilay@cs.wisc.edu        };
3911118Snilay@cs.wisc.edu
4011118Snilay@cs.wisc.edu        /**
418174Snilay@cs.wisc.edu         * Base class for all SPARC static instructions.
4211118Snilay@cs.wisc.edu         */
438174Snilay@cs.wisc.edu        class SparcStaticInst : public StaticInst
448174Snilay@cs.wisc.edu        {
458174Snilay@cs.wisc.edu          protected:
468174Snilay@cs.wisc.edu            // Constructor.
478174Snilay@cs.wisc.edu            SparcStaticInst(const char *mnem,
488092Snilay@cs.wisc.edu                 MachInst _machInst, OpClass __opClass)
499302Snilay@cs.wisc.edu                    : StaticInst(mnem, _machInst, __opClass)
509302Snilay@cs.wisc.edu                {
519302Snilay@cs.wisc.edu                }
529302Snilay@cs.wisc.edu
539302Snilay@cs.wisc.edu            std::string generateDisassembly(Addr pc,
549302Snilay@cs.wisc.edu                const SymbolTable *symtab) const;
559302Snilay@cs.wisc.edu
569302Snilay@cs.wisc.edu            void printReg(std::ostream &os, int reg) const;
579302Snilay@cs.wisc.edu        };
589302Snilay@cs.wisc.edu
599302Snilay@cs.wisc.edu        bool passesCondition(uint32_t codes, uint32_t condition);
609302Snilay@cs.wisc.edu
619302Snilay@cs.wisc.edu        inline int64_t sign_ext(uint64_t data, int origWidth)
629302Snilay@cs.wisc.edu        {
639302Snilay@cs.wisc.edu            int shiftAmount = sizeof(uint64_t) - origWidth;
649302Snilay@cs.wisc.edu            return (((int64_t)data) << shiftAmount) >> shiftAmount;
659302Snilay@cs.wisc.edu        }
669302Snilay@cs.wisc.edu}};
679302Snilay@cs.wisc.edu
689302Snilay@cs.wisc.edudef template ROrImmDecode {{
699302Snilay@cs.wisc.edu    {
709572Sbah13@duke.edu        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
719572Sbah13@duke.edu                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
7211025Snilay@cs.wisc.edu    }
739572Sbah13@duke.edu}};
749302Snilay@cs.wisc.edu
7510563Sandreas.hansson@arm.comlet {{
769302Snilay@cs.wisc.edu    def splitOutImm(code):
779572Sbah13@duke.edu        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)')
789572Sbah13@duke.edu        rOrImmMatch = matcher.search(code)
799302Snilay@cs.wisc.edu        if (rOrImmMatch == None):
809572Sbah13@duke.edu            return (False, code, '', '', '')
819572Sbah13@duke.edu        rString = rOrImmMatch.group("rNum")
829302Snilay@cs.wisc.edu        iString = rOrImmMatch.group("iNum")
839572Sbah13@duke.edu        orig_code = code
849572Sbah13@duke.edu        code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code)
859302Snilay@cs.wisc.edu        imm_code = matcher.sub('imm', orig_code)
86        return (True, code, imm_code, rString, iString)
87
88    def genCompositeIop(code, name, Name, parent, opt_flags, **extras):
89        origBlock = CodeBlock(code)
90        composite = code
91        for snippet in extras.values():
92            composite += ('\n' + snippet)
93        compositeBlock = CodeBlock(composite)
94        iop = InstObjParams(name, Name, parent, compositeBlock, opt_flags)
95        iop.code = origBlock.code
96        iop.orig_code = origBlock.orig_code
97        for (name, snippet) in extras.items():
98            exec "iop.%s = CodeBlock(snippet).code" % name
99        return iop
100}};
101
102output decoder {{
103
104        inline void printMnemonic(std::ostream &os, const char * mnemonic)
105        {
106            ccprintf(os, "\t%s   ", mnemonic);
107        }
108
109        void
110        SparcStaticInst::printReg(std::ostream &os, int reg) const
111        {
112            const int MaxGlobal = 8;
113            const int MaxOutput = 16;
114            const int MaxLocal = 24;
115            const int MaxInput = 32;
116            if (reg == FramePointerReg)
117                ccprintf(os, "%%fp");
118            else if (reg == StackPointerReg)
119                ccprintf(os, "%%sp");
120            else if(reg < MaxGlobal)
121                ccprintf(os, "%%g%d", reg);
122            else if(reg < MaxOutput)
123                ccprintf(os, "%%o%d", reg - MaxGlobal);
124            else if(reg < MaxLocal)
125                ccprintf(os, "%%l%d", reg - MaxOutput);
126            else if(reg < MaxInput)
127                ccprintf(os, "%%i%d", reg - MaxLocal);
128            else {
129                ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
130            }
131        }
132
133        std::string SparcStaticInst::generateDisassembly(Addr pc,
134            const SymbolTable *symtab) const
135        {
136            std::stringstream ss;
137
138            printMnemonic(ss, mnemonic);
139
140            // just print the first two source regs... if there's
141            // a third one, it's a read-modify-write dest (Rc),
142            // e.g. for CMOVxx
143            if(_numSrcRegs > 0)
144            {
145                printReg(ss, _srcRegIdx[0]);
146            }
147            if(_numSrcRegs > 1)
148            {
149                ss << ",";
150                printReg(ss, _srcRegIdx[1]);
151            }
152
153            // just print the first dest... if there's a second one,
154            // it's generally implicit
155            if(_numDestRegs > 0)
156            {
157                if(_numSrcRegs > 0)
158                    ss << ",";
159                    printReg(ss, _destRegIdx[0]);
160            }
161
162            return ss.str();
163        }
164
165        bool passesCondition(uint32_t codes, uint32_t condition)
166        {
167            CondCodes condCodes;
168            condCodes.bits = codes;
169            switch(condition)
170            {
171              case Always:
172                return true;
173              case Never:
174                return false;
175              case NotEqual:
176                return !condCodes.z;
177              case Equal:
178                return condCodes.z;
179              case Greater:
180                return !(condCodes.z | (condCodes.n ^ condCodes.v));
181              case LessOrEqual:
182                return condCodes.z | (condCodes.n ^ condCodes.v);
183              case GreaterOrEqual:
184                return !(condCodes.n ^ condCodes.v);
185              case Less:
186                return (condCodes.n ^ condCodes.v);
187              case GreaterUnsigned:
188                return !(condCodes.c | condCodes.z);
189              case LessOrEqualUnsigned:
190                return (condCodes.c | condCodes.z);
191              case CarryClear:
192                return !condCodes.c;
193              case CarrySet:
194                return condCodes.c;
195              case Positive:
196                return !condCodes.n;
197              case Negative:
198                return condCodes.n;
199              case OverflowClear:
200                return !condCodes.v;
201              case OverflowSet:
202                return condCodes.v;
203            }
204            panic("Tried testing condition nonexistant "
205                    "condition code %d", condition);
206        }
207}};
208
209