Previous 199869 Revisions Next

r20786 Thursday 7th February, 2013 at 02:42:38 UTC by Ryan Holtz
arm7ops.c: Fixed behavior of SMLAxy opcode. [MooglyGuy]

nw - not sure if this is correct, but it looks a lot more correct than before. I'm not actually sure what we have in MAME or MESS that uses ARMv5 opcodes.
[src/emu/cpu/arm7]arm7drc.c arm7ops.c

trunk/src/emu/cpu/arm7/arm7ops.c
r20785r20786
15241524
15251525arm7ops_ophandler ops_handler[0x10] =
15261526{
1527   arm7ops_0123, arm7ops_0123, arm7ops_0123, arm7ops_0123,arm7ops_4567,arm7ops_4567,arm7ops_4567,arm7ops_4567,arm7ops_89,arm7ops_89,arm7ops_ab,arm7ops_ab,arm7ops_cd,arm7ops_cd,arm7ops_e,arm7ops_f,
1527   arm7ops_0123, arm7ops_0123, arm7ops_0123, arm7ops_0123,
1528   arm7ops_4567, arm7ops_4567, arm7ops_4567, arm7ops_4567,
1529   arm7ops_89,   arm7ops_89,   arm7ops_ab,   arm7ops_ab,
1530   arm7ops_cd,   arm7ops_cd,   arm7ops_e,    arm7ops_f,
15281531};
15291532
15301533const void arm7ops_0123(arm_state *arm, UINT32 insn)
r20785r20786
16171620      {
16181621         src1 >>= 16;
16191622      }
1620      else
1623
1624      src1 &= 0xffff;
1625      if (src1 & 0x8000)
16211626      {
1622         src1 &= 0xffff;
1623         if (src1 & 0x8000)
1624         {
1625            src1 |= 0xffff;
1626         }
1627         src1 |= 0xffff0000;
16271628      }
16281629
16291630      if (insn & 0x40)
16301631      {
16311632         src2 >>= 16;
16321633      }
1633      else
1634
1635      src2 &= 0xffff;
1636      if (src2 & 0x8000)
16341637      {
1635         src2 &= 0xffff;
1636         if (src2 & 0x8000)
1637         {
1638            src2 |= 0xffff;
1639         }
1638         src2 |= 0xffff0000;
16401639      }
16411640
16421641      // do the signed multiply
trunk/src/emu/cpu/arm7/arm7drc.c
r20785r20786
21922192      log_add_disasm_comment(arm, block, desc->pc, desc->opptr.l[0]);
21932193
21942194   /* 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
21972197
21982198   /* accumulate total cycles */
21992199   compiler->cycles += desc->cycles;
22002200
2201   /* update the icount map variable */
2202   UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles);                      // mapvar  CYCLES,compiler->cycles
2203
22012204   /* is this a hotspot? */
22022205   for (hotnum = 0; hotnum < MIPS3_MAX_HOTSPOTS; hotnum++)
22032206   {
r20785r20786
22722275   UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles);                             // mapvar  CYCLES,compiler->cycles
22732276}
22742277
2278typedef const bool (*drcarm7ops_ophandler)(arm_state*, drcuml_block*, compiler_state*, const opcode_desc*, UINT32);
22752279
2280static 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
2288INLINE 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
2300const 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
2623const bool drcarm7ops_4567(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op)
2624{
2625}
2626
2627const bool drcarm7ops_89(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op)
2628{
2629}
2630
2631const bool drcarm7ops_ab(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op)
2632{
2633}
2634
2635const bool drcarm7ops_cd(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op)
2636{
2637}
2638
2639const bool drcarm7ops_e(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op)
2640{
2641}
2642
2643const bool drcarm7ops_f(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT32 op)
2644{
2645}
2646
22762647/*-------------------------------------------------
22772648    generate_opcode - generate code for a specific
22782649    opcode
r20785r20786
22802651
22812652static int generate_opcode(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
22822653{
2283   int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
2654   //int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
22842655   UINT32 op = desc->opptr.l[0];
22852656   UINT8 opswitch = op >> 26;
22862657   code_label skip;
2658   code_label contdecode;
2659   code_label unexecuted;
22872660
22882661   if (T_IS_SET(GET_CPSR))
22892662   {
2290      UINT32 raddr;
2291
2292      pc = R15;
2293
22942663      // "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
23052664      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   }
23102670
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);
23152674
2675   if (T_IS_SET(GET_CPSR))
2676   {
2677      UML_CALLH(block, *arm->impstate->drcthumb[(op & 0xffc0) >> 6);         // callh   drcthumb[op]
2678      return TRUE;
23162679   }
2317   else
2680
2681   switch (op >> INSN_COND_SHIFT)
23182682   {
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;
23242775   }
23252776
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
23262787   switch (opswitch)
23272788   {
23282789      /* ----- sub-groups ----- */

Previous 199869 Revisions Next


© 1997-2024 The MAME Team