📄 armemu.c
字号:
UNDEF_SWPPC; temp = LHS; BUSUSEDINCPCS;#ifndef MODE32 if (VECTORACCESS (temp) || ADDREXCEPT (temp)) { INTERNALABORT (temp); (void) ARMul_LoadWordN (state, temp); (void) ARMul_LoadWordN (state, temp); } else#endif dest = ARMul_SwapWord (state, temp, state-> Reg [RHSReg]); if (temp & 3) DEST = ARMul_Align (state, temp, dest); else DEST = dest; if (state->abortSig || state->Aborted) TAKEABORT; } else if ((BITS (0, 11) == 0) && (LHSReg == 15)) { /* MRS CPSR */ UNDEF_MRSPC; DEST = ECC | EINT | EMODE; } else { UNDEF_Test; } break; case 0x11: /* TSTP reg */#ifdef MODET if ((BITS (4, 11) & 0xF9) == 0x9) /* LDR register offset, no write-back, down, pre indexed. */ LHPREDOWN (); /* Continue with remaining instruction decode. */#endif if (DESTReg == 15) { /* TSTP reg */#ifdef MODE32 //chy 2006-02-15 if in user mode, can not set cpsr 0:23 //from p165 of ARMARM book state->Cpsr = GETSPSR (state->Bank); ARMul_CPSRAltered (state);#else rhs = DPRegRHS; temp = LHS & rhs; SETR15PSR (temp);#endif } else { /* TST reg */ rhs = DPSRegRHS; dest = LHS & rhs; ARMul_NegZero (state, dest); } break; case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6). */ if (state->is_v5) { if (BITS (4, 7) == 3) { /* BLX(2) */ ARMword temp; if (TFLAG) temp = (pc + 2) | 1; else temp = pc + 4; WriteR15Branch (state, state-> Reg[RHSReg]); state->Reg[14] = temp; break; } } if (state->is_v5e) { if (BIT (4) == 0 && BIT (7) == 1 && (BIT (5) == 0 || BITS (12, 15) == 0)) { /* ElSegundo SMLAWy/SMULWy insn. */ unsigned long long op1 = state-> Reg[BITS (0, 3)]; unsigned long long op2 = state-> Reg[BITS (8, 11)]; unsigned long long result; if (BIT (6)) op2 >>= 16; if (op1 & 0x80000000) op1 -= 1ULL << 32; op2 &= 0xFFFF; if (op2 & 0x8000) op2 -= 65536; result = (op1 * op2) >> 16; if (BIT (5) == 0) { ARMword Rn = state-> Reg[BITS (12, 15)]; if (AddOverflow (result, Rn, result + Rn)) SETS; result += Rn; } state->Reg[BITS (16, 19)] = result; break; } if (BITS (4, 11) == 5) { /* ElSegundo QSUB insn. */ ARMword op1 = state-> Reg[BITS (0, 3)]; ARMword op2 = state-> Reg[BITS (16, 19)]; ARMword result = op1 - op2; if (SubOverflow (op1, op2, result)) { result = POS (result) ? 0x80000000 : 0x7fffffff; SETS; } state->Reg[BITS (12, 15)] = result; break; } }#ifdef MODET if (BITS (4, 11) == 0xB) { /* STRH register offset, write-back, down, pre indexed. */ SHPREDOWNWB (); break; } if (BITS (4, 27) == 0x12FFF1) { /* BX */ WriteR15Branch (state, state->Reg[RHSReg]); 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 (state->is_v5) { if (BITS (4, 7) == 0x7) { ARMword value; extern int SWI_vector_installed; /* Hardware is allowed to optionally override this instruction and treat it as a breakpoint. Since this is a simulator not hardware, we take the position that if a SWI vector was not installed, then an Abort vector was probably not installed either, and so normally this instruction would be ignored, even if an Abort is generated. This is a bad thing, since GDB uses this instruction for its breakpoints (at least in Thumb mode it does). So intercept the instruction here and generate a breakpoint SWI instead. */ if (!SWI_vector_installed) ARMul_OSHandleSWI (state, SWI_Breakpoint); else { /* BKPT - normally this will cause an abort, but on the XScale we must check the DCSR. */ XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc); if (!XScale_debug_moe (state, ARMul_CP14_R10_MOE_BT)) break; } /* Force the next instruction to be refetched. */ state->NextInstr = RESUME; break; } } if (DESTReg == 15) { /* MSR reg to CPSR. */ UNDEF_MSRPC; temp = DPRegRHS;#ifdef MODET /* Don't allow TBIT to be set by MSR. */ temp &= ~TBIT;#endif ARMul_FixCPSR (state, instr, temp); } else UNDEF_Test; break; case 0x13: /* TEQP reg */#ifdef MODET if ((BITS (4, 11) & 0xF9) == 0x9) /* LDR register offset, write-back, down, pre indexed. */ LHPREDOWNWB (); /* Continue with remaining instruction decode. */#endif if (DESTReg == 15) { /* TEQP reg */#ifdef MODE32 state->Cpsr = GETSPSR (state->Bank); ARMul_CPSRAltered (state);#else rhs = DPRegRHS; temp = LHS ^ rhs; SETR15PSR (temp);#endif } else { /* TEQ Reg. */ rhs = DPSRegRHS; dest = LHS ^ rhs; ARMul_NegZero (state, dest); } break; case 0x14: /* CMP reg and MRS SPSR and SWP byte. */ if (state->is_v5e) { if (BIT (4) == 0 && BIT (7) == 1) { /* ElSegundo SMLALxy insn. */ unsigned long long op1 = state-> Reg[BITS (0, 3)]; unsigned long long op2 = state-> Reg[BITS (8, 11)]; unsigned long long dest; unsigned long long result; if (BIT (5)) op1 >>= 16; if (BIT (6)) op2 >>= 16; op1 &= 0xFFFF; if (op1 & 0x8000) op1 -= 65536; op2 &= 0xFFFF; if (op2 & 0x8000) op2 -= 65536; dest = (unsigned long long) state-> Reg[BITS (16, 19)] << 32; dest |= state-> Reg[BITS (12, 15)]; dest += op1 * op2; state->Reg[BITS (12, 15)] = dest; state->Reg[BITS (16, 19)] = dest >> 32; break; } if (BITS (4, 11) == 5) { /* ElSegundo QDADD 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 (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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -