📄 armemu.c
字号:
temp = VFLAG; break; case VC: temp = !VFLAG; break; case MI: temp = NFLAG; break; case PL: temp = !NFLAG; break; case CS: temp = CFLAG; break; case CC: temp = !CFLAG; break; case HI: temp = (CFLAG && !ZFLAG); break; case LS: temp = (!CFLAG || ZFLAG); break; case GE: temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); break; case LT: temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); break; case GT: temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)); break; case LE: temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; break; } /* cc check */ /* Handle the Clock counter here. */ if (state->is_XScale) { ARMword cp14r0; int ok; ok = state->CPRead[14] (state, 0, & cp14r0); if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE)) { unsigned long newcycles, nowtime = ARMul_Time (state); newcycles = nowtime - state->LastTime; state->LastTime = nowtime; if (cp14r0 & ARMul_CP14_R0_CCD) { if (state->CP14R0_CCD == -1) state->CP14R0_CCD = newcycles; else state->CP14R0_CCD += newcycles; if (state->CP14R0_CCD >= 64) { newcycles = 0; while (state->CP14R0_CCD >= 64) state->CP14R0_CCD -= 64, newcycles++; goto check_PMUintr; } } else { ARMword cp14r1; int do_int = 0; state->CP14R0_CCD = -1;check_PMUintr: cp14r0 |= ARMul_CP14_R0_FLAG2; (void) state->CPWrite[14] (state, 0, cp14r0); ok = state->CPRead[14] (state, 1, & cp14r1); /* Coded like this for portability. */ while (ok && newcycles) { if (cp14r1 == 0xffffffff) { cp14r1 = 0; do_int = 1; } else cp14r1 ++; newcycles --; } (void) state->CPWrite[14] (state, 1, cp14r1); if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2)) { ARMword temp; if (state->CPRead[13] (state, 8, & temp) && (temp & ARMul_CP13_R8_PMUS)) ARMul_Abort (state, ARMul_FIQV); else ARMul_Abort (state, ARMul_IRQV); } } } } /* Handle hardware instructions breakpoints here. */ if (state->is_XScale) { if ( (pc | 3) == (read_cp15_reg (14, 0, 8) | 2) || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2)) { if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB)) ARMul_OSHandleSWI (state, SWI_Breakpoint); } } /* Actual execution of instructions begins here. */ /* If the condition codes don't match, stop here. */ if (temp) { mainswitch: if (state->is_XScale) { if (BIT (20) == 0 && BITS (25, 27) == 0) { if (BITS (4, 7) == 0xD) { /* XScale Load Consecutive insn. */ ARMword temp = GetLS7RHS (state, instr); ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp; ARMword addr = BIT (24) ? temp2 : LHS; if (BIT (12)) ARMul_UndefInstr (state, instr); else if (addr & 7) /* Alignment violation. */ ARMul_Abort (state, ARMul_DataAbortV); else { int wb = BIT (21) || (! BIT (24)); state->Reg[BITS (12, 15)] = ARMul_LoadWordN (state, addr); state->Reg[BITS (12, 15) + 1] = ARMul_LoadWordN (state, addr + 4); if (wb) LSBase = temp2; } goto donext; } else if (BITS (4, 7) == 0xF) { /* XScale Store Consecutive insn. */ ARMword temp = GetLS7RHS (state, instr); ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp; ARMword addr = BIT (24) ? temp2 : LHS; if (BIT (12)) ARMul_UndefInstr (state, instr); else if (addr & 7) /* Alignment violation. */ ARMul_Abort (state, ARMul_DataAbortV); else { ARMul_StoreWordN (state, addr, state->Reg[BITS (12, 15)]); ARMul_StoreWordN (state, addr + 4, state->Reg[BITS (12, 15) + 1]); if (BIT (21)|| ! BIT (24)) LSBase = temp2; } goto donext; } } if (ARMul_HandleIwmmxt (state, instr)) goto donext; } switch ((int) BITS (20, 27)) { /* Data Processing Register RHS Instructions. */ case 0x00: /* AND reg and MUL */#ifdef MODET if (BITS (4, 11) == 0xB) { /* STRH register 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 if (BITS (4, 7) == 9) { /* MUL */ rhs = state->Reg[MULRHSReg]; if (MULLHSReg == MULDESTReg) { UNDEF_MULDestEQOp1; state->Reg[MULDESTReg] = 0; } else if (MULDESTReg != 15) state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs; 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 { /* AND reg. */ rhs = DPRegRHS; dest = LHS & rhs; WRITEDEST (dest); } break; case 0x01: /* ANDS reg and MULS */#ifdef MODET if ((BITS (4, 11) & 0xF9) == 0x9) /* LDR register offset, no write-back, down, post indexed. */ LHPOSTDOWN (); /* Fall through to rest of decoding. */#endif if (BITS (4, 7) == 9) { /* MULS */ rhs = state->Reg[MULRHSReg]; if (MULLHSReg == MULDESTReg) { UNDEF_MULDestEQOp1; state->Reg[MULDESTReg] = 0; CLEARN; SETZ; } else if (MULDESTReg != 15) { 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -