📄 isa_desc
字号:
output exec {{ Fault Unknown::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const { panic("attempt to execute unknown instruction " "(inst 0x%08x, opcode 0x%x)", machInst, OPCODE); return Unimplemented_Opcode_Fault; }}};def format Unknown() {{ decode_block = 'return new Unknown(machInst);\n'}};//////////////////////////////////////////////////////////////////////// Utility functions for execute methods//output exec {{ /// Return opa + opb, summing carry into third arg. inline uint64_t addc(uint64_t opa, uint64_t opb, int &carry) { uint64_t res = opa + opb; if (res < opa || res < opb) ++carry; return res; } /// Multiply two 64-bit values (opa * opb), returning the 128-bit /// product in res_hi and res_lo. inline void mul128(uint64_t opa, uint64_t opb, uint64_t &res_hi, uint64_t &res_lo) { // do a 64x64 --> 128 multiply using four 32x32 --> 64 multiplies uint64_t opa_hi = opa<63:32>; uint64_t opa_lo = opa<31:0>; uint64_t opb_hi = opb<63:32>; uint64_t opb_lo = opb<31:0>; res_lo = opa_lo * opb_lo; // The middle partial products logically belong in bit // positions 95 to 32. Thus the lower 32 bits of each product // sum into the upper 32 bits of the low result, while the // upper 32 sum into the low 32 bits of the upper result. uint64_t partial1 = opa_hi * opb_lo; uint64_t partial2 = opa_lo * opb_hi; uint64_t partial1_lo = partial1<31:0> << 32; uint64_t partial1_hi = partial1<63:32>; uint64_t partial2_lo = partial2<31:0> << 32; uint64_t partial2_hi = partial2<63:32>; // Add partial1_lo and partial2_lo to res_lo, keeping track // of any carries out int carry_out = 0; res_lo = addc(partial1_lo, res_lo, carry_out); res_lo = addc(partial2_lo, res_lo, carry_out); // Now calculate the high 64 bits... res_hi = (opa_hi * opb_hi) + partial1_hi + partial2_hi + carry_out; } /// Map 8-bit S-floating exponent to 11-bit T-floating exponent. /// See Table 2-2 of Alpha AHB. inline int map_s(int old_exp) { int hibit = old_exp<7:>; int lobits = old_exp<6:0>; if (hibit == 1) { return (lobits == 0x7f) ? 0x7ff : (0x400 | lobits); } else { return (lobits == 0) ? 0 : (0x380 | lobits); } } /// Convert a 32-bit S-floating value to the equivalent 64-bit /// representation to be stored in an FP reg. inline uint64_t s_to_t(uint32_t s_val) { uint64_t tmp = s_val; return (tmp<31:> << 63 // sign bit | (uint64_t)map_s(tmp<30:23>) << 52 // exponent | tmp<22:0> << 29); // fraction } /// Convert a 64-bit T-floating value to the equivalent 32-bit /// S-floating representation to be stored in memory. inline int32_t t_to_s(uint64_t t_val) { return (t_val<63:62> << 30 // sign bit & hi exp bit | t_val<58:29>); // rest of exp & fraction }}};//////////////////////////////////////////////////////////////////////// The actual decoder specification//decode OPCODE default Unknown::unknown() { format LoadAddress { 0x08: lda({{ Ra = Rb + disp; }}); 0x09: ldah({{ Ra = Rb + (disp << 16); }}); } format LoadOrNop { 0x0a: ldbu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.ub; }}); 0x0c: ldwu({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uw; }}); 0x0b: ldq_u({{ EA = (Rb + disp) & ~7; }}, {{ Ra = Mem.uq; }}); 0x23: ldt({{ EA = Rb + disp; }}, {{ Fa = Mem.df; }}); 0x2a: ldl_l({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}, LOCKED); 0x2b: ldq_l({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, LOCKED); 0x20: copy_load({{EA = Ra;}}, {{fault = xc->copySrcTranslate(EA);}}, IsMemRef, IsLoad, IsCopy); } format LoadOrPrefetch { 0x28: ldl({{ EA = Rb + disp; }}, {{ Ra.sl = Mem.sl; }}); 0x29: ldq({{ EA = Rb + disp; }}, {{ Ra.uq = Mem.uq; }}, EVICT_NEXT); // IsFloating flag on lds gets the prefetch to disassemble // using f31 instead of r31... funcitonally it's unnecessary 0x22: lds({{ EA = Rb + disp; }}, {{ Fa.uq = s_to_t(Mem.ul); }}, PF_EXCLUSIVE, IsFloating); } format Store { 0x0e: stb({{ EA = Rb + disp; }}, {{ Mem.ub = Ra<7:0>; }}); 0x0d: stw({{ EA = Rb + disp; }}, {{ Mem.uw = Ra<15:0>; }}); 0x2c: stl({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}); 0x2d: stq({{ EA = Rb + disp; }}, {{ Mem.uq = Ra.uq; }}); 0x0f: stq_u({{ EA = (Rb + disp) & ~7; }}, {{ Mem.uq = Ra.uq; }}); 0x26: sts({{ EA = Rb + disp; }}, {{ Mem.ul = t_to_s(Fa.uq); }}); 0x27: stt({{ EA = Rb + disp; }}, {{ Mem.df = Fa; }}); 0x24: copy_store({{EA = Rb;}}, {{fault = xc->copy(EA);}}, IsMemRef, IsStore, IsCopy); } format StoreCond { 0x2e: stl_c({{ EA = Rb + disp; }}, {{ Mem.ul = Ra<31:0>; }}, {{ uint64_t tmp = Mem_write_result; // see stq_c Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; }}, LOCKED); 0x2f: stq_c({{ EA = Rb + disp; }}, {{ Mem.uq = Ra; }}, {{ uint64_t tmp = Mem_write_result; // If the write operation returns 0 or 1, then // this was a conventional store conditional, // and the value indicates the success/failure // of the operation. If another value is // returned, then this was a Turbolaser // mailbox access, and we don't update the // result register at all. Ra = (tmp == 0 || tmp == 1) ? tmp : Ra; }}, LOCKED); } format IntegerOperate { 0x10: decode INTFUNC { // integer arithmetic operations 0x00: addl({{ Rc.sl = Ra.sl + Rb_or_imm.sl; }}); 0x40: addlv({{ uint32_t tmp = Ra.sl + Rb_or_imm.sl; // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra.sl<31:> == Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) fault = Integer_Overflow_Fault; Rc.sl = tmp; }}); 0x02: s4addl({{ Rc.sl = (Ra.sl << 2) + Rb_or_imm.sl; }}); 0x12: s8addl({{ Rc.sl = (Ra.sl << 3) + Rb_or_imm.sl; }}); 0x20: addq({{ Rc = Ra + Rb_or_imm; }}); 0x60: addqv({{ uint64_t tmp = Ra + Rb_or_imm; // signed overflow occurs when operands have same sign // and sign of result does not match. if (Ra<63:> == Rb_or_imm<63:> && tmp<63:> != Ra<63:>) fault = Integer_Overflow_Fault; Rc = tmp; }}); 0x22: s4addq({{ Rc = (Ra << 2) + Rb_or_imm; }}); 0x32: s8addq({{ Rc = (Ra << 3) + Rb_or_imm; }}); 0x09: subl({{ Rc.sl = Ra.sl - Rb_or_imm.sl; }}); 0x49: sublv({{ uint32_t tmp = Ra.sl - Rb_or_imm.sl; // signed overflow detection is same as for add, // except we need to look at the *complemented* // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra.sl<31:> != Rb_or_imm.sl<31:> && tmp<31:> != Ra.sl<31:>) fault = Integer_Overflow_Fault; Rc.sl = tmp; }}); 0x0b: s4subl({{ Rc.sl = (Ra.sl << 2) - Rb_or_imm.sl; }}); 0x1b: s8subl({{ Rc.sl = (Ra.sl << 3) - Rb_or_imm.sl; }}); 0x29: subq({{ Rc = Ra - Rb_or_imm; }}); 0x69: subqv({{ uint64_t tmp = Ra - Rb_or_imm; // signed overflow detection is same as for add, // except we need to look at the *complemented* // sign bit of the subtrahend (Rb), i.e., if the initial // signs are the *same* then no overflow can occur if (Ra<63:> != Rb_or_imm<63:> && tmp<63:> != Ra<63:>) fault = Integer_Overflow_Fault; Rc = tmp; }}); 0x2b: s4subq({{ Rc = (Ra << 2) - Rb_or_imm; }}); 0x3b: s8subq({{ Rc = (Ra << 3) - Rb_or_imm; }}); 0x2d: cmpeq({{ Rc = (Ra == Rb_or_imm); }}); 0x6d: cmple({{ Rc = (Ra.sq <= Rb_or_imm.sq); }}); 0x4d: cmplt({{ Rc = (Ra.sq < Rb_or_imm.sq); }}); 0x3d: cmpule({{ Rc = (Ra.uq <= Rb_or_imm.uq); }}); 0x1d: cmpult({{ Rc = (Ra.uq < Rb_or_imm.uq); }}); 0x0f: cmpbge({{ int hi = 7; int lo = 0; uint64_t tmp = 0; for (int i = 0; i < 8; ++i) { tmp |= (Ra.uq<hi:lo> >= Rb_or_imm.uq<hi:lo>) << i; hi += 8; lo += 8; } Rc = tmp; }}); } 0x11: decode INTFUNC { // integer logical operations 0x00: and({{ Rc = Ra & Rb_or_imm; }}); 0x08: bic({{ Rc = Ra & ~Rb_or_imm; }}); 0x20: bis({{ Rc = Ra | Rb_or_imm; }}); 0x28: ornot({{ Rc = Ra | ~Rb_or_imm; }}); 0x40: xor({{ Rc = Ra ^ Rb_or_imm; }}); 0x48: eqv({{ Rc = Ra ^ ~Rb_or_imm; }}); // conditional moves 0x14: cmovlbs({{ Rc = ((Ra & 1) == 1) ? Rb_or_imm : Rc; }}); 0x16: cmovlbc({{ Rc = ((Ra & 1) == 0) ? Rb_or_imm : Rc; }}); 0x24: cmoveq({{ Rc = (Ra == 0) ? Rb_or_imm : Rc; }}); 0x26: cmovne({{ Rc = (Ra != 0) ? Rb_or_imm : Rc; }}); 0x44: cmovlt({{ Rc = (Ra.sq < 0) ? Rb_or_imm : Rc; }}); 0x46: cmovge({{ Rc = (Ra.sq >= 0) ? Rb_or_imm : Rc; }}); 0x64: cmovle({{ Rc = (Ra.sq <= 0) ? Rb_or_imm : Rc; }}); 0x66: cmovgt({{ Rc = (Ra.sq > 0) ? Rb_or_imm : Rc; }}); // For AMASK, RA must be R31. 0x61: decode RA { 31: amask({{ Rc = Rb_or_imm & ~ULL(0x17); }}); } // For IMPLVER, RA must be R31 and the B operand // must be the immediate value 1. 0x6c: decode RA { 31: decode IMM { 1: decode INTIMM { // return EV5 for FULL_SYSTEM and EV6 otherwise 1: implver({{#if FULL_SYSTEM Rc = 1;#else Rc = 2;#endif }}); } } }#if FULL_SYSTEM // The mysterious 11.25... 0x25: WarnUnimpl::eleven25();#endif } 0x12: decode INTFUNC { 0x39: sll({{ Rc = Ra << Rb_or_imm<5:0>; }}); 0x34: srl({{ Rc = Ra.uq >> Rb_or_imm<5:0>; }}); 0x3c: sra({{ Rc = Ra.sq >> Rb_or_imm<5:0>; }}); 0x02: mskbl({{ Rc = Ra & ~(mask( 8) << (Rb_or_imm<2:0> * 8)); }}); 0x12: mskwl({{ Rc = Ra & ~(mask(16) << (Rb_or_imm<2:0> * 8)); }}); 0x22: mskll({{ Rc = Ra & ~(mask(32) << (Rb_or_imm<2:0> * 8)); }}); 0x32: mskql({{ Rc = Ra & ~(mask(64) << (Rb_or_imm<2:0> * 8)); }}); 0x52: mskwh({{ int bv = Rb_or_imm<2:0>; Rc = bv ? (Ra & ~(mask(16) >> (64 - 8 * bv))) : Ra; }}); 0x62: msklh({{ int bv = Rb_or_imm<2:0>; Rc = bv ? (Ra & ~(mask(32) >> (64 - 8 * bv))) : Ra; }}); 0x72: mskqh({{ int bv = Rb_or_imm<2:0>; Rc = bv ? (Ra & ~(mask(64) >> (64 - 8 * bv))) : Ra; }}); 0x06: extbl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))< 7:0>; }}); 0x16: extwl({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<15:0>; }}); 0x26: extll({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8))<31:0>; }}); 0x36: extql({{ Rc = (Ra.uq >> (Rb_or_imm<2:0> * 8)); }}); 0x5a: extwh({{ Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<15:0>; }}); 0x6a: extlh({{ Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>)<31:0>; }}); 0x7a: extqh({{ Rc = (Ra << (64 - (Rb_or_imm<2:0> * 8))<5:0>); }}); 0x0b: insbl({{ Rc = Ra< 7:0> << (Rb_or_imm<2:0> * 8); }}); 0x1b: inswl({{ Rc = Ra<15:0> << (Rb_or_imm<2:0> * 8); }}); 0x2b: insll({{ Rc = Ra<31:0> << (Rb_or_imm<2:0> * 8); }}); 0x3b: insql({{ Rc = Ra << (Rb_or_imm<2:0> * 8); }}); 0x57: inswh({{ int bv = Rb_or_imm<2:0>; Rc = bv ? (Ra.uq<15:0> >> (64 - 8 * bv)) : 0; }}); 0x67: inslh({{ int bv = Rb_or_imm<2:0>; Rc = bv ? (Ra.uq<31:0> >> (64 - 8 * bv)) : 0; }}); 0x77: insqh({{ int bv = Rb_or_imm<2:0>; Rc = bv ? (Ra.uq >> (64 - 8 * bv)) : 0; }}); 0x30: zap({{ uint64_t zapmask = 0; for (int i = 0; i < 8; ++i) { 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 = Integer_Overflow_Fault; 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 = Integer_Overflow_Fault; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -