base.isa revision 2614
1////////////////////////////////////////////////////////////////////
2//
3// Base class for sparc instructions, and some support functions
4//
5
6output header {{
7
8        union CondCodes
9        {
10            struct
11            {
12                uint8_t c:1;
13                uint8_t v:1;
14                uint8_t z:1;
15                uint8_t n:1;
16            };
17            uint32_t bits;
18        };
19
20        enum CondTest
21        {
22            Always=0x8,
23            Never=0x0,
24            NotEqual=0x9,
25            Equal=0x1,
26            Greater=0xA,
27            LessOrEqual=0x2,
28            GreaterOrEqual=0xB,
29            Less=0x3,
30            GreaterUnsigned=0xC,
31            LessOrEqualUnsigned=0x4,
32            CarryClear=0xD,
33            CarrySet=0x5,
34            Positive=0xE,
35            Negative=0x6,
36            OverflowClear=0xF,
37            OverflowSet=0x7
38        };
39
40        extern char * CondTestAbbrev[];
41
42        /**
43         * Base class for all SPARC static instructions.
44         */
45        class SparcStaticInst : public StaticInst
46        {
47          protected:
48            // Constructor.
49            SparcStaticInst(const char *mnem,
50                 MachInst _machInst, OpClass __opClass)
51                    : StaticInst(mnem, _machInst, __opClass)
52                {
53                }
54
55            std::string generateDisassembly(Addr pc,
56                const SymbolTable *symtab) const;
57
58            void printReg(std::ostream &os, int reg) const;
59        };
60
61        bool passesCondition(uint32_t codes, uint32_t condition);
62
63        inline int64_t sign_ext(uint64_t data, int origWidth)
64        {
65            int shiftAmount = 64 - origWidth;
66            return (((int64_t)data) << shiftAmount) >> shiftAmount;
67        }
68}};
69
70output decoder {{
71
72        char * CondTestAbbrev[] =
73        {
74            "nev", //Never
75            "e", //Equal
76            "le", //Less or Equal
77            "l", //Less
78            "leu", //Less or Equal Unsigned
79            "c", //Carry set
80            "n", //Negative
81            "o", //Overflow set
82            "a", //Always
83            "ne", //Not Equal
84            "g", //Greater
85            "ge", //Greater or Equal
86            "gu", //Greater Unsigned
87            "cc", //Carry clear
88            "p", //Positive
89            "oc" //Overflow Clear
90        };
91}};
92
93def template ROrImmDecode {{
94    {
95        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
96                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
97    }
98}};
99
100let {{
101    def splitOutImm(code):
102        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
103        rOrImmMatch = matcher.search(code)
104        if (rOrImmMatch == None):
105            return (False, code, '', '', '')
106        rString = rOrImmMatch.group("rNum")
107        if (rOrImmMatch.group("typeQual") != None):
108            rString += rOrImmMatch.group("typeQual")
109        iString = rOrImmMatch.group("iNum")
110        orig_code = code
111        code = matcher.sub('Rs' + rString, orig_code)
112        imm_code = matcher.sub('imm', orig_code)
113        return (True, code, imm_code, rString, iString)
114}};
115
116output decoder {{
117
118        inline void printMnemonic(std::ostream &os, const char * mnemonic)
119        {
120            ccprintf(os, "\t%s   ", mnemonic);
121        }
122
123        void
124        SparcStaticInst::printReg(std::ostream &os, int reg) const
125        {
126            const int MaxGlobal = 8;
127            const int MaxOutput = 16;
128            const int MaxLocal = 24;
129            const int MaxInput = 32;
130            if (reg == FramePointerReg)
131                ccprintf(os, "%%fp");
132            else if (reg == StackPointerReg)
133                ccprintf(os, "%%sp");
134            else if(reg < MaxGlobal)
135                ccprintf(os, "%%g%d", reg);
136            else if(reg < MaxOutput)
137                ccprintf(os, "%%o%d", reg - MaxGlobal);
138            else if(reg < MaxLocal)
139                ccprintf(os, "%%l%d", reg - MaxOutput);
140            else if(reg < MaxInput)
141                ccprintf(os, "%%i%d", reg - MaxLocal);
142            else {
143                ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
144            }
145        }
146
147        std::string SparcStaticInst::generateDisassembly(Addr pc,
148            const SymbolTable *symtab) const
149        {
150            std::stringstream ss;
151
152            printMnemonic(ss, mnemonic);
153
154            // just print the first two source regs... if there's
155            // a third one, it's a read-modify-write dest (Rc),
156            // e.g. for CMOVxx
157            if(_numSrcRegs > 0)
158            {
159                printReg(ss, _srcRegIdx[0]);
160            }
161            if(_numSrcRegs > 1)
162            {
163                ss << ",";
164                printReg(ss, _srcRegIdx[1]);
165            }
166
167            // just print the first dest... if there's a second one,
168            // it's generally implicit
169            if(_numDestRegs > 0)
170            {
171                if(_numSrcRegs > 0)
172                    ss << ",";
173                    printReg(ss, _destRegIdx[0]);
174            }
175
176            return ss.str();
177        }
178
179        bool passesCondition(uint32_t codes, uint32_t condition)
180        {
181            CondCodes condCodes;
182            condCodes.bits = codes;
183            switch(condition)
184            {
185              case Always:
186                return true;
187              case Never:
188                return false;
189              case NotEqual:
190                return !condCodes.z;
191              case Equal:
192                return condCodes.z;
193              case Greater:
194                return !(condCodes.z | (condCodes.n ^ condCodes.v));
195              case LessOrEqual:
196                return condCodes.z | (condCodes.n ^ condCodes.v);
197              case GreaterOrEqual:
198                return !(condCodes.n ^ condCodes.v);
199              case Less:
200                return (condCodes.n ^ condCodes.v);
201              case GreaterUnsigned:
202                return !(condCodes.c | condCodes.z);
203              case LessOrEqualUnsigned:
204                return (condCodes.c | condCodes.z);
205              case CarryClear:
206                return !condCodes.c;
207              case CarrySet:
208                return condCodes.c;
209              case Positive:
210                return !condCodes.n;
211              case Negative:
212                return condCodes.n;
213              case OverflowClear:
214                return !condCodes.v;
215              case OverflowSet:
216                return condCodes.v;
217            }
218            panic("Tried testing condition nonexistant "
219                    "condition code %d", condition);
220        }
221}};
222
223