base.isa (12234:78ece221f9f5) base.isa (12275:4b4dd932c710)
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

--- 14 unchanged lines hidden (view full) ---

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
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

--- 14 unchanged lines hidden (view full) ---

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, RegId 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 RegId 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
123 sign_ext(uint64_t data, int origWidth)
124 {
125 int shiftAmount = 64 - origWidth;
126 return (((int64_t)data) << shiftAmount) >> shiftAmount;
127 }
128}};
129
130output decoder {{
131
132 const char *CondTestAbbrev[] =
133 {
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
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 {{

--- 77 unchanged lines hidden (view full) ---

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
31def template ROrImmDecode {{
32 {
33 return (I ? (SparcStaticInst *)(new %(class_name)sImm(machInst))
34 : (SparcStaticInst *)(new %(class_name)s(machInst)));
35 }
36}};
37
38output header {{

--- 77 unchanged lines hidden (view full) ---

116 rString += rOrImmMatch.group("typeQual")
117 iString = rOrImmMatch.group("iNum")
118 orig_code = code
119 code = matcher.sub('Rs' + rString, orig_code)
120 imm_code = matcher.sub('imm', orig_code)
121 return (True, code, imm_code, rString, iString)
122}};
123
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 RegId indexArray[], int num) const
255 {
256 if (num <= 0)
257 return;
258 printReg(os, indexArray[0]);
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 {
274 if (_numSrcRegs > reg)
275 printReg(os, _srcRegIdx[reg]);
276 }
277
278 void
279 SparcStaticInst::printDestReg(std::ostream &os, int reg) const
280 {
281 if (_numDestRegs > reg)
282 printReg(os, _destRegIdx[reg]);
283 }
284
285 void
286 SparcStaticInst::printReg(std::ostream &os, RegId 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 RegIndex reg_idx = reg.index();
294 if (reg.isIntReg()) {
295 // If we used a register from the next or previous window,
296 // take out the offset.
297 while (reg_idx >= MaxMicroReg)
298 reg_idx -= MaxMicroReg;
299 if (reg_idx == FramePointerReg)
300 ccprintf(os, "%%fp");
301 else if (reg_idx == StackPointerReg)
302 ccprintf(os, "%%sp");
303 else if (reg_idx < MaxGlobal)
304 ccprintf(os, "%%g%d", reg_idx);
305 else if (reg_idx < MaxOutput)
306 ccprintf(os, "%%o%d", reg_idx - MaxGlobal);
307 else if (reg_idx < MaxLocal)
308 ccprintf(os, "%%l%d", reg_idx - MaxOutput);
309 else if (reg_idx < MaxInput)
310 ccprintf(os, "%%i%d", reg_idx - MaxLocal);
311 else if (reg_idx < MaxMicroReg)
312 ccprintf(os, "%%u%d", reg_idx - MaxInput);
313 // The fake int regs that are really control regs
314 else {
315 switch (reg_idx - MaxMicroReg) {
316 case 1:
317 ccprintf(os, "%%y");
318 break;
319 case 2:
320 ccprintf(os, "%%ccr");
321 break;
322 case 3:
323 ccprintf(os, "%%cansave");
324 break;
325 case 4:
326 ccprintf(os, "%%canrestore");
327 break;
328 case 5:
329 ccprintf(os, "%%cleanwin");
330 break;
331 case 6:
332 ccprintf(os, "%%otherwin");
333 break;
334 case 7:
335 ccprintf(os, "%%wstate");
336 break;
337 }
338 }
339 } else if (reg.isFloatReg()) {
340 ccprintf(os, "%%f%d", reg_idx);
341 } else {
342 switch (reg_idx) {
343 case MISCREG_ASI:
344 ccprintf(os, "%%asi");
345 break;
346 case MISCREG_FPRS:
347 ccprintf(os, "%%fprs");
348 break;
349 case MISCREG_PCR:
350 ccprintf(os, "%%pcr");
351 break;
352 case MISCREG_PIC:
353 ccprintf(os, "%%pic");
354 break;
355 case MISCREG_GSR:
356 ccprintf(os, "%%gsr");
357 break;
358 case MISCREG_SOFTINT:
359 ccprintf(os, "%%softint");
360 break;
361 case MISCREG_SOFTINT_SET:
362 ccprintf(os, "%%softint_set");
363 break;
364 case MISCREG_SOFTINT_CLR:
365 ccprintf(os, "%%softint_clr");
366 break;
367 case MISCREG_TICK_CMPR:
368 ccprintf(os, "%%tick_cmpr");
369 break;
370 case MISCREG_STICK:
371 ccprintf(os, "%%stick");
372 break;
373 case MISCREG_STICK_CMPR:
374 ccprintf(os, "%%stick_cmpr");
375 break;
376 case MISCREG_TPC:
377 ccprintf(os, "%%tpc");
378 break;
379 case MISCREG_TNPC:
380 ccprintf(os, "%%tnpc");
381 break;
382 case MISCREG_TSTATE:
383 ccprintf(os, "%%tstate");
384 break;
385 case MISCREG_TT:
386 ccprintf(os, "%%tt");
387 break;
388 case MISCREG_TICK:
389 ccprintf(os, "%%tick");
390 break;
391 case MISCREG_TBA:
392 ccprintf(os, "%%tba");
393 break;
394 case MISCREG_PSTATE:
395 ccprintf(os, "%%pstate");
396 break;
397 case MISCREG_TL:
398 ccprintf(os, "%%tl");
399 break;
400 case MISCREG_PIL:
401 ccprintf(os, "%%pil");
402 break;
403 case MISCREG_CWP:
404 ccprintf(os, "%%cwp");
405 break;
406 case MISCREG_GL:
407 ccprintf(os, "%%gl");
408 break;
409 case MISCREG_HPSTATE:
410 ccprintf(os, "%%hpstate");
411 break;
412 case MISCREG_HTSTATE:
413 ccprintf(os, "%%htstate");
414 break;
415 case MISCREG_HINTP:
416 ccprintf(os, "%%hintp");
417 break;
418 case MISCREG_HTBA:
419 ccprintf(os, "%%htba");
420 break;
421 case MISCREG_HSTICK_CMPR:
422 ccprintf(os, "%%hstick_cmpr");
423 break;
424 case MISCREG_HVER:
425 ccprintf(os, "%%hver");
426 break;
427 case MISCREG_STRAND_STS_REG:
428 ccprintf(os, "%%strand_sts_reg");
429 break;
430 case MISCREG_FSR:
431 ccprintf(os, "%%fsr");
432 break;
433 default:
434 ccprintf(os, "%%ctrl%d", reg_idx);
435 }
436 }
437 }
438
439 std::string
440 SparcStaticInst::generateDisassembly(Addr pc,
441 const SymbolTable *symtab) const
442 {
443 std::stringstream ss;
444
445 printMnemonic(ss, mnemonic);
446
447 // just print the first two source regs... if there's
448 // a third one, it's a read-modify-write dest (Rc),
449 // e.g. for CMOVxx
450 if (_numSrcRegs > 0)
451 printReg(ss, _srcRegIdx[0]);
452 if (_numSrcRegs > 1) {
453 ss << ",";
454 printReg(ss, _srcRegIdx[1]);
455 }
456
457 // just print the first dest... if there's a second one,
458 // it's generally implicit
459 if (_numDestRegs > 0) {
460 if (_numSrcRegs > 0)
461 ss << ",";
462 printReg(ss, _destRegIdx[0]);
463 }
464
465 return ss.str();
466 }
467
468 bool
469 passesFpCondition(uint32_t fcc, uint32_t condition)
470 {
471 bool u = (fcc == 3);
472 bool g = (fcc == 2);
473 bool l = (fcc == 1);
474 bool e = (fcc == 0);
475 switch (condition) {
476 case FAlways:
477 return 1;
478 case FNever:
479 return 0;
480 case FUnordered:
481 return u;
482 case FGreater:
483 return g;
484 case FUnorderedOrGreater:
485 return u || g;
486 case FLess:
487 return l;
488 case FUnorderedOrLess:
489 return u || l;
490 case FLessOrGreater:
491 return l || g;
492 case FNotEqual:
493 return l || g || u;
494 case FEqual:
495 return e;
496 case FUnorderedOrEqual:
497 return u || e;
498 case FGreaterOrEqual:
499 return g || e;
500 case FUnorderedOrGreaterOrEqual:
501 return u || g || e;
502 case FLessOrEqual:
503 return l || e;
504 case FUnorderedOrLessOrEqual:
505 return u || l || e;
506 case FOrdered:
507 return e || l || g;
508 }
509 panic("Tried testing condition nonexistant "
510 "condition code %d", condition);
511 }
512
513 bool
514 passesCondition(uint32_t codes, uint32_t condition)
515 {
516 CondCodes condCodes;
517 condCodes.bits = 0;
518 condCodes.c = codes & 0x1 ? 1 : 0;
519 condCodes.v = codes & 0x2 ? 1 : 0;
520 condCodes.z = codes & 0x4 ? 1 : 0;
521 condCodes.n = codes & 0x8 ? 1 : 0;
522
523 switch (condition) {
524 case Always:
525 return true;
526 case Never:
527 return false;
528 case NotEqual:
529 return !condCodes.z;
530 case Equal:
531 return condCodes.z;
532 case Greater:
533 return !(condCodes.z | (condCodes.n ^ condCodes.v));
534 case LessOrEqual:
535 return condCodes.z | (condCodes.n ^ condCodes.v);
536 case GreaterOrEqual:
537 return !(condCodes.n ^ condCodes.v);
538 case Less:
539 return (condCodes.n ^ condCodes.v);
540 case GreaterUnsigned:
541 return !(condCodes.c | condCodes.z);
542 case LessOrEqualUnsigned:
543 return (condCodes.c | condCodes.z);
544 case CarryClear:
545 return !condCodes.c;
546 case CarrySet:
547 return condCodes.c;
548 case Positive:
549 return !condCodes.n;
550 case Negative:
551 return condCodes.n;
552 case OverflowClear:
553 return !condCodes.v;
554 case OverflowSet:
555 return condCodes.v;
556 }
557 panic("Tried testing condition nonexistant "
558 "condition code %d", condition);
559 }
560}};
561
562output exec {{
563 /// Check "FP enabled" machine status bit. Called when executing any FP
564 /// instruction.
565 /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
566 /// if not. Non-full-system mode: always returns NoFault.
567 static inline Fault
568 checkFpEnableFault(ExecContext *xc)
569 {
570 if (FullSystem) {
571 PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE);
572 if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) {
573 return NoFault;
574 } else {
575 return std::make_shared<FpDisabled>();
576 }
577 } else {
578 return NoFault;
579 }
580 }
124output exec {{
125 /// Check "FP enabled" machine status bit. Called when executing any FP
126 /// instruction.
127 /// @retval Full-system mode: NoFault if FP is enabled, FpDisabled
128 /// if not. Non-full-system mode: always returns NoFault.
129 static inline Fault
130 checkFpEnableFault(ExecContext *xc)
131 {
132 if (FullSystem) {
133 PSTATE pstate = xc->readMiscReg(MISCREG_PSTATE);
134 if (pstate.pef && xc->readMiscReg(MISCREG_FPRS) & 0x4) {
135 return NoFault;
136 } else {
137 return std::make_shared<FpDisabled>();
138 }
139 } else {
140 return NoFault;
141 }
142 }
143
581 static inline Fault
582 checkVecEnableFault(ExecContext *xc)
583 {
584 return std::make_shared<VecDisabled>();
585 }
586}};
587
588
144 static inline Fault
145 checkVecEnableFault(ExecContext *xc)
146 {
147 return std::make_shared<VecDisabled>();
148 }
149}};
150
151