base.isa (7720:65d338a8dba4) base.isa (7741:340b6f01d69b)
1// Copyright (c) 2006-2007 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 enum FpCondTest
71 {
72 FAlways=0x8,
73 FNever=0x0,
74 FUnordered=0x7,
75 FGreater=0x6,
76 FUnorderedOrGreater=0x5,
77 FLess=0x4,
78 FUnorderedOrLess=0x3,
79 FLessOrGreater=0x2,
80 FNotEqual=0x1,
81 FEqual=0x9,
82 FUnorderedOrEqual=0xA,
83 FGreaterOrEqual=0xB,
84 FUnorderedOrGreaterOrEqual=0xC,
85 FLessOrEqual=0xD,
86 FUnorderedOrLessOrEqual=0xE,
87 FOrdered=0xF
88 };
89
90 extern const char *CondTestAbbrev[];
91
92 /**
93 * Base class for all SPARC static instructions.
94 */
95 class SparcStaticInst : public StaticInst
96 {
97 protected:
98 // Constructor.
99 SparcStaticInst(const char *mnem,
100 ExtMachInst _machInst, OpClass __opClass)
101 : StaticInst(mnem, _machInst, __opClass)
102 {
103 }
104
105 std::string generateDisassembly(Addr pc,
106 const SymbolTable *symtab) const;
107
108 void printReg(std::ostream &os, int reg) const;
109 void printSrcReg(std::ostream &os, int reg) const;
110 void printDestReg(std::ostream &os, int reg) const;
111
112 void printRegArray(std::ostream &os,
113 const RegIndex indexArray[], int num) const;
114
115 void advancePC(SparcISA::PCState &pcState) const;
116 };
117
118 bool passesFpCondition(uint32_t fcc, uint32_t condition);
119
120 bool passesCondition(uint32_t codes, uint32_t condition);
121
1// Copyright (c) 2006-2007 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 enum FpCondTest
71 {
72 FAlways=0x8,
73 FNever=0x0,
74 FUnordered=0x7,
75 FGreater=0x6,
76 FUnorderedOrGreater=0x5,
77 FLess=0x4,
78 FUnorderedOrLess=0x3,
79 FLessOrGreater=0x2,
80 FNotEqual=0x1,
81 FEqual=0x9,
82 FUnorderedOrEqual=0xA,
83 FGreaterOrEqual=0xB,
84 FUnorderedOrGreaterOrEqual=0xC,
85 FLessOrEqual=0xD,
86 FUnorderedOrLessOrEqual=0xE,
87 FOrdered=0xF
88 };
89
90 extern const char *CondTestAbbrev[];
91
92 /**
93 * Base class for all SPARC static instructions.
94 */
95 class SparcStaticInst : public StaticInst
96 {
97 protected:
98 // Constructor.
99 SparcStaticInst(const char *mnem,
100 ExtMachInst _machInst, OpClass __opClass)
101 : StaticInst(mnem, _machInst, __opClass)
102 {
103 }
104
105 std::string generateDisassembly(Addr pc,
106 const SymbolTable *symtab) const;
107
108 void printReg(std::ostream &os, int reg) const;
109 void printSrcReg(std::ostream &os, int reg) const;
110 void printDestReg(std::ostream &os, int reg) const;
111
112 void printRegArray(std::ostream &os,
113 const RegIndex indexArray[], int num) const;
114
115 void advancePC(SparcISA::PCState &pcState) const;
116 };
117
118 bool passesFpCondition(uint32_t fcc, uint32_t condition);
119
120 bool passesCondition(uint32_t codes, uint32_t condition);
121
122 inline int64_t sign_ext(uint64_t data, int origWidth)
122 inline int64_t
123 sign_ext(uint64_t data, int origWidth)
123 {
124 int shiftAmount = 64 - origWidth;
125 return (((int64_t)data) << shiftAmount) >> shiftAmount;
126 }
127}};
128
129output decoder {{
130
131 const char *CondTestAbbrev[] =
132 {
124 {
125 int shiftAmount = 64 - origWidth;
126 return (((int64_t)data) << shiftAmount) >> shiftAmount;
127 }
128}};
129
130output decoder {{
131
132 const char *CondTestAbbrev[] =
133 {
133 "nev", //Never
134 "e", //Equal
135 "le", //Less or Equal
136 "l", //Less
137 "leu", //Less or Equal Unsigned
138 "c", //Carry set
139 "n", //Negative
140 "o", //Overflow set
141 "a", //Always
142 "ne", //Not Equal
143 "g", //Greater
144 "ge", //Greater or Equal
145 "gu", //Greater Unsigned
146 "cc", //Carry clear
147 "p", //Positive
148 "oc" //Overflow Clear
134 "nev", // Never
135 "e", // Equal
136 "le", // Less or Equal
137 "l", // Less
138 "leu", // Less or Equal Unsigned
139 "c", // Carry set
140 "n", // Negative
141 "o", // Overflow set
142 "a", // Always
143 "ne", // Not Equal
144 "g", // Greater
145 "ge", // Greater or Equal
146 "gu", // Greater Unsigned
147 "cc", // Carry clear
148 "p", // Positive
149 "oc" // Overflow Clear
149 };
150}};
151
152def template ROrImmDecode {{
153 {
154 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
155 : (SparcStaticInst *)(new %(class_name)s(machInst)));
156 }
157}};
158
159output header {{
160 union DoubleSingle
161 {
162 double d;
163 uint64_t ui;
164 uint32_t s[2];
165 DoubleSingle(double _d) : d(_d)
166 {}
167 DoubleSingle(uint64_t _ui) : ui(_ui)
168 {}
169 DoubleSingle(uint32_t _s0, uint32_t _s1)
170 {
171 s[0] = _s0;
172 s[1] = _s1;
173 }
174 };
175}};
176
177let {{
178 def filterDoubles(code):
179 assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
180 for opName in ("Frd", "Frs1", "Frs2", "Frd_N"):
181 next_pos = 0
182 operandsREString = (r'''
183 (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
184 ((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
185 (?![\w\.]) # neg. lookahead assertion: prevent partial matches
186 ''' % opName)
187 operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
188 is_src = False
189 is_dest = False
190 extension = None
191 foundOne = False
192 while 1:
193 match = operandsRE.search(code, next_pos)
194 if not match:
195 break
196 foundOne = True
197 op = match.groups()
198 (op_full, op_base, op_ext) = op
199 is_dest_local = (assignRE.match(code, match.end()) != None)
200 is_dest = is_dest or is_dest_local
201 is_src = is_src or not is_dest_local
202 if extension and extension != op_ext:
203 raise Exception, "Inconsistent extensions in double filter."
204 extension = op_ext
205 next_pos = match.end()
206 if foundOne:
207 # Get rid of any unwanted extension
208 code = operandsRE.sub(op_base, code)
209 is_int = False
210 member = "d"
211 if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
212 is_int = True
213 member = "ui"
214 if is_src:
215 code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
216 (opName, opName, opName, member)) + code
217 if is_dest:
218 code += '''
219 %s_low = DoubleSingle(%s).s[1];
220 %s_high = DoubleSingle(%s).s[0];''' % \
221 (opName, opName, opName, opName)
222 if is_int:
223 code = ("uint64_t %s;" % opName) + code
224 else:
225 code = ("double %s;" % opName) + code
226 return code
227}};
228
229let {{
230 def splitOutImm(code):
231 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
232 rOrImmMatch = matcher.search(code)
233 if (rOrImmMatch == None):
234 return (False, code, '', '', '')
235 rString = rOrImmMatch.group("rNum")
236 if (rOrImmMatch.group("typeQual") != None):
237 rString += rOrImmMatch.group("typeQual")
238 iString = rOrImmMatch.group("iNum")
239 orig_code = code
240 code = matcher.sub('Rs' + rString, orig_code)
241 imm_code = matcher.sub('imm', orig_code)
242 return (True, code, imm_code, rString, iString)
243}};
244
245output decoder {{
246
247 inline void printMnemonic(std::ostream &os, const char * mnemonic)
248 {
249 ccprintf(os, "\t%s ", mnemonic);
250 }
251
252 void SparcStaticInst::printRegArray(std::ostream &os,
253 const RegIndex indexArray[], int num) const
254 {
150 };
151}};
152
153def template ROrImmDecode {{
154 {
155 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
156 : (SparcStaticInst *)(new %(class_name)s(machInst)));
157 }
158}};
159
160output header {{
161 union DoubleSingle
162 {
163 double d;
164 uint64_t ui;
165 uint32_t s[2];
166 DoubleSingle(double _d) : d(_d)
167 {}
168 DoubleSingle(uint64_t _ui) : ui(_ui)
169 {}
170 DoubleSingle(uint32_t _s0, uint32_t _s1)
171 {
172 s[0] = _s0;
173 s[1] = _s1;
174 }
175 };
176}};
177
178let {{
179 def filterDoubles(code):
180 assignRE = re.compile(r'\s*=(?!=)', re.MULTILINE)
181 for opName in ("Frd", "Frs1", "Frs2", "Frd_N"):
182 next_pos = 0
183 operandsREString = (r'''
184 (?<![\w\.]) # neg. lookbehind assertion: prevent partial matches
185 ((%s)(?:\.(\w+))?) # match: operand with optional '.' then suffix
186 (?![\w\.]) # neg. lookahead assertion: prevent partial matches
187 ''' % opName)
188 operandsRE = re.compile(operandsREString, re.MULTILINE|re.VERBOSE)
189 is_src = False
190 is_dest = False
191 extension = None
192 foundOne = False
193 while 1:
194 match = operandsRE.search(code, next_pos)
195 if not match:
196 break
197 foundOne = True
198 op = match.groups()
199 (op_full, op_base, op_ext) = op
200 is_dest_local = (assignRE.match(code, match.end()) != None)
201 is_dest = is_dest or is_dest_local
202 is_src = is_src or not is_dest_local
203 if extension and extension != op_ext:
204 raise Exception, "Inconsistent extensions in double filter."
205 extension = op_ext
206 next_pos = match.end()
207 if foundOne:
208 # Get rid of any unwanted extension
209 code = operandsRE.sub(op_base, code)
210 is_int = False
211 member = "d"
212 if extension in ("sb", "ub", "shw", "uhw", "sw", "uw", "sdw", "udw"):
213 is_int = True
214 member = "ui"
215 if is_src:
216 code = ("%s = DoubleSingle(%s_high, %s_low).%s;" % \
217 (opName, opName, opName, member)) + code
218 if is_dest:
219 code += '''
220 %s_low = DoubleSingle(%s).s[1];
221 %s_high = DoubleSingle(%s).s[0];''' % \
222 (opName, opName, opName, opName)
223 if is_int:
224 code = ("uint64_t %s;" % opName) + code
225 else:
226 code = ("double %s;" % opName) + code
227 return code
228}};
229
230let {{
231 def splitOutImm(code):
232 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
233 rOrImmMatch = matcher.search(code)
234 if (rOrImmMatch == None):
235 return (False, code, '', '', '')
236 rString = rOrImmMatch.group("rNum")
237 if (rOrImmMatch.group("typeQual") != None):
238 rString += rOrImmMatch.group("typeQual")
239 iString = rOrImmMatch.group("iNum")
240 orig_code = code
241 code = matcher.sub('Rs' + rString, orig_code)
242 imm_code = matcher.sub('imm', orig_code)
243 return (True, code, imm_code, rString, iString)
244}};
245
246output decoder {{
247
248 inline void printMnemonic(std::ostream &os, const char * mnemonic)
249 {
250 ccprintf(os, "\t%s ", mnemonic);
251 }
252
253 void SparcStaticInst::printRegArray(std::ostream &os,
254 const RegIndex indexArray[], int num) const
255 {
255 if(num <= 0)
256 if (num <= 0)
256 return;
257 printReg(os, indexArray[0]);
257 return;
258 printReg(os, indexArray[0]);
258 for(int x = 1; x < num; x++)
259 {
259 for (int x = 1; x < num; x++) {
260 os << ", ";
261 printReg(os, indexArray[x]);
262 }
263 }
264
265 void
266 SparcStaticInst::advancePC(SparcISA::PCState &pcState) const
267 {
268 pcState.advance();
269 }
270
271 void
272 SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
273 {
260 os << ", ";
261 printReg(os, indexArray[x]);
262 }
263 }
264
265 void
266 SparcStaticInst::advancePC(SparcISA::PCState &pcState) const
267 {
268 pcState.advance();
269 }
270
271 void
272 SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
273 {
274 if(_numSrcRegs > reg)
274 if (_numSrcRegs > reg)
275 printReg(os, _srcRegIdx[reg]);
276 }
277
278 void
279 SparcStaticInst::printDestReg(std::ostream &os, int reg) const
280 {
275 printReg(os, _srcRegIdx[reg]);
276 }
277
278 void
279 SparcStaticInst::printDestReg(std::ostream &os, int reg) const
280 {
281 if(_numDestRegs > reg)
281 if (_numDestRegs > reg)
282 printReg(os, _destRegIdx[reg]);
283 }
284
285 void
286 SparcStaticInst::printReg(std::ostream &os, int reg) const
287 {
288 const int MaxGlobal = 8;
289 const int MaxOutput = 16;
290 const int MaxLocal = 24;
291 const int MaxInput = 32;
292 const int MaxMicroReg = 40;
293 if (reg < FP_Base_DepTag) {
282 printReg(os, _destRegIdx[reg]);
283 }
284
285 void
286 SparcStaticInst::printReg(std::ostream &os, int reg) const
287 {
288 const int MaxGlobal = 8;
289 const int MaxOutput = 16;
290 const int MaxLocal = 24;
291 const int MaxInput = 32;
292 const int MaxMicroReg = 40;
293 if (reg < FP_Base_DepTag) {
294 //If we used a register from the next or previous window,
295 //take out the offset.
294 // If we used a register from the next or previous window,
295 // take out the offset.
296 while (reg >= MaxMicroReg)
297 reg -= MaxMicroReg;
298 if (reg == FramePointerReg)
299 ccprintf(os, "%%fp");
300 else if (reg == StackPointerReg)
301 ccprintf(os, "%%sp");
296 while (reg >= MaxMicroReg)
297 reg -= MaxMicroReg;
298 if (reg == FramePointerReg)
299 ccprintf(os, "%%fp");
300 else if (reg == StackPointerReg)
301 ccprintf(os, "%%sp");
302 else if(reg < MaxGlobal)
302 else if (reg < MaxGlobal)
303 ccprintf(os, "%%g%d", reg);
303 ccprintf(os, "%%g%d", reg);
304 else if(reg < MaxOutput)
304 else if (reg < MaxOutput)
305 ccprintf(os, "%%o%d", reg - MaxGlobal);
305 ccprintf(os, "%%o%d", reg - MaxGlobal);
306 else if(reg < MaxLocal)
306 else if (reg < MaxLocal)
307 ccprintf(os, "%%l%d", reg - MaxOutput);
307 ccprintf(os, "%%l%d", reg - MaxOutput);
308 else if(reg < MaxInput)
308 else if (reg < MaxInput)
309 ccprintf(os, "%%i%d", reg - MaxLocal);
309 ccprintf(os, "%%i%d", reg - MaxLocal);
310 else if(reg < MaxMicroReg)
310 else if (reg < MaxMicroReg)
311 ccprintf(os, "%%u%d", reg - MaxInput);
311 ccprintf(os, "%%u%d", reg - MaxInput);
312 //The fake int regs that are really control regs
312 // The fake int regs that are really control regs
313 else {
314 switch (reg - MaxMicroReg) {
315 case 1:
316 ccprintf(os, "%%y");
317 break;
318 case 2:
319 ccprintf(os, "%%ccr");
320 break;
321 case 3:
322 ccprintf(os, "%%cansave");
323 break;
324 case 4:
325 ccprintf(os, "%%canrestore");
326 break;
327 case 5:
328 ccprintf(os, "%%cleanwin");
329 break;
330 case 6:
331 ccprintf(os, "%%otherwin");
332 break;
333 case 7:
334 ccprintf(os, "%%wstate");
335 break;
336 }
337 }
338 } else if (reg < Ctrl_Base_DepTag) {
339 ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
340 } else {
341 switch (reg - Ctrl_Base_DepTag) {
342 case MISCREG_ASI:
343 ccprintf(os, "%%asi");
344 break;
345 case MISCREG_FPRS:
346 ccprintf(os, "%%fprs");
347 break;
348 case MISCREG_PCR:
349 ccprintf(os, "%%pcr");
350 break;
351 case MISCREG_PIC:
352 ccprintf(os, "%%pic");
353 break;
354 case MISCREG_GSR:
355 ccprintf(os, "%%gsr");
356 break;
357 case MISCREG_SOFTINT:
358 ccprintf(os, "%%softint");
359 break;
360 case MISCREG_SOFTINT_SET:
361 ccprintf(os, "%%softint_set");
362 break;
363 case MISCREG_SOFTINT_CLR:
364 ccprintf(os, "%%softint_clr");
365 break;
366 case MISCREG_TICK_CMPR:
367 ccprintf(os, "%%tick_cmpr");
368 break;
369 case MISCREG_STICK:
370 ccprintf(os, "%%stick");
371 break;
372 case MISCREG_STICK_CMPR:
373 ccprintf(os, "%%stick_cmpr");
374 break;
375 case MISCREG_TPC:
376 ccprintf(os, "%%tpc");
377 break;
378 case MISCREG_TNPC:
379 ccprintf(os, "%%tnpc");
380 break;
381 case MISCREG_TSTATE:
382 ccprintf(os, "%%tstate");
383 break;
384 case MISCREG_TT:
385 ccprintf(os, "%%tt");
386 break;
387 case MISCREG_TICK:
388 ccprintf(os, "%%tick");
389 break;
390 case MISCREG_TBA:
391 ccprintf(os, "%%tba");
392 break;
393 case MISCREG_PSTATE:
394 ccprintf(os, "%%pstate");
395 break;
396 case MISCREG_TL:
397 ccprintf(os, "%%tl");
398 break;
399 case MISCREG_PIL:
400 ccprintf(os, "%%pil");
401 break;
402 case MISCREG_CWP:
403 ccprintf(os, "%%cwp");
404 break;
405 case MISCREG_GL:
406 ccprintf(os, "%%gl");
407 break;
408 case MISCREG_HPSTATE:
409 ccprintf(os, "%%hpstate");
410 break;
411 case MISCREG_HTSTATE:
412 ccprintf(os, "%%htstate");
413 break;
414 case MISCREG_HINTP:
415 ccprintf(os, "%%hintp");
416 break;
417 case MISCREG_HTBA:
418 ccprintf(os, "%%htba");
419 break;
420 case MISCREG_HSTICK_CMPR:
421 ccprintf(os, "%%hstick_cmpr");
422 break;
423 case MISCREG_HVER:
424 ccprintf(os, "%%hver");
425 break;
426 case MISCREG_STRAND_STS_REG:
427 ccprintf(os, "%%strand_sts_reg");
428 break;
429 case MISCREG_FSR:
430 ccprintf(os, "%%fsr");
431 break;
432 default:
433 ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
434 }
435 }
436 }
437
313 else {
314 switch (reg - MaxMicroReg) {
315 case 1:
316 ccprintf(os, "%%y");
317 break;
318 case 2:
319 ccprintf(os, "%%ccr");
320 break;
321 case 3:
322 ccprintf(os, "%%cansave");
323 break;
324 case 4:
325 ccprintf(os, "%%canrestore");
326 break;
327 case 5:
328 ccprintf(os, "%%cleanwin");
329 break;
330 case 6:
331 ccprintf(os, "%%otherwin");
332 break;
333 case 7:
334 ccprintf(os, "%%wstate");
335 break;
336 }
337 }
338 } else if (reg < Ctrl_Base_DepTag) {
339 ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
340 } else {
341 switch (reg - Ctrl_Base_DepTag) {
342 case MISCREG_ASI:
343 ccprintf(os, "%%asi");
344 break;
345 case MISCREG_FPRS:
346 ccprintf(os, "%%fprs");
347 break;
348 case MISCREG_PCR:
349 ccprintf(os, "%%pcr");
350 break;
351 case MISCREG_PIC:
352 ccprintf(os, "%%pic");
353 break;
354 case MISCREG_GSR:
355 ccprintf(os, "%%gsr");
356 break;
357 case MISCREG_SOFTINT:
358 ccprintf(os, "%%softint");
359 break;
360 case MISCREG_SOFTINT_SET:
361 ccprintf(os, "%%softint_set");
362 break;
363 case MISCREG_SOFTINT_CLR:
364 ccprintf(os, "%%softint_clr");
365 break;
366 case MISCREG_TICK_CMPR:
367 ccprintf(os, "%%tick_cmpr");
368 break;
369 case MISCREG_STICK:
370 ccprintf(os, "%%stick");
371 break;
372 case MISCREG_STICK_CMPR:
373 ccprintf(os, "%%stick_cmpr");
374 break;
375 case MISCREG_TPC:
376 ccprintf(os, "%%tpc");
377 break;
378 case MISCREG_TNPC:
379 ccprintf(os, "%%tnpc");
380 break;
381 case MISCREG_TSTATE:
382 ccprintf(os, "%%tstate");
383 break;
384 case MISCREG_TT:
385 ccprintf(os, "%%tt");
386 break;
387 case MISCREG_TICK:
388 ccprintf(os, "%%tick");
389 break;
390 case MISCREG_TBA:
391 ccprintf(os, "%%tba");
392 break;
393 case MISCREG_PSTATE:
394 ccprintf(os, "%%pstate");
395 break;
396 case MISCREG_TL:
397 ccprintf(os, "%%tl");
398 break;
399 case MISCREG_PIL:
400 ccprintf(os, "%%pil");
401 break;
402 case MISCREG_CWP:
403 ccprintf(os, "%%cwp");
404 break;
405 case MISCREG_GL:
406 ccprintf(os, "%%gl");
407 break;
408 case MISCREG_HPSTATE:
409 ccprintf(os, "%%hpstate");
410 break;
411 case MISCREG_HTSTATE:
412 ccprintf(os, "%%htstate");
413 break;
414 case MISCREG_HINTP:
415 ccprintf(os, "%%hintp");
416 break;
417 case MISCREG_HTBA:
418 ccprintf(os, "%%htba");
419 break;
420 case MISCREG_HSTICK_CMPR:
421 ccprintf(os, "%%hstick_cmpr");
422 break;
423 case MISCREG_HVER:
424 ccprintf(os, "%%hver");
425 break;
426 case MISCREG_STRAND_STS_REG:
427 ccprintf(os, "%%strand_sts_reg");
428 break;
429 case MISCREG_FSR:
430 ccprintf(os, "%%fsr");
431 break;
432 default:
433 ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
434 }
435 }
436 }
437
438 std::string SparcStaticInst::generateDisassembly(Addr pc,
439 const SymbolTable *symtab) const
438 std::string
439 SparcStaticInst::generateDisassembly(Addr pc,
440 const SymbolTable *symtab) const
440 {
441 std::stringstream ss;
442
443 printMnemonic(ss, mnemonic);
444
445 // just print the first two source regs... if there's
446 // a third one, it's a read-modify-write dest (Rc),
447 // e.g. for CMOVxx
441 {
442 std::stringstream ss;
443
444 printMnemonic(ss, mnemonic);
445
446 // just print the first two source regs... if there's
447 // a third one, it's a read-modify-write dest (Rc),
448 // e.g. for CMOVxx
448 if(_numSrcRegs > 0)
449 {
449 if (_numSrcRegs > 0)
450 printReg(ss, _srcRegIdx[0]);
450 printReg(ss, _srcRegIdx[0]);
451 }
452 if(_numSrcRegs > 1)
453 {
451 if (_numSrcRegs > 1) {
454 ss << ",";
455 printReg(ss, _srcRegIdx[1]);
456 }
457
458 // just print the first dest... if there's a second one,
459 // it's generally implicit
452 ss << ",";
453 printReg(ss, _srcRegIdx[1]);
454 }
455
456 // just print the first dest... if there's a second one,
457 // it's generally implicit
460 if(_numDestRegs > 0)
461 {
462 if(_numSrcRegs > 0)
458 if (_numDestRegs > 0) {
459 if (_numSrcRegs > 0)
463 ss << ",";
464 printReg(ss, _destRegIdx[0]);
465 }
466
467 return ss.str();
468 }
469
460 ss << ",";
461 printReg(ss, _destRegIdx[0]);
462 }
463
464 return ss.str();
465 }
466
470 bool passesFpCondition(uint32_t fcc, uint32_t condition)
467 bool
468 passesFpCondition(uint32_t fcc, uint32_t condition)
471 {
472 bool u = (fcc == 3);
473 bool g = (fcc == 2);
474 bool l = (fcc == 1);
475 bool e = (fcc == 0);
469 {
470 bool u = (fcc == 3);
471 bool g = (fcc == 2);
472 bool l = (fcc == 1);
473 bool e = (fcc == 0);
476 switch(condition)
477 {
474 switch (condition) {
478 case FAlways:
479 return 1;
480 case FNever:
481 return 0;
482 case FUnordered:
483 return u;
484 case FGreater:
485 return g;
486 case FUnorderedOrGreater:
487 return u || g;
488 case FLess:
489 return l;
490 case FUnorderedOrLess:
491 return u || l;
492 case FLessOrGreater:
493 return l || g;
494 case FNotEqual:
495 return l || g || u;
496 case FEqual:
497 return e;
498 case FUnorderedOrEqual:
499 return u || e;
500 case FGreaterOrEqual:
501 return g || e;
502 case FUnorderedOrGreaterOrEqual:
503 return u || g || e;
504 case FLessOrEqual:
505 return l || e;
506 case FUnorderedOrLessOrEqual:
507 return u || l || e;
508 case FOrdered:
509 return e || l || g;
510 }
511 panic("Tried testing condition nonexistant "
512 "condition code %d", condition);
513 }
514
475 case FAlways:
476 return 1;
477 case FNever:
478 return 0;
479 case FUnordered:
480 return u;
481 case FGreater:
482 return g;
483 case FUnorderedOrGreater:
484 return u || g;
485 case FLess:
486 return l;
487 case FUnorderedOrLess:
488 return u || l;
489 case FLessOrGreater:
490 return l || g;
491 case FNotEqual:
492 return l || g || u;
493 case FEqual:
494 return e;
495 case FUnorderedOrEqual:
496 return u || e;
497 case FGreaterOrEqual:
498 return g || e;
499 case FUnorderedOrGreaterOrEqual:
500 return u || g || e;
501 case FLessOrEqual:
502 return l || e;
503 case FUnorderedOrLessOrEqual:
504 return u || l || e;
505 case FOrdered:
506 return e || l || g;
507 }
508 panic("Tried testing condition nonexistant "
509 "condition code %d", condition);
510 }
511
515 bool passesCondition(uint32_t codes, uint32_t condition)
512 bool
513 passesCondition(uint32_t codes, uint32_t condition)
516 {
517 CondCodes condCodes;
518 condCodes.bits = 0;
519 condCodes.c = codes & 0x1 ? 1 : 0;
520 condCodes.v = codes & 0x2 ? 1 : 0;
521 condCodes.z = codes & 0x4 ? 1 : 0;
522 condCodes.n = codes & 0x8 ? 1 : 0;
523
514 {
515 CondCodes condCodes;
516 condCodes.bits = 0;
517 condCodes.c = codes & 0x1 ? 1 : 0;
518 condCodes.v = codes & 0x2 ? 1 : 0;
519 condCodes.z = codes & 0x4 ? 1 : 0;
520 condCodes.n = codes & 0x8 ? 1 : 0;
521
524 switch(condition)
525 {
522 switch (condition) {
526 case Always:
527 return true;
528 case Never:
529 return false;
530 case NotEqual:
531 return !condCodes.z;
532 case Equal:
533 return condCodes.z;
534 case Greater:
535 return !(condCodes.z | (condCodes.n ^ condCodes.v));
536 case LessOrEqual:
537 return condCodes.z | (condCodes.n ^ condCodes.v);
538 case GreaterOrEqual:
539 return !(condCodes.n ^ condCodes.v);
540 case Less:
541 return (condCodes.n ^ condCodes.v);
542 case GreaterUnsigned:
543 return !(condCodes.c | condCodes.z);
544 case LessOrEqualUnsigned:
545 return (condCodes.c | condCodes.z);
546 case CarryClear:
547 return !condCodes.c;
548 case CarrySet:
549 return condCodes.c;
550 case Positive:
551 return !condCodes.n;
552 case Negative:
553 return condCodes.n;
554 case OverflowClear:
555 return !condCodes.v;
556 case OverflowSet:
557 return condCodes.v;
558 }
559 panic("Tried testing condition nonexistant "
560 "condition code %d", condition);
561 }
562}};
563
564output exec {{
565 /// Check "FP enabled" machine status bit. Called when executing any FP
566 /// instruction in full-system mode.
567 /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
568 /// if not. Non-full-system mode: always returns NoFault.
569#if FULL_SYSTEM
523 case Always:
524 return true;
525 case Never:
526 return false;
527 case NotEqual:
528 return !condCodes.z;
529 case Equal:
530 return condCodes.z;
531 case Greater:
532 return !(condCodes.z | (condCodes.n ^ condCodes.v));
533 case LessOrEqual:
534 return condCodes.z | (condCodes.n ^ condCodes.v);
535 case GreaterOrEqual:
536 return !(condCodes.n ^ condCodes.v);
537 case Less:
538 return (condCodes.n ^ condCodes.v);
539 case GreaterUnsigned:
540 return !(condCodes.c | condCodes.z);
541 case LessOrEqualUnsigned:
542 return (condCodes.c | condCodes.z);
543 case CarryClear:
544 return !condCodes.c;
545 case CarrySet:
546 return condCodes.c;
547 case Positive:
548 return !condCodes.n;
549 case Negative:
550 return condCodes.n;
551 case OverflowClear:
552 return !condCodes.v;
553 case OverflowSet:
554 return condCodes.v;
555 }
556 panic("Tried testing condition nonexistant "
557 "condition code %d", condition);
558 }
559}};
560
561output exec {{
562 /// Check "FP enabled" machine status bit. Called when executing any FP
563 /// instruction in full-system mode.
564 /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
565 /// if not. Non-full-system mode: always returns NoFault.
566#if FULL_SYSTEM
570 inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
567 inline Fault
568 checkFpEnableFault(%(CPU_exec_context)s *xc)
571 {
572 Fault fault = NoFault; // dummy... this ipr access should not fault
573 if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef &&
569 {
570 Fault fault = NoFault; // dummy... this ipr access should not fault
571 if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef &&
574 xc->readMiscReg(MISCREG_FPRS) & 0x4)
572 xc->readMiscReg(MISCREG_FPRS) & 0x4) {
575 return NoFault;
573 return NoFault;
576 else
574 } else {
577 return new FpDisabled;
575 return new FpDisabled;
576 }
578 }
579#else
577 }
578#else
580 inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
579 inline Fault
580 checkFpEnableFault(%(CPU_exec_context)s *xc)
581 {
582 return NoFault;
583 }
584#endif
585}};
586
587
581 {
582 return NoFault;
583 }
584#endif
585}};
586
587