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

📄 arm9rutinasarm.cpp

📁 ARM9Core v0.4, 在x86 Win32 下模拟仿真ARM9 微处理器的Library.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LSM

	//Para cada registro, lo transfiere si su bit esta a 1
	for ((u==1)? i = 0 : i=15;
		 (u==1)? (i<16): (i>=0);
		 (u==1)?  i++  : i--) {

		if (listaRegistros & (0x1<<i)) {
			nCiclos--;
			//Lectura de memoria
			resultado = core->readMemoriaWord(dirEfectiva);
			
			//Escribe el resultado en el registro correspondiente
			LSM_WRITEREGS

			//Post-indexada
			dirEfectiva += dirOffset;
		}

	}

	//W=1 (Write-back)
	if (w) {
		contexto->bancoRegistros[rn].u_word = dirEfectiva;
	}

	CHK_ABORT

	//lsmCPSR (Se restaura el CPSR con el SPSR)
	if (lsmCPSR) {
		contexto->escribirCPSR(contexto->SPSR[contexto->modo-1].u_word);
	}
	
	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina STM pre-index (Store multiple)
/*-------------------------------------------------------------------------*/
RUT_stm_pre:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LSM

	//Para cada registro, lo transfiere si su bit esta a 1
	for ((u==1)? i = 0 : i=15;
		 (u==1)? (i<16): (i>=0);
		 (u==1)?  i++  : i--) {

		if (listaRegistros & (0x1<<i)) {
			nCiclos--;
			//Pre-indexada
			dirEfectiva += dirOffset;

			//Carga el valor del registro correspondiente
			LSM_READREGS

			//Escritura en memoria
			core->writeMemoriaWord(resultado, dirEfectiva);
					
		}

	}

	//W=1 (Write-back)
	if (w) {
		contexto->bancoRegistros[rn].u_word = dirEfectiva;
	}
	
	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina STM post-index (Store multiple)
/*-------------------------------------------------------------------------*/
RUT_stm_post:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LSM

	//Para cada registro, lo transfiere si su bit esta a 1
	for ((u==1)? i = 0 : i=15;
		 (u==1)? (i<16): (i>=0);
		 (u==1)?  i++  : i--) {

		if (listaRegistros & (0x1<<i)) {
			nCiclos--;

			//Carga el valor del registro correspondiente
			LSM_READREGS

			//Escritura en memoria
			core->writeMemoriaWord(resultado, dirEfectiva);
			
			//Post-indexada
			dirEfectiva += dirOffset;
		}

	}

	//W=1 (Write-back)
	if (w) {
		contexto->bancoRegistros[rn].u_word = dirEfectiva;
	}
	
	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina SWP (Swap Memory and Register)
/*-------------------------------------------------------------------------*/
RUT_swap:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS

		
	if (b) {
		resultado = unsigned int (core->readMemoriaByte(operando1));
		CHK_ABORT
		core->writeMemoriaByte((uint8)operando2, operando1);

	} else {
		dirEfectiva = operando1 & 0xFFFFFFFC;
		resultado = core->readMemoriaWord(dirEfectiva);
		CHK_ABORT
		core->writeMemoriaWord(operando2, dirEfectiva);

	} 

	contexto->bancoRegistros[rd].u_word = resultado;
	
	
	nCiclos-=2;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina MUL (Multiply and accumulate)
/*-------------------------------------------------------------------------*/
RUT_mul:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_MUL

	v = contexto->flags.v;

	//MUL
	if (a) {
		//Acumula
		__asm {
			mov eax, operando1
			mov ebx, operando2
			mov edx, 0
			mul ebx				;edx:eax = eax * ebx
			add eax, acumulador	;eax = eax + acc
			pushf				;guarda los flags en la fila
			mov resultado, eax
		}
		
	}else{
		//No acumula
		__asm {
			mov eax, operando1
			mov ebx, operando2
			mov edx, 0
			mul ebx				;edx:eax = eax * ebx
			pushf				;guarda los flags en la fila
			mov resultado, eax
		}
	}
	
	//Guarda los flags
	GETFLAGS
	contexto->flags.v = v;

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos-=5;
	goto LecturaInstruccion;




/*-------------------------------------------------------------------------*/
/*	Rutina MULL (Multiply and accumulate long)
/*-------------------------------------------------------------------------*/
RUT_mull:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_MUL

	v = contexto->flags.v;

	//MUL
	if (a && !u) {
		//Acumula y sin signo
		__asm {

			mov eax, operando1
			mov ebx, operando2
			mov edx, 0
			mul ebx				;edx:eax = eax * ebx

			movd mm0, eax
			movd mm1, edx
			punpckldq mm0, mm1	;Monta los dos registros de 32 bits en uno de 64

			movd mm1, acumulador
			movd mm2, acumulador2
			punpckldq mm1, mm2	;Monta el registro acumulador

			movq uvar1_64, mm0
			movq uvar2_64, mm1
		}

		uvar1_64 += uvar2_64;
		
		__asm {
			movq mm0, uvar1_64
			movd resultado, mm0	;Parte baja del resultado
			punpckhdq mm0, mm1	;Pone la parte alta de mm0 en la parte baja
			movd resultado2, mm0 ;Parte alta del resultado
			emms
		}

		contexto->flags.n = (uvar1_64 < 0)?1:0;
		contexto->flags.z = (uvar1_64 == 0)?1:0;

	}else if (a && u) {
		//Acumula y con signo
		
		__asm {

			mov eax, operando1
			mov ebx, operando2
			mov edx, 0
			imul ebx				;edx:eax = eax * ebx

			movd mm0, eax
			movd mm1, edx
			punpckldq mm0, mm1	;Monta los dos registros de 32 bits en uno de 64

			movd mm1, acumulador
			movd mm2, acumulador2
			punpckldq mm1, mm2	;Monta el registro acumulador

			movq var1_64, mm0
			movq var2_64, mm1
		}

		var1_64 += var2_64;
		
		__asm {
			movq mm0, var1_64
			movd resultado, mm0	;Parte baja del resultado
			punpckhdq mm0, mm1	;Pone la parte alta de mm0 en la parte baja
			movd resultado2, mm0 ;Parte alta del resultado
			emms
		}

		contexto->flags.n = (var1_64 < 0)?1:0;
		contexto->flags.z = (var1_64 == 0)?1:0;
		
	}else if(!a && !u){
		//No acumula y sin signo
		__asm {
			mov eax, operando1
			mov ebx, operando2
			mov edx, 0
			mul ebx				;edx:eax = eax * ebx
			pushf				;guarda los flags en la fila
			mov resultado, eax
			mov resultado2, edx
		}

		//Guarda los flags
		GETFLAGS
	}else if(!a && u){
		//No acumula y con signo
		__asm {
			mov eax, operando1
			mov ebx, operando2
			mov edx, 0
			imul ebx			;edx:eax = eax * ebx
			pushf				;guarda los flags en la fila
			mov resultado, eax
			mov resultado2, edx
		}

		//Guarda los flags
		GETFLAGS
	}
	
	contexto->flags.v = v;

	contexto->bancoRegistros[rn].u_word = resultado;
	contexto->bancoRegistros[rd].u_word = resultado2;

	nCiclos-=6;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina MSR (Move Status Register to Register)
