📄 arm9rutinasarm.cpp
字号:
//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 + -