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 + -
显示快捷键?