/*-------------------------------------------------------------------------*/
RUT_msr:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_MSR

	//CPSR
	if (!r) {
		operando2 = (contexto->leerCPSR());
		//f
		if (mascara & 0x8) {
			operando2 = (operando1 & 0xFF000000) | (operando2 & 0x00FFFFFF);
		}
		if ((contexto->modo != USER_MODE) && (!esMISR)) {
			//s
			if (mascara & 0x4) { 
				operando2 = (operando1 & 0x00FF0000) | (operando2 & 0xFF00FFFF);
			}
			//x
			if (mascara & 0x2) { 
				operando2 = (operando1 & 0x0000FF00) | (operando2 & 0xFFFF00FF);
			}
			//c
			if (mascara & 0x1) { 
				operando2 = (operando1 & 0x000000FF) | (operando2 & 0xFFFFFF00);
				nCiclos-=2;
			}
		}

		contexto->escribirCPSR(operando2);

	//SPSR
	} else if ((contexto->modo != USER_MODE) && (contexto->modo != SYSTEM_MODE)) {
		operando2 = (contexto->SPSR[contexto->modo - 1].u_word);
		//f
		if (mascara & 0x8) {
			operando2 = (operando1 & 0xFF000000) | (operando2 & 0x00FFFFFF);
		}
		//s
		if (!esMISR) {
			if (mascara & 0x4) { 
				operando2 = (operando1 & 0x00FF0000) | (operando2 & 0xFF00FFFF);
			}
			//x
			if (mascara & 0x2) { 
				operando2 = (operando1 & 0x0000FF00) | (operando2 & 0xFFFF00FF);
			}
			//c
			if (mascara & 0x1) { 
				operando2 = (operando1 & 0x000000FF) | (operando2 & 0xFFFFFF00);
				nCiclos-=2;
			}
		}

		contexto->SPSR[contexto->modo - 1].u_word = operando2;

	}

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina MRS (Move Register to Status Register)
/*-------------------------------------------------------------------------*/
RUT_mrs:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	rd = instruccion.DPIS.Rd;
	r = instruccion.MISR.R;

	//CPSR
	if (!r) {
		contexto->bancoRegistros[rd].u_word = contexto->leerCPSR();
		
	//SPSR
	} else if ((contexto->modo != USER_MODE) && (contexto->modo != SYSTEM_MODE)) {
		contexto->bancoRegistros[rd].u_word = (contexto->SPSR[contexto->modo - 1].u_word);
		
	}

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina SWI (Software Interrupt)
/*-------------------------------------------------------------------------*/
RUT_swi:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	operando1 = instruccion.SWI.swiNumber;
	

	core->marcarExcepcion (EXCEP_SWI, operando1);

	nCiclos-=3;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina CODP (Coprocessor Data Processing)
/*-------------------------------------------------------------------------*/
RUT_codp:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	operando1 = instruccion.CODP.cp_num;
	coproDP fdp = core->getCoproDP(operando1);
	
	if (fdp != NULL) {
		nCiclos -= fdp(instruccion.u_word);
	} else {
		core->marcarExcepcion (EXCEP_UNDEFINED, operando1);
	}

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina COLS (Coprocessor Load Store)
/*-------------------------------------------------------------------------*/
RUT_cols:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	operando1 = instruccion.COLS.cp_num;
	coproLS fls = core->getCoproLS(operando1);
	
	if (fls != NULL) {
		nCiclos -= fls(instruccion.u_word);
	} else {
		core->marcarExcepcion (EXCEP_UNDEFINED, operando1);
	}

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina CORT (Coprocessor Register Transfer)
/*-------------------------------------------------------------------------*/
RUT_cort:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	operando1 = instruccion.CORT.cp_num;
	coproRT frt = core->getCoproRT(operando1);
	
	if (frt != NULL) {
		nCiclos -= frt(instruccion.u_word);
	} else {
		core->marcarExcepcion (EXCEP_UNDEFINED, operando1);
	}

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina INDEFINIDA
/*-------------------------------------------------------------------------*/
RUT_undefined:

	core->marcarExcepcion (EXCEP_UNDEFINED);

	nCiclos--;
	goto LecturaInstruccion;
}



⌨️ 快捷键说明

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