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

📄 arm9rutinasarm.cpp

📁 ARM9Core v0.4, 在x86 Win32 下模拟仿真ARM9 微处理器的Library.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	
	//ORR	
	__asm {
		or		eax, ebx		;or
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	GETFLAGS_SHIFTER

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

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina BIC (DP)
/*-------------------------------------------------------------------------*/
RUT_bic:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT_CARRY
	}
	
	//BIC	
	__asm {
		not		ebx				;NOT Op2
		and		eax, ebx		;Rn and NOT Op2
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	GETFLAGS_SHIFTER

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

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina TST (DP)
/*-------------------------------------------------------------------------*/
RUT_tst:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT_CARRY
	}
	
	//TST	
	__asm {
		and		eax, ebx		;and
		pushf					;guarda los flags en la pila
	}

	//Guarda los flags
	GETFLAGS_SHIFTER

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina TEQ (DP)
/*-------------------------------------------------------------------------*/
RUT_teq:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT_CARRY
	}
	
	//TEQ	
	__asm {
		xor		eax, ebx		;or exlusiva
		pushf					;guarda los flags en la pila
	}

	//Guarda los flags
	GETFLAGS_SHIFTER

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina CMP (DP)
/*-------------------------------------------------------------------------*/
RUT_cmp:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT
	}

	//CMP	
	__asm {
		mov		operando2, ebx	;preserva para el flag de carry
		neg		ebx		
		add		eax, ebx		;resta
		pushf					;guarda los flags en la pila
	}

	//Guarda los flags
	signo2 = signo2 ^ 0x80000000;
	GETFLAGS_SUB

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina CMN (DP)
/*-------------------------------------------------------------------------*/
RUT_cmn:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT
	}
	
	//CMN	
	__asm {
		add		eax, ebx		;suma
		pushf					;guarda los flags en la pila
	}

	//Guarda los flags
	GETFLAGS

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutinas Branch y Branch with link (BBL)
/*-------------------------------------------------------------------------*/
RUT_bbl:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	//Link
	l = instruccion.BBL.L;

	//Link: Guarda en el registro link la direccion de la instruccion siguiente
	if (l)
		contexto->bancoRegistros[14].u_word = contexto->PC->u_word;

	//El valor del PC al ejecutarse la instruccion de salto es la direccion
	//de la instruccion siguiente a la siguiente (por el pipeline segmentado)
	//Para emularlo sumamos 4 al calculo de direccion final del salto
	contexto->PC->u_word = contexto->PC->u_word + 4 + (instruccion.BBL.offset<<2);

	nCiclos-=3;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina Branch and Exchange (BX)
/*-------------------------------------------------------------------------*/
RUT_bx:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	rm = instruccion.BX.Rm;

	contexto->PC->u_word = contexto->bancoRegistros[rm].u_word;

	nCiclos-=3;
	goto LecturaInstruccion;




/*-------------------------------------------------------------------------*/
/*	Rutina LDR pre-index (Load single word and unsigned byte)
/*-------------------------------------------------------------------------*/
RUT_ldr_pre:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS_SHIFT

	//Calcular la dir. efectiva (y guardarla, si eso)
	PREINDEX
	
	if (b) {
		resultado = unsigned int (core->readMemoriaByte(dirEfectiva));
	} else {
		dirEfectiva2 = dirEfectiva & 0xFFFFFFFC;
		resultado = core->readMemoriaWord(dirEfectiva2);

		//Ajusta la palabra cargada
		rot = ((dirEfectiva2>>2) - (dirEfectiva>>2));
		__asm {
			mov	eax, resultado
			mov	ecx, rot
			ror	eax, cl
			mov	resultado, eax
		}
	} 

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


/*-------------------------------------------------------------------------*/
/*	Rutina STR pre-index (Store single word and unsigned byte)
/*-------------------------------------------------------------------------*/
RUT_str_pre:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS_SHIFT

	//Calcular la dir. efectiva (y guardarla, si eso)
	PREINDEX
	
	if (b) {
		core->writeMemoriaByte(contexto->bancoRegistros[rd].u_byte, dirEfectiva);
	} else {
		dirEfectiva2 = dirEfectiva & 0xFFFFFFFC;
		core->writeMemoriaWord(contexto->bancoRegistros[rd].u_word, dirEfectiva2);
	} 
	
	
	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina LDR post-index (Load single word and unsigned byte)
