📄 ppc_opc.c
字号:
PPC_OPC_TEMPL_X(gCPU.current_opc, rD, SR, rB); // FIXME: check insn gCPU.gpr[rD] = gCPU.sr[SR & 0xf];}/* * mfsrin Move from Segment Register Indirect * .572 */void ppc_opc_mfsrin(){ if (gCPU.msr & MSR_PR) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); return; } int rD, rA, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB); // FIXME: check insn gCPU.gpr[rD] = gCPU.sr[gCPU.gpr[rB] >> 28];}/* * mftb Move from Time Base * .574 */void ppc_opc_mftb(){ int rD, spr1, spr2; PPC_OPC_TEMPL_X(gCPU.current_opc, rD, spr1, spr2); switch (spr2) { case 8: switch (spr1) { case 12: { gCPU.tb = gCPU.ptb / TB_TO_PTB_FACTOR; gCPU.gpr[rD] = gCPU.tb; return; } case 13: { gCPU.tb = gCPU.ptb / TB_TO_PTB_FACTOR; gCPU.gpr[rD] = gCPU.tb >> 32; return; } } break; }}/* * mtcrf Move to Condition Register Fields * .576 */void ppc_opc_mtcrf(){ int rS; uint32 crm; uint32 CRM; PPC_OPC_TEMPL_XFX(gCPU.current_opc, rS, crm); CRM = ((crm&0x80)?0xf0000000:0)|((crm&0x40)?0x0f000000:0)|((crm&0x20)?0x00f00000:0)|((crm&0x10)?0x000f0000:0)| ((crm&0x08)?0x0000f000:0)|((crm&0x04)?0x00000f00:0)|((crm&0x02)?0x000000f0:0)|((crm&0x01)?0x0000000f:0); gCPU.cr = (gCPU.gpr[rS] & CRM) | (gCPU.cr & ~CRM);}/* * mtfsb0x Move to FPSCR Bit 0 * .577 */void ppc_opc_mtfsb0x(){ int crbD, n1, n2; PPC_OPC_TEMPL_X(gCPU.current_opc, crbD, n1, n2); if (crbD != 1 && crbD != 2) { gCPU.fpscr &= ~(1<<(31-crbD)); } if (gCPU.current_opc & PPC_OPC_Rc) { // update cr1 flags PPC_OPC_ERR("mtfsb0. unimplemented.\n"); }}/* * mtfsb1x Move to FPSCR Bit 1 * .578 */void ppc_opc_mtfsb1x(){ int crbD, n1, n2; PPC_OPC_TEMPL_X(gCPU.current_opc, crbD, n1, n2); if (crbD != 1 && crbD != 2) { gCPU.fpscr |= 1<<(31-crbD); } if (gCPU.current_opc & PPC_OPC_Rc) { // update cr1 flags PPC_OPC_ERR("mtfsb1. unimplemented.\n"); }}/* * mtfsfx Move to FPSCR Fields * .579 */void ppc_opc_mtfsfx(){ int frB; uint32 fm, FM; PPC_OPC_TEMPL_XFL(gCPU.current_opc, frB, fm); FM = ((fm&0x80)?0xf0000000:0)|((fm&0x40)?0x0f000000:0)|((fm&0x20)?0x00f00000:0)|((fm&0x10)?0x000f0000:0)| ((fm&0x08)?0x0000f000:0)|((fm&0x04)?0x00000f00:0)|((fm&0x02)?0x000000f0:0)|((fm&0x01)?0x0000000f:0); gCPU.fpscr = (gCPU.fpr[frB] & FM) | (gCPU.fpscr & ~FM); if (gCPU.current_opc & PPC_OPC_Rc) { // update cr1 flags PPC_OPC_ERR("mtfsf. unimplemented.\n"); }}/* * mtfsfix Move to FPSCR Field Immediate * .580 */void ppc_opc_mtfsfix(){ int crfD, n1; uint32 imm; PPC_OPC_TEMPL_X(gCPU.current_opc, crfD, n1, imm); crfD >>= 2; imm >>= 1; crfD = 7-crfD; gCPU.fpscr &= ppc_cmp_and_mask[crfD]; gCPU.fpscr |= imm<<(crfD*4); if (gCPU.current_opc & PPC_OPC_Rc) { // update cr1 flags PPC_OPC_ERR("mtfsfi. unimplemented.\n"); }}/* * mtmsr Move to Machine State Register * .581 */void ppc_opc_mtmsr(){ if (gCPU.msr & MSR_PR) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); return; } int rS, rA, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB); PPC_OPC_ASSERT((rA == 0) && (rB == 0)); ppc_set_msr(gCPU.gpr[rS]);}/* * mtspr Move to Special-Purpose Register * .584 */void ppc_opc_mtspr(){ int rS, spr1, spr2; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, spr1, spr2); /* if(!(spr1 == 8 && spr2 == 0)) if( !(spr1 == 9 && spr2 == 0)) fprintf(stderr, "In %s, opc=0x%x,spr1=%d,spr2=%d\n", __FUNCTION__, gCPU.current_opc, spr1, spr2); */ switch (spr2) { case 0: switch (spr1) { case 1: gCPU.xer = gCPU.gpr[rS]; return; case 8: gCPU.lr = gCPU.gpr[rS]; return; case 9: gCPU.ctr = gCPU.gpr[rS]; return; } break; case 8: //altivec makes this register unpriviledged if (spr1 == 0) { gCPU.vrsave = gCPU.gpr[rS]; return; } switch(spr1){ case 28: gCPU.tbl = gCPU.gpr[rS]; return; case 29: gCPU.tbu = gCPU.gpr[rS]; return; } break; } if (gCPU.msr & MSR_PR) { // ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); //printf("Warning: execute mtspr in user mode\n"); //return; } switch (spr2) { case 0: switch (spr1) {/* case 18: gCPU.gpr[rD] = gCPU.dsisr; return; case 19: gCPU.gpr[rD] = gCPU.dar; return;*/ case 22: { gCPU.dec = gCPU.gpr[rS]; gCPU.pdec = gCPU.dec; gCPU.pdec *= TB_TO_PTB_FACTOR; return; } case 25: if (!ppc_mmu_set_sdr1(gCPU.gpr[rS], true)) { PPC_OPC_ERR("cannot set sdr1\n"); } return; case 26: gCPU.srr[0] = gCPU.gpr[rS]; return; case 27: gCPU.srr[1] = gCPU.gpr[rS]; return; default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } break; case 1: switch (spr1) { case 16: e500_mmu.pid[0] = gCPU.gpr[rS]; //printf("write pid0=0x%x\n", gCPU.gpr[rS]); return; case 26:gCPU.csrr[0] = gCPU.gpr[rS];return; case 27:gCPU.csrr[1] = gCPU.gpr[rS];return; case 29:gCPU.dear = gCPU.gpr[rS];return; case 30:gCPU.esr = gCPU.gpr[rS];return; case 31:gCPU.ivpr = gCPU.gpr[rS];return; default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } case 8: switch (spr1) { case 16: gCPU.sprg[0] = gCPU.gpr[rS]; return; case 17: gCPU.sprg[1] = gCPU.gpr[rS]; return; case 18: gCPU.sprg[2] = gCPU.gpr[rS]; return; case 19: gCPU.sprg[3] = gCPU.gpr[rS]; return; case 20: gCPU.sprg[4] = gCPU.gpr[rS]; return; case 21: gCPU.sprg[5] = gCPU.gpr[rS]; return; case 22: gCPU.sprg[6] = gCPU.gpr[rS]; return; case 23: gCPU.sprg[7] = gCPU.gpr[rS]; return;/* case 26: gCPU.gpr[rD] = gCPU.ear; return; case 31: gCPU.gpr[rD] = gCPU.pvr; return;*/ default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } break; case 9: switch (spr1) { case 16:gCPU.dbsr = gCPU.gpr[rS]; return; case 20:gCPU.dbcr[0] = gCPU.gpr[rS]; return; case 21:gCPU.dbcr[1] = gCPU.gpr[rS]; return; case 22:gCPU.dbcr[2] = gCPU.gpr[rS]; return; case 28:gCPU.dac[0] = gCPU.gpr[rS]; return; case 29:gCPU.dac[1] = gCPU.gpr[rS]; return; default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } break; case 10: switch (spr1){ case 16: /* W1C, write one to clear */ gCPU.tsr &= ~(gCPU.tsr & gCPU.gpr[rS]) ; return; case 20:gCPU.tcr = gCPU.gpr[rS];return; default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } break; case 12: if(spr1 >= 16 && spr1 < 32){ gCPU.ivor[spr1 - 16] = gCPU.gpr[rS]; return; } switch (spr1){ default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } break; case 16: switch (spr1) { case 0: gCPU.spefscr = gCPU.gpr[rS]; return; case 16: gCPU.ibatu[0] = gCPU.gpr[rS]; gCPU.ibat_bl17[0] = ~(BATU_BL(gCPU.ibatu[0])<<17); return; case 17: gCPU.ibatl[0] = gCPU.gpr[rS]; return; case 18: gCPU.ibatu[1] = gCPU.gpr[rS]; gCPU.ibat_bl17[1] = ~(BATU_BL(gCPU.ibatu[1])<<17); return; case 19: gCPU.ibatl[1] = gCPU.gpr[rS]; return; case 20: gCPU.ibatu[2] = gCPU.gpr[rS]; gCPU.ibat_bl17[2] = ~(BATU_BL(gCPU.ibatu[2])<<17); return; case 21: gCPU.ibatl[2] = gCPU.gpr[rS]; return; case 22: gCPU.ibatu[3] = gCPU.gpr[rS]; gCPU.ibat_bl17[3] = ~(BATU_BL(gCPU.ibatu[3])<<17); return; case 23: gCPU.ibatl[3] = gCPU.gpr[rS]; return; case 24: gCPU.dbatu[0] = gCPU.gpr[rS]; gCPU.dbat_bl17[0] = ~(BATU_BL(gCPU.dbatu[0])<<17); return; case 25: gCPU.dbatl[0] = gCPU.gpr[rS]; return; case 26: gCPU.dbatu[1] = gCPU.gpr[rS]; gCPU.dbat_bl17[1] = ~(BATU_BL(gCPU.dbatu[1])<<17); return; case 27: gCPU.dbatl[1] = gCPU.gpr[rS]; return; case 28: gCPU.dbatu[2] = gCPU.gpr[rS]; gCPU.dbat_bl17[2] = ~(BATU_BL(gCPU.dbatu[2])<<17); return; case 29: gCPU.dbatl[2] = gCPU.gpr[rS]; return; case 30: gCPU.dbatu[3] = gCPU.gpr[rS]; gCPU.dbat_bl17[3] = ~(BATU_BL(gCPU.dbatu[3])<<17); return; case 31: gCPU.dbatl[3] = gCPU.gpr[rS]; return; default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } break; case 17: switch(spr1){ case 26: gCPU.mcsrr[0] = gCPU.gpr[rS]; return; case 27: gCPU.mcsrr[1] = gCPU.gpr[rS]; return; case 28: gCPU.mcsr = gCPU.gpr[rS]; return; default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } break; case 19: switch(spr1){ case 16: e500_mmu.mas[0] = gCPU.gpr[rS]; return; case 17: e500_mmu.mas[1] = gCPU.gpr[rS]; return; case 18: e500_mmu.mas[2] = gCPU.gpr[rS]; return; case 19: e500_mmu.mas[3] = gCPU.gpr[rS]; return; case 20: e500_mmu.mas[4] = gCPU.gpr[rS]; return; case 22: e500_mmu.mas[6] = gCPU.gpr[rS]; return; case 25: e500_mmu.pid[1] = gCPU.gpr[rS]; //printf("write pid 1 0x%x\n", gCPU.gpr[rS]); return; case 26: e500_mmu.pid[2] = gCPU.gpr[rS]; //printf("write pid 2 0x%x\n", gCPU.gpr[rS]); return; default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } break; case 29: switch(spr1) { case 17: return; case 24: return; case 25: return; case 26: return; } case 31: switch (spr1) { case 16:// PPC_OPC_WARN("write(%08x) to spr %d:%d (HID0) not supported! @%08x\n", gCPU.gpr[rS], spr1, spr2, gCPU.pc); gCPU.hid[0] = gCPU.gpr[rS]; return; case 17: return; case 18: PPC_OPC_ERR("write(%08x) to spr %d:%d (IABR) not supported!\n", gCPU.gpr[rS], spr1, spr2); return; case 19: gCPU.l1csr[1] = gCPU.gpr[rS]; return; case 20: gCPU.iac[0] = gCPU.gpr[rS]; return; case 21: PPC_OPC_ERR("write(%08x) to spr %d:%d (DABR) not supported!\n", gCPU.gpr[rS], spr1, spr2); return; case 27: PPC_OPC_WARN("write(%08x) to spr %d:%d (ICTC) not supported!\n", gCPU.gpr[rS], spr1, spr2); return; case 28:// PPC_OPC_WARN("write(%08x) to spr %d:%d (THRM1) not supported!\n", gCPU.gpr[rS], spr1, spr2); return; case 29:// PPC_OPC_WARN("write(%08x) to spr %d:%d (THRM2) not supported!\n", gCPU.gpr[rS], spr1, spr2); return; case 30:// PPC_OPC_WARN("write(%08x) to spr %d:%d (THRM3) not supported!\n", gCPU.gpr[rS], spr1, spr2); return; case 31: return; default:fprintf(stderr, "spr2=0x%x,spr1=0x%x,pc=0x%x,no such spr\n", spr2,spr1,gCPU.pc);break; } } fprintf(stderr, "unknown mtspr: %i:%i\n", spr1, spr2); fprintf(stderr, "pc=0x%x\n",gCPU.pc); skyeye_exit(-1);}/* * mtsr Move to Segment Register * .587 */void ppc_opc_mtsr(){ if (gCPU.msr & MSR_PR) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); return; } int rS, SR, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, SR, rB); // FIXME: check insn gCPU.sr[SR & 0xf] = gCPU.gpr[rS];}/* * mtsrin Move to Segment Register Indirect * .591 */void ppc_opc_mtsrin(){ if (gCPU.msr & MSR_PR) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); return; } int rS, rA, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB); // FIXME: check insn gCPU.sr[gCPU.gpr[rB] >> 28] = gCPU.gpr[rS];}/* * rfi Return from Interrupt * .607 */void ppc_opc_rfi(){ if (gCPU.msr & MSR_PR) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); return; } ppc_set_msr(gCPU.srr[1] & MSR_RFI_SAVE_MASK); gCPU.npc = gCPU.srr[0] & 0xfffffffc;}/* * sc System Call * .621 *///#include "io/graphic/gcard.h"void ppc_opc_sc(){ if (gCPU.gpr[3] == 0x113724fa && gCPU.gpr[4] == 0x77810f9b) { //gcard_osi(0); return; } ppc_exception(SYSCALL ,0 ,0);}/* * sync Synchronize * .672 */void ppc_opc_sync(){ // NO-OP}/* * tlbie Translation Lookaside Buffer Invalidate Entry * .676 */void ppc_opc_tlbia(){ if (gCPU.msr & MSR_PR) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); return; } int rS, rA, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB); // FIXME: check rS.. for 0 ppc_mmu_tlb_invalidate();}/* * tlbie Translation Lookaside Buffer Invalidate All * .676 */void ppc_opc_tlbie(){ if (gCPU.msr & MSR_PR) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); return; } int rS, rA, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB); // FIXME: check rS.. for 0 ppc_mmu_tlb_invalidate();}/* * tlbsync Translation Lookaside Buffer Syncronize * .677 */void ppc_opc_tlbsync(){ if (gCPU.msr & MSR_PR) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0); return; } int rS, rA, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB); // FIXME: check rS.. for 0 ppc_mmu_tlb_invalidate();}/* * tw Trap Word * .678 */void ppc_opc_tw(){ int TO, rA, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, TO, rA, rB); uint32 a = gCPU.gpr[rA]; uint32 b = gCPU.gpr[rB]; if (((TO & 16) && ((sint32)a < (sint32)b)) || ((TO & 8) && ((sint32)a > (sint32)b)) || ((TO & 4) && (a == b)) || ((TO & 2) && (a < b)) || ((TO & 1) && (a > b))) { ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_TRAP, 0); }}/* * twi Trap Word Immediate * .679 */void ppc_opc_twi(){ int TO, rA; uint32 imm; PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, TO, rA, imm); uint32 a = gCPU.gpr[rA]; if (((TO & 16) && ((sint32)a < (sint32)imm)) || ((TO & 8) && ((sint32)a > (sint32)imm)) || ((TO & 4) && (a == imm)) || ((TO & 2) && (a < imm)) || ((TO & 1) && (a > imm))) { ppc_exception(PROG, PPC_EXC_PROGRAM_TRAP, 0); }}/* dcba Data Cache Block Allocate * .??? */void ppc_opc_dcba(){ /* NO-OP */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -