base.isa (2632:1bb2f91485ea) base.isa (2944:10dcffb2904f)
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
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;
88 void printReg(std::ostream &os, RegIndex reg) const;
89 void printSrcReg(std::ostream &os, int reg) const;
90 void printDestReg(std::ostream &os, int reg) const;
91
92 void printRegArray(std::ostream &os,
93 const RegIndex indexArray[], int num) 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
94 };
95
96 bool passesCondition(uint32_t codes, uint32_t condition);
97
98 inline int64_t sign_ext(uint64_t data, int origWidth)
99 {
100 int shiftAmount = 64 - origWidth;
101 return (((int64_t)data) << shiftAmount) >> shiftAmount;
102 }
103}};
104
105output decoder {{
106
107 char * CondTestAbbrev[] =
108 {
109 "nev", //Never
110 "e", //Equal
111 "le", //Less or Equal
112 "l", //Less
113 "leu", //Less or Equal Unsigned
114 "c", //Carry set
115 "n", //Negative
116 "o", //Overflow set
117 "a", //Always
118 "ne", //Not Equal
119 "g", //Greater
120 "ge", //Greater or Equal
121 "gu", //Greater Unsigned
122 "cc", //Carry clear
123 "p", //Positive
124 "oc" //Overflow Clear
125 };
126}};
127
128def template ROrImmDecode {{
129 {
130 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
131 : (SparcStaticInst *)(new %(class_name)s(machInst)));
132 }
133}};
134
135let {{
136 def splitOutImm(code):
137 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
138 rOrImmMatch = matcher.search(code)
139 if (rOrImmMatch == None):
140 return (False, code, '', '', '')
141 rString = rOrImmMatch.group("rNum")
142 if (rOrImmMatch.group("typeQual") != None):
143 rString += rOrImmMatch.group("typeQual")
144 iString = rOrImmMatch.group("iNum")
145 orig_code = code
146 code = matcher.sub('Rs' + rString, orig_code)
147 imm_code = matcher.sub('imm', orig_code)
148 return (True, code, imm_code, rString, iString)
149}};
150
151output decoder {{
152
153 inline void printMnemonic(std::ostream &os, const char * mnemonic)
154 {
155 ccprintf(os, "\t%s ", mnemonic);
156 }
157
158 void SparcStaticInst::printRegArray(std::ostream &os,
159 const RegIndex indexArray[], int num) const
160 {
161 if(num <= 0)
162 return;
163 printReg(os, indexArray[0]);
164 for(int x = 1; x < num; x++)
165 {
166 os << ", ";
167 printReg(os, indexArray[x]);
168 }
169 }
170
153 void
171 void
154 SparcStaticInst::printReg(std::ostream &os, int reg) const
172 SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
155 {
173 {
174 if(_numSrcRegs > reg)
175 printReg(os, _srcRegIdx[reg]);
176 }
177
178 void
179 SparcStaticInst::printDestReg(std::ostream &os, int reg) const
180 {
181 if(_numDestRegs > reg)
182 printReg(os, _destRegIdx[reg]);
183 }
184
185 void
186 SparcStaticInst::printReg(std::ostream &os, RegIndex reg) const
187 {
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
188 const int MaxGlobal = 8;
189 const int MaxOutput = 16;
190 const int MaxLocal = 24;
191 const int MaxInput = 32;
192 if (reg == FramePointerReg)
193 ccprintf(os, "%%fp");
194 else if (reg == StackPointerReg)
195 ccprintf(os, "%%sp");
196 else if(reg < MaxGlobal)
197 ccprintf(os, "%%g%d", reg);
198 else if(reg < MaxOutput)
199 ccprintf(os, "%%o%d", reg - MaxGlobal);
200 else if(reg < MaxLocal)
201 ccprintf(os, "%%l%d", reg - MaxOutput);
202 else if(reg < MaxInput)
203 ccprintf(os, "%%i%d", reg - MaxLocal);
204 else {
205 ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
206 }
207 }
208
209 std::string SparcStaticInst::generateDisassembly(Addr pc,
210 const SymbolTable *symtab) const
211 {
212 std::stringstream ss;
213
214 printMnemonic(ss, mnemonic);
215
216 // just print the first two source regs... if there's
217 // a third one, it's a read-modify-write dest (Rc),
218 // e.g. for CMOVxx
219 if(_numSrcRegs > 0)
220 {
221 printReg(ss, _srcRegIdx[0]);
222 }
223 if(_numSrcRegs > 1)
224 {
225 ss << ",";
226 printReg(ss, _srcRegIdx[1]);
227 }
228
229 // just print the first dest... if there's a second one,
230 // it's generally implicit
231 if(_numDestRegs > 0)
232 {
233 if(_numSrcRegs > 0)
234 ss << ",";
235 printReg(ss, _destRegIdx[0]);
236 }
237
238 return ss.str();
239 }
240
241 bool passesCondition(uint32_t codes, uint32_t condition)
242 {
243 CondCodes condCodes;
244 condCodes.bits = codes;
245 switch(condition)
246 {
247 case Always:
248 return true;
249 case Never:
250 return false;
251 case NotEqual:
252 return !condCodes.z;
253 case Equal:
254 return condCodes.z;
255 case Greater:
256 return !(condCodes.z | (condCodes.n ^ condCodes.v));
257 case LessOrEqual:
258 return condCodes.z | (condCodes.n ^ condCodes.v);
259 case GreaterOrEqual:
260 return !(condCodes.n ^ condCodes.v);
261 case Less:
262 return (condCodes.n ^ condCodes.v);
263 case GreaterUnsigned:
264 return !(condCodes.c | condCodes.z);
265 case LessOrEqualUnsigned:
266 return (condCodes.c | condCodes.z);
267 case CarryClear:
268 return !condCodes.c;
269 case CarrySet:
270 return condCodes.c;
271 case Positive:
272 return !condCodes.n;
273 case Negative:
274 return condCodes.n;
275 case OverflowClear:
276 return !condCodes.v;
277 case OverflowSet:
278 return condCodes.v;
279 }
280 panic("Tried testing condition nonexistant "
281 "condition code %d", condition);
282 }
283}};
284