trunk/src/emu/cpu/arm7/arm7drc.c
| r20785 | r20786 | |
| 2192 | 2192 | log_add_disasm_comment(arm, block, desc->pc, desc->opptr.l[0]); |
| 2193 | 2193 | |
| 2194 | 2194 | /* set the PC map variable */ |
| 2195 | | expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 3 : desc->pc; |
| 2196 | | UML_MAPVAR(block, MAPVAR_PC, expc); // mapvar PC,expc |
| 2195 | //expc = (desc->flags & OPFLAG_IN_DELAY_SLOT) ? desc->pc - 3 : desc->pc; |
| 2196 | UML_MAPVAR(block, MAPVAR_PC, desc->pc); // mapvar PC,pc |
| 2197 | 2197 | |
| 2198 | 2198 | /* accumulate total cycles */ |
| 2199 | 2199 | compiler->cycles += desc->cycles; |
| 2200 | 2200 | |
| 2201 | /* update the icount map variable */ |
| 2202 | UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles |
| 2203 | |
| 2201 | 2204 | /* is this a hotspot? */ |
| 2202 | 2205 | for (hotnum = 0; hotnum < MIPS3_MAX_HOTSPOTS; hotnum++) |
| 2203 | 2206 | { |
| r20785 | r20786 | |
| 2272 | 2275 | UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles); // mapvar CYCLES,compiler->cycles |
| 2273 | 2276 | } |
| 2274 | 2277 | |
| 2278 | typedef const bool (*drcarm7ops_ophandler)(arm_state*, drcuml_block*, compiler_state*, const opcode_desc*, UINT32); |
| 2275 | 2279 | |
| 2280 | static drcarm7ops_ophandler drcops_handler[0x10] = |
| 2281 | { |
| 2282 | drcarm7ops_0123, drcarm7ops_0123, drcarm7ops_0123, drcarm7ops_0123, |
| 2283 | drcarm7ops_4567, drcarm7ops_4567, drcarm7ops_4567, drcarm7ops_4567, |
| 2284 | drcarm7ops_89, drcarm7ops_89, drcarm7ops_ab, drcarm7ops_ab, |
| 2285 | drcarm7ops_cd, drcarm7ops_cd, drcarm7ops_e, drcarm7ops_f, |
| 2286 | }; |
| 2287 | |
| 2288 | INLINE void saturate_qbit_overflow(arm_state *arm, drcuml_block *block) |
| 2289 | { |
| 2290 | UML_MOV(block, I1, 0); |
| 2291 | UML_DCMP(block, I0, 0x000000007fffffffL); |
| 2292 | UML_MOVc(block, COND_G, I1, Q_MASK); |
| 2293 | UML_MOVc(block, COND_G, I0, 0x7fffffff); |
| 2294 | UML_DCMP(block, I0, 0xffffffff80000000L); |
| 2295 | UML_MOVc(block, COND_L, I1, Q_MASK); |
| 2296 | UML_MOVc(block, COND_L, I0, 0x80000000); |
| 2297 | UML_OR(block, DRC_CPSR, DRC_CPSR, I1); |
| 2298 | } |
| 2299 | |
| 2300 | const bool drcarm7ops_0123(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op) |
| 2301 | { |
| 2302 | code_label done; |
| 2303 | /* Branch and Exchange (BX) */ |
| 2304 | if ((insn & 0x0ffffff0) == 0x012fff10) // bits 27-4 == 000100101111111111110001 |
| 2305 | { |
| 2306 | UML_MOV(block, DRC_PC, DRC_REG(insn & 0x0f)); |
| 2307 | UML_TEST(block, DRC_PC, 1); |
| 2308 | UML_JMPc(block, COND_Z, done = compiler->labelnum++); |
| 2309 | UML_OR(block, DRC_CPSR, DRC_CPSR, T_MASK); |
| 2310 | UML_AND(block, DRC_PC, DRC_PC, ~1); |
| 2311 | } |
| 2312 | else if ((insn & 0x0ff000f0) == 0x01600010) // CLZ - v5 |
| 2313 | { |
| 2314 | UINT32 rm = insn&0xf; |
| 2315 | UINT32 rd = (insn>>12)&0xf; |
| 2316 | |
| 2317 | UML_LZCNT(block, DRC_REG(rd), DRC_REG(rm)); |
| 2318 | UML_ADD(block, DRC_PC, DRC_PC, 4); |
| 2319 | } |
| 2320 | else if ((insn & 0x0ff000f0) == 0x01000050) // QADD - v5 |
| 2321 | { |
| 2322 | UINT32 rm = insn&0xf; |
| 2323 | UINT32 rn = (insn>>16)&0xf; |
| 2324 | UINT32 rd = (insn>>12)&0xf; |
| 2325 | UML_DSEXT(block, I0, DRC_REG(rm), SIZE_DWORD); |
| 2326 | UML_DSEXT(block, I1, DRC_REG(rn), SIZE_DWORD); |
| 2327 | UML_DADD(block, I0, I0, I1); |
| 2328 | saturate_qbit_overflow(arm, block); |
| 2329 | UML_MOV(block, DRC_REG(rd), I0); |
| 2330 | UML_ADD(block, DRC_PC, DRC_PC, 4); |
| 2331 | } |
| 2332 | else if ((insn & 0x0ff000f0) == 0x01400050) // QDADD - v5 |
| 2333 | { |
| 2334 | UINT32 rm = insn&0xf; |
| 2335 | UINT32 rn = (insn>>16)&0xf; |
| 2336 | UINT32 rd = (insn>>12)&0xf; |
| 2337 | |
| 2338 | UML_DSEXT(block, I1, DRC_REG(rn), SIZE_DWORD); |
| 2339 | UML_DADD(block, I0, I1, I1); |
| 2340 | saturate_qbit_overflow(arm, block); |
| 2341 | |
| 2342 | UML_DSEXT(block, I0, DRC_REG(rm), SIZE_DWORD); |
| 2343 | UML_DSEXT(block, I1, DRC_REG(rn), SIZE_DWORD); |
| 2344 | UML_DADD(block, I1, I1, I1); |
| 2345 | UML_DADD(block, I0, I0, I1); |
| 2346 | saturate_qbit_overflow(arm, block); |
| 2347 | UML_MOV(block, DRC_REG(rd), I0); |
| 2348 | |
| 2349 | UML_ADD(block, DRC_PC, DRC_PC, 4); |
| 2350 | } |
| 2351 | else if ((insn & 0x0ff000f0) == 0x01200050) // QSUB - v5 |
| 2352 | { |
| 2353 | UINT32 rm = insn&0xf; |
| 2354 | UINT32 rn = (insn>>16)&0xf; |
| 2355 | UINT32 rd = (insn>>12)&0xf; |
| 2356 | |
| 2357 | UML_DSEXT(block, I0, DRC_REG(rm), SIZE_DWORD); |
| 2358 | UML_DSEXT(block, I1, DRC_REG(rn), SIZE_DWORD); |
| 2359 | UML_DSUB(block, I0, I0, I1); |
| 2360 | saturate_qbit_overflow(arm, block); |
| 2361 | UML_MOV(block, DRC_REG(rd), I0); |
| 2362 | UML_ADD(block, DRC_PC, DRC_PC, 4); |
| 2363 | } |
| 2364 | else if ((insn & 0x0ff000f0) == 0x01600050) // QDSUB - v5 |
| 2365 | { |
| 2366 | UINT32 rm = insn&0xf; |
| 2367 | UINT32 rn = (insn>>16)&0xf; |
| 2368 | UINT32 rd = (insn>>12)&0xf; |
| 2369 | |
| 2370 | UML_DSEXT(block, I1, DRC_REG(rn), SIZE_DWORD); |
| 2371 | UML_DADD(block, I0, I1, I1); |
| 2372 | saturate_qbit_overflow(arm, block); |
| 2373 | |
| 2374 | UML_DSEXT(block, I0, DRC_REG(rm), SIZE_DWORD); |
| 2375 | UML_DSEXT(block, I1, DRC_REG(rn), SIZE_DWORD); |
| 2376 | UML_DADD(block, I1, I1, I1); |
| 2377 | UML_DSUB(block, I0, I0, I1); |
| 2378 | saturate_qbit_overflow(arm, block); |
| 2379 | UML_MOV(block, DRC_REG(rd), I0); |
| 2380 | |
| 2381 | UML_ADD(block, DRC_PC, DRC_PC, 4); |
| 2382 | } |
| 2383 | else if ((insn & 0x0ff00090) == 0x01000080) // SMLAxy - v5 |
| 2384 | { |
| 2385 | UINT32 rm = insn&0xf; |
| 2386 | UINT32 rn = (insn>>16)&0xf; |
| 2387 | UINT32 rd = (insn>>12)&0xf; |
| 2388 | UINT32 rr = (insn>>8)&0xf; |
| 2389 | |
| 2390 | INT32 src1 = GET_REGISTER(arm, insn&0xf); |
| 2391 | INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf); |
| 2392 | INT32 res1; |
| 2393 | |
| 2394 | UML_MOV(block, I0, DRC_REG(rm)); |
| 2395 | UML_MOV(block, I1, DRC_REG(rr)); |
| 2396 | |
| 2397 | // select top and bottom halves of src1/src2 and sign extend if necessary |
| 2398 | if (insn & 0x20) |
| 2399 | { |
| 2400 | UML_SHR(block, I0, I0, 16); |
| 2401 | } |
| 2402 | else |
| 2403 | { |
| 2404 | UML_SEXT(block, I1, I1, SIZE_WORD); |
| 2405 | src1 &= 0xffff; |
| 2406 | if (src1 & 0x8000) |
| 2407 | { |
| 2408 | src1 |= 0xffff; |
| 2409 | } |
| 2410 | } |
| 2411 | |
| 2412 | if (insn & 0x40) |
| 2413 | { |
| 2414 | src2 >>= 16; |
| 2415 | } |
| 2416 | else |
| 2417 | { |
| 2418 | src2 &= 0xffff; |
| 2419 | if (src2 & 0x8000) |
| 2420 | { |
| 2421 | src2 |= 0xffff; |
| 2422 | } |
| 2423 | } |
| 2424 | |
| 2425 | // do the signed multiply |
| 2426 | res1 = src1 * src2; |
| 2427 | // and the accumulate. NOTE: only the accumulate can cause an overflow, which is why we do it this way. |
| 2428 | saturate_qbit_overflow(arm, (INT64)res1 + (INT64)GET_REGISTER(arm, (insn>>12)&0xf)); |
| 2429 | |
| 2430 | SET_REGISTER(arm, (insn>>16)&0xf, res1 + GET_REGISTER(arm, (insn>>12)&0xf)); |
| 2431 | R15 += 4; |
| 2432 | } |
| 2433 | else if ((insn & 0x0ff00090) == 0x01400080) // SMLALxy - v5 |
| 2434 | { |
| 2435 | INT32 src1 = GET_REGISTER(arm, insn&0xf); |
| 2436 | INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf); |
| 2437 | INT64 dst; |
| 2438 | |
| 2439 | // select top and bottom halves of src1/src2 and sign extend if necessary |
| 2440 | if (insn & 0x20) |
| 2441 | { |
| 2442 | src1 >>= 16; |
| 2443 | } |
| 2444 | else |
| 2445 | { |
| 2446 | src1 &= 0xffff; |
| 2447 | if (src1 & 0x8000) |
| 2448 | { |
| 2449 | src1 |= 0xffff; |
| 2450 | } |
| 2451 | } |
| 2452 | |
| 2453 | if (insn & 0x40) |
| 2454 | { |
| 2455 | src2 >>= 16; |
| 2456 | } |
| 2457 | else |
| 2458 | { |
| 2459 | src2 &= 0xffff; |
| 2460 | if (src2 & 0x8000) |
| 2461 | { |
| 2462 | src2 |= 0xffff; |
| 2463 | } |
| 2464 | } |
| 2465 | |
| 2466 | dst = (INT64)GET_REGISTER(arm, (insn>>12)&0xf); |
| 2467 | dst |= (INT64)GET_REGISTER(arm, (insn>>16)&0xf)<<32; |
| 2468 | |
| 2469 | // do the multiply and accumulate |
| 2470 | dst += (INT64)src1 * (INT64)src2; |
| 2471 | |
| 2472 | // write back the result |
| 2473 | SET_REGISTER(cpustart, (insn>>12)&0xf, (UINT32)(dst&0xffffffff)); |
| 2474 | SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)(dst>>32)); |
| 2475 | } |
| 2476 | else if ((insn & 0x0ff00090) == 0x01600080) // SMULxy - v5 |
| 2477 | { |
| 2478 | INT32 src1 = GET_REGISTER(arm, insn&0xf); |
| 2479 | INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf); |
| 2480 | INT32 res; |
| 2481 | |
| 2482 | // select top and bottom halves of src1/src2 and sign extend if necessary |
| 2483 | if (insn & 0x20) |
| 2484 | { |
| 2485 | src1 >>= 16; |
| 2486 | } |
| 2487 | else |
| 2488 | { |
| 2489 | src1 &= 0xffff; |
| 2490 | if (src1 & 0x8000) |
| 2491 | { |
| 2492 | src1 |= 0xffff; |
| 2493 | } |
| 2494 | } |
| 2495 | |
| 2496 | if (insn & 0x40) |
| 2497 | { |
| 2498 | src2 >>= 16; |
| 2499 | } |
| 2500 | else |
| 2501 | { |
| 2502 | src2 &= 0xffff; |
| 2503 | if (src2 & 0x8000) |
| 2504 | { |
| 2505 | src2 |= 0xffff; |
| 2506 | } |
| 2507 | } |
| 2508 | |
| 2509 | res = src1 * src2; |
| 2510 | SET_REGISTER(cpustart, (insn>>16)&0xf, res); |
| 2511 | } |
| 2512 | else if ((insn & 0x0ff000b0) == 0x012000a0) // SMULWy - v5 |
| 2513 | { |
| 2514 | INT32 src1 = GET_REGISTER(arm, insn&0xf); |
| 2515 | INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf); |
| 2516 | INT64 res; |
| 2517 | |
| 2518 | if (insn & 0x40) |
| 2519 | { |
| 2520 | src2 >>= 16; |
| 2521 | } |
| 2522 | else |
| 2523 | { |
| 2524 | src2 &= 0xffff; |
| 2525 | if (src2 & 0x8000) |
| 2526 | { |
| 2527 | src2 |= 0xffff; |
| 2528 | } |
| 2529 | } |
| 2530 | |
| 2531 | res = (INT64)src1 * (INT64)src2; |
| 2532 | res >>= 16; |
| 2533 | SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)res); |
| 2534 | } |
| 2535 | else if ((insn & 0x0ff000b0) == 0x01200080) // SMLAWy - v5 |
| 2536 | { |
| 2537 | INT32 src1 = GET_REGISTER(arm, insn&0xf); |
| 2538 | INT32 src2 = GET_REGISTER(arm, (insn>>8)&0xf); |
| 2539 | INT32 src3 = GET_REGISTER(arm, (insn>>12)&0xf); |
| 2540 | INT64 res; |
| 2541 | |
| 2542 | if (insn & 0x40) |
| 2543 | { |
| 2544 | src2 >>= 16; |
| 2545 | } |
| 2546 | else |
| 2547 | { |
| 2548 | src2 &= 0xffff; |
| 2549 | if (src2 & 0x8000) |
| 2550 | { |
| 2551 | src2 |= 0xffff; |
| 2552 | } |
| 2553 | } |
| 2554 | |
| 2555 | res = (INT64)src1 * (INT64)src2; |
| 2556 | res >>= 16; |
| 2557 | |
| 2558 | // check for overflow and set the Q bit |
| 2559 | saturate_qbit_overflow(arm, (INT64)src3 + res); |
| 2560 | |
| 2561 | // do the real accumulate |
| 2562 | src3 += (INT32)res; |
| 2563 | |
| 2564 | // write the result back |
| 2565 | SET_REGISTER(cpustart, (insn>>16)&0xf, (UINT32)res); |
| 2566 | } |
| 2567 | else |
| 2568 | /* Multiply OR Swap OR Half Word Data Transfer */ |
| 2569 | if ((insn & 0x0e000000) == 0 && (insn & 0x80) && (insn & 0x10)) // bits 27-25=000 bit 7=1 bit 4=1 |
| 2570 | { |
| 2571 | /* Half Word Data Transfer */ |
| 2572 | if (insn & 0x60) // bits = 6-5 != 00 |
| 2573 | { |
| 2574 | HandleHalfWordDT(arm, insn); |
| 2575 | } |
| 2576 | else |
| 2577 | /* Swap */ |
| 2578 | if (insn & 0x01000000) // bit 24 = 1 |
| 2579 | { |
| 2580 | HandleSwap(arm, insn); |
| 2581 | } |
| 2582 | /* Multiply Or Multiply Long */ |
| 2583 | else |
| 2584 | { |
| 2585 | /* multiply long */ |
| 2586 | if (insn & 0x800000) // Bit 23 = 1 for Multiply Long |
| 2587 | { |
| 2588 | /* Signed? */ |
| 2589 | if (insn & 0x00400000) |
| 2590 | HandleSMulLong(arm, insn); |
| 2591 | else |
| 2592 | HandleUMulLong(arm, insn); |
| 2593 | } |
| 2594 | /* multiply */ |
| 2595 | else |
| 2596 | { |
| 2597 | HandleMul(arm, insn); |
| 2598 | } |
| 2599 | R15 += 4; |
| 2600 | } |
| 2601 | } |
| 2602 | /* Data Processing OR PSR Transfer */ |
| 2603 | else if ((insn & 0x0c000000) == 0) // bits 27-26 == 00 - This check can only exist properly after Multiplication check above |
| 2604 | { |
| 2605 | /* PSR Transfer (MRS & MSR) */ |
| 2606 | if (((insn & 0x00100000) == 0) && ((insn & 0x01800000) == 0x01000000)) // S bit must be clear, and bit 24,23 = 10 |
| 2607 | { |
| 2608 | HandlePSRTransfer(arm, insn); |
| 2609 | ARM7_ICOUNT += 2; // PSR only takes 1 - S Cycle, so we add + 2, since at end, we -3.. |
| 2610 | R15 += 4; |
| 2611 | } |
| 2612 | /* Data Processing */ |
| 2613 | else |
| 2614 | { |
| 2615 | HandleALU(arm, insn); |
| 2616 | } |
| 2617 | } |
| 2618 | |
| 2619 | UML_LABEL(block, done); |
| 2620 | return true; |
| 2621 | } |
| 2622 | |
| 2623 | const bool drcarm7ops_4567(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op) |
| 2624 | { |
| 2625 | } |
| 2626 | |
| 2627 | const bool drcarm7ops_89(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op) |
| 2628 | { |
| 2629 | } |
| 2630 | |
| 2631 | const bool drcarm7ops_ab(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op) |
| 2632 | { |
| 2633 | } |
| 2634 | |
| 2635 | const bool drcarm7ops_cd(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op) |
| 2636 | { |
| 2637 | } |
| 2638 | |
| 2639 | const bool drcarm7ops_e(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op) |
| 2640 | { |
| 2641 | } |
| 2642 | |
| 2643 | const bool drcarm7ops_f(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op) |
| 2644 | { |
| 2645 | } |
| 2646 | |
| 2276 | 2647 | /*------------------------------------------------- |
| 2277 | 2648 | generate_opcode - generate code for a specific |
| 2278 | 2649 | opcode |
| r20785 | r20786 | |
| 2280 | 2651 | |
| 2281 | 2652 | static int generate_opcode(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) |
| 2282 | 2653 | { |
| 2283 | | int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); |
| 2654 | //int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0); |
| 2284 | 2655 | UINT32 op = desc->opptr.l[0]; |
| 2285 | 2656 | UINT8 opswitch = op >> 26; |
| 2286 | 2657 | code_label skip; |
| 2658 | code_label contdecode; |
| 2659 | code_label unexecuted; |
| 2287 | 2660 | |
| 2288 | 2661 | if (T_IS_SET(GET_CPSR)) |
| 2289 | 2662 | { |
| 2290 | | UINT32 raddr; |
| 2291 | | |
| 2292 | | pc = R15; |
| 2293 | | |
| 2294 | 2663 | // "In Thumb state, bit [0] is undefined and must be ignored. Bits [31:1] contain the PC." |
| 2295 | | raddr = pc & (~1); |
| 2296 | | |
| 2297 | | if ( COPRO_CTRL & COPRO_CTRL_MMU_EN ) |
| 2298 | | { |
| 2299 | | if (!arm7_tlb_translate(arm, &raddr, ARM7_TLB_ABORT_P | ARM7_TLB_READ)) |
| 2300 | | { |
| 2301 | | goto skip_exec; |
| 2302 | | } |
| 2303 | | } |
| 2304 | | |
| 2305 | 2664 | UML_AND(block, I0, DRC_PC, ~1); |
| 2306 | | UML_TEST(block, mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN); // test COPRO_CTRL, COPRO_CTRL_MMU_EN |
| 2307 | | UML_MOVc(block, COND_Z, I0, 0); // movz i0, 0 |
| 2308 | | UML_MOVc(block, COND_NZ, I0, ARM7_TLB_ABORT_P | ARM7_TLB_READ); // movnz i0, ARM7_TLB_ABORT_P | ARM7_TLB_READ |
| 2309 | | UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate); // callhnz tlb_translate); |
| 2665 | } |
| 2666 | else |
| 2667 | { |
| 2668 | UML_AND(block, I0, DRC_PC, ~3); |
| 2669 | } |
| 2310 | 2670 | |
| 2311 | | insn = arm->direct->read_decrypted_word(raddr); |
| 2312 | | thumb_handler[(insn & 0xffc0) >> 6](arm, pc, insn); |
| 2313 | | UML_OR(block, I3, I3, ); // or i2, i2, i3 |
| 2314 | | UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate); // callhnz tlb_translate |
| 2671 | UML_TEST(block, mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN); // test COPRO_CTRL, COPRO_CTRL_MMU_EN |
| 2672 | UML_MOVc(block, COND_NZ, I2, ARM7_TLB_ABORT_P | ARM7_TLB_READ); // movnz i0, ARM7_TLB_ABORT_P | ARM7_TLB_READ |
| 2673 | UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate); // callhnz tlb_translate); |
| 2315 | 2674 | |
| 2675 | if (T_IS_SET(GET_CPSR)) |
| 2676 | { |
| 2677 | UML_CALLH(block, *arm->impstate->drcthumb[(op & 0xffc0) >> 6); // callh drcthumb[op] |
| 2678 | return TRUE; |
| 2316 | 2679 | } |
| 2317 | | else |
| 2680 | |
| 2681 | switch (op >> INSN_COND_SHIFT) |
| 2318 | 2682 | { |
| 2319 | | UML_AND(block, I0, DRC_PC, ~1); |
| 2320 | | UML_TEST(block, mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN); // test COPRO_CTRL, COPRO_CTRL_MMU_EN |
| 2321 | | UML_MOVc(block, COND_NZ, I3, ARM7_TLB_READ); // movnz i3, ARM7_TLB_READ |
| 2322 | | UML_OR(block, I3, I3, I3); // or i2, i2, i3 |
| 2323 | | UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate); // callhnz tlb_translate |
| 2683 | case COND_EQ: |
| 2684 | UML_TEST(block, DRC_CPSR, Z_MASK); |
| 2685 | UML_JMPc(block, COND_Z, unexecuted = compiler->labelnum++); |
| 2686 | break; |
| 2687 | case COND_NE: |
| 2688 | UML_TEST(block, DRC_CPSR, Z_MASK); |
| 2689 | UML_JMPc(block, COND_NZ, unexecuted = compiler->labelnum++); |
| 2690 | break; |
| 2691 | case COND_CS: |
| 2692 | UML_TEST(block, DRC_CPSR, C_MASK); |
| 2693 | UML_JMPc(block, COND_Z, unexecuted = compiler->labelnum++); |
| 2694 | break; |
| 2695 | case COND_CC: |
| 2696 | UML_TEST(block, DRC_CPSR, C_MASK); |
| 2697 | UML_JMPc(block, COND_NZ, unexecuted = compiler->labelnum++); |
| 2698 | break; |
| 2699 | case COND_MI: |
| 2700 | UML_TEST(block, DRC_CPSR, N_MASK); |
| 2701 | UML_JMPc(block, COND_Z, unexecuted = compiler->labelnum++); |
| 2702 | break; |
| 2703 | case COND_PL: |
| 2704 | UML_TEST(block, DRC_CPSR, N_MASK); |
| 2705 | UML_JMPc(block, COND_NZ, unexecuted = compiler->labelnum++); |
| 2706 | break; |
| 2707 | case COND_VS: |
| 2708 | UML_TEST(block, DRC_CPSR, V_MASK); |
| 2709 | UML_JMPc(block, COND_Z, unexecuted = compiler->labelnum++); |
| 2710 | break; |
| 2711 | case COND_VC: |
| 2712 | UML_TEST(block, DRC_CPSR, V_MASK); |
| 2713 | UML_JMPc(block, COND_NZ, unexecuted = compiler->labelnum++); |
| 2714 | break; |
| 2715 | case COND_HI: |
| 2716 | UML_TEST(block, DRC_CPSR, Z_MASK); |
| 2717 | UML_JMPc(block, COND_NZ, unexecuted = compiler->labelnum++); |
| 2718 | UML_TEST(block, DRC_CPSR, C_MASK); |
| 2719 | UML_JMPc(block, COND_Z, unexecuted = compiler->labelnum++); |
| 2720 | break; |
| 2721 | case COND_LS: |
| 2722 | UML_TEST(block, DRC_CPSR, Z_MASK); |
| 2723 | UML_JMPc(block, COND_NZ, contdecode = compiler->labelnum++); |
| 2724 | UML_TEST(block, DRC_CPSR, C_MASK); |
| 2725 | UML_JMPc(block, COND_Z, contdecode); |
| 2726 | UML_JMP(block, unexecuted); |
| 2727 | break; |
| 2728 | case COND_GE: |
| 2729 | UML_TEST(block, DRC_CPSR, N_MASK); |
| 2730 | UML_MOVc(block, COND_Z, I0, 0); |
| 2731 | UML_MOVc(block, COND_NZ, I0, 1); |
| 2732 | UML_TEST(block, DRC_CPSR, V_MASK); |
| 2733 | UML_MOVc(block, COND_Z, I1, 0); |
| 2734 | UML_MOVc(block, COND_NZ, I1, 1); |
| 2735 | UML_CMP(block, I0, I1); |
| 2736 | UML_JMPc(block, COND_NE, unexecuted); |
| 2737 | break; |
| 2738 | case COND_LT: |
| 2739 | UML_TEST(block, DRC_CPSR, N_MASK); |
| 2740 | UML_MOVc(block, COND_Z, I0, 0); |
| 2741 | UML_MOVc(block, COND_NZ, I0, 1); |
| 2742 | UML_TEST(block, DRC_CPSR, V_MASK); |
| 2743 | UML_MOVc(block, COND_Z, I1, 0); |
| 2744 | UML_MOVc(block, COND_NZ, I1, 1); |
| 2745 | UML_CMP(block, I0, I1); |
| 2746 | UML_JMPc(block, COND_E, unexecuted); |
| 2747 | break; |
| 2748 | case COND_GT: |
| 2749 | UML_TEST(block, DRC_CPSR, Z_MASK); |
| 2750 | UML_JMPc(block, COND_NZ, unexecuted); |
| 2751 | UML_TEST(block, DRC_CPSR, N_MASK); |
| 2752 | UML_MOVc(block, COND_Z, I0, 0); |
| 2753 | UML_MOVc(block, COND_NZ, I0, 1); |
| 2754 | UML_TEST(block, DRC_CPSR, V_MASK); |
| 2755 | UML_MOVc(block, COND_Z, I1, 0); |
| 2756 | UML_MOVc(block, COND_NZ, I1, 1); |
| 2757 | UML_CMP(block, I0, I1); |
| 2758 | UML_JMPc(block, COND_NE, unexecuted); |
| 2759 | break; |
| 2760 | case COND_LE: |
| 2761 | UML_TEST(block, DRC_CPSR, N_MASK); |
| 2762 | UML_MOVc(block, COND_Z, I0, 0); |
| 2763 | UML_MOVc(block, COND_NZ, I0, 1); |
| 2764 | UML_TEST(block, DRC_CPSR, V_MASK); |
| 2765 | UML_MOVc(block, COND_Z, I1, 0); |
| 2766 | UML_MOVc(block, COND_NZ, I1, 1); |
| 2767 | UML_CMP(block, I0, I1); |
| 2768 | UML_JMPc(block, COND_NE, contdecode); |
| 2769 | UML_TEST(block, DRC_CPSR, Z_MASK); |
| 2770 | UML_JMPc(block, COND_Z, unexecuted); |
| 2771 | break; |
| 2772 | case COND_NV: |
| 2773 | UML_JMP(block, unexecuted); |
| 2774 | break; |
| 2324 | 2775 | } |
| 2325 | 2776 | |
| 2777 | UML_LABEL(block, contdecode); |
| 2778 | |
| 2779 | drcops_handler[(op & 0xF000000) >> 24](arm, block, compiler, desc); |
| 2780 | |
| 2781 | UML_LABEL(block, unexecuted); |
| 2782 | UML_ADD(block, DRC_PC, DRC_PC, 4); |
| 2783 | UML_ADD(block, MAPVAR_CYCLES, MAPVAR_CYCLES, 2); // add cycles, cycles, 2 |
| 2784 | |
| 2785 | UML_LABEL(block, skip); |
| 2786 | |
| 2326 | 2787 | switch (opswitch) |
| 2327 | 2788 | { |
| 2328 | 2789 | /* ----- sub-groups ----- */ |