⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isa_desc

📁 linux下基于c++的处理器仿真平台。具有处理器流水线
💻
📖 第 1 页 / 共 5 页
字号:
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 + -