base.isa (4004:d551cf1bba0d) base.isa (4172:141705d83494)
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 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
116 bool passesFpCondition(uint32_t fcc, uint32_t condition);
117
118 bool passesCondition(uint32_t codes, uint32_t condition);
119
120 inline int64_t sign_ext(uint64_t data, int origWidth)
121 {
122 int shiftAmount = 64 - origWidth;
123 return (((int64_t)data) << shiftAmount) >> shiftAmount;
124 }
125}};
126
127output decoder {{
128
129 char * CondTestAbbrev[] =
130 {
131 "nev", //Never
132 "e", //Equal
133 "le", //Less or Equal
134 "l", //Less
135 "leu", //Less or Equal Unsigned
136 "c", //Carry set
137 "n", //Negative
138 "o", //Overflow set
139 "a", //Always
140 "ne", //Not Equal
141 "g", //Greater
142 "ge", //Greater or Equal
143 "gu", //Greater Unsigned
144 "cc", //Carry clear
145 "p", //Positive
146 "oc" //Overflow Clear
147 };
148}};
149
150def template ROrImmDecode {{
151 {
152 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
153 : (SparcStaticInst *)(new %(class_name)s(machInst)));
154 }
155}};
156
157let {{
158 def splitOutImm(code):
159 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
160 rOrImmMatch = matcher.search(code)
161 if (rOrImmMatch == None):
162 return (False, code, '', '', '')
163 rString = rOrImmMatch.group("rNum")
164 if (rOrImmMatch.group("typeQual") != None):
165 rString += rOrImmMatch.group("typeQual")
166 iString = rOrImmMatch.group("iNum")
167 orig_code = code
168 code = matcher.sub('Rs' + rString, orig_code)
169 imm_code = matcher.sub('imm', orig_code)
170 return (True, code, imm_code, rString, iString)
171}};
172
173output decoder {{
174
175 inline void printMnemonic(std::ostream &os, const char * mnemonic)
176 {
177 ccprintf(os, "\t%s ", mnemonic);
178 }
179
180 void SparcStaticInst::printRegArray(std::ostream &os,
181 const RegIndex indexArray[], int num) const
182 {
183 if(num <= 0)
184 return;
185 printReg(os, indexArray[0]);
186 for(int x = 1; x < num; x++)
187 {
188 os << ", ";
189 printReg(os, indexArray[x]);
190 }
191 }
192
193 void
194 SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
195 {
196 if(_numSrcRegs > reg)
197 printReg(os, _srcRegIdx[reg]);
198 }
199
200 void
201 SparcStaticInst::printDestReg(std::ostream &os, int reg) const
202 {
203 if(_numDestRegs > reg)
204 printReg(os, _destRegIdx[reg]);
205 }
206
207 void
208 SparcStaticInst::printReg(std::ostream &os, int reg) const
209 {
210 const int MaxGlobal = 8;
211 const int MaxOutput = 16;
212 const int MaxLocal = 24;
213 const int MaxInput = 32;
214 const int MaxMicroReg = 40;
215 if (reg < FP_Base_DepTag) {
216 //If we used a register from the next or previous window,
217 //take out the offset.
218 while (reg >= MaxMicroReg)
219 reg -= MaxMicroReg;
220 if (reg == FramePointerReg)
221 ccprintf(os, "%%fp");
222 else if (reg == StackPointerReg)
223 ccprintf(os, "%%sp");
224 else if(reg < MaxGlobal)
225 ccprintf(os, "%%g%d", reg);
226 else if(reg < MaxOutput)
227 ccprintf(os, "%%o%d", reg - MaxGlobal);
228 else if(reg < MaxLocal)
229 ccprintf(os, "%%l%d", reg - MaxOutput);
230 else if(reg < MaxInput)
231 ccprintf(os, "%%i%d", reg - MaxLocal);
232 else if(reg < MaxMicroReg)
233 ccprintf(os, "%%u%d", reg - MaxInput);
234 //The fake int regs that are really control regs
235 else {
236 switch (reg - MaxMicroReg) {
237 case 1:
238 ccprintf(os, "%%y");
239 break;
240 case 2:
241 ccprintf(os, "%%ccr");
242 break;
243 case 3:
244 ccprintf(os, "%%cansave");
245 break;
246 case 4:
247 ccprintf(os, "%%canrestore");
248 break;
249 case 5:
250 ccprintf(os, "%%cleanwin");
251 break;
252 case 6:
253 ccprintf(os, "%%otherwin");
254 break;
255 case 7:
256 ccprintf(os, "%%wstate");
257 break;
258 }
259 }
260 } else if (reg < Ctrl_Base_DepTag) {
261 ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
262 } else {
263 switch (reg - Ctrl_Base_DepTag) {
264 case MISCREG_ASI:
265 ccprintf(os, "%%asi");
266 break;
267 case MISCREG_FPRS:
268 ccprintf(os, "%%fprs");
269 break;
270 case MISCREG_PCR:
271 ccprintf(os, "%%pcr");
272 break;
273 case MISCREG_PIC:
274 ccprintf(os, "%%pic");
275 break;
276 case MISCREG_GSR:
277 ccprintf(os, "%%gsr");
278 break;
279 case MISCREG_SOFTINT:
280 ccprintf(os, "%%softint");
281 break;
282 case MISCREG_SOFTINT_SET:
283 ccprintf(os, "%%softint_set");
284 break;
285 case MISCREG_SOFTINT_CLR:
286 ccprintf(os, "%%softint_clr");
287 break;
288 case MISCREG_TICK_CMPR:
289 ccprintf(os, "%%tick_cmpr");
290 break;
291 case MISCREG_STICK:
292 ccprintf(os, "%%stick");
293 break;
294 case MISCREG_STICK_CMPR:
295 ccprintf(os, "%%stick_cmpr");
296 break;
297 case MISCREG_TPC:
298 ccprintf(os, "%%tpc");
299 break;
300 case MISCREG_TNPC:
301 ccprintf(os, "%%tnpc");
302 break;
303 case MISCREG_TSTATE:
304 ccprintf(os, "%%tstate");
305 break;
306 case MISCREG_TT:
307 ccprintf(os, "%%tt");
308 break;
309 case MISCREG_TICK:
310 ccprintf(os, "%%tick");
311 break;
312 case MISCREG_TBA:
313 ccprintf(os, "%%tba");
314 break;
315 case MISCREG_PSTATE:
316 ccprintf(os, "%%pstate");
317 break;
318 case MISCREG_TL:
319 ccprintf(os, "%%tl");
320 break;
321 case MISCREG_PIL:
322 ccprintf(os, "%%pil");
323 break;
324 case MISCREG_CWP:
325 ccprintf(os, "%%cwp");
326 break;
327 case MISCREG_GL:
328 ccprintf(os, "%%gl");
329 break;
330 case MISCREG_HPSTATE:
331 ccprintf(os, "%%hpstate");
332 break;
333 case MISCREG_HTSTATE:
334 ccprintf(os, "%%htstate");
335 break;
336 case MISCREG_HINTP:
337 ccprintf(os, "%%hintp");
338 break;
339 case MISCREG_HTBA:
340 ccprintf(os, "%%htba");
341 break;
342 case MISCREG_HSTICK_CMPR:
343 ccprintf(os, "%%hstick_cmpr");
344 break;
345 case MISCREG_HVER:
346 ccprintf(os, "%%hver");
347 break;
348 case MISCREG_STRAND_STS_REG:
349 ccprintf(os, "%%strand_sts_reg");
350 break;
351 case MISCREG_FSR:
352 ccprintf(os, "%%fsr");
353 break;
354 default:
355 ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
356 }
357 }
358 }
359
360 std::string SparcStaticInst::generateDisassembly(Addr pc,
361 const SymbolTable *symtab) const
362 {
363 std::stringstream ss;
364
365 printMnemonic(ss, mnemonic);
366
367 // just print the first two source regs... if there's
368 // a third one, it's a read-modify-write dest (Rc),
369 // e.g. for CMOVxx
370 if(_numSrcRegs > 0)
371 {
372 printReg(ss, _srcRegIdx[0]);
373 }
374 if(_numSrcRegs > 1)
375 {
376 ss << ",";
377 printReg(ss, _srcRegIdx[1]);
378 }
379
380 // just print the first dest... if there's a second one,
381 // it's generally implicit
382 if(_numDestRegs > 0)
383 {
384 if(_numSrcRegs > 0)
385 ss << ",";
386 printReg(ss, _destRegIdx[0]);
387 }
388
389 return ss.str();
390 }
391
392 bool passesFpCondition(uint32_t fcc, uint32_t condition)
393 {
394 bool u = (fcc == 3);
395 bool g = (fcc == 2);
396 bool l = (fcc == 1);
397 bool e = (fcc == 0);
398 switch(condition)
399 {
400 case FAlways:
401 return 1;
402 case FNever:
403 return 0;
404 case FUnordered:
405 return u;
406 case FGreater:
407 return g;
408 case FUnorderedOrGreater:
409 return u || g;
410 case FLess:
411 return l;
412 case FUnorderedOrLess:
413 return u || l;
414 case FLessOrGreater:
415 return l || g;
416 case FNotEqual:
417 return l || g || u;
418 case FEqual:
419 return e;
420 case FUnorderedOrEqual:
421 return u || e;
422 case FGreaterOrEqual:
423 return g || e;
424 case FUnorderedOrGreaterOrEqual:
425 return u || g || e;
426 case FLessOrEqual:
427 return l || e;
428 case FUnorderedOrLessOrEqual:
429 return u || l || e;
430 case FOrdered:
431 return e || l || g;
432 }
433 panic("Tried testing condition nonexistant "
434 "condition code %d", condition);
435 }
436
437 bool passesCondition(uint32_t codes, uint32_t condition)
438 {
439 CondCodes condCodes;
440 condCodes.bits = 0;
441 condCodes.c = codes & 0x1 ? 1 : 0;
442 condCodes.v = codes & 0x2 ? 1 : 0;
443 condCodes.z = codes & 0x4 ? 1 : 0;
444 condCodes.n = codes & 0x8 ? 1 : 0;
445
446 switch(condition)
447 {
448 case Always:
449 return true;
450 case Never:
451 return false;
452 case NotEqual:
453 return !condCodes.z;
454 case Equal:
455 return condCodes.z;
456 case Greater:
457 return !(condCodes.z | (condCodes.n ^ condCodes.v));
458 case LessOrEqual:
459 return condCodes.z | (condCodes.n ^ condCodes.v);
460 case GreaterOrEqual:
461 return !(condCodes.n ^ condCodes.v);
462 case Less:
463 return (condCodes.n ^ condCodes.v);
464 case GreaterUnsigned:
465 return !(condCodes.c | condCodes.z);
466 case LessOrEqualUnsigned:
467 return (condCodes.c | condCodes.z);
468 case CarryClear:
469 return !condCodes.c;
470 case CarrySet:
471 return condCodes.c;
472 case Positive:
473 return !condCodes.n;
474 case Negative:
475 return condCodes.n;
476 case OverflowClear:
477 return !condCodes.v;
478 case OverflowSet:
479 return condCodes.v;
480 }
481 panic("Tried testing condition nonexistant "
482 "condition code %d", condition);
483 }
484}};
485
486output exec {{
487 /// Check "FP enabled" machine status bit. Called when executing any FP
488 /// instruction in full-system mode.
489 /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
490 /// if not. Non-full-system mode: always returns NoFault.
491#if FULL_SYSTEM
492 inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
493 {
494 Fault fault = NoFault; // dummy... this ipr access should not fault
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 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
116 bool passesFpCondition(uint32_t fcc, uint32_t condition);
117
118 bool passesCondition(uint32_t codes, uint32_t condition);
119
120 inline int64_t sign_ext(uint64_t data, int origWidth)
121 {
122 int shiftAmount = 64 - origWidth;
123 return (((int64_t)data) << shiftAmount) >> shiftAmount;
124 }
125}};
126
127output decoder {{
128
129 char * CondTestAbbrev[] =
130 {
131 "nev", //Never
132 "e", //Equal
133 "le", //Less or Equal
134 "l", //Less
135 "leu", //Less or Equal Unsigned
136 "c", //Carry set
137 "n", //Negative
138 "o", //Overflow set
139 "a", //Always
140 "ne", //Not Equal
141 "g", //Greater
142 "ge", //Greater or Equal
143 "gu", //Greater Unsigned
144 "cc", //Carry clear
145 "p", //Positive
146 "oc" //Overflow Clear
147 };
148}};
149
150def template ROrImmDecode {{
151 {
152 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
153 : (SparcStaticInst *)(new %(class_name)s(machInst)));
154 }
155}};
156
157let {{
158 def splitOutImm(code):
159 matcher = re.compile(r'Rs(?P<rNum>\d)_or_imm(?P<iNum>\d+)(?P<typeQual>\.\w+)?')
160 rOrImmMatch = matcher.search(code)
161 if (rOrImmMatch == None):
162 return (False, code, '', '', '')
163 rString = rOrImmMatch.group("rNum")
164 if (rOrImmMatch.group("typeQual") != None):
165 rString += rOrImmMatch.group("typeQual")
166 iString = rOrImmMatch.group("iNum")
167 orig_code = code
168 code = matcher.sub('Rs' + rString, orig_code)
169 imm_code = matcher.sub('imm', orig_code)
170 return (True, code, imm_code, rString, iString)
171}};
172
173output decoder {{
174
175 inline void printMnemonic(std::ostream &os, const char * mnemonic)
176 {
177 ccprintf(os, "\t%s ", mnemonic);
178 }
179
180 void SparcStaticInst::printRegArray(std::ostream &os,
181 const RegIndex indexArray[], int num) const
182 {
183 if(num <= 0)
184 return;
185 printReg(os, indexArray[0]);
186 for(int x = 1; x < num; x++)
187 {
188 os << ", ";
189 printReg(os, indexArray[x]);
190 }
191 }
192
193 void
194 SparcStaticInst::printSrcReg(std::ostream &os, int reg) const
195 {
196 if(_numSrcRegs > reg)
197 printReg(os, _srcRegIdx[reg]);
198 }
199
200 void
201 SparcStaticInst::printDestReg(std::ostream &os, int reg) const
202 {
203 if(_numDestRegs > reg)
204 printReg(os, _destRegIdx[reg]);
205 }
206
207 void
208 SparcStaticInst::printReg(std::ostream &os, int reg) const
209 {
210 const int MaxGlobal = 8;
211 const int MaxOutput = 16;
212 const int MaxLocal = 24;
213 const int MaxInput = 32;
214 const int MaxMicroReg = 40;
215 if (reg < FP_Base_DepTag) {
216 //If we used a register from the next or previous window,
217 //take out the offset.
218 while (reg >= MaxMicroReg)
219 reg -= MaxMicroReg;
220 if (reg == FramePointerReg)
221 ccprintf(os, "%%fp");
222 else if (reg == StackPointerReg)
223 ccprintf(os, "%%sp");
224 else if(reg < MaxGlobal)
225 ccprintf(os, "%%g%d", reg);
226 else if(reg < MaxOutput)
227 ccprintf(os, "%%o%d", reg - MaxGlobal);
228 else if(reg < MaxLocal)
229 ccprintf(os, "%%l%d", reg - MaxOutput);
230 else if(reg < MaxInput)
231 ccprintf(os, "%%i%d", reg - MaxLocal);
232 else if(reg < MaxMicroReg)
233 ccprintf(os, "%%u%d", reg - MaxInput);
234 //The fake int regs that are really control regs
235 else {
236 switch (reg - MaxMicroReg) {
237 case 1:
238 ccprintf(os, "%%y");
239 break;
240 case 2:
241 ccprintf(os, "%%ccr");
242 break;
243 case 3:
244 ccprintf(os, "%%cansave");
245 break;
246 case 4:
247 ccprintf(os, "%%canrestore");
248 break;
249 case 5:
250 ccprintf(os, "%%cleanwin");
251 break;
252 case 6:
253 ccprintf(os, "%%otherwin");
254 break;
255 case 7:
256 ccprintf(os, "%%wstate");
257 break;
258 }
259 }
260 } else if (reg < Ctrl_Base_DepTag) {
261 ccprintf(os, "%%f%d", reg - FP_Base_DepTag);
262 } else {
263 switch (reg - Ctrl_Base_DepTag) {
264 case MISCREG_ASI:
265 ccprintf(os, "%%asi");
266 break;
267 case MISCREG_FPRS:
268 ccprintf(os, "%%fprs");
269 break;
270 case MISCREG_PCR:
271 ccprintf(os, "%%pcr");
272 break;
273 case MISCREG_PIC:
274 ccprintf(os, "%%pic");
275 break;
276 case MISCREG_GSR:
277 ccprintf(os, "%%gsr");
278 break;
279 case MISCREG_SOFTINT:
280 ccprintf(os, "%%softint");
281 break;
282 case MISCREG_SOFTINT_SET:
283 ccprintf(os, "%%softint_set");
284 break;
285 case MISCREG_SOFTINT_CLR:
286 ccprintf(os, "%%softint_clr");
287 break;
288 case MISCREG_TICK_CMPR:
289 ccprintf(os, "%%tick_cmpr");
290 break;
291 case MISCREG_STICK:
292 ccprintf(os, "%%stick");
293 break;
294 case MISCREG_STICK_CMPR:
295 ccprintf(os, "%%stick_cmpr");
296 break;
297 case MISCREG_TPC:
298 ccprintf(os, "%%tpc");
299 break;
300 case MISCREG_TNPC:
301 ccprintf(os, "%%tnpc");
302 break;
303 case MISCREG_TSTATE:
304 ccprintf(os, "%%tstate");
305 break;
306 case MISCREG_TT:
307 ccprintf(os, "%%tt");
308 break;
309 case MISCREG_TICK:
310 ccprintf(os, "%%tick");
311 break;
312 case MISCREG_TBA:
313 ccprintf(os, "%%tba");
314 break;
315 case MISCREG_PSTATE:
316 ccprintf(os, "%%pstate");
317 break;
318 case MISCREG_TL:
319 ccprintf(os, "%%tl");
320 break;
321 case MISCREG_PIL:
322 ccprintf(os, "%%pil");
323 break;
324 case MISCREG_CWP:
325 ccprintf(os, "%%cwp");
326 break;
327 case MISCREG_GL:
328 ccprintf(os, "%%gl");
329 break;
330 case MISCREG_HPSTATE:
331 ccprintf(os, "%%hpstate");
332 break;
333 case MISCREG_HTSTATE:
334 ccprintf(os, "%%htstate");
335 break;
336 case MISCREG_HINTP:
337 ccprintf(os, "%%hintp");
338 break;
339 case MISCREG_HTBA:
340 ccprintf(os, "%%htba");
341 break;
342 case MISCREG_HSTICK_CMPR:
343 ccprintf(os, "%%hstick_cmpr");
344 break;
345 case MISCREG_HVER:
346 ccprintf(os, "%%hver");
347 break;
348 case MISCREG_STRAND_STS_REG:
349 ccprintf(os, "%%strand_sts_reg");
350 break;
351 case MISCREG_FSR:
352 ccprintf(os, "%%fsr");
353 break;
354 default:
355 ccprintf(os, "%%ctrl%d", reg - Ctrl_Base_DepTag);
356 }
357 }
358 }
359
360 std::string SparcStaticInst::generateDisassembly(Addr pc,
361 const SymbolTable *symtab) const
362 {
363 std::stringstream ss;
364
365 printMnemonic(ss, mnemonic);
366
367 // just print the first two source regs... if there's
368 // a third one, it's a read-modify-write dest (Rc),
369 // e.g. for CMOVxx
370 if(_numSrcRegs > 0)
371 {
372 printReg(ss, _srcRegIdx[0]);
373 }
374 if(_numSrcRegs > 1)
375 {
376 ss << ",";
377 printReg(ss, _srcRegIdx[1]);
378 }
379
380 // just print the first dest... if there's a second one,
381 // it's generally implicit
382 if(_numDestRegs > 0)
383 {
384 if(_numSrcRegs > 0)
385 ss << ",";
386 printReg(ss, _destRegIdx[0]);
387 }
388
389 return ss.str();
390 }
391
392 bool passesFpCondition(uint32_t fcc, uint32_t condition)
393 {
394 bool u = (fcc == 3);
395 bool g = (fcc == 2);
396 bool l = (fcc == 1);
397 bool e = (fcc == 0);
398 switch(condition)
399 {
400 case FAlways:
401 return 1;
402 case FNever:
403 return 0;
404 case FUnordered:
405 return u;
406 case FGreater:
407 return g;
408 case FUnorderedOrGreater:
409 return u || g;
410 case FLess:
411 return l;
412 case FUnorderedOrLess:
413 return u || l;
414 case FLessOrGreater:
415 return l || g;
416 case FNotEqual:
417 return l || g || u;
418 case FEqual:
419 return e;
420 case FUnorderedOrEqual:
421 return u || e;
422 case FGreaterOrEqual:
423 return g || e;
424 case FUnorderedOrGreaterOrEqual:
425 return u || g || e;
426 case FLessOrEqual:
427 return l || e;
428 case FUnorderedOrLessOrEqual:
429 return u || l || e;
430 case FOrdered:
431 return e || l || g;
432 }
433 panic("Tried testing condition nonexistant "
434 "condition code %d", condition);
435 }
436
437 bool passesCondition(uint32_t codes, uint32_t condition)
438 {
439 CondCodes condCodes;
440 condCodes.bits = 0;
441 condCodes.c = codes & 0x1 ? 1 : 0;
442 condCodes.v = codes & 0x2 ? 1 : 0;
443 condCodes.z = codes & 0x4 ? 1 : 0;
444 condCodes.n = codes & 0x8 ? 1 : 0;
445
446 switch(condition)
447 {
448 case Always:
449 return true;
450 case Never:
451 return false;
452 case NotEqual:
453 return !condCodes.z;
454 case Equal:
455 return condCodes.z;
456 case Greater:
457 return !(condCodes.z | (condCodes.n ^ condCodes.v));
458 case LessOrEqual:
459 return condCodes.z | (condCodes.n ^ condCodes.v);
460 case GreaterOrEqual:
461 return !(condCodes.n ^ condCodes.v);
462 case Less:
463 return (condCodes.n ^ condCodes.v);
464 case GreaterUnsigned:
465 return !(condCodes.c | condCodes.z);
466 case LessOrEqualUnsigned:
467 return (condCodes.c | condCodes.z);
468 case CarryClear:
469 return !condCodes.c;
470 case CarrySet:
471 return condCodes.c;
472 case Positive:
473 return !condCodes.n;
474 case Negative:
475 return condCodes.n;
476 case OverflowClear:
477 return !condCodes.v;
478 case OverflowSet:
479 return condCodes.v;
480 }
481 panic("Tried testing condition nonexistant "
482 "condition code %d", condition);
483 }
484}};
485
486output exec {{
487 /// Check "FP enabled" machine status bit. Called when executing any FP
488 /// instruction in full-system mode.
489 /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
490 /// if not. Non-full-system mode: always returns NoFault.
491#if FULL_SYSTEM
492 inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
493 {
494 Fault fault = NoFault; // dummy... this ipr access should not fault
495 if (xc->readMiscRegWithEffect(MISCREG_PSTATE) & PSTATE::pef &&
496 xc->readMiscRegWithEffect(MISCREG_FPRS) & 0x4)
495 if (xc->readMiscReg(MISCREG_PSTATE) & PSTATE::pef &&
496 xc->readMiscReg(MISCREG_FPRS) & 0x4)
497 return NoFault;
498 else
499 return new FpDisabled;
500 }
501#else
502 inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
503 {
504 return NoFault;
505 }
506#endif
507}};
508
509
497 return NoFault;
498 else
499 return new FpDisabled;
500 }
501#else
502 inline Fault checkFpEnableFault(%(CPU_exec_context)s *xc)
503 {
504 return NoFault;
505 }
506#endif
507}};
508
509