base.isa revision 2516
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 = sizeof(uint64_t) - 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    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