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 + -
显示快捷键?