📄 armemu.c
字号:
/* Continue with remaining instruction decoding. */
#endif
rhs = DPSRegRHS;
dest = LHS | rhs;
WRITESDEST (dest);
break;
case 0x1a: /* MOV reg */
#ifdef MODET
if (BITS (4, 11) == 0xB)
{
/* STRH register offset, write-back, up, pre indexed. */
SHPREUPWB ();
break;
}
if (BITS (4, 7) == 0xD)
{
Handle_Load_Double (state, instr);
break;
}
if (BITS (4, 7) == 0xF)
{
Handle_Store_Double (state, instr);
break;
}
#endif
dest = DPRegRHS;
WRITEDEST (dest);
break;
case 0x1b: /* MOVS reg */
#ifdef MODET
if ((BITS (4, 11) & 0xF9) == 0x9)
/* LDR register offset, write-back, up, pre indexed. */
LHPREUPWB ();
/* Continue with remaining instruction decoding. */
#endif
dest = DPSRegRHS;
WRITESDEST (dest);
break;
case 0x1c: /* BIC reg */
#ifdef MODET
if (BITS (4, 7) == 0xB)
{
/* STRH immediate offset, no write-back, up, pre indexed. */
SHPREUP ();
break;
}
if (BITS (4, 7) == 0xD)
{
Handle_Load_Double (state, instr);
break;
}
else if (BITS (4, 7) == 0xF)
{
Handle_Store_Double (state, instr);
break;
}
#endif
rhs = DPRegRHS;
dest = LHS & ~rhs;
WRITEDEST (dest);
break;
case 0x1d: /* BICS reg */
#ifdef MODET
if ((BITS (4, 7) & 0x9) == 0x9)
/* LDR immediate offset, no write-back, up, pre indexed. */
LHPREUP ();
/* Continue with instruction decoding. */
#endif
rhs = DPSRegRHS;
dest = LHS & ~rhs;
WRITESDEST (dest);
break;
case 0x1e: /* MVN reg */
#ifdef MODET
if (BITS (4, 7) == 0xB)
{
/* STRH immediate offset, write-back, up, pre indexed. */
SHPREUPWB ();
break;
}
if (BITS (4, 7) == 0xD)
{
Handle_Load_Double (state, instr);
break;
}
if (BITS (4, 7) == 0xF)
{
Handle_Store_Double (state, instr);
break;
}
#endif
dest = ~DPRegRHS;
WRITEDEST (dest);
break;
case 0x1f: /* MVNS reg */
#ifdef MODET
if ((BITS (4, 7) & 0x9) == 0x9)
/* LDR immediate offset, write-back, up, pre indexed. */
LHPREUPWB ();
/* Continue instruction decoding. */
#endif
dest = ~DPSRegRHS;
WRITESDEST (dest);
break;
/* Data Processing Immediate RHS Instructions. */
case 0x20: /* AND immed */
dest = LHS & DPImmRHS;
WRITEDEST (dest);
break;
case 0x21: /* ANDS immed */
DPSImmRHS;
dest = LHS & rhs;
WRITESDEST (dest);
break;
case 0x22: /* EOR immed */
dest = LHS ^ DPImmRHS;
WRITEDEST (dest);
break;
case 0x23: /* EORS immed */
DPSImmRHS;
dest = LHS ^ rhs;
WRITESDEST (dest);
break;
case 0x24: /* SUB immed */
dest = LHS - DPImmRHS;
WRITEDEST (dest);
break;
case 0x25: /* SUBS immed */
lhs = LHS;
rhs = DPImmRHS;
dest = lhs - rhs;
if ((lhs >= rhs) || ((rhs | lhs) >> 31))
{
ARMul_SubCarry (state, lhs, rhs, dest);
ARMul_SubOverflow (state, lhs, rhs, dest);
}
else
{
CLEARC;
CLEARV;
}
WRITESDEST (dest);
break;
case 0x26: /* RSB immed */
dest = DPImmRHS - LHS;
WRITEDEST (dest);
break;
case 0x27: /* RSBS immed */
lhs = LHS;
rhs = DPImmRHS;
dest = rhs - lhs;
if ((rhs >= lhs) || ((rhs | lhs) >> 31))
{
ARMul_SubCarry (state, rhs, lhs, dest);
ARMul_SubOverflow (state, rhs, lhs, dest);
}
else
{
CLEARC;
CLEARV;
}
WRITESDEST (dest);
break;
case 0x28: /* ADD immed */
dest = LHS + DPImmRHS;
WRITEDEST (dest);
break;
case 0x29: /* ADDS immed */
lhs = LHS;
rhs = DPImmRHS;
dest = lhs + rhs;
ASSIGNZ (dest == 0);
if ((lhs | rhs) >> 30)
{
/* Possible C,V,N to set. */
ASSIGNN (NEG (dest));
ARMul_AddCarry (state, lhs, rhs, dest);
ARMul_AddOverflow (state, lhs, rhs, dest);
}
else
{
CLEARN;
CLEARC;
CLEARV;
}
WRITESDEST (dest);
break;
case 0x2a: /* ADC immed */
dest = LHS + DPImmRHS + CFLAG;
WRITEDEST (dest);
break;
case 0x2b: /* ADCS immed */
lhs = LHS;
rhs = DPImmRHS;
dest = lhs + rhs + CFLAG;
ASSIGNZ (dest == 0);
if ((lhs | rhs) >> 30)
{
/* Possible C,V,N to set. */
ASSIGNN (NEG (dest));
ARMul_AddCarry (state, lhs, rhs, dest);
ARMul_AddOverflow (state, lhs, rhs, dest);
}
else
{
CLEARN;
CLEARC;
CLEARV;
}
WRITESDEST (dest);
break;
case 0x2c: /* SBC immed */
dest = LHS - DPImmRHS - !CFLAG;
WRITEDEST (dest);
break;
case 0x2d: /* SBCS immed */
lhs = LHS;
rhs = DPImmRHS;
dest = lhs - rhs - !CFLAG;
if ((lhs >= rhs) || ((rhs | lhs) >> 31))
{
ARMul_SubCarry (state, lhs, rhs, dest);
ARMul_SubOverflow (state, lhs, rhs, dest);
}
else
{
CLEARC;
CLEARV;
}
WRITESDEST (dest);
break;
case 0x2e: /* RSC immed */
dest = DPImmRHS - LHS - !CFLAG;
WRITEDEST (dest);
break;
case 0x2f: /* RSCS immed */
lhs = LHS;
rhs = DPImmRHS;
dest = rhs - lhs - !CFLAG;
if ((rhs >= lhs) || ((rhs | lhs) >> 31))
{
ARMul_SubCarry (state, rhs, lhs, dest);
ARMul_SubOverflow (state, rhs, lhs, dest);
}
else
{
CLEARC;
CLEARV;
}
WRITESDEST (dest);
break;
case 0x30: /* TST immed */
UNDEF_Test;
break;
case 0x31: /* TSTP immed */
if (DESTReg == 15)
{
/* TSTP immed. */
#ifdef MODE32
state->Cpsr = GETSPSR (state->Bank);
ARMul_CPSRAltered (state);
#else
temp = LHS & DPImmRHS;
SETR15PSR (temp);
#endif
}
else
{
/* TST immed. */
DPSImmRHS;
dest = LHS & rhs;
ARMul_NegZero (state, dest);
}
break;
case 0x32: /* TEQ immed and MSR immed to CPSR */
if (DESTReg == 15)
/* MSR immed to CPSR. */
ARMul_FixCPSR (state, instr, DPImmRHS);
else
UNDEF_Test;
break;
case 0x33: /* TEQP immed */
if (DESTReg == 15)
{
/* TEQP immed. */
#ifdef MODE32
state->Cpsr = GETSPSR (state->Bank);
ARMul_CPSRAltered (state);
#else
temp = LHS ^ DPImmRHS;
SETR15PSR (temp);
#endif
}
else
{
DPSImmRHS; /* TEQ immed */
dest = LHS ^ rhs;
ARMul_NegZero (state, dest);
}
break;
case 0x34: /* CMP immed */
UNDEF_Test;
break;
case 0x35: /* CMPP immed */
if (DESTReg == 15)
{
/* CMPP immed. */
#ifdef MODE32
state->Cpsr = GETSPSR (state->Bank);
ARMul_CPSRAltered (state);
#else
temp = LHS - DPImmRHS;
SETR15PSR (temp);
#endif
break;
}
else
{
/* CMP immed. */
lhs = LHS;
rhs = DPImmRHS;
dest = lhs - rhs;
ARMul_NegZero (state, dest);
if ((lhs >= rhs) || ((rhs | lhs) >> 31))
{
ARMul_SubCarry (state, lhs, rhs, dest);
ARMul_SubOverflow (state, lhs, rhs, dest);
}
else
{
CLEARC;
CLEARV;
}
}
break;
case 0x36: /* CMN immed and MSR immed to SPSR */
if (DESTReg == 15)
ARMul_FixSPSR (state, instr, DPImmRHS);
else
UNDEF_Test;
break;
case 0x37: /* CMNP immed. */
if (DESTReg == 15)
{
/* CMNP immed. */
#ifdef MODE32
state->Cpsr = GETSPSR (state->Bank);
ARMul_CPSRAltered (state);
#else
temp = LHS + DPImmRHS;
SETR15PSR (temp);
#endif
break;
}
else
{
/* CMN immed. */
lhs = LHS;
rhs = DPImmRHS;
dest = lhs + rhs;
ASSIGNZ (dest == 0);
if ((lhs | rhs) >> 30)
{
/* Possible C,V,N to set. */
ASSIGNN (NEG (dest));
ARMul_AddCarry (state, lhs, rhs, dest);
ARMul_AddOverflow (state, lhs, rhs, dest);
}
else
{
CLEARN;
CLEARC;
CLEARV;
}
}
break;
case 0x38: /* ORR immed. */
dest = LHS | DPImmRHS;
WRITEDEST (dest);
break;
case 0x39: /* ORRS immed. */
DPSImmRHS;
dest = LHS | rhs;
WRITESDEST (dest);
break;
case 0x3a: /* MOV immed. */
dest = DPImmRHS;
WRITEDEST (dest);
break;
case 0x3b: /* MOVS immed. */
DPSImmRHS;
WRITESDEST (rhs);
break;
case 0x3c: /* BIC immed. */
dest = LHS & ~DPImmRHS;
WRITEDEST (dest);
break;
case 0x3d: /* BICS immed. */
DPSImmRHS;
dest = LHS & ~rhs;
WRITESDEST (dest);
break;
case 0x3e: /* MVN immed. */
dest = ~DPImmRHS;
WRITEDEST (dest);
break;
case 0x3f: /* MVNS immed. */
DPSImmRHS;
WRITESDEST (~rhs);
break;
/* Single Data Transfer Immediate RHS Instructions. */
case 0x40: /* Store Word, No WriteBack, Post Dec, Immed. */
lhs = LHS;
if (StoreWord (state, instr, lhs))
LSBase = lhs - LSImmRHS;
break;
case 0x41: /* Load Word, No WriteBack, Post Dec, Immed. */
lhs = LHS;
if (LoadWord (state, instr, lhs))
LSBase = lhs - LSImmRHS;
break;
case 0x42: /* Store Word, WriteBack, Post Dec, Immed. */
UNDEF_LSRBaseEQDestWb;
UNDEF_LSRPCBaseWb;
lhs = LHS;
temp = lhs - LSImmRHS;
state->NtransSig = LOW;
if (StoreWord (state, instr, lhs))
LSBase = temp;
state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
break;
case 0x43: /* Load Word, WriteBack, Post Dec, Immed. */
UNDEF_LSRBaseEQDestWb;
UNDEF_LSRPCBaseWb;
lhs = LHS;
state->NtransSig = LOW;
if (LoadWord (state, instr, lhs))
LSBase = lhs - LSImmRHS;
state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
break;
case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed. */
lhs = LHS;
if (StoreByte (state, instr, lhs))
LSBase = lhs - LSImmRHS;
break;
case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed. */
lhs = LHS;
if (LoadByte (state, instr, lhs, LUNSIGNED))
LSBase = lhs - LSImmRHS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -