📄 armemu.c
字号:
dest = state->Reg[MULLHSReg] * rhs; ARMul_NegZero (state, dest); state->Reg[MULDESTReg] = dest; } else UNDEF_MULPCDest; for (dest = 0, temp = 0; dest < 32; dest++) if (rhs & (1L << dest)) temp = dest; /* Mult takes this many/2 I cycles. */ ARMul_Icycles (state, ARMul_MultTable[temp], 0L); } else { /* ANDS reg. */ rhs = DPSRegRHS; dest = LHS & rhs; WRITESDEST (dest); } break; case 0x02: /* EOR reg and MLA */#ifdef MODET if (BITS (4, 11) == 0xB) { /* STRH register offset, write-back, down, post indexed. */ SHDOWNWB (); break; }#endif if (BITS (4, 7) == 9) { /* MLA */ rhs = state->Reg[MULRHSReg]; if (MULLHSReg == MULDESTReg) { UNDEF_MULDestEQOp1; state->Reg[MULDESTReg] = state->Reg[MULACCReg]; } else if (MULDESTReg != 15) state->Reg[MULDESTReg] = state-> Reg[MULLHSReg] * rhs + state->Reg[MULACCReg]; else UNDEF_MULPCDest; for (dest = 0, temp = 0; dest < 32; dest++) if (rhs & (1L << dest)) temp = dest; /* Mult takes this many/2 I cycles. */ ARMul_Icycles (state, ARMul_MultTable[temp], 0L); } else { rhs = DPRegRHS; dest = LHS ^ rhs; WRITEDEST (dest); } break; case 0x03: /* EORS reg and MLAS */#ifdef MODET if ((BITS (4, 11) & 0xF9) == 0x9) /* LDR register offset, write-back, down, post-indexed. */ LHPOSTDOWN (); /* Fall through to rest of the decoding. */#endif if (BITS (4, 7) == 9) { /* MLAS */ rhs = state->Reg[MULRHSReg]; if (MULLHSReg == MULDESTReg) { UNDEF_MULDestEQOp1; dest = state->Reg[MULACCReg]; ARMul_NegZero (state, dest); state->Reg[MULDESTReg] = dest; } else if (MULDESTReg != 15) { dest = state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg]; ARMul_NegZero (state, dest); state->Reg[MULDESTReg] = dest; } else UNDEF_MULPCDest; for (dest = 0, temp = 0; dest < 32; dest++) if (rhs & (1L << dest)) temp = dest; /* Mult takes this many/2 I cycles. */ ARMul_Icycles (state, ARMul_MultTable[temp], 0L); } else { /* EORS Reg. */ rhs = DPSRegRHS; dest = LHS ^ rhs; WRITESDEST (dest); } break; case 0x04: /* SUB reg */#ifdef MODET if (BITS (4, 7) == 0xB) { /* STRH immediate offset, no write-back, down, post indexed. */ SHDOWNWB (); 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 0x05: /* SUBS reg */#ifdef MODET if ((BITS (4, 7) & 0x9) == 0x9) /* LDR immediate offset, no write-back, down, post indexed. */ LHPOSTDOWN (); /* Fall through to the rest of the instruction decoding. */#endif lhs = LHS; rhs = DPRegRHS; 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 0x06: /* RSB reg */#ifdef MODET if (BITS (4, 7) == 0xB) { /* STRH immediate offset, write-back, down, post indexed. */ SHDOWNWB (); break; }#endif rhs = DPRegRHS; dest = rhs - LHS; WRITEDEST (dest); break; case 0x07: /* RSBS reg */#ifdef MODET if ((BITS (4, 7) & 0x9) == 0x9) /* LDR immediate offset, write-back, down, post indexed. */ LHPOSTDOWN (); /* Fall through to remainder of instruction decoding. */#endif lhs = LHS; rhs = DPRegRHS; 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 0x08: /* ADD reg */#ifdef MODET if (BITS (4, 11) == 0xB) { /* STRH register offset, no write-back, up, post indexed. */ SHUPWB (); break; } if (BITS (4, 7) == 0xD) { Handle_Load_Double (state, instr); break; } if (BITS (4, 7) == 0xF) { Handle_Store_Double (state, instr); break; }#endif#ifdef MODET if (BITS (4, 7) == 0x9) { /* MULL */ /* 32x32 = 64 */ ARMul_Icycles (state, Multiply64 (state, instr, LUNSIGNED, LDEFAULT), 0L); break; }#endif rhs = DPRegRHS; dest = LHS + rhs; WRITEDEST (dest); break; case 0x09: /* ADDS reg */#ifdef MODET if ((BITS (4, 11) & 0xF9) == 0x9) /* LDR register offset, no write-back, up, post indexed. */ LHPOSTUP (); /* Fall through to remaining instruction decoding. */#endif#ifdef MODET if (BITS (4, 7) == 0x9) { /* MULL */ /* 32x32=64 */ ARMul_Icycles (state, Multiply64 (state, instr, LUNSIGNED, LSCC), 0L); break; }#endif 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; } WRITESDEST (dest); break; case 0x0a: /* ADC reg */#ifdef MODET if (BITS (4, 11) == 0xB) { /* STRH register offset, write-back, up, post-indexed. */ SHUPWB (); break; } if (BITS (4, 7) == 0x9) { /* MULL */ /* 32x32=64 */ ARMul_Icycles (state, MultiplyAdd64 (state, instr, LUNSIGNED, LDEFAULT), 0L); break; }#endif rhs = DPRegRHS; dest = LHS + rhs + CFLAG; WRITEDEST (dest); break; case 0x0b: /* ADCS reg */#ifdef MODET if ((BITS (4, 11) & 0xF9) == 0x9) /* LDR register offset, write-back, up, post indexed. */ LHPOSTUP (); /* Fall through to remaining instruction decoding. */ if (BITS (4, 7) == 0x9) { /* MULL */ /* 32x32=64 */ ARMul_Icycles (state, MultiplyAdd64 (state, instr, LUNSIGNED, LSCC), 0L); break; }#endif lhs = LHS; rhs = DPRegRHS; 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 0x0c: /* SBC reg */#ifdef MODET if (BITS (4, 7) == 0xB) { /* STRH immediate offset, no write-back, up post indexed. */ SHUPWB (); break; } if (BITS (4, 7) == 0xD) { Handle_Load_Double (state, instr); break; } if (BITS (4, 7) == 0xF) { Handle_Store_Double (state, instr); break; } if (BITS (4, 7) == 0x9) { /* MULL */ /* 32x32=64 */ ARMul_Icycles (state, Multiply64 (state, instr, LSIGNED, LDEFAULT), 0L); break; }#endif rhs = DPRegRHS; dest = LHS - rhs - !CFLAG; WRITEDEST (dest); break; case 0x0d: /* SBCS reg */#ifdef MODET if ((BITS (4, 7) & 0x9) == 0x9) /* LDR immediate offset, no write-back, up, post indexed. */ LHPOSTUP (); if (BITS (4, 7) == 0x9) { /* MULL */ /* 32x32=64 */ ARMul_Icycles (state, Multiply64 (state, instr, LSIGNED, LSCC), 0L); break; }#endif lhs = LHS; rhs = DPRegRHS; 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 0x0e: /* RSC reg */#ifdef MODET if (BITS (4, 7) == 0xB) { /* STRH immediate offset, write-back, up, post indexed. */ SHUPWB (); break; } if (BITS (4, 7) == 0x9) { /* MULL */ /* 32x32=64 */ ARMul_Icycles (state, MultiplyAdd64 (state, instr, LSIGNED, LDEFAULT), 0L); break; }#endif rhs = DPRegRHS; dest = rhs - LHS - !CFLAG; WRITEDEST (dest); break; case 0x0f: /* RSCS reg */#ifdef MODET if ((BITS (4, 7) & 0x9) == 0x9) /* LDR immediate offset, write-back, up, post indexed. */ LHPOSTUP (); /* Fall through to remaining instruction decoding. */ if (BITS (4, 7) == 0x9) { /* MULL */ /* 32x32=64 */ ARMul_Icycles (state, MultiplyAdd64 (state, instr, LSIGNED, LSCC), 0L); break; }#endif lhs = LHS; rhs = DPRegRHS; 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 0x10: /* TST reg and MRS CPSR and SWP word. */ if (state->is_v5e) { if (BIT (4) == 0 && BIT (7) == 1) { /* ElSegundo SMLAxy 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; op1 *= op2; if (AddOverflow (op1, Rn, op1 + Rn)) SETS; state->Reg[BITS (16, 19)] = op1 + Rn; break; } if (BITS (4, 11) == 5) { /* ElSegundo QADD insn. */ ARMword op1 = state-> Reg[BITS (0, 3)]; ARMword op2 = state-> Reg[BITS (16, 19)]; ARMword result = op1 + op2; if (AddOverflow (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, 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -