📄 instructions_ppc.c
字号:
/* *-------------------------------- * bcctrx UISA Form XL * Jump to count register * v1 *-------------------------------- */void i_bcctrx(uint32_t icode) { uint32_t bo=(icode>>21)&0x1f; uint32_t bi=(icode>>16)&0x1f; int lk = icode &1; int cond_ok; cond_ok = (bo & (1<<4)) | (((CR>>(31-bi))&1)==((bo>>(4-1))&1)); if(cond_ok) { if(lk) { LR=CIA+4; } NIA = CTR & 0xfffffffc; } dprintf("instr i_bcctrx(%08x)\n",icode);}/* stolen from pearpc */static inline uint32_tmix_mask(int32_t mb,int32_t me) { uint32_t mask; if (mb <= me) { if (me-mb == 31) { mask = 0xffffffff; } else { mask = ((1<<(me-mb+1))-1)<<(31-me); } } else { int rot = 31-me; uint32_t w = (1<<(32-mb+me+1))-1; if(rot) { mask = (w>>rot) | (w<<(32-rot)); } else { mask = w; } } return mask;}/* * ----------------------------------------------- * rlwimix UISA Form M * Rotate left immediate then mask insert * mix_mask not verified * ----------------------------------------------- */void i_rlwimix(uint32_t icode) { int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; int sl = (icode>>11) & 0x1f; int mb = (icode>>6) & 0x1f; int me = (icode>>1) & 0x1f; int rc = icode & 1; uint32_t r; uint32_t mask; uint32_t result; r=(GPR(s)<<sl) | (GPR(s) >> (32-sl)); mask = mix_mask(mb,me); result = GPR(a) = (r & mask) | (GPR(a) & ~mask); if(rc) { update_cr0(result); } fprintf(stderr,"instr i_rlwimix(%08x) not tested\n",icode);}/* * ------------------------------------------------------- * rlwinmx * Rotate left word immediate then and with mask * mix_mask not verified * ------------------------------------------------------- */void i_rlwinmx(uint32_t icode) { int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; int sl = (icode>>11) & 0x1f; int mb = (icode>>6) & 0x1f; int me = (icode>>1) & 0x1f; int rc = icode & 1; uint32_t r; uint32_t mask; uint32_t result; r=(GPR(s)<<sl) | (GPR(s) >> (32-sl)); mask = mix_mask(mb,me); result = GPR(a) = (r & mask); if(rc) { update_cr0(result); } dprintf("instr i_rlwinmx(%08x)\n",icode);}void i_rlwnmx(uint32_t icode) { int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; int b = (icode>>11) & 0x1f; int sl; int mb = (icode>>6) & 0x1f; int me = (icode>>1) & 0x1f; int rc = icode & 1; uint32_t r; uint32_t mask; uint32_t result; sl = GPR(b) & 0x1f; r=(GPR(s)<<sl) | (GPR(s) >> (32-sl)); mask = mix_mask(mb,me); result = GPR(a) = (r & mask); if(rc) { update_cr0(result); } fprintf(stderr,"instr i_rlwnmx(%08x) not tested\n",icode);}/* * ----------------------------- * ori UISA Form D * OR immediate * v1 * ----------------------------- */void i_ori(uint32_t icode) { int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; uint16_t uimm = icode; GPR(a) = GPR(s) | uimm; /* no registers else are changed */}/* * ------------------------------------------ * oris UISA Form D * OR immediate shifted * v1 * ------------------------------------------ */void i_oris(uint32_t icode) { int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; uint32_t uimm = (icode & 0xffff)<<16; GPR(a) = GPR(s) | uimm; /* no registers else are changed */}/* * --------------------------------------------------------------------- * xori UISA Form D * XOR immediate * v1 * --------------------------------------------------------------------- */void i_xori(uint32_t icode) { int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; uint16_t uimm = (icode & 0xffff); GPR(a) = GPR(s) ^ uimm; dprintf("instr i_xori(%08x)\n",icode);}/* * ------------------------------------------------------------------- * xoris UISA Form D * XOR Immediate shifted * v1 * ------------------------------------------------------------------- */void i_xoris(uint32_t icode) { int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; uint32_t uimm = (icode & 0xffff)<<16; GPR(a) = GPR(s) ^ uimm; /* no registers else are changed */ dprintf("instr i_xoris(%08x)\n",icode);}/* * ----------------------- * andi. UISA Form D * v1 * ----------------------- */void i_andi_(uint32_t icode) { uint32_t result; int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; uint16_t uimm = icode&0xffff; result = GPR(s) & uimm; update_cr0(result); GPR(a) = result; dprintf("instr i_andi(%08x)\n",icode);}/* * ---------------------------- * andis. UISA Form D * v1 * ---------------------------- */void i_andis_(uint32_t icode) { uint32_t result; int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; uint32_t uimm = (icode&0xffff)<<16; result = GPR(s) & uimm; GPR(a) = result; update_cr0(result); dprintf("instr i_andis(%08x)\n",icode);}void i_rldiclx(uint32_t icode) { fprintf(stderr,"instr i_rldclx(%08x) not implemented\n",icode);}void i_rldicrx(uint32_t icode) { fprintf(stderr,"instr i_rldicrx(%08x) not implemented\n",icode);}void i_rldicx(uint32_t icode) { fprintf(stderr,"instr i_rldicx(%08x) not implemented\n",icode);}void i_rldimix(uint32_t icode) { fprintf(stderr,"instr i_rldimix(%08x) not implemented\n",icode);}void i_rldclx(uint32_t icode) { fprintf(stderr,"instr i_rldclx(%08x) not implemented\n",icode);}void i_rldcrx(uint32_t icode) { fprintf(stderr,"instr i_rldcrx(%08x) not implemented\n",icode);}/* * ----------------------------------------------------------- * cmp UISA Form X * 866UM says on page 127 that the L bit is ignored * v1 * ----------------------------------------------------------- */void i_cmp(uint32_t icode) { uint32_t crfd=7-((icode>>23)&7); uint32_t a=(icode>>16)&0x1f; uint32_t b=(icode>>11)&0x1f; int32_t Ra = GPR(a); int32_t Rb = GPR(b); uint32_t c;#if 0 int L=(icode>>21)&1; if(L) { fprintf(stderr,"Invalid instruction format for cmp icode %08x at %08x\n",icode,CIA); }#endif if(Ra<Rb) { c=8; } else if(Ra>Rb) { c=4; } else { c=2; } if (XER & XER_SO) { c |= 1; } CR &= 0xffffffff ^ (0xf<<(crfd<<2)); CR |= c<<(crfd<<2); dprintf("instr i_cmp(%08x)\n",icode);}/* * -------------------------------------------------------- * tw UISA Form X * Trap Word * -------------------------------------------------------- */void i_tw(uint32_t icode) { int to = (icode>>21)&0x1f; int a = (icode>>16)&0x1f; int b = (icode>>11)&0x1f; int32_t A = GPR(a); int32_t B = GPR(b); if(((int32_t)A < (int32_t)B) && (to & (1<<0))) { // Exception } if(((int32_t)A > (int32_t)B) && (to & (1<<1))) { // Exception } if((A==B) && (to & (1<<2))) { // Exception } if(((uint32_t)A < (uint32_t)B) && (to & (1<<3))) { // Exception } if(((uint32_t)A > (uint32_t)B) && (to & (1<<4))) { // Exception } fprintf(stderr,"instr i_tw(%08x) not implemented\n",icode);}/* * ------------------------------------------------------------ * subfcx * Subtract from Carrying * ------------------------------------------------------------ */void i_subfcx(uint32_t icode) { int d = (icode>>21)&0x1f; int a = (icode>>16)&0x1f; int b = (icode>>11)&0x1f; int rc = icode & 1; int oe = icode & (1<<10); uint32_t result; uint32_t op1 = GPR(b),op2 = GPR(a); GPR(d) = result = op1 - op2; if(sub_carry(op1,op2,result)) { XER = XER | XER_CA; } else { XER = XER & ~XER_CA; } if(oe) { if(sub_overflow(op1,op2,result)) { XER = XER | XER_OV | XER_SO; } else { XER = XER & ~XER_OV; } } if(rc) { update_cr0(result); } dprintf("instr i_subfcx(%08x)\n",icode);}void i_mulhdux(uint32_t icode) { fprintf(stderr,"instr i_mulhdux(%08x) not implemented\n",icode);}/* * -------------------------------------- * ADDCx UISA Form XO * v1 * -------------------------------------- */ void i_addcx(uint32_t icode) { int d = (icode>>21)&0x1f; int a = (icode>>16)&0x1f; int b = (icode>>11)&0x1f; int oe = icode&(1<<10); int rc = icode&1; uint32_t result,op1,op2; op1=GPR(a); op2 = GPR(b); GPR(d) = result = op1+op2; if(add_carry(op1,op2,result)) { XER = XER | XER_CA; } else { XER = XER & ~XER_CA; } if(oe) { if(add_overflow( op1,op2,result)) { XER |= XER_SO | XER_OV; } else { XER &= ~XER_OV; } } if(rc) { update_cr0(result); } dprintf("instr i_addcx(%08x)\n",icode);}/* * --------------------------------------------------- * mulhwux UISA Form XO * Multiply high word unsigned * v1 * --------------------------------------------------- */void i_mulhwux(uint32_t icode) { int d = (icode>>21)&0x1f; int a = (icode>>16)&0x1f; int b = (icode>>11)&0x1f; int rc = icode & 1; uint32_t result; uint64_t prod = (uint64_t)GPR(a) * (uint64_t)GPR(b); result = GPR(d) = (prod >> 32); if(rc) { update_cr0(result); } dprintf("instr i_mulhwux(%08x)\n",icode);}/* * --------------------------------------------------------------- * mfcr UISA Form X * Move from Condition register * v1 * --------------------------------------------------------------- */void i_mfcr(uint32_t icode) { int d=(icode>>21)&0x1f;#if 0 check_illegal icode#endif GPR(d) = CR; dprintf("instr i_mfcr(%08x)\n",icode);}/* * ------------------------------------------- * lwarx UISA Form X * Load word and reserve indexed * v1 * ------------------------------------------- */void i_lwarx(uint32_t icode) { int d=(icode>>21)&0x1f; int a=(icode>>16)&0x1f; int b=(icode>>11)&0x1f; uint32_t ea; if(a==0) { ea=GPR(b); } else { ea=GPR(a)+GPR(b); } if(!(ea&3)) { fprintf(stderr,"DSI exception 0x00300 missing here\n"); return; // Alignment exception } gcpu.reservation_valid=1; gcpu.reservation=ea; GPR(d)=MMU_Read32(ea); dprintf("instr i_lwarx(%08x)\n",icode);}void i_ldx(uint32_t icode) { fprintf(stderr,"instr i_ldx(%08x) not implemented\n",icode);}/* * ---------------------------------------------------- * lwzx UISA Form X * Load Word and zero indexed * v1 * ---------------------------------------------------- */void i_lwzx(uint32_t icode) { int d = (icode>>21)&0x1f; int a = (icode>>16)&0x1f; int b = (icode>>11)&0x1f; uint32_t ea; if(a==0) { ea=GPR(b); } else { ea=GPR(a)+GPR(b); } GPR(d)=MMU_Read32(ea); dprintf("instr i_lwzx(%08x)\n",icode);}/* * -------------------------------------------------------- * slwx * Shift left word * -------------------------------------------------------- */void i_slwx(uint32_t icode) { int s=(icode>>21); int a=(icode>>16); int b=(icode>>11); int rc = icode & 1; int sh = GPR(b) & 0x3f; uint32_t result; if(sh>31) { result = GPR(a) = 0; } else { result = GPR(a) = GPR(s) << sh; } if(rc) { update_cr0(result); } dprintf("instr i_slwx(%08x)\n",icode);}/* * ---------------------------- * cntlzw UISA Form X * v1 * ---------------------------- */void i_cntlzwx(uint32_t icode) { int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; int b = (icode>>11) & 0x1f; uint32_t result; int rc = icode&1; if(b) { fprintf(stderr,"Illegal instruction format\n"); return; } result = GPR(a) = count_leading_zeros(GPR(s)); if(rc) { update_cr0(result); } dprintf("instr i_cntlzwx(%08x)\n",icode);}void i_sldx(uint32_t icode) { fprintf(stderr,"instr i_sldx(%08x) not implemented\n",icode);}/* * ---------------------------- * andx UISA Form X * v1 * ---------------------------- */void i_andx(uint32_t icode) { uint32_t result; int s = (icode>>21) & 0x1f; int a = (icode>>16) & 0x1f; int b = (icode>>11) & 0x1f; int rc=icode&1; result = GPR(s) & GPR(b); GPR(a) = result; if(rc) { update_cr0(result); } dprintf("instr i_andx(%08x) not implemented\n",icode);}/* * -------------------------------------- * cmpl UISA Form X * v1 * -------------------------------------- */void i_cmpl(uint32_t icode) { uint32_t crfd=7-((icode>>23)&7); uint32_t a=(icode>>16)&0x1f; uint32_t b=(icode>>11)&0x1f; uint32_t Ra = GPR(a); uint32_t Rb = GPR(b); int L=(icode>>21)&1; uint32_t c; if(L) { fprintf(stderr,"Invalid instruction for cmpl\n"); return; } if(Ra<Rb) { c=8; } else if(Ra>Rb) { c=4; } else { c=2; } if (XER & XER_SO) { c |= 1; } CR &= 0xffffffff ^ (0xf<<(crfd<<2)); CR |= c<<(crfd<<2); fprintf(stderr,"instr i_cmpl(%08x)\n",icode);}/* * ------------------------------------------------------- * subfx UISA Form XO * Subtract from * ------------------------------------------------------- */void i_subfx(uint32_t icode) { int d = (icode>>21)&0x1f; int a = (icode>>16)&0x1f; int b = (icode>>11)&0x1f; int rc = icode & 1; int oe = icode & (1<<10); uint32_t op1 = GPR(b),op2 = GPR(a); uint32_t result; result = GPR(d) = op1-op2; if(oe) { if(sub_overflow(op1,op2,result)) { XER = XER | XER_OV | XER_SO; } else { XER = XER & ~XER_OV; } } if(rc) { update_cr0(result); } dprintf("instr i_subfx(%08x)\n",icode);}/* Load doubleword with update index: 64 Bit impl. only */void i_ldux(uint32_t icode) { fprintf(stderr,"instr i_ldux(%08x) not implemented\n",icode);}/* * ------------------------------------------------ * dcbst VEA Form X * Data cache block store * Currently does nothing because no cache is * emulated * v1 * ------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -