base.isa revision 2632:1bb2f91485ea
1// Copyright (c) 2006 The Regents of The University of Michigan
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are
6// met: redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer;
8// redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution;
11// neither the name of the copyright holders nor the names of its
12// contributors may be used to endorse or promote products derived from
13// this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26//
27// Authors: Ali Saidi
28//          Gabe Black
29//          Steve Reinhardt
30
31////////////////////////////////////////////////////////////////////
32//
33// Base class for sparc instructions, and some support functions
34//
35
36output header {{
37
38        union CondCodes
39        {
40            struct
41            {
42                uint8_t c:1;
43                uint8_t v:1;
44                uint8_t z:1;
45                uint8_t n:1;
46            };
47            uint32_t bits;
48        };
49
50        enum CondTest
51        {
52            Always=0x8,
53            Never=0x0,
54            NotEqual=0x9,
55            Equal=0x1,
56            Greater=0xA,
57            LessOrEqual=0x2,
58            GreaterOrEqual=0xB,
59            Less=0x3,
60            GreaterUnsigned=0xC,
61            LessOrEqualUnsigned=0x4,
62            CarryClear=0xD,
63            CarrySet=0x5,
64            Positive=0xE,
65            Negative=0x6,
66            OverflowClear=0xF,
67            OverflowSet=0x7
68        };
69
70        extern char * CondTestAbbrev[];
71
72        /**
73         * Base class for all SPARC static instructions.
74         */
75        class SparcStaticInst : public StaticInst
76        {
77          protected:
78            // Constructor.
79            SparcStaticInst(const char *mnem,
80                 MachInst _machInst, OpClass __opClass)
81                    : StaticInst(mnem, _machInst, __opClass)
82                {
83                }
84
85            std::string generateDisassembly(Addr pc,
86                const SymbolTable *symtab) const;
87
88            void printReg(std::ostream &os, int reg) const;
89        };
90
91        bool passesCondition(uint32_t codes, uint32_t condition);
92
93        inline int64_t sign_ext(uint64_t data, int origWidth)
94        {
95            int shiftAmount = 64 - origWidth;
96            return (((int64_t)data) << shiftAmount) >> shiftAmount;
97        }
98}};
99
100output decoder {{
101
102        char * CondTestAbbrev[] =
103        {
104            "nev", //Never
105            "e", //Equal
106            "le", //Less or Equal
107            "l", //Less
108            "leu", //Less or Equal Unsigned
109            "c", //Carry set
110            "n", //Negative
111            "o", //Overflow set
112            "a", //Always
113            "ne", //Not Equal
114            "g", //Greater
115            "ge", //Greater or Equal
116            "gu", //Greater Unsigned
117            "cc", //Carry clear
118            "p", //Positive
119            "oc" //Overflow Clear
120        };
121}};
122
123def template ROrImmDecode {{
124    {
125        return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
126                  : (SparcStaticInst *)(new %(class_name)s(machInst)));
127    }
128}};
129
130let {{
131    def splitOutImm(code):
132        matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
133        rOrImmMatch = matcher.search(code)
134        if (rOrImmMatch == None):
135            return (False, code, '', '', '')
136        rString = rOrImmMatch.group("rNum")
137        if (rOrImmMatch.group("typeQual") != None):
138            rString += rOrImmMatch.group("typeQual")
139        iString = rOrImmMatch.group("iNum")
140        orig_code = code
141        code = matcher.sub('Rs' + rString, orig_code)
142        imm_code = matcher.sub('imm', orig_code)
143        return (True, code, imm_code, rString, iString)
144}};
145
146output decoder {{
147
148        inline void printMnemonic(std::ostream &os, const char * mnemonic)
149        {
150            ccprintf(os, "\t%s   ", mnemonic);
151        }
152
153        void
154        SparcStaticInst::printReg(std::ostream &os, int reg) const
155        {
156            const int MaxGlobal = 8;
157            const int MaxOutput = 16;
158            const int MaxLocal = 24;
159            const int MaxInput = 32;
160            if (reg == FramePointerReg)
161                ccprintf(os, "%%fp");
162            else if (reg == StackPointerReg)
163                ccprintf(os, "%%sp");
164            else if(reg < MaxGlobal)
165                ccprintf(os, "%%g%d", reg);
166            else if(reg < MaxOutput)
167                ccprintf(os, "%%o%d", reg - MaxGlobal);
168            else if(reg < MaxLocal)
169                ccprintf(os, "%%l%d", reg - MaxOutput);
170            else if(reg < MaxInput)
171                ccprintf(os, "%%i%d", reg - MaxLocal);
172            else {
173                ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
174            }
175        }
176
177        std::string SparcStaticInst::generateDisassembly(Addr pc,
178            const SymbolTable *symtab) const
179        {
180            std::stringstream ss;
181
182            printMnemonic(ss, mnemonic);
183
184            // just print the first two source regs... if there's
185            // a third one, it's a read-modify-write dest (Rc),
186            // e.g. for CMOVxx
187            if(_numSrcRegs > 0)
188            {
189                printReg(ss, _srcRegIdx[0]);
190            }
191            if(_numSrcRegs > 1)
192            {
193                ss << ",";
194                printReg(ss, _srcRegIdx[1]);
195            }
196
197            // just print the first dest... if there's a second one,
198            // it's generally implicit
199            if(_numDestRegs > 0)
200            {
201                if(_numSrcRegs > 0)
202                    ss << ",";
203                    printReg(ss, _destRegIdx[0]);
204            }
205
206            return ss.str();
207        }
208
209        bool passesCondition(uint32_t codes, uint32_t condition)
210        {
211            CondCodes condCodes;
212            condCodes.bits = codes;
213            switch(condition)
214            {
215              case Always:
216                return true;
217              case Never:
218                return false;
219              case NotEqual:
220                return !condCodes.z;
221              case Equal:
222                return condCodes.z;
223              case Greater:
224                return !(condCodes.z | (condCodes.n ^ condCodes.v));
225              case LessOrEqual:
226                return condCodes.z | (condCodes.n ^ condCodes.v);
227              case GreaterOrEqual:
228                return !(condCodes.n ^ condCodes.v);
229              case Less:
230                return (condCodes.n ^ condCodes.v);
231              case GreaterUnsigned:
232                return !(condCodes.c | condCodes.z);
233              case LessOrEqualUnsigned:
234                return (condCodes.c | condCodes.z);
235              case CarryClear:
236                return !condCodes.c;
237              case CarrySet:
238                return condCodes.c;
239              case Positive:
240                return !condCodes.n;
241              case Negative:
242                return condCodes.n;
243              case OverflowClear:
244                return !condCodes.v;
245              case OverflowSet:
246                return condCodes.v;
247            }
248            panic("Tried testing condition nonexistant "
249                    "condition code %d", condition);
250        }
251}};
252
253