base.isa revision 2526
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        /**
41         * Base class for all SPARC static instructions.
42         */
43        class SparcStaticInst : public StaticInst
44        {
45          protected:
46            // Constructor.
47            SparcStaticInst(const char *mnem,
48                 MachInst _machInst, OpClass __opClass)
49                    : StaticInst(mnem, _machInst, __opClass)
50                {
51                }
52
53            std::string generateDisassembly(Addr pc,
54                const SymbolTable *symtab) const;
55
56            void printReg(std::ostream &os, int reg) const;
57        };
58
59        bool passesCondition(uint32_t codes, uint32_t condition);
60
61        inline int64_t sign_ext(uint64_t data, int origWidth)
62        {
63            int shiftAmount = 64 - origWidth;
64            return (((int64_t)data) << shiftAmount) >> shiftAmount;
65        }
66}};
67
68def template ROrImmDecode {{
69    {
70        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
71                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
72    }
73}};
74
75let {{
76    def splitOutImm(code):
77        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)')
78        rOrImmMatch = matcher.search(code)
79        if (rOrImmMatch == None):
80            return (False, code, '', '', '')
81        rString = rOrImmMatch.group("rNum")
82        iString = rOrImmMatch.group("iNum")
83        orig_code = code
84        code = matcher.sub('Rs' + rOrImmMatch.group("rNum"), orig_code)
85        imm_code = matcher.sub('imm', orig_code)
86        return (True, code, imm_code, rString, iString)
87}};
88
89output decoder {{
90
91        inline void printMnemonic(std::ostream &os, const char * mnemonic)
92        {
93            ccprintf(os, "\t%s   ", mnemonic);
94        }
95
96        void
97        SparcStaticInst::printReg(std::ostream &os, int reg) const
98        {
99            const int MaxGlobal = 8;
100            const int MaxOutput = 16;
101            const int MaxLocal = 24;
102            const int MaxInput = 32;
103            if (reg == FramePointerReg)
104                ccprintf(os, "%%fp");
105            else if (reg == StackPointerReg)
106                ccprintf(os, "%%sp");
107            else if(reg < MaxGlobal)
108                ccprintf(os, "%%g%d", reg);
109            else if(reg < MaxOutput)
110                ccprintf(os, "%%o%d", reg - MaxGlobal);
111            else if(reg < MaxLocal)
112                ccprintf(os, "%%l%d", reg - MaxOutput);
113            else if(reg < MaxInput)
114                ccprintf(os, "%%i%d", reg - MaxLocal);
115            else {
116                ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
117            }
118        }
119
120        std::string SparcStaticInst::generateDisassembly(Addr pc,
121            const SymbolTable *symtab) const
122        {
123            std::stringstream ss;
124
125            printMnemonic(ss, mnemonic);
126
127            // just print the first two source regs... if there's
128            // a third one, it's a read-modify-write dest (Rc),
129            // e.g. for CMOVxx
130            if(_numSrcRegs > 0)
131            {
132                printReg(ss, _srcRegIdx[0]);
133            }
134            if(_numSrcRegs > 1)
135            {
136                ss << ",";
137                printReg(ss, _srcRegIdx[1]);
138            }
139
140            // just print the first dest... if there's a second one,
141            // it's generally implicit
142            if(_numDestRegs > 0)
143            {
144                if(_numSrcRegs > 0)
145                    ss << ",";
146                    printReg(ss, _destRegIdx[0]);
147            }
148
149            return ss.str();
150        }
151
152        bool passesCondition(uint32_t codes, uint32_t condition)
153        {
154            CondCodes condCodes;
155            condCodes.bits = codes;
156            switch(condition)
157            {
158              case Always:
159                return true;
160              case Never:
161                return false;
162              case NotEqual:
163                return !condCodes.z;
164              case Equal:
165                return condCodes.z;
166              case Greater:
167                return !(condCodes.z | (condCodes.n ^ condCodes.v));
168              case LessOrEqual:
169                return condCodes.z | (condCodes.n ^ condCodes.v);
170              case GreaterOrEqual:
171                return !(condCodes.n ^ condCodes.v);
172              case Less:
173                return (condCodes.n ^ condCodes.v);
174              case GreaterUnsigned:
175                return !(condCodes.c | condCodes.z);
176              case LessOrEqualUnsigned:
177                return (condCodes.c | condCodes.z);
178              case CarryClear:
179                return !condCodes.c;
180              case CarrySet:
181                return condCodes.c;
182              case Positive:
183                return !condCodes.n;
184              case Negative:
185                return condCodes.n;
186              case OverflowClear:
187                return !condCodes.v;
188              case OverflowSet:
189                return condCodes.v;
190            }
191            panic("Tried testing condition nonexistant "
192                    "condition code %d", condition);
193        }
194}};
195
196