ppc_mmu.c
来自「skyeye是一个可以模拟嵌入式硬件开发板的系统软件」· C语言 代码 · 共 2,269 行 · 第 1/5 页
C
2,269 行
if (NB==0) NB=32; uint32 ea = rA ? gCPU.gpr[rA] : 0; uint32 r = 0; int i = 4; uint8 v; while (NB > 0) { if (!i) { i = 4; gCPU.gpr[rD] = r; rD++; rD%=32; r = 0; } if (ppc_read_effective_byte(ea, &v)) { return; } r<<=8; r|=v; ea++; i--; NB--; } while (i) { r<<=8; i--; } gCPU.gpr[rD] = r;}/* * lswx Load String Word Indexed * .550 */void ppc_opc_lswx(){ int rA, rD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB); int NB = XER_n(gCPU.xer); uint32 ea = gCPU.gpr[rB] + (rA ? gCPU.gpr[rA] : 0); uint32 r = 0; int i = 4; uint8 v; while (NB > 0) { if (!i) { i = 4; gCPU.gpr[rD] = r; rD++; rD%=32; r = 0; } if (ppc_read_effective_byte(ea, &v)) { return; } r<<=8; r|=v; ea++; i--; NB--; } while (i) { r<<=8; i--; } gCPU.gpr[rD] = r;}/* * lwarx Load Word and Reserve Indexed * .553 */void ppc_opc_lwarx(){ int rA, rD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB); uint32 r; int ret = ppc_read_effective_word((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB], &r); if (ret == PPC_MMU_OK) { gCPU.gpr[rD] = r; gCPU.reserve = r; gCPU.have_reservation = 1; }}/* * lwbrx Load Word Byte-Reverse Indexed * .556 */void ppc_opc_lwbrx(){ int rA, rD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB); uint32 r; int ret = ppc_read_effective_word((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB], &r); if (ret == PPC_MMU_OK) { gCPU.gpr[rD] = ppc_bswap_word(r); }}/* * lwz Load Word and Zero * .557 */void ppc_opc_lwz(){ int rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rD, rA, imm); uint32 r; int ret = ppc_read_effective_word((rA?gCPU.gpr[rA]:0)+imm, &r); if (ret == PPC_MMU_OK) { gCPU.gpr[rD] = r; } }/* * lbzu Load Word and Zero with Update * .558 */void ppc_opc_lwzu(){ int rA, rD; uint32 imm; PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rD, rA, imm); // FIXME: check rA!=0 && rA!=rD uint32 r; int ret = ppc_read_effective_word(gCPU.gpr[rA]+imm, &r); if (ret == PPC_MMU_OK) { gCPU.gpr[rA] += imm; gCPU.gpr[rD] = r; } }/* * lwzux Load Word and Zero with Update Indexed * .559 */void ppc_opc_lwzux(){ int rA, rD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB); // FIXME: check rA!=0 && rA!=rD uint32 r; int ret = ppc_read_effective_word(gCPU.gpr[rA]+gCPU.gpr[rB], &r); if (ret == PPC_MMU_OK) { gCPU.gpr[rA] += gCPU.gpr[rB]; gCPU.gpr[rD] = r; }}/* * lwzx Load Word and Zero Indexed * .560 */void ppc_opc_lwzx(){ int rA, rD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB); uint32 r; int ret = ppc_read_effective_word((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB], &r); if (ret == PPC_MMU_OK) { gCPU.gpr[rD] = r; }}/* lvx Load Vector Indexed * v.127 */void ppc_opc_lvx(){#ifndef __VEC_EXC_OFF__ if ((gCPU.msr & MSR_VEC) == 0) { ppc_exception(PPC_EXC_NO_VEC, 0, 0); return; }#endif VECTOR_DEBUG; int rA, vrD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, rA, rB); Vector_t r; int ea = ((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB]); int ret = ppc_read_effective_qword(ea, &r); if (ret == PPC_MMU_OK) { gCPU.vr[vrD] = r; }}/* lvxl Load Vector Index LRU * v.128 */void ppc_opc_lvxl(){ ppc_opc_lvx(); /* This instruction should hint to the cache that the value won't be * needed again in memory anytime soon. We don't emulate the cache, * so this is effectively exactly the same as lvx. */}/* lvebx Load Vector Element Byte Indexed * v.119 */void ppc_opc_lvebx(){#ifndef __VEC_EXC_OFF__ if ((gCPU.msr & MSR_VEC) == 0) { ppc_exception(PPC_EXC_NO_VEC, 0, 0); return; }#endif VECTOR_DEBUG; int rA, vrD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, rA, rB); uint32 ea; uint8 r; ea = (rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB]; int ret = ppc_read_effective_byte(ea, &r); if (ret == PPC_MMU_OK) { VECT_B(gCPU.vr[vrD], ea & 0xf) = r; }}/* lvehx Load Vector Element Half Word Indexed * v.121 */void ppc_opc_lvehx(){#ifndef __VEC_EXC_OFF__ if ((gCPU.msr & MSR_VEC) == 0) { ppc_exception(PPC_EXC_NO_VEC, 0, 0); return; }#endif VECTOR_DEBUG; int rA, vrD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, rA, rB); uint32 ea; uint16 r; ea = ((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB]) & ~1; int ret = ppc_read_effective_half(ea, &r); if (ret == PPC_MMU_OK) { VECT_H(gCPU.vr[vrD], (ea & 0xf) >> 1) = r; }}/* lvewx Load Vector Element Word Indexed * v.122 */void ppc_opc_lvewx(){#ifndef __VEC_EXC_OFF__ if ((gCPU.msr & MSR_VEC) == 0) { ppc_exception(PPC_EXC_NO_VEC, 0, 0); return; }#endif VECTOR_DEBUG; int rA, vrD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, rA, rB); uint32 ea; uint32 r; ea = ((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB]) & ~3; int ret = ppc_read_effective_word(ea, &r); if (ret == PPC_MMU_OK) { VECT_W(gCPU.vr[vrD], (ea & 0xf) >> 2) = r; }}#if HOST_ENDIANESS == HOST_ENDIANESS_LEstatic byte lvsl_helper[] = { 0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00};#elif HOST_ENDIANESS == HOST_ENDIANESS_BEstatic byte lvsl_helper[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F};#else#error Endianess not supported!#endif/* * lvsl Load Vector for Shift Left * v.123 */void ppc_opc_lvsl(){#ifndef __VEC_EXC_OFF__ if ((gCPU.msr & MSR_VEC) == 0) { ppc_exception(PPC_EXC_NO_VEC, 0, 0); return; }#endif VECTOR_DEBUG; int rA, vrD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, rA, rB); uint32 ea; ea = ((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB]);#if HOST_ENDIANESS == HOST_ENDIANESS_LE memmove(&gCPU.vr[vrD], lvsl_helper+0x10-(ea & 0xf), 16);#elif HOST_ENDIANESS == HOST_ENDIANESS_BE memmove(&gCPU.vr[vrD], lvsl_helper+(ea & 0xf), 16);#else#error Endianess not supported!#endif}/* * lvsr Load Vector for Shift Right * v.125 */void ppc_opc_lvsr(){#ifndef __VEC_EXC_OFF__ if ((gCPU.msr & MSR_VEC) == 0) { ppc_exception(PPC_EXC_NO_VEC, 0, 0); return; }#endif VECTOR_DEBUG; int rA, vrD, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, vrD, rA, rB); uint32 ea; ea = ((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB]);#if HOST_ENDIANESS == HOST_ENDIANESS_LE memmove(&gCPU.vr[vrD], lvsl_helper+(ea & 0xf), 16);#elif HOST_ENDIANESS == HOST_ENDIANESS_BE memmove(&gCPU.vr[vrD], lvsl_helper+0x10-(ea & 0xf), 16);#else#error Endianess not supported!#endif}/* * dst Data Stream Touch * v.115 */void ppc_opc_dst(){ VECTOR_DEBUG; /* Since we are not emulating the cache, this is a nop */}/* * stb Store Byte * .632 */void ppc_opc_stb(){ int rA, rS; uint32 imm; PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rS, rA, imm); ppc_write_effective_byte((rA?gCPU.gpr[rA]:0)+imm, (uint8)gCPU.gpr[rS]) != PPC_MMU_FATAL;}/* * stbu Store Byte with Update * .633 */void ppc_opc_stbu(){ int rA, rS; uint32 imm; PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, rS, rA, imm); // FIXME: check rA!=0 int ret = ppc_write_effective_byte(gCPU.gpr[rA]+imm, (uint8)gCPU.gpr[rS]); if (ret == PPC_MMU_OK) { gCPU.gpr[rA] += imm; }}/* * stbux Store Byte with Update Indexed * .634 */void ppc_opc_stbux(){ int rA, rS, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB); // FIXME: check rA!=0 int ret = ppc_write_effective_byte(gCPU.gpr[rA]+gCPU.gpr[rB], (uint8)gCPU.gpr[rS]); if (ret == PPC_MMU_OK) { gCPU.gpr[rA] += gCPU.gpr[rB]; }}/* * stbx Store Byte Indexed * .635 */void ppc_opc_stbx(){ int rA, rS, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, rS, rA, rB); ppc_write_effective_byte((rA?gCPU.gpr[rA]:0)+gCPU.gpr[rB], (uint8)gCPU.gpr[rS]) != PPC_MMU_FATAL;}/* * stfd Store Floating-Point Double * .642 */void ppc_opc_stfd(){ if ((gCPU.msr & MSR_FP) == 0) { ppc_exception(PPC_EXC_NO_FPU, 0, 0); return; } int rA, frS; uint32 imm; PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, frS, rA, imm); ppc_write_effective_dword((rA?gCPU.gpr[rA]:0)+imm, gCPU.fpr[frS]) != PPC_MMU_FATAL;}/* * stfdu Store Floating-Point Double with Update * .643 */void ppc_opc_stfdu(){ if ((gCPU.msr & MSR_FP) == 0) { ppc_exception(PPC_EXC_NO_FPU ,0 ,0); return; } int rA, frS; uint32 imm; PPC_OPC_TEMPL_D_SImm(gCPU.current_opc, frS, rA, imm); // FIXME: check rA!=0 int ret = ppc_write_effective_dword(gCPU.gpr[rA]+imm, gCPU.fpr[frS]); if (ret == PPC_MMU_OK) { gCPU.gpr[rA] += imm; }}/* * stfd Store Floating-Point Double with Update Indexed * .644 */void ppc_opc_stfdux(){ if ((gCPU.msr & MSR_FP) == 0) { ppc_exception(PPC_EXC_NO_FPU, 0, 0); return; } int rA, frS, rB; PPC_OPC_TEMPL_X(gCPU.current_opc, frS, rA, rB); // FIXME: check rA!=0 int ret = ppc_write_effective_dword(gCPU.gpr[rA]+gCPU.gpr[rB], gCPU.fpr[frS]); if (ret == PPC_MMU_OK) { gCPU.gpr[rA] += gCPU.gpr[rB]; }}/* * tlbivax TLB invalidated virtual address indexed * .786 */void ppc_opc_tlbivax(){ //fprintf(stderr,"tlbivax is called, but not implemented\n"); int i,j; for(i = 0; i < L2_TLB0_SIZE; i++) if(!l2_tlb0_4k[i].iprot) l2_tlb0_4k[i].v = 0; for(j = 0; j < L2_TLB1_SIZE; j++) if(!l2_tlb1_vsp[i].iprot)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?