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

📄 ppc_opc.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	PearPC *	ppc_opc.cc * *	Copyright (C) 2003 Sebastian Biallas (sb@biallas.net) *	Copyright (C) 2004 Dainel Foesch (dfoesch@cs.nmsu.edu) * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License version 2 as *	published by the Free Software Foundation. * *	This program is distributed in the hope that it will be useful, *	but WITHOUT ANY WARRANTY; without even the implied warranty of *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *	GNU General Public License for more details. * *	You should have received a copy of the GNU General Public License *	along with this program; if not, write to the Free Software *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//*#include "debug/tracers.h"#include "cpu/debug.h"#include "io/pic/pic.h"#include "info.h"*/#include <stdio.h>#include "ppc_cpu.h"#include "ppc_exc.h"#include "ppc_e500_exc.h"#include "ppc_mmu.h"#include "ppc_opc.h"#include "ppc_dec.h"#include "tracers.h"#include "debug.h"void ppc_set_msr(uint32 newmsr){/*	if ((newmsr & MSR_EE) && !(gCPU.msr & MSR_EE)) {		if (pic_check_interrupt()) {			gCPU.exception_pending = true;			gCPU.ext_exception = true;		}	}*/	ppc_mmu_tlb_invalidate();#ifndef PPC_CPU_ENABLE_SINGLESTEP	if (newmsr & MSR_SE) {		PPC_CPU_WARN("MSR[SE] (singlestep enable) set, but compiled w/o SE support.\n");	}#else 	gCPU.singlestep_ignore = true;#endif	if (newmsr & PPC_CPU_UNSUPPORTED_MSR_BITS) {		PPC_CPU_ERR("unsupported bits in MSR set: %08x @%08x\n", newmsr & PPC_CPU_UNSUPPORTED_MSR_BITS, gCPU.pc);	}	if (newmsr & MSR_POW) {		// doze();		newmsr &= ~MSR_POW;	}	gCPU.msr = newmsr;	}/* *	bx		Branch *	.435 */void ppc_opc_bx(){	uint32 li;	PPC_OPC_TEMPL_I(gCPU.current_opc, li);	if (!(gCPU.current_opc & PPC_OPC_AA)) {		li += gCPU.pc;	}	if (gCPU.current_opc & PPC_OPC_LK) {		gCPU.lr = gCPU.pc + 4;	}	gCPU.npc = li;}/* *	bcx		Branch Conditional *	.436 */void ppc_opc_bcx(){	uint32 BO, BI, BD;	PPC_OPC_TEMPL_B(gCPU.current_opc, BO, BI, BD);	if (!(BO & 4)) {		gCPU.ctr--;	}	bool bo2 = ((BO & 2)?1:0);	bool bo8 = ((BO & 8)?1:0); // branch condition true	bool cr = ((gCPU.cr & (1<<(31-BI)))?1:0) ;	if (((BO & 4) || ((gCPU.ctr!=0) ^ bo2))	&& ((BO & 16) || (!(cr ^ bo8)))) {		if (!(gCPU.current_opc & PPC_OPC_AA)) {			BD += gCPU.pc;		}		if (gCPU.current_opc & PPC_OPC_LK) {			gCPU.lr = gCPU.pc + 4;		}		gCPU.npc = BD;	}	//fprintf(stderr,"in %s,BO=0x%x,BI=0x%x,BD=0x%x,cr=0x%x,cr^bo8=0x%x,ctr=0x%x,pc=0x%x\n",__FUNCTION__,BO,BI,BD,gCPU.cr,(cr ^ bo8),gCPU.ctr, gCPU.pc);}/* *	bcctrx		Branch Conditional to Count Register *	.438 */void ppc_opc_bcctrx(){	uint32 BO, BI, BD;	PPC_OPC_TEMPL_XL(gCPU.current_opc, BO, BI, BD);	PPC_OPC_ASSERT(BD==0);	PPC_OPC_ASSERT(!(BO & 2));     	bool bo8 = ((BO & 8)?1:0);	bool cr = ((gCPU.cr & (1<<(31-BI)))?1:0);	if ((BO & 16) || (!(cr ^ bo8))) {		if (gCPU.current_opc & PPC_OPC_LK) {			gCPU.lr = gCPU.pc + 4;		}		gCPU.npc = gCPU.ctr & 0xfffffffc;	}	//fprintf(stderr,"in %s,BO=0x%x,BI=0x%x,BD=0x%x,cr=0x%x,cr^bo8=0x%x,ctr=0x%x,pc=0x%x,npc=0x%x\n",__FUNCTION__,BO,BI,BD,gCPU.cr,(cr ^ bo8),gCPU.ctr, gCPU.pc,gCPU.npc);}/* *	bclrx		Branch Conditional to Link Register *	.440 */void ppc_opc_bclrx(){	uint32 BO, BI, BD;	PPC_OPC_TEMPL_XL(gCPU.current_opc, BO, BI, BD);	PPC_OPC_ASSERT(BD==0);	if (!(BO & 4)) {		gCPU.ctr--;	}	bool bo2 = ((BO & 2)?1:0);	bool bo8 = ((BO & 8)?1:0);	bool cr = ((gCPU.cr & (1<<(31-BI)))?1:0);	if (((BO & 4) || ((gCPU.ctr!=0) ^ bo2))	&& ((BO & 16) || (!(cr ^ bo8)))) {		BD = gCPU.lr & 0xfffffffc;		if (gCPU.current_opc & PPC_OPC_LK) {			gCPU.lr = gCPU.pc + 4;		}		gCPU.npc = BD;	}}/* *	dcbf		Data Cache Block Flush *	.458 */void ppc_opc_dcbf(){	// NO-OP}/* *	dcbi		Data Cache Block Invalidate *	.460 */void ppc_opc_dcbi(){	if (gCPU.msr & MSR_PR) {		ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0);		return;	}	// FIXME: check addr}/* *	dcbst		Data Cache Block Store *	.461 */void ppc_opc_dcbst(){	// NO-OP}/* *	dcbt		Data Cache Block Touch *	.462 */void ppc_opc_dcbt(){	// NO-OP}/* *	dcbtst		Data Cache Block Touch for Store *	.463 */void ppc_opc_dcbtst(){	// NO-OP}/* *	eciwx		External Control In Word Indexed *	.474 */void ppc_opc_eciwx(){	PPC_OPC_ERR("eciwx unimplemented.\n");}/* *	ecowx		External Control Out Word Indexed *	.476 */void ppc_opc_ecowx(){	PPC_OPC_ERR("ecowx unimplemented.\n");}/* *	eieio		Enforce In-Order Execution of I/O *	.478 */void ppc_opc_eieio(){	// NO-OP}/* *	icbi		Instruction Cache Block Invalidate *	.519 */void ppc_opc_icbi(){	// NO-OP}/* *	isync		Instruction Synchronize *	.520 */void ppc_opc_isync(){	// NO-OP}static uint32 ppc_cmp_and_mask[8] = {	0xfffffff0,	0xffffff0f,	0xfffff0ff,	0xffff0fff,	0xfff0ffff,	0xff0fffff,	0xf0ffffff,	0x0fffffff,};/* *	mcrf		Move Condition Register Field *	.561 */void ppc_opc_mcrf(){	uint32 crD, crS, bla;	PPC_OPC_TEMPL_X(gCPU.current_opc, crD, crS, bla);	// FIXME: bla == 0	crD>>=2;	crS>>=2;	crD = 7-crD;	crS = 7-crS;	uint32 c = (gCPU.cr>>(crS*4)) & 0xf;	gCPU.cr &= ppc_cmp_and_mask[crD];	gCPU.cr |= c<<(crD*4);}/* *	mcrfs		Move to Condition Register from FPSCR *	.562 */void ppc_opc_mcrfs(){	PPC_OPC_ERR("mcrfs unimplemented.\n");}/* *	mcrxr		Move to Condition Register from XER *	.563 */void ppc_opc_mcrxr(){	PPC_OPC_ERR("mcrxr unimplemented.\n");}/* *	mfcr		Move from Condition Register *	.564 */void ppc_opc_mfcr(){	int rD, rA, rB;	PPC_OPC_TEMPL_X(gCPU.current_opc, rD, rA, rB);	PPC_OPC_ASSERT(rA==0 && rB==0);	gCPU.gpr[rD] = gCPU.cr;}/* *	mffs		Move from FPSCR *	.565 */void ppc_opc_mffsx(){	int frD, rA, rB;	PPC_OPC_TEMPL_X(gCPU.current_opc, frD, rA, rB);	PPC_OPC_ASSERT(rA==0 && rB==0);	gCPU.fpr[frD] = gCPU.fpscr;	if (gCPU.current_opc & PPC_OPC_Rc) {		// update cr1 flags		PPC_OPC_ERR("mffs. unimplemented.\n");	}}/* *	mfmsr		Move from Machine State Register *	.566 */void ppc_opc_mfmsr(){	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);	PPC_OPC_ASSERT((rA == 0) && (rB == 0));	gCPU.gpr[rD] = gCPU.msr;}/* *	mfspr		Move from Special-Purpose Register *	.567 */void ppc_opc_mfspr(){	int rD, spr1, spr2;	PPC_OPC_TEMPL_XO(gCPU.current_opc, rD, spr1, spr2);	if (gCPU.msr & MSR_PR) {		//ppc_exception(PPC_EXC_PROGRAM, PPC_EXC_PROGRAM_PRIV, 0);		//printf("Warning, execute mfspe in user mode\n");		//return;	}	switch (spr2) {	case 0:		switch (spr1) {		case 1: gCPU.gpr[rD] = gCPU.xer; return;		case 8: gCPU.gpr[rD] = gCPU.lr; return;		case 9: gCPU.gpr[rD] = gCPU.ctr; return;		case 18: gCPU.gpr[rD] = gCPU.dsisr; return;		case 19: gCPU.gpr[rD] = gCPU.dar; return;		case 22: {			gCPU.dec = gCPU.pdec / TB_TO_PTB_FACTOR;			gCPU.gpr[rD] = gCPU.dec;			return;		}		case 25: gCPU.gpr[rD] = gCPU.sdr1; return;		case 26: gCPU.gpr[rD] = gCPU.srr[0]; return;		case 27: gCPU.gpr[rD] = gCPU.srr[1]; return;		}		break;	case 1:		switch(spr1) {			case 16: gCPU.gpr[rD] = e500_mmu.pid[1];return;			case 29: gCPU.gpr[rD] = gCPU.dear;return;			case 30: gCPU.gpr[rD] = gCPU.esr; return;		}		break;	case 8:		switch (spr1) {		case 12: {			/*			gCPU.tb = gCPU.ptb / TB_TO_PTB_FACTOR;			gCPU.gpr[rD] = gCPU.tb;			*/			gCPU.gpr[rD] = gCPU.tbl;			return;		}		case 13: {			/*			gCPU.tb = gCPU.ptb / TB_TO_PTB_FACTOR;			gCPU.gpr[rD] = gCPU.tb >> 32;			*/			gCPU.gpr[rD] = gCPU.tbu;			return;		}		case 0: gCPU.gpr[rD] = gCPU.vrsave; return;		case 16: gCPU.gpr[rD] = gCPU.sprg[0]; return;		case 1:		case 17: gCPU.gpr[rD] = gCPU.sprg[1]; return;		case 2:		case 18: gCPU.gpr[rD] = gCPU.sprg[2]; return;		case 3:		case 19: gCPU.gpr[rD] = gCPU.sprg[3]; return;		case 4:		case 20: gCPU.gpr[rD] = gCPU.sprg[4]; return;		case 5:                case 21: gCPU.gpr[rD] = gCPU.sprg[5]; return;		case 6:                case 22: gCPU.gpr[rD] = gCPU.sprg[6]; return;                case 23:		case 7: 			gCPU.gpr[rD] = gCPU.sprg[7]; return;		case 26: 			gCPU.gpr[rD] = gCPU.ear; return;		case 31: gCPU.gpr[rD] = gCPU.pvr; return;		default:			fprintf(stderr, "unknown mfspr: %i:%i\n", spr1, spr2);		        fprintf(stderr, "pc=0x%x\n", gCPU.pc);        		skyeye_exit(-1);		}		break;	case 9:		switch(spr1) {			case 16:gCPU.gpr[rD] = gCPU.dbsr; return;			case 20:gCPU.gpr[rD] = gCPU.dbcr[0]; return;                        case 21:gCPU.gpr[rD] = gCPU.dbcr[1]; return;                        case 22:gCPU.gpr[rD] = gCPU.dbcr[2]; return;                        case 28:gCPU.gpr[rD] = gCPU.dac[0]; return;                        case 29:gCPU.gpr[rD] = gCPU.dac[1]; return;		}		break;	case 16:		switch (spr1) {		case 0: gCPU.gpr[rD] = gCPU.spefscr; return;		case 16: gCPU.gpr[rD] = gCPU.ibatu[0]; return;		case 17: gCPU.gpr[rD] = gCPU.ibatl[0]; return;		case 18: gCPU.gpr[rD] = gCPU.ibatu[1]; return;		case 19: gCPU.gpr[rD] = gCPU.ibatl[1]; return;		case 20: gCPU.gpr[rD] = gCPU.ibatu[2]; return;		case 21: gCPU.gpr[rD] = gCPU.ibatl[2]; return;		case 22: gCPU.gpr[rD] = gCPU.ibatu[3]; return;		case 23: gCPU.gpr[rD] = gCPU.ibatl[3]; return;		case 24: gCPU.gpr[rD] = gCPU.dbatu[0]; return;		case 25: gCPU.gpr[rD] = gCPU.dbatl[0]; return;		case 26: gCPU.gpr[rD] = gCPU.dbatu[1]; return;		case 27: gCPU.gpr[rD] = gCPU.dbatl[1]; return;		case 28: gCPU.gpr[rD] = gCPU.dbatu[2]; return;		case 29: gCPU.gpr[rD] = gCPU.dbatl[2]; return;		case 30: gCPU.gpr[rD] = gCPU.dbatu[3]; return;		case 31: gCPU.gpr[rD] = gCPU.dbatl[3]; return;		}		break;	case 19:                switch(spr1) {			case 16:                                gCPU.gpr[rD] = e500_mmu.mas[0];                                return;                        case 17:                                gCPU.gpr[rD] = e500_mmu.mas[1];                                return;                        case 18:                                gCPU.gpr[rD] = e500_mmu.mas[2];                                return;                        case 19:                                gCPU.gpr[rD] = e500_mmu.mas[3];                                return;                        case 20:                                gCPU.gpr[rD] = e500_mmu.mas[4];                                return;                        case 22:                                gCPU.gpr[rD] = e500_mmu.mas[6];                                return;                        case 25:                                gCPU.gpr[rD] = e500_mmu.pid[1];                                return;                        case 26:                                gCPU.gpr[rD] = e500_mmu.pid[2];                                return;                }                break;	case 21:                switch(spr1) {                        case 17:gCPU.gpr[rD] = e500_mmu.tlbcfg[1]; return;                }                break;	case 29:		switch (spr1) {		case 16:			gCPU.gpr[rD] = 0;			return;		case 17:			gCPU.gpr[rD] = 0;			return;		case 18:			gCPU.gpr[rD] = 0;			return;		case 24:			gCPU.gpr[rD] = 0;			return;		case 25:			gCPU.gpr[rD] = 0;			return;		case 26:			gCPU.gpr[rD] = 0;			return;		case 28:			gCPU.gpr[rD] = 0;			return;		case 29:			gCPU.gpr[rD] = 0;			return;		case 30:			gCPU.gpr[rD] = 0;			return;		}		break;	case 31:		switch (spr1) {		case 16://			PPC_OPC_WARN("read from spr %d:%d (HID0) not supported!\n", spr1, spr2);			gCPU.gpr[rD] = gCPU.hid[0];			return;		case 17:			PPC_OPC_WARN("read from spr %d:%d (HID1) not supported!\n", spr1, spr2);			gCPU.gpr[rD] = gCPU.hid[1];			return;		case 18:			gCPU.gpr[rD] = 0;			return;		case 19:			gCPU.gpr[rD] = gCPU.l1csr[1];			return;		case 20:			gCPU.gpr[rD] = gCPU.iac[0];			return;		case 21:			gCPU.gpr[rD] = 0;			return;		case 22:			gCPU.gpr[rD] = 0;			return;		case 23:			gCPU.gpr[rD] = 0;			return;		case 25:			PPC_OPC_WARN("read from spr %d:%d (L2CR) not supported! (from %08x)\n", spr1, spr2, gCPU.pc);			gCPU.gpr[rD] = 0;			return;		case 27:			PPC_OPC_WARN("read from spr %d:%d (ICTC) not supported!\n", spr1, spr2);			gCPU.gpr[rD] = 0;			return;		case 28://			PPC_OPC_WARN("read from spr %d:%d (THRM1) not supported!\n", spr1, spr2);			gCPU.gpr[rD] = 0;			return;		case 29://			PPC_OPC_WARN("read from spr %d:%d (THRM2) not supported!\n", spr1, spr2);			gCPU.gpr[rD] = 0;			return;		case 30://			PPC_OPC_WARN("read from spr %d:%d (THRM3) not supported!\n", spr1, spr2);			gCPU.gpr[rD] = 0;			return;		case 31://			PPC_OPC_WARN("read from spr %d:%d (???) not supported!\n", spr1, spr2);			gCPU.gpr[rD] = 0;			return;		}		break;	}	fprintf(stderr, "unknown mfspr: %i:%i\n", spr1, spr2);	fprintf(stderr, "pc=0x%x\n", gCPU.pc);	skyeye_exit(-1);	//SINGLESTEP("invalid mfspr\n");}/* *	mfsr		Move from Segment Register *	.570 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -