// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Operand* Peephole::SimplifyBinary(Opcode opcode, Operand* opA, Operand* opB, Block* block, FloatMode mode, bool constMoveAllowed) { // This is used by code that does expression reassociation. switch(opcode) { case Instr_Add: return HandleAdd(opA, opB, block, constMoveAllowed); case Instr_Sub: return HandleSub(opA, opB, block); case Instr_Mul: return HandleMul(opA, opB, block, constMoveAllowed); case Instr_Div: return HandleDiv(opA, opB, block, false); case Instr_Udiv: return HandleUdiv(opA, opB, block); case Instr_Fadd: return HandleFadd(opA, opB, mode); case Instr_Fsub: return HandleFsub(opA, opB, mode); case Instr_Fmul: return HandleFmul(opA, opB, mode); case Instr_Fdiv: return HandleFdiv(opA, opB, mode); case Instr_And: return HandleAnd(opA, opB, block, constMoveAllowed); case Instr_Or: return HandleOr(opA, opB, block, constMoveAllowed); case Instr_Xor: return HandleXor(opA, opB, block, constMoveAllowed); } return nullptr; }
int arm_execute( int cycles ) { data32_t pc; data32_t insn; arm_ICount = cycles; do { #ifdef MAME_DEBUG if (mame_debug) MAME_Debug(); #endif /* load instruction */ pc = R15; insn = READ32( pc & ADDRESS_MASK ); switch (insn >> INSN_COND_SHIFT) { case COND_EQ: if (Z_IS_CLEAR(pc)) goto L_Next; break; case COND_NE: if (Z_IS_SET(pc)) goto L_Next; break; case COND_CS: if (C_IS_CLEAR(pc)) goto L_Next; break; case COND_CC: if (C_IS_SET(pc)) goto L_Next; break; case COND_MI: if (N_IS_CLEAR(pc)) goto L_Next; break; case COND_PL: if (N_IS_SET(pc)) goto L_Next; break; case COND_VS: if (V_IS_CLEAR(pc)) goto L_Next; break; case COND_VC: if (V_IS_SET(pc)) goto L_Next; break; case COND_HI: if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next; break; case COND_LS: if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next; break; case COND_GE: if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */ break; case COND_LT: if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next; break; case COND_GT: if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next; break; case COND_LE: if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next; break; case COND_NV: goto L_Next; } /* Condition satisfied, so decode the instruction */ if ((insn & 0x0fc000f0u) == 0x00000090u) /* Multiplication */ { HandleMul(insn); R15 += 4; } else if (!(insn & 0x0c000000u)) /* Data processing */ { HandleALU(insn); } else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */ { HandleMemSingle(insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */ { HandleMemBlock(insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x0a000000u) /* Branch */ { HandleBranch(insn); } else if ((insn & 0x0f000000u) == 0x0f000000u) /* Software interrupt */ { pc=R15+4; R15 = eARM_MODE_SVC; /* Set SVC mode so PC is saved to correct R14 bank */ SetRegister( 14, pc ); /* save PC */ R15 = (pc&PSR_MASK)|0x8|eARM_MODE_SVC|(pc&MODE_MASK); } else /* Undefined */ { logerror("%08x: Undefined instruction\n",R15); L_Next: arm_ICount -= S_CYCLE; R15 += 4; } arm_ICount -= 3; } while( arm_ICount > 0 ); return cycles - arm_ICount; } /* arm_execute */
void arm_cpu_device::execute_run() { UINT32 pc; UINT32 insn; do { debugger_instruction_hook(this, R15 & ADDRESS_MASK); /* load instruction */ pc = R15; insn = m_direct->read_decrypted_dword( pc & ADDRESS_MASK ); switch (insn >> INSN_COND_SHIFT) { case COND_EQ: if (Z_IS_CLEAR(pc)) goto L_Next; break; case COND_NE: if (Z_IS_SET(pc)) goto L_Next; break; case COND_CS: if (C_IS_CLEAR(pc)) goto L_Next; break; case COND_CC: if (C_IS_SET(pc)) goto L_Next; break; case COND_MI: if (N_IS_CLEAR(pc)) goto L_Next; break; case COND_PL: if (N_IS_SET(pc)) goto L_Next; break; case COND_VS: if (V_IS_CLEAR(pc)) goto L_Next; break; case COND_VC: if (V_IS_SET(pc)) goto L_Next; break; case COND_HI: if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next; break; case COND_LS: if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next; break; case COND_GE: if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */ break; case COND_LT: if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next; break; case COND_GT: if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next; break; case COND_LE: if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next; break; case COND_NV: goto L_Next; } /* Condition satisfied, so decode the instruction */ if ((insn & 0x0fc000f0u) == 0x00000090u) /* Multiplication */ { HandleMul(insn); R15 += 4; } else if (!(insn & 0x0c000000u)) /* Data processing */ { HandleALU(insn); } else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */ { HandleMemSingle(insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */ { HandleMemBlock(insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x0a000000u) /* Branch */ { HandleBranch(insn); } else if ((insn & 0x0f000000u) == 0x0e000000u) /* Coprocessor */ { if (m_copro_type == ARM_COPRO_TYPE_VL86C020) HandleCoProVL86C020(insn); else HandleCoPro(insn); R15 += 4; } else if ((insn & 0x0f000000u) == 0x0f000000u) /* Software interrupt */ { pc=R15+4; R15 = eARM_MODE_SVC; /* Set SVC mode so PC is saved to correct R14 bank */ SetRegister( 14, pc ); /* save PC */ R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK); m_icount -= 2 * S_CYCLE + N_CYCLE; } else /* Undefined */ { logerror("%08x: Undefined instruction\n",R15); L_Next: m_icount -= S_CYCLE; R15 += 4; } arm_check_irq_state(); } while( m_icount > 0 ); } /* arm_execute */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Operand* Peephole::Simplify(Instruction* instr) { // Set the insertion point for new instructions; all new instructions // after the current one, in the order they are created. irGen_.SetInsertionPoint(instr); switch(instr->GetOpcode()) { case Instr_Add: { return PreserveUSO(instr, HandleAdd(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock())); } case Instr_Sub: { return PreserveUSO(instr, HandleSub(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock())); } case Instr_Mul: { return PreserveUSO(instr, HandleMul(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock())); } case Instr_Div: { auto arithInstr = instr->As<ArithmeticInstr>(); return PreserveUSO(instr, HandleDiv(arithInstr->LeftOp(), arithInstr->RightOp(), instr->ParentBlock(), arithInstr->HasNoRemainder())); } case Instr_Udiv: { return PreserveUSO(instr, HandleUdiv(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock())); } case Instr_Mod: { return PreserveUSO(instr, HandleMod(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock())); } case Instr_Umod: { return PreserveUSO(instr, HandleUmod(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock())); } case Instr_Fadd: { auto arithInstr = instr->As<ArithmeticInstr>(); return HandleFadd(arithInstr->LeftOp(), arithInstr->RightOp(), arithInstr->GetFPMode()); } case Instr_Fsub: { auto arithInstr = instr->As<ArithmeticInstr>(); return HandleFsub(arithInstr->LeftOp(), arithInstr->RightOp(), arithInstr->GetFPMode()); } case Instr_Fmul: { auto arithInstr = instr->As<ArithmeticInstr>(); return HandleFmul(arithInstr->LeftOp(), arithInstr->RightOp(), arithInstr->GetFPMode()); } case Instr_Fdiv: { auto arithInstr = instr->As<ArithmeticInstr>(); return HandleFdiv(arithInstr->LeftOp(), arithInstr->RightOp(), arithInstr->GetFPMode()); } case Instr_And: return HandleAnd(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock()); case Instr_Or: return HandleOr(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock()); case Instr_Xor: return HandleXor(instr->GetSourceOp(0), instr->GetSourceOp(1), instr->ParentBlock()); case Instr_Shl: return HandleShl(instr->As<ShlInstr>()); case Instr_Shr: return HandleShr(instr->As<ShrInstr>()); case Instr_Ushr: return HandleUshr(instr->As<UshrInstr>()); case Instr_Cmp: return HandleCmp(instr->As<CmpInstr>()); case Instr_Ucmp: return HandleUcmp(instr->As<UcmpInstr>()); case Instr_Fcmp: return HandleFcmp(instr->As<FcmpInstr>()); case Instr_Trunc: return HandleTrunc(instr->As<TruncInstr>()); case Instr_Sext: return HandleSext(instr->As<SextInstr>()); case Instr_Zext: return HandleZext(instr->As<ZextInstr>()); case Instr_Ftrunc: return HandleFtrunc(instr->As<FtruncInstr>()); case Instr_Fext: return HandleFext(instr->As<FextInstr>()); case Instr_Ftoi: return HandleFtoi(instr->As<FtoiInstr>()); case Instr_Ftoui: return HandleFtoui(instr->As<FtouiInstr>()); case Instr_Itof: return HandleItof(instr->As<ItofInstr>()); case Instr_Itop: return HandleItop(instr->As<ItopInstr>()); case Instr_Ptoi: return HandlePtoi(instr->As<PtoiInstr>()); case Instr_Ptop: return HandlePtop(instr->As<PtopInstr>()); case Instr_Uitof: return HandleUitof(instr->As<UitofInstr>()); case Instr_Call: return HandleCall(instr->As<CallInstr>()); case Instr_Address: return HandleAddress(instr->As<AddressInstr>()); case Instr_Index: return HandleIndex(instr->As<IndexInstr>()); case Instr_Element: return HandleElement(instr->As<ElementInstr>()); case Instr_Load: return HandleLoad(instr->As<LoadInstr>()); case Instr_Store: return HandleStore(instr->As<StoreInstr>()); case Instr_Question: return HandleQuestion(instr->As<QuestionInstr>()); case Instr_Phi: return HandlePhi(instr->As<PhiInstr>()); } // This is an instruction that is not supported. return nullptr; }
static CPU_EXECUTE( arm ) { UINT32 pc; UINT32 insn; ARM_REGS *cpustate = get_safe_token(device); cpustate->icount = cycles; do { debugger_instruction_hook(device, R15 & ADDRESS_MASK); /* load instruction */ pc = R15; insn = memory_decrypted_read_dword( cpustate->program, pc & ADDRESS_MASK ); switch (insn >> INSN_COND_SHIFT) { case COND_EQ: if (Z_IS_CLEAR(pc)) goto L_Next; break; case COND_NE: if (Z_IS_SET(pc)) goto L_Next; break; case COND_CS: if (C_IS_CLEAR(pc)) goto L_Next; break; case COND_CC: if (C_IS_SET(pc)) goto L_Next; break; case COND_MI: if (N_IS_CLEAR(pc)) goto L_Next; break; case COND_PL: if (N_IS_SET(pc)) goto L_Next; break; case COND_VS: if (V_IS_CLEAR(pc)) goto L_Next; break; case COND_VC: if (V_IS_SET(pc)) goto L_Next; break; case COND_HI: if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next; break; case COND_LS: if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next; break; case COND_GE: if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */ break; case COND_LT: if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next; break; case COND_GT: if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next; break; case COND_LE: if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next; break; case COND_NV: goto L_Next; } /* Condition satisfied, so decode the instruction */ if ((insn & 0x0fc000f0u) == 0x00000090u) /* Multiplication */ { HandleMul(cpustate, insn); R15 += 4; } else if (!(insn & 0x0c000000u)) /* Data processing */ { HandleALU(cpustate, insn); } else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */ { HandleMemSingle(cpustate, insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */ { HandleMemBlock(cpustate, insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x0a000000u) /* Branch */ { HandleBranch(cpustate, insn); } else if ((insn & 0x0f000000u) == 0x0e000000u) /* Coprocessor */ { HandleCoPro(cpustate, insn); R15 += 4; } else if ((insn & 0x0f000000u) == 0x0f000000u) /* Software interrupt */ { pc=R15+4; R15 = eARM_MODE_SVC; /* Set SVC mode so PC is saved to correct R14 bank */ SetRegister( cpustate, 14, pc ); /* save PC */ R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK); cpustate->icount -= 2 * S_CYCLE + N_CYCLE; } else /* Undefined */ { logerror("%08x: Undefined instruction\n",R15); L_Next: cpustate->icount -= S_CYCLE; R15 += 4; } arm_check_irq_state(cpustate); } while( cpustate->icount > 0 ); return cycles - cpustate->icount; } /* arm_execute */
void arm2_execute_run(int tube_cycles) { #ifdef TRACE int i; #endif UINT32 pc; UINT32 insn; //int m_icount = number; do { //debugger_instruction_hook(this, R15 & ADDRESS_MASK); /* load instruction */ pc = R15; #ifdef INCLUDE_DEBUGGER if (arm2_debug_enabled) { debug_preexec(&arm2_cpu_debug, pc & ADDRESS_MASK); } #endif insn = cpu_read32( pc & ADDRESS_MASK ); #ifdef TRACE if ((pc & ADDRESS_MASK) == 0xa060) { m_trace = 1; } if (m_trace) { printf("%08X %08X ", pc, insn); for (i = eR0; i <= eR7; i++) { printf("%08X ", m_sArmRegister[i]); } if(darm_armv7_disasm(&d, insn) == 0 && darm_str2(&d, &str, 0) == 0) { printf("%s\r\n", str.total); } else { printf("***\r\n"); } } if ((pc & ADDRESS_MASK) == 0xa0c0) { m_trace = 0; } if ((pc & ADDRESS_MASK) == 0xa2ac) { m_trace = 0; } if ((insn & 0x0D900000) == 0x01000000) { printf("S bit not set in %08x at %08x\r\n", insn, pc & ADDRESS_MASK); insn |= INSN_S; } #endif switch (insn >> INSN_COND_SHIFT) { case COND_EQ: if (Z_IS_CLEAR(pc)) goto L_Next; break; case COND_NE: if (Z_IS_SET(pc)) goto L_Next; break; case COND_CS: if (C_IS_CLEAR(pc)) goto L_Next; break; case COND_CC: if (C_IS_SET(pc)) goto L_Next; break; case COND_MI: if (N_IS_CLEAR(pc)) goto L_Next; break; case COND_PL: if (N_IS_SET(pc)) goto L_Next; break; case COND_VS: if (V_IS_CLEAR(pc)) goto L_Next; break; case COND_VC: if (V_IS_SET(pc)) goto L_Next; break; case COND_HI: if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next; break; case COND_LS: if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next; break; case COND_GE: if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */ break; case COND_LT: if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next; break; case COND_GT: if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next; break; case COND_LE: if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next; break; case COND_NV: goto L_Next; } /* Condition satisfied, so decode the instruction */ if ((insn & 0x0fc000f0u) == 0x00000090u) /* Multiplication */ { HandleMul(insn); R15 += 4; } else if (!(insn & 0x0c000000u)) /* Data processing */ { HandleALU(insn); } else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */ { HandleMemSingle(insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */ { HandleMemBlock(insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x0a000000u) /* Branch */ { HandleBranch(insn); } else if ((insn & 0x0f000000u) == 0x0e000000u) /* Coprocessor */ { if (m_copro_type == ARM_COPRO_TYPE_VL86C020) HandleCoProVL86C020(insn); else HandleCoPro(insn); R15 += 4; } else if ((insn & 0x0f000000u) == 0x0f000000u) /* Software interrupt */ { pc=R15+4; R15 = eARM_MODE_SVC; /* Set SVC mode so PC is saved to correct R14 bank */ SetRegister( 14, pc ); /* save PC */ R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK); CYCLE_COUNT(2 * S_CYCLE + N_CYCLE); } else /* Undefined */ { logerror("%08x: Undefined instruction\n",R15); L_Next: CYCLE_COUNT(S_CYCLE); R15 += 4; } //arm2_check_irq_state(); tubeUseCycles(1); } while (tubeContinueRunning()); //while( m_icount > 0 ); //while (number--); } /* arm_execute */
int ArmRun( int cycles ) { UINT32 pc; UINT32 insn; arm_icount = cycles; arm.ArmLeftCycles = cycles; do { /* load instruction */ pc = R15; insn = Arm_program_opcode_dword_32le( pc & ADDRESS_MASK ); switch (insn >> INSN_COND_SHIFT) { case COND_EQ: if (Z_IS_CLEAR(pc)) goto L_Next; break; case COND_NE: if (Z_IS_SET(pc)) goto L_Next; break; case COND_CS: if (C_IS_CLEAR(pc)) goto L_Next; break; case COND_CC: if (C_IS_SET(pc)) goto L_Next; break; case COND_MI: if (N_IS_CLEAR(pc)) goto L_Next; break; case COND_PL: if (N_IS_SET(pc)) goto L_Next; break; case COND_VS: if (V_IS_CLEAR(pc)) goto L_Next; break; case COND_VC: if (V_IS_SET(pc)) goto L_Next; break; case COND_HI: if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next; break; case COND_LS: if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next; break; case COND_GE: if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */ break; case COND_LT: if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next; break; case COND_GT: if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next; break; case COND_LE: if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next; break; case COND_NV: goto L_Next; } /* Condition satisfied, so decode the instruction */ if ((insn & 0x0fc000f0u) == 0x00000090u) /* Multiplication */ { HandleMul(insn); R15 += 4; } else if (!(insn & 0x0c000000u)) /* Data processing */ { HandleALU(insn); } else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */ { HandleMemSingle(insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */ { HandleMemBlock(insn); R15 += 4; } else if ((insn & 0x0e000000u) == 0x0a000000u) /* Branch */ { HandleBranch(insn); } else if ((insn & 0x0f000000u) == 0x0e000000u) /* Coprocessor */ { HandleCoPro(insn); R15 += 4; } else if ((insn & 0x0f000000u) == 0x0f000000u) /* Software interrupt */ { pc=R15+4; R15 = eARM_MODE_SVC; /* Set SVC mode so PC is saved to correct R14 bank */ SetRegister( 14, pc ); /* save PC */ R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK); change_pc(pc&ADDRESS_MASK); arm_icount -= 2 * S_CYCLE + N_CYCLE; } else /* Undefined */ { L_Next: arm_icount -= S_CYCLE; R15 += 4; } arm_check_irq_state(); } while( arm_icount > 0 ); arm.ArmTotalCycles += (cycles - arm_icount); return cycles - arm_icount; } /* arm_execute */