/*-------------------------------------------------------------------------*/
RUT_ldr_post:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS_SHIFT

	
	if (b) {
		resultado = unsigned int (core->readMemoriaByte(operando1));
	} else {
		dirEfectiva = operando1 & 0xFFFFFFFC;
		resultado = core->readMemoriaWord(dirEfectiva);

		//Ajusta la palabra cargada
		rot = ((dirEfectiva>>2) - (operando1>>2));
		__asm {
			mov	eax, resultado
			mov	ecx, rot
			ror	eax, cl
			mov	resultado, eax
		}
	} 

	
	//Calcular la dir. efectiva (y guardarla)
	POSTINDEX

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


/*-------------------------------------------------------------------------*/
/*	Rutina STR post-index (Store single word and unsigned byte)
/*-------------------------------------------------------------------------*/
RUT_str_post:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS_SHIFT

	
	if (b) {
		core->writeMemoriaByte(contexto->bancoRegistros[rd].u_byte, operando1);
	} else {
		dirEfectiva = operando1 & 0xFFFFFFFC;
		core->writeMemoriaWord(contexto->bancoRegistros[rd].u_word, dirEfectiva);
	} 

	//Calcular la dir. efectiva (y guardarla)
	POSTINDEX
	
	
	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina LDR HW/B pre-index (Load half-word / signed byte)
/*-------------------------------------------------------------------------*/
RUT_ldr_hw_pre:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS_EXTRAS

	//Calcular la dir. efectiva (y guardarla, si eso)
	PREINDEX
	
	switch (esSignedHalfword) {
	case 2:
		resultado = (int8)(core->readMemoriaByte(dirEfectiva));
		break;
	case 3:
		resultado = (int16)(core->readMemoriaHalfword(dirEfectiva));
		break;
	default:
		resultado = unsigned int (core->readMemoriaHalfword(dirEfectiva));
	}

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


/*-------------------------------------------------------------------------*/
/*	Rutina STR HW pre-index (Store half-word / signed byte)
/*-------------------------------------------------------------------------*/
RUT_str_hw_pre:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS_EXTRAS

	//Calcular la dir. efectiva (y guardarla, si eso)
	PREINDEX
	
	core->writeMemoriaHalfword(contexto->bancoRegistros[rd].u_halfword, dirEfectiva);
	
	
	nCiclos--;
	goto LecturaInstruccion;




/*-------------------------------------------------------------------------*/
/*	Rutina LDR HW/B post-index (Load half-word / signed byte)
/*-------------------------------------------------------------------------*/
RUT_ldr_hw_post:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS_EXTRAS
	
	switch (esSignedHalfword) {
	case 2:
		resultado = (int8)(core->readMemoriaByte(operando1));
		break;
	case 3:
		resultado = (int16)(core->readMemoriaHalfword(operando1));
		break;
	default:
		resultado = unsigned int (core->readMemoriaHalfword(operando1));
	}

	//Calcular la dir. efectiva (y guardarla)
	POSTINDEX

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


/*-------------------------------------------------------------------------*/
/*	Rutina STR HW post-index (Store half-word / signed byte)
/*-------------------------------------------------------------------------*/
RUT_str_hw_post:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_LS_EXTRAS

	core->writeMemoriaHalfword(contexto->bancoRegistros[rd].u_halfword, operando1);

	//Calcular la dir. efectiva (y guardarla)
	POSTINDEX
	
	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina LDM pre-index (Load multiple)
/*-------------------------------------------------------------------------*/
RUT_ldm_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;
			//Lectura de memoria
			resultado = core->readMemoriaWord(dirEfectiva);

			//Escribe el resultado en el registro correspondiente
			LSM_WRITEREGS
		}

	}

	//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 LDM post-index (Load multiple)
/*-------------------------------------------------------------------------*/
RUT_ldm_post:

⌨️ 快捷键说明

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