📄 armemu.c
字号:
if (AddOverflow (op1, op2d, result)) { SETS; result = POS (result) ? 0x80000000 : 0x7fffffff; } state->Reg[BITS (12, 15)] = result; break; } }#ifdef MODET if (BITS (4, 7) == 0xB) { /* STRH immediate offset, no write-back, down, pre indexed. */ SHPREDOWN (); break; } if (BITS (4, 7) == 0xD) { Handle_Load_Double (state, instr); break; } if (BITS (4, 7) == 0xF) { Handle_Store_Double (state, instr); break; }#endif if (BITS (4, 11) == 9) { /* SWP */ UNDEF_SWPPC; temp = LHS; BUSUSEDINCPCS;#ifndef MODE32 if (VECTORACCESS (temp) || ADDREXCEPT (temp)) { INTERNALABORT (temp); (void) ARMul_LoadByte (state, temp); (void) ARMul_LoadByte (state, temp); } else#endif DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]); if (state->abortSig || state->Aborted) TAKEABORT; } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS SPSR */ UNDEF_MRSPC; DEST = GETSPSR (state->Bank); } else UNDEF_Test; break; case 0x15: /* CMPP reg. */#ifdef MODET if ((BITS (4, 7) & 0x9) == 0x9) /* LDR immediate offset, no write-back, down, pre indexed. */ LHPREDOWN (); /* Continue with remaining instruction decode. */#endif if (DESTReg == 15) { /* CMPP reg. */#ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); ARMul_CPSRAltered (state);#else rhs = DPRegRHS; temp = LHS - rhs; SETR15PSR (temp);#endif } else { /* CMP reg. */ lhs = LHS; rhs = DPRegRHS; 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 0x16: /* CMN reg and MSR reg to SPSR */ if (state->is_v5e) { if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0) { /* ElSegundo SMULxy insn. */ ARMword op1 = state->Reg[BITS (0, 3)]; ARMword op2 = state->Reg[BITS (8, 11)]; ARMword Rn = state->Reg[BITS (12, 15)]; if (BIT (5)) op1 >>= 16; if (BIT (6)) op2 >>= 16; op1 &= 0xFFFF; op2 &= 0xFFFF; if (op1 & 0x8000) op1 -= 65536; if (op2 & 0x8000) op2 -= 65536; state->Reg[BITS (16, 19)] = op1 * op2; break; } if (BITS (4, 11) == 5) { /* ElSegundo QDSUB insn. */ ARMword op1 = state->Reg[BITS (0, 3)]; ARMword op2 = state->Reg[BITS (16, 19)]; ARMword op2d = op2 + op2; ARMword result; if (AddOverflow (op2, op2, op2d)) { SETS; op2d = POS (op2d) ? 0x80000000 : 0x7fffffff; } result = op1 - op2d; if (SubOverflow (op1, op2d, result)) { SETS; result = POS (result) ? 0x80000000 : 0x7fffffff; } state->Reg[BITS (12, 15)] = result; break; } } if (state->is_v5) { if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF) { /* ARM5 CLZ insn. */ ARMword op1 = state->Reg[BITS (0, 3)]; int result = 32; if (op1) for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1) result++; state->Reg[BITS (12, 15)] = result; break; } }#ifdef MODET if (BITS (4, 7) == 0xB) { /* STRH immediate offset, write-back, down, pre indexed. */ SHPREDOWNWB (); break; } if (BITS (4, 7) == 0xD) { Handle_Load_Double (state, instr); break; } if (BITS (4, 7) == 0xF) { Handle_Store_Double (state, instr); break; }#endif if (DESTReg == 15) { /* MSR */ UNDEF_MSRPC; ARMul_FixSPSR (state, instr, DPRegRHS); } else { UNDEF_Test; } break; case 0x17: /* CMNP reg */#ifdef MODET if ((BITS (4, 7) & 0x9) == 0x9) /* LDR immediate offset, write-back, down, pre indexed. */ LHPREDOWNWB (); /* Continue with remaining instruction decoding. */#endif if (DESTReg == 15) {#ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); ARMul_CPSRAltered (state);#else rhs = DPRegRHS; temp = LHS + rhs; SETR15PSR (temp);#endif break; } else { /* CMN reg. */ lhs = LHS; rhs = DPRegRHS; 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 0x18: /* ORR reg */#ifdef MODET if (BITS (4, 11) == 0xB) { /* STRH register offset, no write-back, up, pre indexed. */ SHPREUP (); break; } if (BITS (4, 7) == 0xD) { Handle_Load_Double (state, instr); break; } if (BITS (4, 7) == 0xF) { Handle_Store_Double (state, instr); break; }#endif rhs = DPRegRHS; dest = LHS | rhs; WRITEDEST (dest); break; case 0x19: /* ORRS reg */#ifdef MODET if ((BITS (4, 11) & 0xF9) == 0x9) /* LDR register offset, no write-back, up, pre indexed. */ LHPREUP (); /* 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -