decoder.isa
来自「M5,一个功能强大的多处理器系统模拟器.很多针对处理器架构,性能的研究都使用它作」· ISA 代码 · 共 861 行 · 第 1/3 页
ISA
861 行
if (Rb_or_imm<i:>) zapmask |= (mask(8) << (i * 8)); } Rc = Ra & ~zapmask; }}); 0x31: zapnot({{ uint64_t zapmask = 0; for (int i = 0; i < 8; ++i) { if (!Rb_or_imm<i:>) zapmask |= (mask(8) << (i * 8)); } Rc = Ra & ~zapmask; }}); } 0x13: decode INTFUNC { // integer multiplies 0x00: mull({{ Rc.sl = Ra.sl * Rb_or_imm.sl; }}, IntMultOp); 0x20: mulq({{ Rc = Ra * Rb_or_imm; }}, IntMultOp); 0x30: umulh({{ uint64_t hi, lo; mul128(Ra, Rb_or_imm, hi, lo); Rc = hi; }}, IntMultOp); 0x40: mullv({{ // 32-bit multiply with trap on overflow int64_t Rax = Ra.sl; // sign extended version of Ra.sl int64_t Rbx = Rb_or_imm.sl; int64_t tmp = Rax * Rbx; // To avoid overflow, all the upper 32 bits must match // the sign bit of the lower 32. We code this as // checking the upper 33 bits for all 0s or all 1s. uint64_t sign_bits = tmp<63:31>; if (sign_bits != 0 && sign_bits != mask(33)) fault = new IntegerOverflowFault; Rc.sl = tmp<31:0>; }}, IntMultOp); 0x60: mulqv({{ // 64-bit multiply with trap on overflow uint64_t hi, lo; mul128(Ra, Rb_or_imm, hi, lo); // all the upper 64 bits must match the sign bit of // the lower 64 if (!((hi == 0 && lo<63:> == 0) || (hi == mask(64) && lo<63:> == 1))) fault = new IntegerOverflowFault; Rc = lo; }}, IntMultOp); } 0x1c: decode INTFUNC { 0x00: decode RA { 31: sextb({{ Rc.sb = Rb_or_imm< 7:0>; }}); } 0x01: decode RA { 31: sextw({{ Rc.sw = Rb_or_imm<15:0>; }}); } 0x32: ctlz({{ uint64_t count = 0; uint64_t temp = Rb; if (temp<63:32>) temp >>= 32; else count += 32; if (temp<31:16>) temp >>= 16; else count += 16; if (temp<15:8>) temp >>= 8; else count += 8; if (temp<7:4>) temp >>= 4; else count += 4; if (temp<3:2>) temp >>= 2; else count += 2; if (temp<1:1>) temp >>= 1; else count += 1; if ((temp<0:0>) != 0x1) count += 1; Rc = count; }}, IntAluOp); 0x33: cttz({{ uint64_t count = 0; uint64_t temp = Rb; if (!(temp<31:0>)) { temp >>= 32; count += 32; } if (!(temp<15:0>)) { temp >>= 16; count += 16; } if (!(temp<7:0>)) { temp >>= 8; count += 8; } if (!(temp<3:0>)) { temp >>= 4; count += 4; } if (!(temp<1:0>)) { temp >>= 2; count += 2; } if (!(temp<0:0> & ULL(0x1))) count += 1; Rc = count; }}, IntAluOp); format FailUnimpl { 0x30: ctpop(); 0x31: perr(); 0x34: unpkbw(); 0x35: unpkbl(); 0x36: pkwb(); 0x37: pklb(); 0x38: minsb8(); 0x39: minsw4(); 0x3a: minub8(); 0x3b: minuw4(); 0x3c: maxub8(); 0x3d: maxuw4(); 0x3e: maxsb8(); 0x3f: maxsw4(); } format BasicOperateWithNopCheck { 0x70: decode RB { 31: ftoit({{ Rc = Fa.uq; }}, FloatCvtOp); } 0x78: decode RB { 31: ftois({{ Rc.sl = t_to_s(Fa.uq); }}, FloatCvtOp); } } } } // Conditional branches. format CondBranch { 0x39: beq({{ cond = (Ra == 0); }}); 0x3d: bne({{ cond = (Ra != 0); }}); 0x3e: bge({{ cond = (Ra.sq >= 0); }}); 0x3f: bgt({{ cond = (Ra.sq > 0); }}); 0x3b: ble({{ cond = (Ra.sq <= 0); }}); 0x3a: blt({{ cond = (Ra.sq < 0); }}); 0x38: blbc({{ cond = ((Ra & 1) == 0); }}); 0x3c: blbs({{ cond = ((Ra & 1) == 1); }}); 0x31: fbeq({{ cond = (Fa == 0); }}); 0x35: fbne({{ cond = (Fa != 0); }}); 0x36: fbge({{ cond = (Fa >= 0); }}); 0x37: fbgt({{ cond = (Fa > 0); }}); 0x33: fble({{ cond = (Fa <= 0); }}); 0x32: fblt({{ cond = (Fa < 0); }}); } // unconditional branches format UncondBranch { 0x30: br(); 0x34: bsr(IsCall); } // indirect branches 0x1a: decode JMPFUNC { format Jump { 0: jmp(); 1: jsr(IsCall); 2: ret(IsReturn); 3: jsr_coroutine(IsCall, IsReturn); } } // Square root and integer-to-FP moves 0x14: decode FP_SHORTFUNC { // Integer to FP register moves must have RB == 31 0x4: decode RB { 31: decode FP_FULLFUNC { format BasicOperateWithNopCheck { 0x004: itofs({{ Fc.uq = s_to_t(Ra.ul); }}, FloatCvtOp); 0x024: itoft({{ Fc.uq = Ra.uq; }}, FloatCvtOp); 0x014: FailUnimpl::itoff(); // VAX-format conversion } } } // Square root instructions must have FA == 31 0xb: decode FA { 31: decode FP_TYPEFUNC { format FloatingPointOperate {#if SS_COMPATIBLE_FP 0x0b: sqrts({{ if (Fb < 0.0) fault = new ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp);#else 0x0b: sqrts({{ if (Fb.sf < 0.0) fault = new ArithmeticFault; Fc.sf = sqrt(Fb.sf); }}, FloatSqrtOp);#endif 0x2b: sqrtt({{ if (Fb < 0.0) fault = new ArithmeticFault; Fc = sqrt(Fb); }}, FloatSqrtOp); } } } // VAX-format sqrtf and sqrtg are not implemented 0xa: FailUnimpl::sqrtfg(); } // IEEE floating point 0x16: decode FP_SHORTFUNC_TOP2 { // The top two bits of the short function code break this // space into four groups: binary ops, compares, reserved, and // conversions. See Table 4-12 of AHB. There are different // special cases in these different groups, so we decode on // these top two bits first just to select a decode strategy. // Most of these instructions may have various trapping and // rounding mode flags set; these are decoded in the // FloatingPointDecode template used by the // FloatingPointOperate format. // add/sub/mul/div: just decode on the short function code // and source type. All valid trapping and rounding modes apply. 0: decode FP_TRAPMODE { // check for valid trapping modes here 0,1,5,7: decode FP_TYPEFUNC { format FloatingPointOperate {#if SS_COMPATIBLE_FP 0x00: adds({{ Fc = Fa + Fb; }}); 0x01: subs({{ Fc = Fa - Fb; }}); 0x02: muls({{ Fc = Fa * Fb; }}, FloatMultOp); 0x03: divs({{ Fc = Fa / Fb; }}, FloatDivOp);#else 0x00: adds({{ Fc.sf = Fa.sf + Fb.sf; }}); 0x01: subs({{ Fc.sf = Fa.sf - Fb.sf; }}); 0x02: muls({{ Fc.sf = Fa.sf * Fb.sf; }}, FloatMultOp); 0x03: divs({{ Fc.sf = Fa.sf / Fb.sf; }}, FloatDivOp);#endif 0x20: addt({{ Fc = Fa + Fb; }}); 0x21: subt({{ Fc = Fa - Fb; }}); 0x22: mult({{ Fc = Fa * Fb; }}, FloatMultOp); 0x23: divt({{ Fc = Fa / Fb; }}, FloatDivOp); } } } // Floating-point compare instructions must have the default // rounding mode, and may use the default trapping mode or // /SU. Both trapping modes are treated the same by M5; the // only difference on the real hardware (as far a I can tell) // is that without /SU you'd get an imprecise trap if you // tried to compare a NaN with something else (instead of an // "unordered" result). 1: decode FP_FULLFUNC { format BasicOperateWithNopCheck { 0x0a5, 0x5a5: cmpteq({{ Fc = (Fa == Fb) ? 2.0 : 0.0; }}, FloatCmpOp); 0x0a7, 0x5a7: cmptle({{ Fc = (Fa <= Fb) ? 2.0 : 0.0; }}, FloatCmpOp); 0x0a6, 0x5a6: cmptlt({{ Fc = (Fa < Fb) ? 2.0 : 0.0; }}, FloatCmpOp); 0x0a4, 0x5a4: cmptun({{ // unordered Fc = (!(Fa < Fb) && !(Fa == Fb) && !(Fa > Fb)) ? 2.0 : 0.0; }}, FloatCmpOp); } } // The FP-to-integer and integer-to-FP conversion insts // require that FA be 31. 3: decode FA { 31: decode FP_TYPEFUNC { format FloatingPointOperate { 0x2f: decode FP_ROUNDMODE { format FPFixedRounding { // "chopped" i.e. round toward zero 0: cvttq({{ Fc.sq = (int64_t)trunc(Fb); }}, Chopped); // round to minus infinity 1: cvttq({{ Fc.sq = (int64_t)floor(Fb); }}, MinusInfinity); } default: cvttq({{ Fc.sq = (int64_t)nearbyint(Fb); }}); } // The cvtts opcode is overloaded to be cvtst if the trap // mode is 2 or 6 (which are not valid otherwise) 0x2c: decode FP_FULLFUNC { format BasicOperateWithNopCheck { // trap on denorm version "cvtst/s" is // simulated same as cvtst 0x2ac, 0x6ac: cvtst({{ Fc = Fb.sf; }}); } default: cvtts({{ Fc.sf = Fb; }}); } // The trapping mode for integer-to-FP conversions // must be /SUI or nothing; /U and /SU are not // allowed. The full set of rounding modes are // supported though. 0x3c: decode FP_TRAPMODE { 0,7: cvtqs({{ Fc.sf = Fb.sq; }}); } 0x3e: decode FP_TRAPMODE { 0,7: cvtqt({{ Fc = Fb.sq; }}); } } } } } // misc FP operate
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?