base.isa revision 2561
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+)')
103        rOrImmMatch = matcher.search(code)
104        if (rOrImmMatch == None):
105            return (False, code, '', '', '')
106        rString = rOrImmMatch.group("rNum")
107        iString = rOrImmMatch.group("iNum")
108        orig_code = code
109        code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code)
110        imm_code = matcher.sub('imm', orig_code)
111        return (True, code, imm_code, rString, iString)
112}};
113
114output decoder {{
115
116        inline void printMnemonic(std::ostream &os, const char * mnemonic)
117        {
118            ccprintf(os, "\t%s   ", mnemonic);
119        }
120
121        void
122        SparcStaticInst::printReg(std::ostream &os, int reg) const
123        {
124            const int MaxGlobal = 8;
125            const int MaxOutput = 16;
126            const int MaxLocal = 24;
127            const int MaxInput = 32;
128            if (reg == FramePointerReg)
129                ccprintf(os, "%%fp");
130            else if (reg == StackPointerReg)
131                ccprintf(os, "%%sp");
132            else if(reg < MaxGlobal)
133                ccprintf(os, "%%g%d", reg);
134            else if(reg < MaxOutput)
135                ccprintf(os, "%%o%d", reg - MaxGlobal);
136            else if(reg < MaxLocal)
137                ccprintf(os, "%%l%d", reg - MaxOutput);
138            else if(reg < MaxInput)
139                ccprintf(os, "%%i%d", reg - MaxLocal);
140            else {
141                ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
142            }
143        }
144
145        std::string SparcStaticInst::generateDisassembly(Addr pc,
146            const SymbolTable *symtab) const
147        {
148            std::stringstream ss;
149
150            printMnemonic(ss, mnemonic);
151
152            // just print the first two source regs... if there's
153            // a third one, it's a read-modify-write dest (Rc),
154            // e.g. for CMOVxx
155            if(_numSrcRegs > 0)
156            {
157                printReg(ss, _srcRegIdx[0]);
158            }
159            if(_numSrcRegs > 1)
160            {
161                ss << ",";
162                printReg(ss, _srcRegIdx[1]);
163            }
164
165            // just print the first dest... if there's a second one,
166            // it's generally implicit
167            if(_numDestRegs > 0)
168            {
169                if(_numSrcRegs > 0)
170                    ss << ",";
171                    printReg(ss, _destRegIdx[0]);
172            }
173
174            return ss.str();
175        }
176
177        bool passesCondition(uint32_t codes, uint32_t condition)
178        {
179            CondCodes condCodes;
180            condCodes.bits = codes;
181            switch(condition)
182            {
183              case Always:
184                return true;
185              case Never:
186                return false;
187              case NotEqual:
188                return !condCodes.z;
189              case Equal:
190                return condCodes.z;
191              case Greater:
192                return !(condCodes.z | (condCodes.n ^ condCodes.v));
193              case LessOrEqual:
194                return condCodes.z | (condCodes.n ^ condCodes.v);
195              case GreaterOrEqual:
196                return !(condCodes.n ^ condCodes.v);
197              case Less:
198                return (condCodes.n ^ condCodes.v);
199              case GreaterUnsigned:
200                return !(condCodes.c | condCodes.z);
201              case LessOrEqualUnsigned:
202                return (condCodes.c | condCodes.z);
203              case CarryClear:
204                return !condCodes.c;
205              case CarrySet:
206                return condCodes.c;
207              case Positive:
208                return !condCodes.n;
209              case Negative:
210                return condCodes.n;
211              case OverflowClear:
212                return !condCodes.v;
213              case OverflowSet:
214                return condCodes.v;
215            }
216            panic("Tried testing condition nonexistant "
217                    "condition code %d", condition);
218        }
219}};
220
221