Previous 199869 Revisions Next

r20738 Tuesday 5th February, 2013 at 02:05:54 UTC by Ryan Holtz
arm7 drc checkpoint, nw
[src/emu/cpu/arm7]arm7.h arm7drc.c arm7help.h arm7tdrc.c* arm7thmb.c

trunk/src/emu/cpu/arm7/arm7drc.c
r20737r20738
6161    CONSTANTS
6262***************************************************************************/
6363
64typedef const void (*arm7thumb_drcophandler)(arm_state*, drcuml_block*, compiler_state*, opcode_desc*);
65
66#include "arm7tdrc.c"
67
6468/* map variables */
6569#define MAPVAR_PC                       M0
6670#define MAPVAR_CYCLES                   M1
r20737r20738
137141   code_handle *   entry;                      /* entry point */
138142   code_handle *   nocode;                     /* nocode exception handler */
139143   code_handle *   out_of_cycles;              /* out of cycles exception handler */
144   code_handle *   tlb_translate;              /* tlb translation handler */
145   code_handle *   detect_fault;               /* tlb fault detection handler */
146   code_handle *   check_irq;                  /* irq check handler */
140147   code_handle *   read8;                      /* read byte */
141148   code_handle *   write8;                     /* write byte */
142149   code_handle *   read16;                     /* read half */
r20737r20738
146153
147154   /* fast RAM */
148155   UINT32              fastram_select;
149   fast_ram_info       fastram[MIPS3_MAX_FASTRAM];
156   fast_ram_info       fastram[ARM7_MAX_FASTRAM];
150157};
151158
152159
r20737r20738
165172static void static_generate_nocode_handler(arm_state *arm);
166173static void static_generate_out_of_cycles(arm_state *arm);
167174static void static_generate_tlb_translate(arm_state *arm);
175static void static_generate_detect_fault(arm_state *arm);
176static void static_generate_check_irq(arm_state *arm);
168177
169178static void generate_update_cycles(arm_state *arm, drcuml_block *block, compiler_state *compiler, parameter param, int allow_exception);
170179static void generate_checksum_block(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast);
r20737r20738
296305   arm->impstate->drcuml = auto_alloc(device->machine(), drcuml_state(*device, *cache, flags, 1, 32, 1));
297306
298307   /* add symbols for our stuff */
299   arm->impstate->drcuml->symbol_add(&arm->pc, sizeof(mips3->pc), "pc");
300   arm->impstate->drcuml->symbol_add(&arm->icount, sizeof(mips3->icount), "icount");
308   arm->impstate->drcuml->symbol_add(&arm->icount, sizeof(arm->icount), "icount");
301309   for (int regnum = 0; regnum < 37; regnum++)
302310   {
303311      char buf[10];
r20737r20738
476484}
477485
478486/*-------------------------------------------------
479    mips3_exit - cleanup from execution
487    arm7_exit - cleanup from execution
480488-------------------------------------------------*/
481489
482static CPU_EXIT( mips3 )
490static CPU_EXIT( arm7 )
483491{
484492   arm_state *arm = get_safe_token(device);
485493
r20737r20738
491499
492500
493501/*-------------------------------------------------
494    mips3_translate - perform virtual-to-physical
502    arm7_translate - perform virtual-to-physical
495503    address translation
496504-------------------------------------------------*/
497505
r20737r20738
12241232      static_generate_nocode_handler(arm);
12251233      static_generate_out_of_cycles(arm);
12261234      static_generate_tlb_translate(arm);
1235      static_generate_detect_fault(arm);
12271236      //static_generate_tlb_mismatch(arm);
12281237
1229      /* append exception handlers for various types */
1230      /*static_generate_exception(mips3, EXCEPTION_INTERRUPT,     TRUE,  "exception_interrupt");
1231      static_generate_exception(mips3, EXCEPTION_INTERRUPT,     FALSE, "exception_interrupt_norecover");
1232      static_generate_exception(mips3, EXCEPTION_TLBMOD,        TRUE,  "exception_tlbmod");
1233      static_generate_exception(mips3, EXCEPTION_TLBLOAD,       TRUE,  "exception_tlbload");
1234      static_generate_exception(mips3, EXCEPTION_TLBSTORE,      TRUE,  "exception_tlbstore");
1235      static_generate_exception(mips3, EXCEPTION_TLBLOAD_FILL,  TRUE,  "exception_tlbload_fill");
1236      static_generate_exception(mips3, EXCEPTION_TLBSTORE_FILL, TRUE,  "exception_tlbstore_fill");
1237      static_generate_exception(mips3, EXCEPTION_ADDRLOAD,      TRUE,  "exception_addrload");
1238      static_generate_exception(mips3, EXCEPTION_ADDRSTORE,     TRUE,  "exception_addrstore");
1239      static_generate_exception(mips3, EXCEPTION_SYSCALL,       TRUE,  "exception_syscall");
1240      static_generate_exception(mips3, EXCEPTION_BREAK,         TRUE,  "exception_break");
1241      static_generate_exception(mips3, EXCEPTION_INVALIDOP,     TRUE,  "exception_invalidop");
1242      static_generate_exception(mips3, EXCEPTION_BADCOP,        TRUE,  "exception_badcop");
1243      static_generate_exception(mips3, EXCEPTION_OVERFLOW,      TRUE,  "exception_overflow");
1244      static_generate_exception(mips3, EXCEPTION_TRAP,          TRUE,  "exception_trap");*/
1245
12461238      /* add subroutines for memory accesses */
1247      //for (mode = 0; mode < 3; mode++)
1248      //{
1249         static_generate_memory_accessor(mips3, mode, 1, FALSE, FALSE, "read8",       &mips3->impstate->read8[mode]);
1250         static_generate_memory_accessor(mips3, mode, 1, TRUE,  FALSE, "write8",      &mips3->impstate->write8[mode]);
1251         static_generate_memory_accessor(mips3, mode, 2, FALSE, FALSE, "read16",      &mips3->impstate->read16[mode]);
1252         static_generate_memory_accessor(mips3, mode, 2, TRUE,  FALSE, "write16",     &mips3->impstate->write16[mode]);
1253         static_generate_memory_accessor(mips3, mode, 4, FALSE, FALSE, "read32",      &mips3->impstate->read32[mode]);
1254         static_generate_memory_accessor(mips3, mode, 4, FALSE, TRUE,  "read32mask",  &mips3->impstate->read32mask[mode]);
1255         static_generate_memory_accessor(mips3, mode, 4, TRUE,  FALSE, "write32",     &mips3->impstate->write32[mode]);
1256         static_generate_memory_accessor(mips3, mode, 4, TRUE,  TRUE,  "write32mask", &mips3->impstate->write32mask[mode]);
1257         static_generate_memory_accessor(mips3, mode, 8, FALSE, FALSE, "read64",      &mips3->impstate->read64[mode]);
1258         static_generate_memory_accessor(mips3, mode, 8, FALSE, TRUE,  "read64mask",  &mips3->impstate->read64mask[mode]);
1259         static_generate_memory_accessor(mips3, mode, 8, TRUE,  FALSE, "write64",     &mips3->impstate->write64[mode]);
1260         static_generate_memory_accessor(mips3, mode, 8, TRUE,  TRUE,  "write64mask", &mips3->impstate->write64mask[mode]);
1261      //}
1239      static_generate_memory_accessor(arm, mode, 1, FALSE, FALSE, "read8",       &arm->impstate->read8);
1240      static_generate_memory_accessor(arm, mode, 1, TRUE,  FALSE, "write8",      &arm->impstate->write8);
1241      static_generate_memory_accessor(arm, mode, 2, FALSE, FALSE, "read16",      &arm->impstate->read16);
1242      static_generate_memory_accessor(arm, mode, 2, TRUE,  FALSE, "write16",     &arm->impstate->write16);
1243      static_generate_memory_accessor(arm, mode, 4, FALSE, FALSE, "read32",      &arm->impstate->read32);
1244      static_generate_memory_accessor(arm, mode, 4, TRUE,  FALSE, "write32",     &arm->impstate->write32);
12621245   }
12631246   catch (drcuml_block::abort_compilation &)
12641247   {
r20737r20738
14351418   /* forward references */
14361419   alloc_handle(drcuml, &arm->impstate->exception_norecover[EXCEPTION_INTERRUPT], "interrupt_norecover");
14371420   alloc_handle(drcuml, &arm->impstate->nocode, "nocode");
1421   alloc_handle(drcuml, &arm->impstate->detect_fault, "detect_fault");
1422   alloc_handle(drcuml, &arm->impstate->tlb_translate, "tlb_translate");
14381423
14391424   alloc_handle(drcuml, &arm->impstate->entry, "entry");
1440   UML_HANDLE(block, *arm->impstate->entry);                                     // handle  entry
1425   UML_HANDLE(block, *arm->impstate->entry);                           // handle  entry
14411426
14421427   /* load fast integer registers */
14431428   load_fast_iregs(arm, block);
14441429
1430   UML_CALLH(block, *arm->impstate->check_irq);
1431
1432   /* generate a hash jump via the current mode and PC */
1433   UML_HASHJMP(block, 0, mem(&arm->pc), *arm->impstate->nocode);      // hashjmp 0,<pc>,nocode
1434   block->end();
1435}
1436
1437
1438/*-------------------------------------------------
1439    static_generate_check_irq - generate a handler
1440    to check IRQs
1441-------------------------------------------------*/
1442
1443static void static_generate_check_irq(arm_state *arm)
1444{
1445   drcuml_state *drcuml = arm->impstate->drcuml;
1446   drcuml_block *block;
1447   int nodabt = 0;
1448   int nopabt = 0;
1449   int irqadjust = 0;
1450   int nofiq = 0;
1451   int irq32 = 0;
1452   int swi32 = 0;
1453   int done = 0;
1454   int label = 1;
1455
1456   /* begin generating */
1457   block = drcuml->begin_block(120);
1458
1459   /* generate a hash jump via the current mode and PC */
1460   alloc_handle(drcuml, &arm->impstate->check_irq, "check_irq");
1461   UML_HANDLE(block, *arm->impstate->check_irq);                  // handle  check_irq
14451462   /* Exception priorities:
14461463
14471464       Reset
r20737r20738
15441561   UML_MOV(block, mem(&arm->pendingUnd, 0);                     // mov      pendingUnd, 0
15451562   UML_JMP(block, irqadjust);                                 // jmp      irqadjust
15461563
1547   UML_LABEL(block, nound);                                              // nound:
1564   UML_LABEL(block, nopabt);                                           // nopabt:
15481565
15491566   // Software Interrupt
15501567   UML_TEST(block, mem(&arm->pendingSwi, 1);                     // test      pendingSwi, 1
r20737r20738
15831600
15841601   UML_LABEL(block, done);                                    // done:
15851602
1586   /* generate a hash jump via the current mode and PC */
1587   UML_HASHJMP(block, mem(&arm->impstate->mode), mem(&arm->pc), *arm->impstate->nocode);
1588                                                      // hashjmp <mode>,<pc>,nocode
15891603   block->end();
1590}
1604};
15911605
1592
15931606/*-------------------------------------------------
15941607    static_generate_nocode_handler - generate an
15951608    exception handler for "out of code"
r20737r20738
16581671   block = drcuml->begin_block(1024);
16591672
16601673   /* add a global entry for this */
1661   alloc_handle(drcuml, handleptr, name);
1662   UML_HANDLE(block, **handleptr);                           // handle   *handleptr
1674   alloc_handle(drcuml, &arm->impstate->detect_fault, "detect_fault");
1675   UML_HANDLE(block, *arm->impstate->detect_fault);                  // handle     detect_fault
16631676
16641677   UML_ROLAND(block, I6, I4, 32-4, 0x0f<<1);                  // roland   i6, i4, 32-4, 0xf<<1
16651678   UML_ROLAND(block, I6, mem(&COPRO_DOMAIN_ACCESS_CONTROL), I6, 3);// roland   i6, COPRO_DOMAIN_ACCESS_CONTROL, i6, 3
r20737r20738
17471760   /* begin generating */
17481761   block = drcuml->begin_block(170);
17491762
1750   /* add a global entry for this */
1751   alloc_handle(drcuml, handleptr, name);
1752   UML_HANDLE(block, **handleptr);                           // handle   *handleptr
1763   alloc_handle(drcuml, &arm->impstate->tlb_translate, "tlb_translate");
1764   UML_HANDLE(block, *arm->impstate->tlb_translate);               // handle     tlb_translate
17531765
17541766   // I3: vaddr
17551767   UML_CMP(block, I0, 32 * 1024 * 1024);                     // cmp      i0, 32*1024*1024
r20737r20738
19321944
19331945static void static_generate_memory_accessor(arm_state *arm, int size, bool istlb, bool iswrite, const char *name, code_handle **handleptr)
19341946{
1935   /* on entry, address is in I0; data for writes is in I1 */
1947   /* on entry, address is in I0; data for writes is in I1, fetch type in I2 */
19361948   /* on exit, read result is in I0 */
19371949   /* routine trashes I0-I3 */
1938   //code_handle &exception_tlb = *mips3->impstate->exception[iswrite ? EXCEPTION_TLBSTORE : EXCEPTION_TLBLOAD];
1939   //code_handle &exception_tlbfill = *mips3->impstate->exception[iswrite ? EXCEPTION_TLBSTORE_FILL : EXCEPTION_TLBLOAD_FILL];
1940   //code_handle &exception_addrerr = *mips3->impstate->exception[iswrite ? EXCEPTION_ADDRSTORE : EXCEPTION_ADDRLOAD];
19411950   drcuml_state *drcuml = arm->impstate->drcuml;
19421951   drcuml_block *block;
19431952   int tlbmiss = 0;
r20737r20738
19551964      UML_TEST(block, mem(&COPRO_CTRL), COPRO_CTRL_MMU_EN);            // test      COPRO_CTRL, COPRO_CTRL_MMU_EN
19561965      if (iswrite)
19571966      {
1958         UML_MOVc(block, COND_NZ, I2, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE);// movnz   i2, ARM7_TLB_ABORT_D | ARM7_TLB_WRITE
1967         UML_MOVc(block, COND_NZ, I3, ARM7_TLB_WRITE);               // movnz   i3, ARM7_TLB_WRITE
19591968      }
19601969      else
19611970      {
1962         UML_MOVc(block, COND_NZ, I2, ARM7_TLB_ABORT_D | ARM7_TLB_READ);   // movnz   i2, ARM7_TLB_ABORT_D | ARM7_TLB_READ
1971         UML_MOVc(block, COND_NZ, I3, ARM7_TLB_READ);               // movnz   i3, ARM7_TLB_READ
19631972      }
1973      UML_OR(block, I2, I2, I3);                                 // or      i2, i2, i3
19641974      UML_CALLHc(block, COND_NZ, *arm->impstate->tlb_translate);         // callhnz   tlb_translate
19651975   }
19661976
r20737r20738
20142024               }
20152025               else if (size == 2)
20162026               {
2017                  UML_XOR(block, I0, I0, mips3->bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0));
2027                  UML_XOR(block, I0, I0, arm->bigendian ? WORD_XOR_BE(0) : WORD_XOR_LE(0));
20182028                                                                  // xor     i0, i0, wordxor
20192029                  UML_STORE(block, fastbase, I0, I1, SIZE_WORD, SCALE_x1);      // store   fastbase, i0, i1, word_x1
20202030               }
r20737r20738
20702080   block->end();
20712081}
20722082
2083/***************************************************************************
2084    CODE GENERATION
2085***************************************************************************/
2086
2087/*-------------------------------------------------
2088    generate_update_cycles - generate code to
2089    subtract cycles from the icount and generate
2090    an exception if out
2091-------------------------------------------------*/
2092
2093static void generate_update_cycles(arm_state *arm, drcuml_block *block, compiler_state *compiler, parameter param)
2094{
2095   /* check full interrupts if pending */
2096   if (compiler->checkints)
2097   {
2098      code_label skip;
2099
2100      compiler->checkints = FALSE;
2101      UML_CALLH(block, *arm->impstate->check_irq);
2102   }
2103
2104   /* account for cycles */
2105   if (compiler->cycles > 0)
2106   {
2107      UML_SUB(block, mem(&arm->icount), mem(&arm->icount), MAPVAR_CYCLES);    // sub     icount,icount,cycles
2108      UML_MAPVAR(block, MAPVAR_CYCLES, 0);                                    // mapvar  cycles,0
2109      UML_EXHc(block, COND_S, *arm->impstate->out_of_cycles, param);         // exh     out_of_cycles,nextpc
2110   }
2111   compiler->cycles = 0;
2112}
2113
2114
2115/*-------------------------------------------------
2116    generate_checksum_block - generate code to
2117    validate a sequence of opcodes
2118-------------------------------------------------*/
2119
2120static void generate_checksum_block(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *seqhead, const opcode_desc *seqlast)
2121{
2122   const opcode_desc *curdesc;
2123   if (LOG_UML)
2124   {
2125      block->append_comment("[Validation for %08X]", seqhead->pc);                // comment
2126   }
2127
2128   /* loose verify or single instruction: just compare and fail */
2129   if (!(arm->impstate->drcoptions & ARM7DRC_STRICT_VERIFY) || seqhead->next() == NULL)
2130   {
2131      if (!(seqhead->flags & OPFLAG_VIRTUAL_NOOP))
2132      {
2133         UINT32 sum = seqhead->opptr.l[0];
2134         void *base = arm->direct->read_decrypted_ptr(seqhead->physpc);
2135         UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4);            // load    i0,base,0,dword
2136
2137         if (seqhead->delay.first() != NULL && seqhead->physpc != seqhead->delay.first()->physpc)
2138         {
2139            base = arm->direct->read_decrypted_ptr(seqhead->delay.first()->physpc);
2140            UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4);         // load    i1,base,dword
2141            UML_ADD(block, I0, I0, I1);                           // add     i0,i0,i1
2142
2143            sum += seqhead->delay.first()->opptr.l[0];
2144         }
2145
2146         UML_CMP(block, I0, sum);                                       // cmp     i0,opptr[0]
2147         UML_EXHc(block, COND_NE, *arm->impstate->nocode, epc(seqhead));   // exne    nocode,seqhead->pc
2148      }
2149   }
2150
2151   /* full verification; sum up everything */
2152   else
2153   {
2154      UINT32 sum = 0;
2155      void *base = arm->direct->read_decrypted_ptr(seqhead->physpc);
2156      UML_LOAD(block, I0, base, 0, SIZE_DWORD, SCALE_x4);               // load    i0,base,0,dword
2157      sum += seqhead->opptr.l[0];
2158      for (curdesc = seqhead->next(); curdesc != seqlast->next(); curdesc = curdesc->next())
2159         if (!(curdesc->flags & OPFLAG_VIRTUAL_NOOP))
2160         {
2161            base = arm->direct->read_decrypted_ptr(curdesc->physpc);
2162            UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4);         // load    i1,base,dword
2163            UML_ADD(block, I0, I0, I1);                           // add     i0,i0,i1
2164            sum += curdesc->opptr.l[0];
2165
2166            if (curdesc->delay.first() != NULL && (curdesc == seqlast || (curdesc->next() != NULL && curdesc->next()->physpc != curdesc->delay.first()->physpc)))
2167            {
2168               base = arm->direct->read_decrypted_ptr(curdesc->delay.first()->physpc);
2169               UML_LOAD(block, I1, base, 0, SIZE_DWORD, SCALE_x4);      // load    i1,base,dword
2170               UML_ADD(block, I0, I0, I1);                        // add     i0,i0,i1
2171               sum += curdesc->delay.first()->opptr.l[0];
2172            }
2173         }
2174      UML_CMP(block, I0, sum);                                 // cmp     i0,sum
2175      UML_EXHc(block, COND_NE, *arm->impstate->nocode, epc(seqhead));      // exne    nocode,seqhead->pc
2176   }
2177}
2178
2179
2180/*-------------------------------------------------
2181    generate_sequence_instruction - generate code
2182    for a single instruction in a sequence
2183-------------------------------------------------*/
2184
2185static void generate_sequence_instruction(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
2186{
2187   offs_t expc;
2188   int hotnum;
2189
2190   /* add an entry for the log */
2191   if (LOG_UML && !(desc->flags & OPFLAG_VIRTUAL_NOOP))
2192      log_add_disasm_comment(arm, block, desc->pc, desc->opptr.l[0]);
2193
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
2197
2198   /* accumulate total cycles */
2199   compiler->cycles += desc->cycles;
2200
2201   /* is this a hotspot? */
2202   for (hotnum = 0; hotnum < MIPS3_MAX_HOTSPOTS; hotnum++)
2203   {
2204      if (arm->impstate->hotspot[hotnum].pc != 0 && desc->pc == arm->impstate->hotspot[hotnum].pc && desc->opptr.l[0] == arm->impstate->hotspot[hotnum].opcode)
2205      {
2206         compiler->cycles += arm->impstate->hotspot[hotnum].cycles;
2207         break;
2208      }
2209   }
2210
2211   /* update the icount map variable */
2212   UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles);                  // mapvar  CYCLES,compiler->cycles
2213
2214   /* if we are debugging, call the debugger */
2215   if ((arm->device->machine().debug_flags & DEBUG_FLAG_ENABLED) != 0)
2216   {
2217      UML_MOV(block, mem(&R15), desc->pc);                        // mov     [pc],desc->pc
2218      save_fast_iregs(arm, block);
2219      UML_DEBUG(block, desc->pc);                                 // debug   desc->pc
2220   }
2221
2222   /* if we hit an unmapped address, fatal error */
2223   if (desc->flags & OPFLAG_COMPILER_UNMAPPED)
2224   {
2225      UML_MOV(block, mem(&R15), desc->pc);                        // mov     R15,desc->pc
2226      save_fast_iregs(arm, block);
2227      UML_EXIT(block, EXECUTE_UNMAPPED_CODE);                        // exit    EXECUTE_UNMAPPED_CODE
2228   }
2229
2230   /* otherwise, unless this is a virtual no-op, it's a regular instruction */
2231   else if (!(desc->flags & OPFLAG_VIRTUAL_NOOP))
2232   {
2233      /* compile the instruction */
2234      if (!generate_opcode(arm, block, compiler, desc))
2235      {
2236         UML_MOV(block, mem(&R15), desc->pc);                     // mov     R15,desc->pc
2237         UML_MOV(block, mem(&arm->impstate->arg0), desc->opptr.l[0]);   // mov     [arg0],desc->opptr.l
2238         UML_CALLC(block, cfunc_unimplemented, arm);                    // callc   cfunc_unimplemented
2239      }
2240   }
2241}
2242
2243
2244/*------------------------------------------------------------------
2245    generate_delay_slot_and_branch
2246------------------------------------------------------------------*/
2247
2248static void generate_delay_slot_and_branch(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc, UINT8 linkreg)
2249{
2250   compiler_state compiler_temp = *compiler;
2251   UINT32 op = desc->opptr.l[0];
2252
2253   /* update the cycles and jump through the hash table to the target */
2254   if (desc->targetpc != BRANCH_TARGET_DYNAMIC)
2255   {
2256      generate_update_cycles(arm, block, &compiler_temp, desc->targetpc, TRUE);   // <subtract cycles>
2257      UML_HASHJMP(block, 0, desc->targetpc, *arm->impstate->nocode);
2258                                                               // hashjmp 0,desc->targetpc,nocode
2259   }
2260   else
2261   {
2262      generate_update_cycles(arm, block, &compiler_temp, mem(&arm->impstate->jmpdest), TRUE);
2263                                                               // <subtract cycles>
2264      UML_HASHJMP(block, 0, mem(&arm->impstate->jmpdest), *arm->impstate->nocode);// hashjmp 0,<rsreg>,nocode
2265   }
2266
2267   /* update the label */
2268   compiler->labelnum = compiler_temp.labelnum;
2269
2270   /* reset the mapvar to the current cycles and account for skipped slots */
2271   compiler->cycles += desc->skipslots;
2272   UML_MAPVAR(block, MAPVAR_CYCLES, compiler->cycles);                             // mapvar  CYCLES,compiler->cycles
2273}
2274
2275
2276/*-------------------------------------------------
2277    generate_opcode - generate code for a specific
2278    opcode
2279-------------------------------------------------*/
2280
2281static int generate_opcode(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
2282{
2283   int in_delay_slot = ((desc->flags & OPFLAG_IN_DELAY_SLOT) != 0);
2284   UINT32 op = desc->opptr.l[0];
2285   UINT8 opswitch = op >> 26;
2286   code_label skip;
2287
2288   if (T_IS_SET(GET_CPSR))
2289   {
2290
2291   }
2292
2293   switch (opswitch)
2294   {
2295      /* ----- sub-groups ----- */
2296
2297      case 0x00:  /* SPECIAL - MIPS I */
2298         UML_DCMP(block, R64(RSREG), R64(RTREG));                                // dcmp    <rsreg>,<rtreg>
2299         UML_JMPc(block, COND_NE, skip = compiler->labelnum++);                  // jmp     skip,NE
2300         generate_delay_slot_and_branch(mips3, block, compiler, desc, 0);        // <next instruction + hashjmp>
2301         UML_LABEL(block, skip);                                             // skip:
2302         return TRUE;
2303
20732304DEFINE_LEGACY_CPU_DEVICE(ARM7, arm7);
20742305DEFINE_LEGACY_CPU_DEVICE(ARM7_BE, arm7_be);
20752306DEFINE_LEGACY_CPU_DEVICE(ARM7500, arm7500);
trunk/src/emu/cpu/arm7/arm7thmb.c
r20737r20738
33#include "arm7thmb.h"
44#include "arm7help.h"
55
6// this is our master dispatch jump table for THUMB mode, representing [(insn & 0xffc0) >> 6] bits of the 16-bit decoded instruction
6// this is our master dispatch jump table for THUMB mode, representing [(INSN & 0xffc0) >> 6] bits of the 16-bit decoded instruction
77arm7thumb_ophandler thumb_handler[0x40*0x10] =
88{
99// #define THUMB_SHIFT_R       ((UINT16)0x0800)
10   tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,
10   tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,     tg00_0,
11   tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,     tg00_1,
1112// #define THUMB_INSN_ADDSUB   ((UINT16)0x0800)   // #define THUMB_ADDSUB_TYPE   ((UINT16)0x0600)
12   tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_13,    tg01_13,    tg01_13,    tg01_13,    tg01_13,    tg01_13,    tg01_13,    tg01_13,
13   tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,     tg01_0,
14   tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_10,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_11,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_12,    tg01_13,    tg01_13,    tg01_13,    tg01_13,    tg01_13,    tg01_13,    tg01_13,    tg01_13,
1315// #define THUMB_INSN_CMP      ((UINT16)0x0800)
14   tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,
16   tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,     tg02_0,
17   tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,     tg02_1,
1518// #define THUMB_INSN_SUB      ((UINT16)0x0800)
16   tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,
19   tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,     tg03_0,
20   tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,     tg03_1,
1721//#define THUMB_GROUP4_TYPE   ((UINT16)0x0c00)  //#define THUMB_ALUOP_TYPE    ((UINT16)0x03c0)  // #define THUMB_HIREG_OP      ((UINT16)0x0300)  // #define THUMB_HIREG_H       ((UINT16)0x00c0)
18   tg04_00_00, tg04_00_01, tg04_00_02, tg04_00_03, tg04_00_04, tg04_00_05, tg04_00_06, tg04_00_07, tg04_00_08, tg04_00_09, tg04_00_0a, tg04_00_0b, tg04_00_0c, tg04_00_0d, tg04_00_0e, tg04_00_0f, tg04_01_00, tg04_01_01, tg04_01_02, tg04_01_03, tg04_01_10, tg04_01_11, tg04_01_12, tg04_01_13, tg04_01_20, tg04_01_21, tg04_01_22, tg04_01_23, tg04_01_30, tg04_01_31, tg04_01_32, tg04_01_33, tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,
22   tg04_00_00, tg04_00_01, tg04_00_02, tg04_00_03, tg04_00_04, tg04_00_05, tg04_00_06, tg04_00_07, tg04_00_08, tg04_00_09, tg04_00_0a, tg04_00_0b, tg04_00_0c, tg04_00_0d, tg04_00_0e, tg04_00_0f, tg04_01_00, tg04_01_01, tg04_01_02, tg04_01_03, tg04_01_10, tg04_01_11, tg04_01_12, tg04_01_13, tg04_01_20, tg04_01_21, tg04_01_22, tg04_01_23, tg04_01_30, tg04_01_31, tg04_01_32, tg04_01_33,
23   tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,  tg04_0203,
1924//#define THUMB_GROUP5_TYPE   ((UINT16)0x0e00)
20   tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_7,     tg05_7,     tg05_7,     tg05_7,     tg05_7,     tg05_7,     tg05_7,     tg05_7,
25   tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_0,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_1,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_2,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_3,     tg05_3,
26   tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_4,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_5,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_6,     tg05_7,     tg05_7,     tg05_7,     tg05_7,     tg05_7,     tg05_7,     tg05_7,     tg05_7,
2127//#define THUMB_LSOP_L        ((UINT16)0x0800)
22   tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,
28   tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,     tg06_0,
29   tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,     tg06_1,
2330//#define THUMB_LSOP_L        ((UINT16)0x0800)
24   tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,
31   tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,     tg07_0,
32   tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,     tg07_1,
2533// #define THUMB_HALFOP_L      ((UINT16)0x0800)
26   tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,
34   tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,     tg08_0,
35   tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,     tg08_1,
2736// #define THUMB_STACKOP_L     ((UINT16)0x0800)
28   tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,
37   tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,     tg09_0,
38   tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,     tg09_1,
2939// #define THUMB_RELADDR_SP    ((UINT16)0x0800)
30   tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,
40   tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,     tg0a_0,
41   tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,     tg0a_1,
3142// #define THUMB_STACKOP_TYPE  ((UINT16)0x0f00)
32   tg0b_0,     tg0b_0,     tg0b_0,     tg0b_0,     tg0b_1,     tg0b_1,     tg0b_1,     tg0b_1,     tg0b_2,     tg0b_2,     tg0b_2,     tg0b_2,     tg0b_3,     tg0b_3,     tg0b_3,     tg0b_3,     tg0b_4,     tg0b_4,     tg0b_4,     tg0b_4,     tg0b_5,     tg0b_5,     tg0b_5,     tg0b_5,     tg0b_6,     tg0b_6,     tg0b_6,     tg0b_6,     tg0b_7,     tg0b_7,     tg0b_7,     tg0b_7,     tg0b_8,     tg0b_8,     tg0b_8,     tg0b_8,     tg0b_9,     tg0b_9,     tg0b_9,     tg0b_9,     tg0b_a,     tg0b_a,     tg0b_a,     tg0b_a,     tg0b_b,     tg0b_b,     tg0b_b,     tg0b_b,     tg0b_c,     tg0b_c,     tg0b_c,     tg0b_c,     tg0b_d,     tg0b_d,     tg0b_d,     tg0b_d,     tg0b_e,     tg0b_e,     tg0b_e,     tg0b_e,     tg0b_f,     tg0b_f,     tg0b_f,     tg0b_f,
43   tg0b_0,     tg0b_0,     tg0b_0,     tg0b_0,     tg0b_1,     tg0b_1,     tg0b_1,     tg0b_1,     tg0b_2,     tg0b_2,     tg0b_2,     tg0b_2,     tg0b_3,     tg0b_3,     tg0b_3,     tg0b_3,     tg0b_4,     tg0b_4,     tg0b_4,     tg0b_4,     tg0b_5,     tg0b_5,     tg0b_5,     tg0b_5,     tg0b_6,     tg0b_6,     tg0b_6,     tg0b_6,     tg0b_7,     tg0b_7,     tg0b_7,     tg0b_7,
44   tg0b_8,     tg0b_8,     tg0b_8,     tg0b_8,     tg0b_9,     tg0b_9,     tg0b_9,     tg0b_9,     tg0b_a,     tg0b_a,     tg0b_a,     tg0b_a,     tg0b_b,     tg0b_b,     tg0b_b,     tg0b_b,     tg0b_c,     tg0b_c,     tg0b_c,     tg0b_c,     tg0b_d,     tg0b_d,     tg0b_d,     tg0b_d,     tg0b_e,     tg0b_e,     tg0b_e,     tg0b_e,     tg0b_f,     tg0b_f,     tg0b_f,     tg0b_f,
3345// #define THUMB_MULTLS        ((UINT16)0x0800)
34   tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,
46   tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,     tg0c_0,
47   tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,     tg0c_1,
3548// #define THUMB_COND_TYPE     ((UINT16)0x0f00)
36   tg0d_0,     tg0d_0,     tg0d_0,     tg0d_0,     tg0d_1,     tg0d_1,     tg0d_1,     tg0d_1,     tg0d_2,     tg0d_2,     tg0d_2,     tg0d_2,     tg0d_3,     tg0d_3,     tg0d_3,     tg0d_3,     tg0d_4,     tg0d_4,     tg0d_4,     tg0d_4,     tg0d_5,     tg0d_5,     tg0d_5,     tg0d_5,     tg0d_6,     tg0d_6,     tg0d_6,     tg0d_6,     tg0d_7,     tg0d_7,     tg0d_7,     tg0d_7,     tg0d_8,     tg0d_8,     tg0d_8,     tg0d_8,     tg0d_9,     tg0d_9,     tg0d_9,     tg0d_9,     tg0d_a,     tg0d_a,     tg0d_a,     tg0d_a,     tg0d_b,     tg0d_b,     tg0d_b,     tg0d_b,     tg0d_c,     tg0d_c,     tg0d_c,     tg0d_c,     tg0d_d,     tg0d_d,     tg0d_d,     tg0d_d,     tg0d_e,     tg0d_e,     tg0d_e,     tg0d_e,     tg0d_f,     tg0d_f,     tg0d_f,     tg0d_f,
49   tg0d_0,     tg0d_0,     tg0d_0,     tg0d_0,     tg0d_1,     tg0d_1,     tg0d_1,     tg0d_1,     tg0d_2,     tg0d_2,     tg0d_2,     tg0d_2,     tg0d_3,     tg0d_3,     tg0d_3,     tg0d_3,     tg0d_4,     tg0d_4,     tg0d_4,     tg0d_4,     tg0d_5,     tg0d_5,     tg0d_5,     tg0d_5,     tg0d_6,     tg0d_6,     tg0d_6,     tg0d_6,     tg0d_7,     tg0d_7,     tg0d_7,     tg0d_7,
50   tg0d_8,     tg0d_8,     tg0d_8,     tg0d_8,     tg0d_9,     tg0d_9,     tg0d_9,     tg0d_9,     tg0d_a,     tg0d_a,     tg0d_a,     tg0d_a,     tg0d_b,     tg0d_b,     tg0d_b,     tg0d_b,     tg0d_c,     tg0d_c,     tg0d_c,     tg0d_c,     tg0d_d,     tg0d_d,     tg0d_d,     tg0d_d,     tg0d_e,     tg0d_e,     tg0d_e,     tg0d_e,     tg0d_f,     tg0d_f,     tg0d_f,     tg0d_f,
3751// #define THUMB_BLOP_LO       ((UINT16)0x0800)
38   tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,
52   tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,     tg0e_0,
53   tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,     tg0e_1,
3954// #define THUMB_BLOP_LO       ((UINT16)0x0800)
40   tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,
55   tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,     tg0f_0,
56   tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,     tg0f_1,
4157};
4258
4359   /* Shift operations */
4460
45const void tg00_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Shift left */
61const void tg00_0(arm_state *arm, UINT32 pc, UINT32 op) /* Shift left */
4662{
4763   UINT32 rs, rd, rrs;
4864   INT32 offs;
4965
5066   SET_CPSR(GET_CPSR & ~(N_MASK | Z_MASK));
5167
52   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
53   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
68   rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
69   rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
5470   rrs = GET_REGISTER(arm, rs);
55   offs = (insn & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
71   offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
5672   if (offs != 0)
5773   {
5874      SET_REGISTER(arm, rd, rrs << offs);
r20737r20738
7490   R15 += 2;
7591}
7692
77const void tg00_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Shift right */
93const void tg00_1(arm_state *arm, UINT32 pc, UINT32 op) /* Shift right */
7894{
7995   UINT32 rs, rd, rrs;
8096   INT32 offs;
8197
82   SET_CPSR(GET_CPSR & ~(N_MASK | Z_MASK));
83
84   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
85   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
98   rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
99   rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
86100   rrs = GET_REGISTER(arm, rs);
87   offs = (insn & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
101   offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
88102   if (offs != 0)
89103   {
90104      SET_REGISTER(arm, rd, rrs >> offs);
r20737r20738
114128   R15 += 2;
115129}
116130
117/* Arithmetic */
131   /* Arithmetic */
118132
119const void tg01_0(arm_state *arm, UINT32 pc, UINT32 insn)
133const void tg01_0(arm_state *arm, UINT32 pc, UINT32 op)
120134{
121135   UINT32 rs, rd, rrs;
122136   INT32 offs;
123137   /* ASR.. */
124   //if (insn & THUMB_SHIFT_R) /* Shift right */
138   //if (op & THUMB_SHIFT_R) /* Shift right */
125139   {
126      rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
127      rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
140      rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
141      rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
128142      rrs = GET_REGISTER(arm, rs);
129      offs = (insn & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
143      offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
130144      if (offs == 0)
131145      {
132146         offs = 32;
r20737r20738
164178   }
165179}
166180
167const void tg01_10(arm_state *arm, UINT32 pc, UINT32 insn)  /* ADD Rd, Rs, Rn */
181const void tg01_10(arm_state *arm, UINT32 pc, UINT32 op)  /* ADD Rd, Rs, Rn */
168182{
169   UINT32 rn, rs, rd;
170
171
172   rn = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
173   rs = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
174   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
183   UINT32 rn = GET_REGISTER(arm, (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
184   UINT32 rs = GET_REGISTER(arm, (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
185   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
175186   SET_REGISTER(arm, rd, rs + rn);
176187   HandleThumbALUAddFlags(GET_REGISTER(arm, rd), rs, rn);
177188
178189}
179190
180const void tg01_11(arm_state *arm, UINT32 pc, UINT32 insn) /* SUB Rd, Rs, Rn */
191const void tg01_11(arm_state *arm, UINT32 pc, UINT32 op) /* SUB Rd, Rs, Rn */
181192{
182   UINT32 rn, rs, rd;
183
184   rn = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
185   rs = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
186   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
193   UINT32 rn = GET_REGISTER(arm, (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT);
194   UINT32 rs = GET_REGISTER(arm, (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
195   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
187196   SET_REGISTER(arm, rd, rs - rn);
188197   HandleThumbALUSubFlags(GET_REGISTER(arm, rd), rs, rn);
189198
190199}
191200
192const void tg01_12(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD Rd, Rs, #imm */
201const void tg01_12(arm_state *arm, UINT32 pc, UINT32 op) /* ADD Rd, Rs, #imm */
193202{
194   UINT32 rs, rd, imm;
195
196   imm = (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
197   rs = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
198   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
203   UINT32 imm = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
204   UINT32 rs = GET_REGISTER(arm, (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
205   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
199206   SET_REGISTER(arm, rd, rs + imm);
200207   HandleThumbALUAddFlags(GET_REGISTER(arm, rd), rs, imm);
201208
202209}
203210
204const void tg01_13(arm_state *arm, UINT32 pc, UINT32 insn) /* SUB Rd, Rs, #imm */
211const void tg01_13(arm_state *arm, UINT32 pc, UINT32 op) /* SUB Rd, Rs, #imm */
205212{
206   UINT32 rs, rd, imm;
207
208   imm = (insn & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
209   rs = GET_REGISTER(arm, (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
210   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
213   UINT32 imm = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
214   UINT32 rs = GET_REGISTER(arm, (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT);
215   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
211216   SET_REGISTER(arm, rd, rs - imm);
212217   HandleThumbALUSubFlags(GET_REGISTER(arm, rd), rs,imm);
213218
214219}
215220
216/* CMP / MOV */
221   /* CMP / MOV */
217222
218const void tg02_0(arm_state *arm, UINT32 pc, UINT32 insn)
223const void tg02_0(arm_state *arm, UINT32 pc, UINT32 op)
219224{
220   UINT32 rd, op2;
221
222   rd = (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
223   op2 = (insn & THUMB_INSN_IMM);
225   UINT32 rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
226   UINT32 op2 = (op & THUMB_INSN_IMM);
224227   SET_REGISTER(arm, rd, op2);
225228   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
226229   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
227230   R15 += 2;
228231}
229232
230const void tg02_1(arm_state *arm, UINT32 pc, UINT32 insn)
233const void tg02_1(arm_state *arm, UINT32 pc, UINT32 op)
231234{
232   UINT32 rn, rd, op2;
233
234   rn = GET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
235   op2 = insn & THUMB_INSN_IMM;
236   rd = rn - op2;
235   UINT32 rn = GET_REGISTER(arm, (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
236   UINT32 op2 = op & THUMB_INSN_IMM;
237   UINT32 rd = rn - op2;
237238   HandleThumbALUSubFlags(rd, rn, op2);
238   //mame_printf_debug("%08x: xxx Thumb instruction: CMP R%d (%08x), %02x (N=%d, Z=%d, C=%d, V=%d)\n", pc, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, GET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT), op2, N_IS_SET(GET_CPSR) ? 1 : 0, Z_IS_SET(GET_CPSR) ? 1 : 0, C_IS_SET(GET_CPSR) ? 1 : 0, V_IS_SET(GET_CPSR) ? 1 : 0);
239239}
240240
241   /* ADD/SUB immediate */
241242
242
243/* ADD/SUB immediate */
244
245const void tg03_0(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD Rd, #Offset8 */
243const void tg03_0(arm_state *arm, UINT32 pc, UINT32 op) /* ADD Rd, #Offset8 */
246244{
247   UINT32 rn, rd, op2;
248
249   rn = GET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
250   op2 = insn & THUMB_INSN_IMM;
251   rd = rn + op2;
252   //mame_printf_debug("%08x:  Thumb instruction: ADD R%d, %02x\n", pc, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, op2);
253   SET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
245   UINT32 rn = GET_REGISTER(arm, (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
246   UINT32 op2 = op & THUMB_INSN_IMM;
247   UINT32 rd = rn + op2;
248   SET_REGISTER(arm, (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
254249   HandleThumbALUAddFlags(rd, rn, op2);
255250}
256251
257const void tg03_1(arm_state *arm, UINT32 pc, UINT32 insn) /* SUB Rd, #Offset8 */
252const void tg03_1(arm_state *arm, UINT32 pc, UINT32 op) /* SUB Rd, #Offset8 */
258253{
259   UINT32 rn, rd, op2;
260
261   rn = GET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
262   op2 = insn & THUMB_INSN_IMM;
263   //mame_printf_debug("%08x:  Thumb instruction: SUB R%d, %02x\n", pc, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, op2);
264   rd = rn - op2;
265   SET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
254   UINT32 rn = GET_REGISTER(arm, (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT);
255   UINT32 op2 = op & THUMB_INSN_IMM;
256   UINT32 rd = rn - op2;
257   SET_REGISTER(arm, (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, rd);
266258   HandleThumbALUSubFlags(rd, rn, op2);
267259}
268260
261   /* Rd & Rm instructions */
269262
270
271/* Rd & Rm instructions */
272
273const void tg04_00_00(arm_state *arm, UINT32 pc, UINT32 insn) /* AND Rd, Rs */
263const void tg04_00_00(arm_state *arm, UINT32 pc, UINT32 op) /* AND Rd, Rs */
274264{
275   UINT32 rs, rd;
276
277   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
278   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
265   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
266   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
279267   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) & GET_REGISTER(arm, rs));
280268   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
281269   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
282270   R15 += 2;
283
284271}
285272
286const void tg04_00_01(arm_state *arm, UINT32 pc, UINT32 insn) /* EOR Rd, Rs */
273const void tg04_00_01(arm_state *arm, UINT32 pc, UINT32 op) /* EOR Rd, Rs */
287274{
288   UINT32 rs, rd;
289
290   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
291   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
275   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
276   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
292277   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) ^ GET_REGISTER(arm, rs));
293278   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
294279   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
295280   R15 += 2;
296
297281}
298282
299const void tg04_00_02(arm_state *arm, UINT32 pc, UINT32 insn) /* LSL Rd, Rs */
283const void tg04_00_02(arm_state *arm, UINT32 pc, UINT32 op) /* LSL Rd, Rs */
300284{
301   UINT32 rs, rd, rrd;
302   INT32 offs;
303
304   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
305   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
306   rrd = GET_REGISTER(arm, rd);
307   offs = GET_REGISTER(arm, rs) & 0x000000ff;
285   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
286   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
287   UINT32 rrd = GET_REGISTER(arm, rd);
288   INT32 offs = GET_REGISTER(arm, rs) & 0x000000ff;
308289   if (offs > 0)
309290   {
310291      if (offs < 32)
r20737r20738
340321   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
341322   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
342323   R15 += 2;
343
344324}
345325
346const void tg04_00_03(arm_state *arm, UINT32 pc, UINT32 insn) /* LSR Rd, Rs */
326const void tg04_00_03(arm_state *arm, UINT32 pc, UINT32 op) /* LSR Rd, Rs */
347327{
348   UINT32 rs, rd, rrd;
349   INT32 offs;
350
351   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
352   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
353   rrd = GET_REGISTER(arm, rd);
354   offs = GET_REGISTER(arm, rs) & 0x000000ff;
328   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
329   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
330   UINT32 rrd = GET_REGISTER(arm, rd);
331   INT32 offs = GET_REGISTER(arm, rs) & 0x000000ff;
355332   if (offs >  0)
356333   {
357334      if (offs < 32)
r20737r20738
387364   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
388365   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
389366   R15 += 2;
390
391367}
392368
393const void tg04_00_04(arm_state *arm, UINT32 pc, UINT32 insn) /* ASR Rd, Rs */
369const void tg04_00_04(arm_state *arm, UINT32 pc, UINT32 op) /* ASR Rd, Rs */
394370{
395   UINT32 rs, rd, rrs, rrd;
396
397   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
398   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
399   rrs = GET_REGISTER(arm, rs)&0xff;
400   rrd = GET_REGISTER(arm, rd);
371   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
372   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
373   UINT32 rrs = GET_REGISTER(arm, rs)&0xff;
374   UINT32 rrd = GET_REGISTER(arm, rd);
401375   if (rrs != 0)
402376   {
403377      if (rrs >= 32)
r20737r20738
430404   SET_CPSR(GET_CPSR & ~(N_MASK | Z_MASK));
431405   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
432406   R15 += 2;
433
434407}
435408
436const void tg04_00_05(arm_state *arm, UINT32 pc, UINT32 insn) /* ADC Rd, Rs */
409const void tg04_00_05(arm_state *arm, UINT32 pc, UINT32 op) /* ADC Rd, Rs */
437410{
438   UINT32 rn, rs, rd, op2;
439
440   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
441   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
442   op2=(GET_CPSR & C_MASK) ? 1 : 0;
443   rn=GET_REGISTER(arm, rd) + GET_REGISTER(arm, rs) + op2;
411   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
412   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
413   UINT32 op2 = (GET_CPSR & C_MASK) ? 1 : 0;
414   UINT32 rn = GET_REGISTER(arm, rd) + GET_REGISTER(arm, rs) + op2;
444415   HandleThumbALUAddFlags(rn, GET_REGISTER(arm, rd), (GET_REGISTER(arm, rs))); // ?
445416   SET_REGISTER(arm, rd, rn);
446
447417}
448418
449const void tg04_00_06(arm_state *arm, UINT32 pc, UINT32 insn)  /* SBC Rd, Rs */
419const void tg04_00_06(arm_state *arm, UINT32 pc, UINT32 op)  /* SBC Rd, Rs */
450420{
451   UINT32 rn, rs, rd, op2;
452
453   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
454   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
455   op2=(GET_CPSR & C_MASK) ? 0 : 1;
456   rn=GET_REGISTER(arm, rd) - GET_REGISTER(arm, rs) - op2;
421   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
422   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
423   UINT32 op2 = (GET_CPSR & C_MASK) ? 0 : 1;
424   UINT32 rn = GET_REGISTER(arm, rd) - GET_REGISTER(arm, rs) - op2;
457425   HandleThumbALUSubFlags(rn, GET_REGISTER(arm, rd), (GET_REGISTER(arm, rs))); //?
458426   SET_REGISTER(arm, rd, rn);
459
460427}
461428
462const void tg04_00_07(arm_state *arm, UINT32 pc, UINT32 insn) /* ROR Rd, Rs */
429const void tg04_00_07(arm_state *arm, UINT32 pc, UINT32 op) /* ROR Rd, Rs */
463430{
464   UINT32 rs, rd, imm, rrd;
465
466   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
467   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
468   rrd = GET_REGISTER(arm, rd);
469   imm = GET_REGISTER(arm, rs) & 0x0000001f;
431   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
432   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
433   UINT32 rrd = GET_REGISTER(arm, rd);
434   UINT32 imm = GET_REGISTER(arm, rs) & 0x0000001f;
470435   SET_REGISTER(arm, rd, (rrd >> imm) | (rrd << (32 - imm)));
471436   if (rrd & (1 << (imm - 1)))
472437   {
r20737r20738
479444   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
480445   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
481446   R15 += 2;
482
483447}
484448
485const void tg04_00_08(arm_state *arm, UINT32 pc, UINT32 insn) /* TST Rd, Rs */
449const void tg04_00_08(arm_state *arm, UINT32 pc, UINT32 op) /* TST Rd, Rs */
486450{
487   UINT32 rs, rd;
488
489   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
490   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
451   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
452   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
491453   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
492454   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd) & GET_REGISTER(arm, rs)));
493455   R15 += 2;
494
495456}
496457
497const void tg04_00_09(arm_state *arm, UINT32 pc, UINT32 insn) /* NEG Rd, Rs */
458const void tg04_00_09(arm_state *arm, UINT32 pc, UINT32 op) /* NEG Rd, Rs */
498459{
499   UINT32 rn, rs, rd, rrs;
500
501   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
502   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
503   rrs = GET_REGISTER(arm, rs);
504   rn = 0 - rrs;
505   SET_REGISTER(arm, rd, rn);
460   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
461   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
462   UINT32 rrs = GET_REGISTER(arm, rs);
463   SET_REGISTER(arm, rd, 0 - rrs);
506464   HandleThumbALUSubFlags(GET_REGISTER(arm, rd), 0, rrs);
507
508465}
509466
510const void tg04_00_0a(arm_state *arm, UINT32 pc, UINT32 insn) /* CMP Rd, Rs */
467const void tg04_00_0a(arm_state *arm, UINT32 pc, UINT32 op) /* CMP Rd, Rs */
511468{
512   UINT32 rn, rs, rd;
513
514   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
515   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
516   rn = GET_REGISTER(arm, rd) - GET_REGISTER(arm, rs);
469   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
470   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
471   UINT32 rn = GET_REGISTER(arm, rd) - GET_REGISTER(arm, rs);
517472   HandleThumbALUSubFlags(rn, GET_REGISTER(arm, rd), GET_REGISTER(arm, rs));
518
519473}
520474
521
522const void tg04_00_0b(arm_state *arm, UINT32 pc, UINT32 insn) /* CMN Rd, Rs - check flags, add dasm */
475const void tg04_00_0b(arm_state *arm, UINT32 pc, UINT32 op) /* CMN Rd, Rs - check flags, add dasm */
523476{
524   UINT32 rn, rs, rd;
525
526   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
527   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
528   rn = GET_REGISTER(arm, rd) + GET_REGISTER(arm, rs);
477   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
478   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
479   UINT32 rn = GET_REGISTER(arm, rd) + GET_REGISTER(arm, rs);
529480   HandleThumbALUAddFlags(rn, GET_REGISTER(arm, rd), GET_REGISTER(arm, rs));
530
531481}
532482
533const void tg04_00_0c(arm_state *arm, UINT32 pc, UINT32 insn) /* ORR Rd, Rs */
483const void tg04_00_0c(arm_state *arm, UINT32 pc, UINT32 op) /* ORR Rd, Rs */
534484{
535   UINT32 rs, rd;
536
537   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
538   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
485   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
486   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
539487   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) | GET_REGISTER(arm, rs));
540488   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
541489   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
542490   R15 += 2;
543
544491}
545492
546const void tg04_00_0d(arm_state *arm, UINT32 pc, UINT32 insn) /* MUL Rd, Rs */
493const void tg04_00_0d(arm_state *arm, UINT32 pc, UINT32 op) /* MUL Rd, Rs */
547494{
548   UINT32 rn, rs, rd;
549
550   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
551   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
552   rn = GET_REGISTER(arm, rd) * GET_REGISTER(arm, rs);
495   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
496   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
497   UINT32 rn = GET_REGISTER(arm, rd) * GET_REGISTER(arm, rs);
553498   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
554499   SET_REGISTER(arm, rd, rn);
555500   SET_CPSR(GET_CPSR | HandleALUNZFlags(rn));
556501   R15 += 2;
557
558502}
559503
560const void tg04_00_0e(arm_state *arm, UINT32 pc, UINT32 insn) /* BIC Rd, Rs */
504const void tg04_00_0e(arm_state *arm, UINT32 pc, UINT32 op) /* BIC Rd, Rs */
561505{
562   UINT32 rs, rd;
563
564   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
565   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
506   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
507   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
566508   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) & (~GET_REGISTER(arm, rs)));
567509   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
568510   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
569511   R15 += 2;
570
571512}
572const void tg04_00_0f(arm_state *arm, UINT32 pc, UINT32 insn) /* MVN Rd, Rs */
573{
574   UINT32 rs, rd, op2;
575513
576   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
577   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
578   op2 = GET_REGISTER(arm, rs);
514const void tg04_00_0f(arm_state *arm, UINT32 pc, UINT32 op) /* MVN Rd, Rs */
515{
516   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
517   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
518   UINT32 op2 = GET_REGISTER(arm, rs);
579519   SET_REGISTER(arm, rd, ~op2);
580520   SET_CPSR(GET_CPSR & ~(Z_MASK | N_MASK));
581521   SET_CPSR(GET_CPSR | HandleALUNZFlags(GET_REGISTER(arm, rd)));
582522   R15 += 2;
583
584523}
585524
586525/* ADD Rd, Rs group */
587526
588const void tg04_01_00(arm_state *arm, UINT32 pc, UINT32 insn)
527const void tg04_01_00(arm_state *arm, UINT32 pc, UINT32 op)
589528{
590//  UINT32 rs, rd;
591//  rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
592//  rd = insn & THUMB_HIREG_RD;
593
594
595   fatalerror("%08x: G4-1-0 Undefined Thumb instruction: %04x %x\n", pc, insn, (insn & THUMB_HIREG_H) >> THUMB_HIREG_H_SHIFT);
596
597   R15 += 2;
598
529   fatalerror("%08x: G4-1-0 Undefined Thumb instruction: %04x %x\n", pc, op, (op & THUMB_HIREG_H) >> THUMB_HIREG_H_SHIFT);
599530}
600531
601const void tg04_01_01(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD Rd, HRs */
532const void tg04_01_01(arm_state *arm, UINT32 pc, UINT32 op) /* ADD Rd, HRs */
602533{
603   UINT32 rs, rd;
604   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
605   rd = insn & THUMB_HIREG_RD;
606
607
534   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
535   UINT32 rd = op & THUMB_HIREG_RD;
608536   SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) + GET_REGISTER(arm, rs+8));
609537   // emulate the effects of pre-fetch
610538   if (rs == 7)
r20737r20738
615543   R15 += 2;
616544}
617545
618const void tg04_01_02(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD HRd, Rs */
546const void tg04_01_02(arm_state *arm, UINT32 pc, UINT32 op) /* ADD HRd, Rs */
619547{
620   UINT32 rs, rd;
621   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
622   rd = insn & THUMB_HIREG_RD;
623
624
548   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
549   UINT32 rd = op & THUMB_HIREG_RD;
625550   SET_REGISTER(arm, rd+8, GET_REGISTER(arm, rd+8) + GET_REGISTER(arm, rs));
626551   if (rd == 7)
627552   {
r20737r20738
631556   R15 += 2;
632557}
633558
634const void tg04_01_03(arm_state *arm, UINT32 pc, UINT32 insn) /* Add HRd, HRs */
559const void tg04_01_03(arm_state *arm, UINT32 pc, UINT32 op) /* Add HRd, HRs */
635560{
636   UINT32 rs, rd;
637   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
638   rd = insn & THUMB_HIREG_RD;
639
640
561   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
562   UINT32 rd = op & THUMB_HIREG_RD;
641563   SET_REGISTER(arm, rd+8, GET_REGISTER(arm, rd+8) + GET_REGISTER(arm, rs+8));
642564   // emulate the effects of pre-fetch
643565   if (rs == 7)
r20737r20738
652574   R15 += 2;
653575}
654576
655
656const void tg04_01_10(arm_state *arm, UINT32 pc, UINT32 insn)  /* CMP Rd, Rs */
577const void tg04_01_10(arm_state *arm, UINT32 pc, UINT32 op)  /* CMP Rd, Rs */
657578{
658   UINT32 rn, rs, rd;
659
660   rs = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
661   rd = GET_REGISTER(arm, insn & THUMB_HIREG_RD);
662   rn = rd - rs;
579   UINT32 rs = GET_REGISTER(arm, ((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
580   UINT32 rd = GET_REGISTER(arm, op & THUMB_HIREG_RD);
581   UINT32 rn = rd - rs;
663582   HandleThumbALUSubFlags(rn, rd, rs);
664
665583}
666584
667const void tg04_01_11(arm_state *arm, UINT32 pc, UINT32 insn) /* CMP Rd, Hs */
585const void tg04_01_11(arm_state *arm, UINT32 pc, UINT32 op) /* CMP Rd, Hs */
668586{
669   UINT32 rn, rs, rd;
670
671   rs = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
672   rd = GET_REGISTER(arm, insn & THUMB_HIREG_RD);
673   rn = rd - rs;
587   UINT32 rs = GET_REGISTER(arm, ((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
588   UINT32 rd = GET_REGISTER(arm, op & THUMB_HIREG_RD);
589   UINT32 rn = rd - rs;
674590   HandleThumbALUSubFlags(rn, rd, rs);
675
676591}
677592
678const void tg04_01_12(arm_state *arm, UINT32 pc, UINT32 insn) /* CMP Hd, Rs */
593const void tg04_01_12(arm_state *arm, UINT32 pc, UINT32 op) /* CMP Hd, Rs */
679594{
680   UINT32 rn, rs, rd;
681
682   rs = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
683   rd = GET_REGISTER(arm, (insn & THUMB_HIREG_RD) + 8);
684   rn = rd - rs;
595   UINT32 rs = GET_REGISTER(arm, ((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
596   UINT32 rd = GET_REGISTER(arm, (op & THUMB_HIREG_RD) + 8);
597   UINT32 rn = rd - rs;
685598   HandleThumbALUSubFlags(rn, rd, rs);
686
687599}
688600
689const void tg04_01_13(arm_state *arm, UINT32 pc, UINT32 insn) /* CMP Hd, Hs */
601const void tg04_01_13(arm_state *arm, UINT32 pc, UINT32 op) /* CMP Hd, Hs */
690602{
691   UINT32 rn, rs, rd;
692
693   rs = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
694   rd = GET_REGISTER(arm, (insn & THUMB_HIREG_RD) + 8);
695   rn = rd - rs;
603   UINT32 rs = GET_REGISTER(arm, ((op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
604   UINT32 rd = GET_REGISTER(arm, (op & THUMB_HIREG_RD) + 8);
605   UINT32 rn = rd - rs;
696606   HandleThumbALUSubFlags(rn, rd, rs);
697
698607}
699608
700   /* MOV group */
609/* MOV group */
701610
702611// "The action of H1 = 0, H2 = 0 for Op = 00 (ADD), Op = 01 (CMP) and Op = 10 (MOV) is undefined, and should not be used."
703const void tg04_01_20(arm_state *arm, UINT32 pc, UINT32 insn) /* MOV Rd, Rs (undefined) */
612const void tg04_01_20(arm_state *arm, UINT32 pc, UINT32 op) /* MOV Rd, Rs (undefined) */
704613{
705   UINT32 rs, rd;
706
707
708   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
709   rd = insn & THUMB_HIREG_RD;
614   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
615   UINT32 rd = op & THUMB_HIREG_RD;
710616   SET_REGISTER(arm, rd, GET_REGISTER(arm, rs));
711617   R15 += 2;
712
713618}
714619
715const void tg04_01_21(arm_state *arm, UINT32 pc, UINT32 insn) /* MOV Rd, Hs */
620const void tg04_01_21(arm_state *arm, UINT32 pc, UINT32 op) /* MOV Rd, Hs */
716621{
717   UINT32 rs, rd;
718
719   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
720   rd = insn & THUMB_HIREG_RD;
622   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
623   UINT32 rd = op & THUMB_HIREG_RD;
624   SET_REGISTER(arm, rd, GET_REGISTER(arm, rs + 8));
721625   if (rs == 7)
722626   {
723      SET_REGISTER(arm, rd, GET_REGISTER(arm, rs + 8) + 4);
627      SET_REGISTER(arm, rd, GET_REGISTER(arm, rd) + 4);
724628   }
725   else
726   {
727      SET_REGISTER(arm, rd, GET_REGISTER(arm, rs + 8));
728   }
729629   R15 += 2;
730
731630}
732631
733const void tg04_01_22(arm_state *arm, UINT32 pc, UINT32 insn) /* MOV Hd, Rs */
632const void tg04_01_22(arm_state *arm, UINT32 pc, UINT32 op) /* MOV Hd, Rs */
734633{
735   UINT32 rs, rd;
736
737   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
738   rd = insn & THUMB_HIREG_RD;
634   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
635   UINT32 rd = op & THUMB_HIREG_RD;
739636   SET_REGISTER(arm, rd + 8, GET_REGISTER(arm, rs));
740637   if (rd != 7)
741638   {
r20737r20738
745642   {
746643      R15 &= ~1;
747644   }
748
749645}
750646
751const void tg04_01_23(arm_state *arm, UINT32 pc, UINT32 insn) /* MOV Hd, Hs */
647const void tg04_01_23(arm_state *arm, UINT32 pc, UINT32 op) /* MOV Hd, Hs */
752648{
753   UINT32 rs, rd;
754
755   rs = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
756   rd = insn & THUMB_HIREG_RD;
649   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
650   UINT32 rd = op & THUMB_HIREG_RD;
757651   if (rs == 7)
758652   {
759653      SET_REGISTER(arm, rd + 8, GET_REGISTER(arm, rs+8)+4);
r20737r20738
766660   {
767661      R15 += 2;
768662   }
769   if (rd == 7)
663   else
770664   {
771665      R15 &= ~1;
772666   }
773
774667}
775668
776
777const void tg04_01_30(arm_state *arm, UINT32 pc, UINT32 insn)
669const void tg04_01_30(arm_state *arm, UINT32 pc, UINT32 op)
778670{
779   UINT32 addr;
780   UINT32 rd;
781
782
783   rd = (insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
784   addr = GET_REGISTER(arm, rd);
671   UINT32 rd = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
672   UINT32 addr = GET_REGISTER(arm, rd);
785673   if (addr & 1)
786674   {
787675      addr &= ~1;
r20737r20738
795683      }
796684   }
797685   R15 = addr;
798
799686}
800687
801const void tg04_01_31(arm_state *arm, UINT32 pc, UINT32 insn)
688const void tg04_01_31(arm_state *arm, UINT32 pc, UINT32 op)
802689{
803   UINT32 addr;
804
805
806   addr = GET_REGISTER(arm, ((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8);
807   if ((((insn & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT) + 8) == 15)
690   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
691   UINT32 addr = GET_REGISTER(arm, rs+8);
692   if (rs == 7)
808693   {
809694      addr += 2;
810695   }
r20737r20738
821706      }
822707   }
823708   R15 = addr;
824
825709}
826710
827const void tg04_01_32(arm_state *arm, UINT32 pc, UINT32 insn)
711const void tg04_01_32(arm_state *arm, UINT32 pc, UINT32 op)
828712{
829//  UINT32 addr;
830//  UINT32 rd;
831
832
833   fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, insn);
834   R15 += 2;
835
713   fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, op);
836714}
837715
838const void tg04_01_33(arm_state *arm, UINT32 pc, UINT32 insn)
716const void tg04_01_33(arm_state *arm, UINT32 pc, UINT32 op)
839717{
840//  UINT32 addr;
841//  UINT32 rd;
842
843
844   fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, insn);
845   R15 += 2;
846
718   fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, op);
847719}
848720
849
850
851
852
853
854const void tg04_0203(arm_state *arm, UINT32 pc, UINT32 insn)
721const void tg04_0203(arm_state *arm, UINT32 pc, UINT32 op)
855722{
856   UINT32 readword;
857
858   readword = READ32((R15 & ~2) + 4 + ((insn & THUMB_INSN_IMM) << 2));
859   SET_REGISTER(arm, (insn & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, readword);
723   UINT32 readword = READ32((R15 & ~2) + 4 + ((op & THUMB_INSN_IMM) << 2));
724   SET_REGISTER(arm, (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT, readword);
860725   R15 += 2;
861726}
862727
863728/* LDR* STR* group */
864729
865const void tg05_0(arm_state *arm, UINT32 pc, UINT32 insn)  /* STR Rd, [Rn, Rm] */
730const void tg05_0(arm_state *arm, UINT32 pc, UINT32 op)  /* STR Rd, [Rn, Rm] */
866731{
867   UINT32 addr;
868   UINT32 rm, rn, rd;
869
870   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
871   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
872   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
873   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
732   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
733   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
734   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
735   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
874736   WRITE32(addr, GET_REGISTER(arm, rd));
875737   R15 += 2;
876
877738}
878739
879const void tg05_1(arm_state *arm, UINT32 pc, UINT32 insn)  /* STRH Rd, [Rn, Rm] */
740const void tg05_1(arm_state *arm, UINT32 pc, UINT32 op)  /* STRH Rd, [Rn, Rm] */
880741{
881   UINT32 addr;
882   UINT32 rm, rn, rd;
883
884   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
885   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
886   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
887   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
742   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
743   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
744   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
745   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
888746   WRITE16(addr, GET_REGISTER(arm, rd));
889747   R15 += 2;
890
891748}
892749
893const void tg05_2(arm_state *arm, UINT32 pc, UINT32 insn)  /* STRB Rd, [Rn, Rm] */
750const void tg05_2(arm_state *arm, UINT32 pc, UINT32 op)  /* STRB Rd, [Rn, Rm] */
894751{
895   UINT32 addr;
896   UINT32 rm, rn, rd;
897
898   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
899   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
900   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
901   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
752   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
753   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
754   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
755   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
902756   WRITE8(addr, GET_REGISTER(arm, rd));
903757   R15 += 2;
904
905758}
906759
907const void tg05_3(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDSB Rd, [Rn, Rm] todo, add dasm */
760const void tg05_3(arm_state *arm, UINT32 pc, UINT32 op)  /* LDSB Rd, [Rn, Rm] todo, add dasm */
908761{
909   UINT32 addr;
910   UINT32 rm, rn, rd, op2;
911
912   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
913   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
914   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
915   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
916   op2 = READ8(addr);
762   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
763   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
764   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
765   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
766   UINT32 op2 = READ8(addr);
917767   if (op2 & 0x00000080)
918768   {
919769      op2 |= 0xffffff00;
920770   }
921771   SET_REGISTER(arm, rd, op2);
922772   R15 += 2;
923
924773}
925774
926const void tg05_4(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDR Rd, [Rn, Rm] */
775const void tg05_4(arm_state *arm, UINT32 pc, UINT32 op)  /* LDR Rd, [Rn, Rm] */
927776{
928   UINT32 addr;
929   UINT32 rm, rn, rd, op2;
930
931   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
932   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
933   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
934   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
935   op2 = READ32(addr);
777   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
778   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
779   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
780   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
781   UINT32 op2 = READ32(addr);
936782   SET_REGISTER(arm, rd, op2);
937783   R15 += 2;
938
939784}
940785
941const void tg05_5(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDRH Rd, [Rn, Rm] */
786const void tg05_5(arm_state *arm, UINT32 pc, UINT32 op)  /* LDRH Rd, [Rn, Rm] */
942787{
943   UINT32 addr;
944   UINT32 rm, rn, rd, op2;
945
946   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
947   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
948   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
949   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
950   op2 = READ16(addr);
788   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
789   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
790   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
791   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
792   UINT32 op2 = READ16(addr);
951793   SET_REGISTER(arm, rd, op2);
952794   R15 += 2;
953
954795}
955796
956const void tg05_6(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDRB Rd, [Rn, Rm] */
797const void tg05_6(arm_state *arm, UINT32 pc, UINT32 op)  /* LDRB Rd, [Rn, Rm] */
957798{
958   UINT32 addr;
959   UINT32 rm, rn, rd, op2;
960
961   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
962   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
963   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
964   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
965   op2 = READ8(addr);
799   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
800   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
801   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
802   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
803   UINT32 op2 = READ8(addr);
966804   SET_REGISTER(arm, rd, op2);
967805   R15 += 2;
968
969806}
970807
971const void tg05_7(arm_state *arm, UINT32 pc, UINT32 insn)  /* LDSH Rd, [Rn, Rm] */
808const void tg05_7(arm_state *arm, UINT32 pc, UINT32 op)  /* LDSH Rd, [Rn, Rm] */
972809{
973   UINT32 addr;
974   UINT32 rm, rn, rd, op2;
975
976   rm = (insn & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
977   rn = (insn & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
978   rd = (insn & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
979   addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
980   op2 = READ16(addr);
810   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
811   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
812   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
813   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
814   UINT32 op2 = READ16(addr);
981815   if (op2 & 0x00008000)
982816   {
983817      op2 |= 0xffff0000;
984818   }
985819   SET_REGISTER(arm, rd, op2);
986820   R15 += 2;
987
988821}
989822
990823   /* Word Store w/ Immediate Offset */
991824
992const void tg06_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
825const void tg06_0(arm_state *arm, UINT32 pc, UINT32 op) /* Store */
993826{
994   UINT32 rn, rd;
995   INT32 offs;
996
997   rn = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
998   rd = insn & THUMB_ADDSUB_RD;
999   offs = ((insn & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
827   UINT32 rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
828   UINT32 rd = op & THUMB_ADDSUB_RD;
829   INT32 offs = ((op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
1000830   WRITE32(GET_REGISTER(arm, rn) + offs, GET_REGISTER(arm, rd));
1001831   R15 += 2;
1002832}
1003833
1004const void tg06_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Load */
834const void tg06_1(arm_state *arm, UINT32 pc, UINT32 op) /* Load */
1005835{
1006   UINT32 rn, rd;
1007   INT32 offs;
1008
1009   rn = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1010   rd = insn & THUMB_ADDSUB_RD;
1011   offs = ((insn & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
836   UINT32 rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
837   UINT32 rd = op & THUMB_ADDSUB_RD;
838   INT32 offs = ((op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
1012839   SET_REGISTER(arm, rd, READ32(GET_REGISTER(arm, rn) + offs)); // fix
1013840   R15 += 2;
1014841}
1015842
1016843/* Byte Store w/ Immeidate Offset */
1017844
1018const void tg07_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
845const void tg07_0(arm_state *arm, UINT32 pc, UINT32 op) /* Store */
1019846{
1020   UINT32 rn, rd;
1021   INT32 offs;
1022
1023   rn = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1024   rd = insn & THUMB_ADDSUB_RD;
1025   offs = (insn & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
847   UINT32 rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
848   UINT32 rd = op & THUMB_ADDSUB_RD;
849   INT32 offs = (op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
1026850   WRITE8(GET_REGISTER(arm, rn) + offs, GET_REGISTER(arm, rd));
1027851   R15 += 2;
1028852}
1029853
1030const void tg07_1(arm_state *arm, UINT32 pc, UINT32 insn)  /* Load */
854const void tg07_1(arm_state *arm, UINT32 pc, UINT32 op)  /* Load */
1031855{
1032   UINT32 rn, rd;
1033   INT32 offs;
1034
1035   rn = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1036   rd = insn & THUMB_ADDSUB_RD;
1037   offs = (insn & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
856   UINT32 rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
857   UINT32 rd = op & THUMB_ADDSUB_RD;
858   INT32 offs = (op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
1038859   SET_REGISTER(arm, rd, READ8(GET_REGISTER(arm, rn) + offs));
1039860   R15 += 2;
1040861}
1041862
1042863/* Load/Store Halfword */
1043864
1044const void tg08_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
865const void tg08_0(arm_state *arm, UINT32 pc, UINT32 op) /* Store */
1045866{
1046   UINT32 rs, rd, imm;
1047
1048   imm = (insn & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
1049   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1050   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
867   UINT32 imm = (op & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
868   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
869   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
1051870   WRITE16(GET_REGISTER(arm, rs) + (imm << 1), GET_REGISTER(arm, rd));
1052871   R15 += 2;
1053872}
1054873
1055const void tg08_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Load */
874const void tg08_1(arm_state *arm, UINT32 pc, UINT32 op) /* Load */
1056875{
1057   UINT32 rs, rd, imm;
1058
1059   imm = (insn & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
1060   rs = (insn & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1061   rd = (insn & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
876   UINT32 imm = (op & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
877   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
878   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
1062879   SET_REGISTER(arm, rd, READ16(GET_REGISTER(arm, rs) + (imm << 1)));
1063880   R15 += 2;
1064881}
1065882
1066   /* Stack-Relative Load/Store */
883/* Stack-Relative Load/Store */
1067884
1068const void tg09_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
885const void tg09_0(arm_state *arm, UINT32 pc, UINT32 op) /* Store */
1069886{
1070   UINT32 rd;
1071   INT32 offs;
1072
1073   rd = (insn & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
1074   offs = (UINT8)(insn & THUMB_INSN_IMM);
887   UINT32 rd = (op & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
888   INT32 offs = (UINT8)(op & THUMB_INSN_IMM);
1075889   WRITE32(GET_REGISTER(arm, 13) + ((UINT32)offs << 2), GET_REGISTER(arm, rd));
1076890   R15 += 2;
1077891}
1078892
1079const void tg09_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Load */
893const void tg09_1(arm_state *arm, UINT32 pc, UINT32 op) /* Load */
1080894{
1081   UINT32 readword;
1082   UINT32 rd;
1083   INT32 offs;
1084
1085   rd = (insn & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
1086   offs = (UINT8)(insn & THUMB_INSN_IMM);
1087   readword = READ32(GET_REGISTER(arm, 13) + ((UINT32)offs << 2));
895   UINT32 rd = (op & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
896   INT32 offs = (UINT8)(op & THUMB_INSN_IMM);
897   UINT32 readword = READ32(GET_REGISTER(arm, 13) + ((UINT32)offs << 2));
1088898   SET_REGISTER(arm, rd, readword);
1089899   R15 += 2;
1090900}
1091901
1092   /* Get relative address */
902/* Get relative address */
1093903
1094const void tg0a_0(arm_state *arm, UINT32 pc, UINT32 insn)  /* ADD Rd, PC, #nn */
904const void tg0a_0(arm_state *arm, UINT32 pc, UINT32 op)  /* ADD Rd, PC, #nn */
1095905{
1096   UINT32 rd;
1097   INT32 offs;
1098
1099   rd = (insn & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
1100   offs = (UINT8)(insn & THUMB_INSN_IMM) << 2;
906   UINT32 rd = (op & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
907   INT32 offs = (UINT8)(op & THUMB_INSN_IMM) << 2;
1101908   SET_REGISTER(arm, rd, ((R15 + 4) & ~2) + offs);
1102909   R15 += 2;
1103910}
1104911
1105const void tg0a_1(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD Rd, SP, #nn */
912const void tg0a_1(arm_state *arm, UINT32 pc, UINT32 op) /* ADD Rd, SP, #nn */
1106913{
1107   UINT32 rd;
1108   INT32 offs;
1109
1110   rd = (insn & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
1111   offs = (UINT8)(insn & THUMB_INSN_IMM) << 2;
914   UINT32 rd = (op & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
915   INT32 offs = (UINT8)(op & THUMB_INSN_IMM) << 2;
1112916   SET_REGISTER(arm, rd, GET_REGISTER(arm, 13) + offs);
1113917   R15 += 2;
1114918}
1115919
1116920   /* Stack-Related Opcodes */
1117921
1118const void tg0b_0(arm_state *arm, UINT32 pc, UINT32 insn) /* ADD SP, #imm */
922const void tg0b_0(arm_state *arm, UINT32 pc, UINT32 op) /* ADD SP, #imm */
1119923{
1120   UINT32 addr;
1121
1122
1123   addr = (insn & THUMB_INSN_IMM);
924   UINT32 addr = (op & THUMB_INSN_IMM);
1124925   addr &= ~THUMB_INSN_IMM_S;
1125   SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + ((insn & THUMB_INSN_IMM_S) ? -(addr << 2) : (addr << 2)));
926   SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + ((op & THUMB_INSN_IMM_S) ? -(addr << 2) : (addr << 2)));
1126927   R15 += 2;
1127
1128928}
1129929
1130const void tg0b_1(arm_state *arm, UINT32 pc, UINT32 insn)
930const void tg0b_1(arm_state *arm, UINT32 pc, UINT32 op)
1131931{
1132//  UINT32 addr;
1133//  INT32 offs;
1134
1135   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1136   R15 += 2;
1137
932   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1138933}
1139934
1140const void tg0b_2(arm_state *arm, UINT32 pc, UINT32 insn)
935const void tg0b_2(arm_state *arm, UINT32 pc, UINT32 op)
1141936{
1142//  UINT32 addr;
1143//  INT32 offs;
1144
1145   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1146   R15 += 2;
1147
937   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1148938}
1149939
1150const void tg0b_3(arm_state *arm, UINT32 pc, UINT32 insn)
940const void tg0b_3(arm_state *arm, UINT32 pc, UINT32 op)
1151941{
1152//  UINT32 addr;
1153//  INT32 offs;
1154
1155   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1156   R15 += 2;
1157
942   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1158943}
1159944
1160const void tg0b_4(arm_state *arm, UINT32 pc, UINT32 insn) /* PUSH {Rlist} */
945const void tg0b_4(arm_state *arm, UINT32 pc, UINT32 op) /* PUSH {Rlist} */
1161946{
1162   INT32 offs;
1163
1164   for (offs = 7; offs >= 0; offs--)
947   for (INT32 offs = 7; offs >= 0; offs--)
1165948   {
1166      if (insn & (1 << offs))
949      if (op & (1 << offs))
1167950      {
1168951         SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) - 4);
1169952         WRITE32(GET_REGISTER(arm, 13), GET_REGISTER(arm, offs));
1170953      }
1171954   }
1172955   R15 += 2;
1173
1174956}
1175957
1176const void tg0b_5(arm_state *arm, UINT32 pc, UINT32 insn) /* PUSH {Rlist}{LR} */
958const void tg0b_5(arm_state *arm, UINT32 pc, UINT32 op) /* PUSH {Rlist}{LR} */
1177959{
1178   INT32 offs;
1179
1180960   SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) - 4);
1181961   WRITE32(GET_REGISTER(arm, 13), GET_REGISTER(arm, 14));
1182   for (offs = 7; offs >= 0; offs--)
962   for (INT32 offs = 7; offs >= 0; offs--)
1183963   {
1184      if (insn & (1 << offs))
964      if (op & (1 << offs))
1185965      {
1186966         SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) - 4);
1187967         WRITE32(GET_REGISTER(arm, 13), GET_REGISTER(arm, offs));
1188968      }
1189969   }
1190970   R15 += 2;
1191
1192971}
1193972
1194const void tg0b_6(arm_state *arm, UINT32 pc, UINT32 insn)
973const void tg0b_6(arm_state *arm, UINT32 pc, UINT32 op)
1195974{
1196//  UINT32 addr;
1197//  INT32 offs;
1198
1199   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1200   R15 += 2;
1201
975   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1202976}
1203977
1204const void tg0b_7(arm_state *arm, UINT32 pc, UINT32 insn)
978const void tg0b_7(arm_state *arm, UINT32 pc, UINT32 op)
1205979{
1206//  UINT32 addr;
1207//  INT32 offs;
1208
1209   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1210   R15 += 2;
1211
980   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1212981}
1213982
1214const void tg0b_8(arm_state *arm, UINT32 pc, UINT32 insn)
983const void tg0b_8(arm_state *arm, UINT32 pc, UINT32 op)
1215984{
1216//  UINT32 addr;
1217//  INT32 offs;
1218
1219   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1220   R15 += 2;
1221
985   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1222986}
1223987
1224const void tg0b_9(arm_state *arm, UINT32 pc, UINT32 insn)
988const void tg0b_9(arm_state *arm, UINT32 pc, UINT32 op)
1225989{
1226//  UINT32 addr;
1227//  INT32 offs;
1228
1229   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1230   R15 += 2;
1231
990   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1232991}
1233992
1234const void tg0b_a(arm_state *arm, UINT32 pc, UINT32 insn)
993const void tg0b_a(arm_state *arm, UINT32 pc, UINT32 op)
1235994{
1236//  UINT32 addr;
1237//  INT32 offs;
1238
1239   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1240   R15 += 2;
1241
995   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1242996}
1243997
1244const void tg0b_b(arm_state *arm, UINT32 pc, UINT32 insn)
998const void tg0b_b(arm_state *arm, UINT32 pc, UINT32 op)
1245999{
1246//  UINT32 addr;
1247//  INT32 offs;
1248
1249   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1250   R15 += 2;
1251
1000   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
12521001}
12531002
1254const void tg0b_c(arm_state *arm, UINT32 pc, UINT32 insn) /* POP {Rlist} */
1003const void tg0b_c(arm_state *arm, UINT32 pc, UINT32 op) /* POP {Rlist} */
12551004{
1256   INT32 offs;
1257
1258   for (offs = 0; offs < 8; offs++)
1005   for (INT32 offs = 0; offs < 8; offs++)
12591006   {
1260      if (insn & (1 << offs))
1007      if (op & (1 << offs))
12611008      {
12621009         SET_REGISTER(arm, offs, READ32(GET_REGISTER(arm, 13)));
12631010         SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + 4);
12641011      }
12651012   }
12661013   R15 += 2;
1267
12681014}
12691015
1270const void tg0b_d(arm_state *arm, UINT32 pc, UINT32 insn) /* POP {Rlist}{PC} */
1016const void tg0b_d(arm_state *arm, UINT32 pc, UINT32 op) /* POP {Rlist}{PC} */
12711017{
1272   INT32 offs;
1273
1274   for (offs = 0; offs < 8; offs++)
1018   for (INT32 offs = 0; offs < 8; offs++)
12751019   {
1276      if (insn & (1 << offs))
1020      if (op & (1 << offs))
12771021      {
12781022         SET_REGISTER(arm, offs, READ32(GET_REGISTER(arm, 13)));
12791023         SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + 4);
12801024      }
12811025   }
12821026   UINT32 addr = READ32(GET_REGISTER(arm, 13));
1283   // in v4T, bit 0 is ignored.  v5 and later, it's an ARM/Thumb flag like the BX instruction
12841027   if (arm->archRev < 5)
12851028   {
12861029      R15 = addr & ~1;
r20737r20738
13031046      R15 = addr;
13041047   }
13051048   SET_REGISTER(arm, 13, GET_REGISTER(arm, 13) + 4);
1306
13071049}
13081050
1309const void tg0b_e(arm_state *arm, UINT32 pc, UINT32 insn)
1051const void tg0b_e(arm_state *arm, UINT32 pc, UINT32 op)
13101052{
1311//  UINT32 addr;
1312//  INT32 offs;
1313
1314   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1315   R15 += 2;
1316
1053   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
13171054}
13181055
1319const void tg0b_f(arm_state *arm, UINT32 pc, UINT32 insn)
1056const void tg0b_f(arm_state *arm, UINT32 pc, UINT32 op)
13201057{
1321//  UINT32 addr;
1322//  INT32 offs;
1323
1324   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, insn);
1325   R15 += 2;
1326
1058   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
13271059}
13281060
13291061/* Multiple Load/Store */
r20737r20738
13341066// GBA "BB Ball" performs an unaligned read with A[1:0] = 2 and expects A[1] not to be ignored [BP 800B90A,(R4&3)!=0]
13351067// GBA "Gadget Racers" performs an unaligned read with A[1:0] = 1 and expects A[0] to be ignored [BP B72,(R0&3)!=0]
13361068
1337const void tg0c_0(arm_state *arm, UINT32 pc, UINT32 insn) /* Store */
1069const void tg0c_0(arm_state *arm, UINT32 pc, UINT32 op) /* Store */
13381070{
1339   UINT32 rd;
1340   INT32 offs;
1341
1342   UINT32 ld_st_address;
1343
1344   rd = (insn & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
1345
1346
1347   ld_st_address = GET_REGISTER(arm, rd);
1348
1349   for (offs = 0; offs < 8; offs++)
1071   UINT32 rd = (op & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
1072   UINT32 ld_st_address = GET_REGISTER(arm, rd);
1073   for (INT32 offs = 0; offs < 8; offs++)
13501074   {
1351      if (insn & (1 << offs))
1075      if (op & (1 << offs))
13521076      {
13531077         WRITE32(ld_st_address & ~3, GET_REGISTER(arm, offs));
13541078         ld_st_address += 4;
r20737r20738
13581082   R15 += 2;
13591083}
13601084
1361
1362const void tg0c_1(arm_state *arm, UINT32 pc, UINT32 insn) /* Load */
1085const void tg0c_1(arm_state *arm, UINT32 pc, UINT32 op) /* Load */
13631086{
1364   UINT32 rd;
1365   INT32 offs;
1366
1367   UINT32 ld_st_address;
1368
1369   rd = (insn & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
1370
1371
1372   ld_st_address = GET_REGISTER(arm, rd);
1373
1374
1375   int rd_in_list;
1376
1377   rd_in_list = insn & (1 << rd);
1378   for (offs = 0; offs < 8; offs++)
1087   UINT32 rd = (op & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
1088   int rd_in_list = op & (1 << rd);
1089   UINT32 ld_st_address = GET_REGISTER(arm, rd);
1090   for (INT32 offs = 0; offs < 8; offs++)
13791091   {
1380      if (insn & (1 << offs))
1092      if (op & (1 << offs))
13811093      {
13821094         SET_REGISTER(arm, offs, READ32(ld_st_address & ~1));
13831095         ld_st_address += 4;
13841096      }
13851097   }
1386
13871098   if (!rd_in_list)
1099   {
13881100      SET_REGISTER(arm, rd, ld_st_address);
1389
1101   }
13901102   R15 += 2;
13911103}
13921104
13931105/* Conditional Branch */
13941106
1395const void tg0d_0(arm_state *arm, UINT32 pc, UINT32 insn) // COND_EQ:
1107const void tg0d_0(arm_state *arm, UINT32 pc, UINT32 op) // COND_EQ:
13961108{
1397   INT32 offs;
1398
1399   offs = (INT8)(insn & THUMB_INSN_IMM);
1400//case
1109   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
14011110   if (Z_IS_SET(GET_CPSR))
14021111   {
14031112      R15 += 4 + (offs << 1);
r20737r20738
14091118
14101119}
14111120
1412const void tg0d_1(arm_state *arm, UINT32 pc, UINT32 insn) // COND_NE:
1121const void tg0d_1(arm_state *arm, UINT32 pc, UINT32 op) // COND_NE:
14131122{
1414   INT32 offs;
1415
1416   offs = (INT8)(insn & THUMB_INSN_IMM);
1417//case
1123   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
14181124   if (Z_IS_CLEAR(GET_CPSR))
14191125   {
14201126      R15 += 4 + (offs << 1);
r20737r20738
14231129   {
14241130      R15 += 2;
14251131   }
1426
14271132}
14281133
1429const void tg0d_2(arm_state *arm, UINT32 pc, UINT32 insn) // COND_CS:
1134const void tg0d_2(arm_state *arm, UINT32 pc, UINT32 op) // COND_CS:
14301135{
1431   INT32 offs;
1432
1433   offs = (INT8)(insn & THUMB_INSN_IMM);
1434//case
1136   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
14351137   if (C_IS_SET(GET_CPSR))
14361138   {
14371139      R15 += 4 + (offs << 1);
r20737r20738
14401142   {
14411143      R15 += 2;
14421144   }
1443
14441145}
14451146
1446const void tg0d_3(arm_state *arm, UINT32 pc, UINT32 insn) // COND_CC:
1147const void tg0d_3(arm_state *arm, UINT32 pc, UINT32 op) // COND_CC:
14471148{
1448   INT32 offs;
1449
1450   offs = (INT8)(insn & THUMB_INSN_IMM);
1451//case
1149   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
14521150   if (C_IS_CLEAR(GET_CPSR))
14531151   {
14541152      R15 += 4 + (offs << 1);
r20737r20738
14571155   {
14581156      R15 += 2;
14591157   }
1460
14611158}
14621159
1463const void tg0d_4(arm_state *arm, UINT32 pc, UINT32 insn) // COND_MI:
1160const void tg0d_4(arm_state *arm, UINT32 pc, UINT32 op) // COND_MI:
14641161{
1465   INT32 offs;
1466
1467   offs = (INT8)(insn & THUMB_INSN_IMM);
1468//case
1162   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
14691163   if (N_IS_SET(GET_CPSR))
14701164   {
14711165      R15 += 4 + (offs << 1);
r20737r20738
14741168   {
14751169      R15 += 2;
14761170   }
1477
14781171}
14791172
1480const void tg0d_5(arm_state *arm, UINT32 pc, UINT32 insn) // COND_PL:
1173const void tg0d_5(arm_state *arm, UINT32 pc, UINT32 op) // COND_PL:
14811174{
1482   INT32 offs;
1483
1484   offs = (INT8)(insn & THUMB_INSN_IMM);
1485//case
1175   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
14861176   if (N_IS_CLEAR(GET_CPSR))
14871177   {
14881178      R15 += 4 + (offs << 1);
r20737r20738
14911181   {
14921182      R15 += 2;
14931183   }
1494
14951184}
14961185
1497const void tg0d_6(arm_state *arm, UINT32 pc, UINT32 insn) // COND_VS:
1186const void tg0d_6(arm_state *arm, UINT32 pc, UINT32 op) // COND_VS:
14981187{
1499   INT32 offs;
1500
1501   offs = (INT8)(insn & THUMB_INSN_IMM);
1502//case
1188   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
15031189   if (V_IS_SET(GET_CPSR))
15041190   {
15051191      R15 += 4 + (offs << 1);
r20737r20738
15081194   {
15091195      R15 += 2;
15101196   }
1511
15121197}
15131198
1514const void tg0d_7(arm_state *arm, UINT32 pc, UINT32 insn) // COND_VC:
1199const void tg0d_7(arm_state *arm, UINT32 pc, UINT32 op) // COND_VC:
15151200{
1516   INT32 offs;
1517
1518   offs = (INT8)(insn & THUMB_INSN_IMM);
1519//case
1201   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
15201202   if (V_IS_CLEAR(GET_CPSR))
15211203   {
15221204      R15 += 4 + (offs << 1);
r20737r20738
15251207   {
15261208      R15 += 2;
15271209   }
1528
15291210}
15301211
1531const void tg0d_8(arm_state *arm, UINT32 pc, UINT32 insn) // COND_HI:
1212const void tg0d_8(arm_state *arm, UINT32 pc, UINT32 op) // COND_HI:
15321213{
1533   INT32 offs;
1534
1535   offs = (INT8)(insn & THUMB_INSN_IMM);
1536//case
1214   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
15371215   if (C_IS_SET(GET_CPSR) && Z_IS_CLEAR(GET_CPSR))
15381216   {
15391217      R15 += 4 + (offs << 1);
r20737r20738
15421220   {
15431221      R15 += 2;
15441222   }
1545
15461223}
15471224
1548const void tg0d_9(arm_state *arm, UINT32 pc, UINT32 insn) // COND_LS:
1225const void tg0d_9(arm_state *arm, UINT32 pc, UINT32 op) // COND_LS:
15491226{
1550   INT32 offs;
1551
1552   offs = (INT8)(insn & THUMB_INSN_IMM);
1553//case
1227   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
15541228   if (C_IS_CLEAR(GET_CPSR) || Z_IS_SET(GET_CPSR))
15551229   {
15561230      R15 += 4 + (offs << 1);
r20737r20738
15591233   {
15601234      R15 += 2;
15611235   }
1562
15631236}
15641237
1565const void tg0d_a(arm_state *arm, UINT32 pc, UINT32 insn) // COND_GE:
1238const void tg0d_a(arm_state *arm, UINT32 pc, UINT32 op) // COND_GE:
15661239{
1567   INT32 offs;
1568
1569   offs = (INT8)(insn & THUMB_INSN_IMM);
1570//case
1240   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
15711241   if (!(GET_CPSR & N_MASK) == !(GET_CPSR & V_MASK))
15721242   {
15731243      R15 += 4 + (offs << 1);
r20737r20738
15761246   {
15771247      R15 += 2;
15781248   }
1579
15801249}
15811250
1582const void tg0d_b(arm_state *arm, UINT32 pc, UINT32 insn) // COND_LT:
1251const void tg0d_b(arm_state *arm, UINT32 pc, UINT32 op) // COND_LT:
15831252{
1584   INT32 offs;
1585
1586   offs = (INT8)(insn & THUMB_INSN_IMM);
1587//case
1253   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
15881254   if (!(GET_CPSR & N_MASK) != !(GET_CPSR & V_MASK))
15891255   {
15901256      R15 += 4 + (offs << 1);
r20737r20738
15931259   {
15941260      R15 += 2;
15951261   }
1596
15971262}
15981263
1599const void tg0d_c(arm_state *arm, UINT32 pc, UINT32 insn) // COND_GT:
1264const void tg0d_c(arm_state *arm, UINT32 pc, UINT32 op) // COND_GT:
16001265{
1601   INT32 offs;
1602
1603   offs = (INT8)(insn & THUMB_INSN_IMM);
1604//case
1266   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
16051267   if (Z_IS_CLEAR(GET_CPSR) && !(GET_CPSR & N_MASK) == !(GET_CPSR & V_MASK))
16061268   {
16071269      R15 += 4 + (offs << 1);
r20737r20738
16101272   {
16111273      R15 += 2;
16121274   }
1613
16141275}
16151276
1616const void tg0d_d(arm_state *arm, UINT32 pc, UINT32 insn) // COND_LE:
1277const void tg0d_d(arm_state *arm, UINT32 pc, UINT32 op) // COND_LE:
16171278{
1618   INT32 offs;
1619
1620   offs = (INT8)(insn & THUMB_INSN_IMM);
1621//case
1279   INT32 offs = (INT8)(op & THUMB_INSN_IMM);
16221280   if (Z_IS_SET(GET_CPSR) || !(GET_CPSR & N_MASK) != !(GET_CPSR & V_MASK))
16231281   {
16241282      R15 += 4 + (offs << 1);
r20737r20738
16271285   {
16281286      R15 += 2;
16291287   }
1630
16311288}
16321289
1633const void tg0d_e(arm_state *arm, UINT32 pc, UINT32 insn) // COND_AL:
1290const void tg0d_e(arm_state *arm, UINT32 pc, UINT32 op) // COND_AL:
16341291{
1635//  INT32 offs;
1636
1637//    offs = (INT8)(insn & THUMB_INSN_IMM);
1638//case
1639   fatalerror("%08x: Undefined Thumb instruction: %04x (ARM9 reserved)\n", pc, insn);
1640   R15 += 2;
1641
1292   fatalerror("%08x: Undefined Thumb instruction: %04x (ARM9 reserved)\n", pc, op);
16421293}
16431294
1644const void tg0d_f(arm_state *arm, UINT32 pc, UINT32 insn) // COND_NV:   // SWI (this is sort of a "hole" in the opcode encoding)
1295const void tg0d_f(arm_state *arm, UINT32 pc, UINT32 op) // COND_NV:   // SWI (this is sort of a "hole" in the opcode encoding)
16451296{
1646//  INT32 offs;
1647
1648//    offs = (INT8)(insn & THUMB_INSN_IMM);
1649
1650//case
16511297   arm->pendingSwi = 1;
16521298   ARM7_CHECKIRQ;
1653
16541299}
16551300
1656   /* B #offs */
1301/* B #offs */
16571302
1658const void tg0e_0(arm_state *arm, UINT32 pc, UINT32 insn)
1303const void tg0e_0(arm_state *arm, UINT32 pc, UINT32 op)
16591304{
1660   INT32 offs;
1661
1662   offs = (insn & THUMB_BRANCH_OFFS) << 1;
1305   INT32 offs = (op & THUMB_BRANCH_OFFS) << 1;
16631306   if (offs & 0x00000800)
16641307   {
16651308      offs |= 0xfffff800;
r20737r20738
16671310   R15 += 4 + offs;
16681311}
16691312
1670
1671const void tg0e_1(arm_state *arm, UINT32 pc, UINT32 insn)
1313const void tg0e_1(arm_state *arm, UINT32 pc, UINT32 op)
16721314{
1673   UINT32 addr;
1674
1675   addr = GET_REGISTER(arm, 14);
1676   addr += (insn & THUMB_BLOP_OFFS) << 1;
1315   UINT32 addr = GET_REGISTER(arm, 14);
1316   addr += (op & THUMB_BLOP_OFFS) << 1;
16771317   addr &= 0xfffffffc;
16781318   SET_REGISTER(arm, 14, (R15 + 4) | 1);
16791319   R15 = addr;
r20737r20738
16811321
16821322   /* BL */
16831323
1684const void tg0f_0(arm_state *arm, UINT32 pc, UINT32 insn)
1324const void tg0f_0(arm_state *arm, UINT32 pc, UINT32 op)
16851325{
1686   UINT32 addr;
1687
1688   addr = (insn & THUMB_BLOP_OFFS) << 12;
1326   UINT32 addr = (op & THUMB_BLOP_OFFS) << 12;
16891327   if (addr & (1 << 22))
16901328   {
16911329      addr |= 0xff800000;
r20737r20738
16951333   R15 += 2;
16961334}
16971335
1698
1699const void tg0f_1(arm_state *arm, UINT32 pc, UINT32 insn) /* BL */
1336const void tg0f_1(arm_state *arm, UINT32 pc, UINT32 op) /* BL */
17001337{
1701   UINT32 addr;
1702
1703   addr = GET_REGISTER(arm, 14) & ~1;
1704   addr += (insn & THUMB_BLOP_OFFS) << 1;
1338   UINT32 addr = GET_REGISTER(arm, 14) & ~1;
1339   addr += (op & THUMB_BLOP_OFFS) << 1;
17051340   SET_REGISTER(arm, 14, (R15 + 2) | 1);
17061341   R15 = addr;
17071342   //R15 += 2;
trunk/src/emu/cpu/arm7/arm7tdrc.c
r0r20738
1#include "emu.h"
2#include "arm7core.h"
3#include "arm7thmb.h"
4#include "arm7help.h"
5
6#ifdef ARM7_USE_DRC
7
8arm7thumb_drcophandler drcthumb_handler[0x40*0x10] =
9{
10// #define THUMB_SHIFT_R       ((UINT16)0x0800)
11   drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,
12   drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,
13   drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,
14   drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,     drctg00_0,
15   drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,
16   drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,
17   drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,
18   drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,     drctg00_1,
19// #define THUMB_INSN_ADDSUB   ((UINT16)0x0800)   // #define THUMB_ADDSUB_TYPE   ((UINT16)0x0600)
20   drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,
21   drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,
22   drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,
23   drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,        drctg01_0,
24   drctg01_10,       drctg01_10,       drctg01_10,       drctg01_10,       drctg01_10,       drctg01_10,       drctg01_10,       drctg01_10,
25   drctg01_11,       drctg01_11,       drctg01_11,       drctg01_11,       drctg01_11,       drctg01_11,       drctg01_11,       drctg01_11,
26   drctg01_12,       drctg01_12,       drctg01_12,       drctg01_12,       drctg01_12,       drctg01_12,       drctg01_12,       drctg01_12,
27   drctg01_13,       drctg01_13,       drctg01_13,       drctg01_13,       drctg01_13,       drctg01_13,       drctg01_13,       drctg01_13,
28// #define THUMB_INSN_CMP      ((UINT16)0x0800)
29   drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,
30   drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,
31   drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,
32   drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,        drctg02_0,
33   drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,
34   drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,
35   drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,
36   drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,        drctg02_1,
37// #define THUMB_INSN_SUB      ((UINT16)0x0800)
38   drctg03_0,      drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,
39   drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,
40   drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,
41   drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,        drctg03_0,
42   drctg03_1,     drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,
43   drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,
44   drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,
45   drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,        drctg03_1,
46//#define THUMB_GROUP4_TYPE   ((UINT16)0x0c00)  //#define THUMB_ALUOP_TYPE    ((UINT16)0x03c0)  // #define THUMB_HIREG_OP      ((UINT16)0x0300)  // #define THUMB_HIREG_H       ((UINT16)0x00c0)
47   drctg04_00_00,   drctg04_00_01,   drctg04_00_02,   drctg04_00_03,   drctg04_00_04,   drctg04_00_05,   drctg04_00_06,   drctg04_00_07,
48   drctg04_00_08,   drctg04_00_09,   drctg04_00_0a,   drctg04_00_0b,   drctg04_00_0c,   drctg04_00_0d,   drctg04_00_0e,   drctg04_00_0f,
49   drctg04_01_00,   drctg04_01_01,   drctg04_01_02,   drctg04_01_03,   drctg04_01_10,   drctg04_01_11,   drctg04_01_12,   drctg04_01_13,
50   drctg04_01_20,   drctg04_01_21,   drctg04_01_22,   drctg04_01_23,   drctg04_01_30,   drctg04_01_31,   drctg04_01_32,   drctg04_01_33,
51   drctg04_0203,     drctg04_0203,    drctg04_0203,    drctg04_0203,    drctg04_0203,    drctg04_0203,    drctg04_0203,    drctg04_0203,
52   drctg04_0203,   drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,
53   drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,
54   drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,     drctg04_0203,
55//#define THUMB_GROUP5_TYPE   ((UINT16)0x0e00)
56   drctg05_0,     drctg05_0,        drctg05_0,        drctg05_0,        drctg05_0,        drctg05_0,        drctg05_0,        drctg05_0,
57   drctg05_1,        drctg05_1,        drctg05_1,        drctg05_1,        drctg05_1,        drctg05_1,        drctg05_1,        drctg05_1,
58   drctg05_2,        drctg05_2,        drctg05_2,        drctg05_2,        drctg05_2,        drctg05_2,        drctg05_2,        drctg05_2,
59   drctg05_3,        drctg05_3,        drctg05_3,        drctg05_3,        drctg05_3,        drctg05_3,        drctg05_3,        drctg05_3,
60   drctg05_4,     drctg05_4,        drctg05_4,        drctg05_4,        drctg05_4,        drctg05_4,        drctg05_4,        drctg05_4,
61   drctg05_5,        drctg05_5,        drctg05_5,        drctg05_5,        drctg05_5,        drctg05_5,        drctg05_5,        drctg05_5,
62   drctg05_6,        drctg05_6,        drctg05_6,        drctg05_6,        drctg05_6,        drctg05_6,        drctg05_6,        drctg05_6,
63   drctg05_7,        drctg05_7,        drctg05_7,        drctg05_7,        drctg05_7,        drctg05_7,        drctg05_7,        drctg05_7,
64//#define THUMB_LSOP_L        ((UINT16)0x0800)
65   drctg06_0,     drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,
66   drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,
67   drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,
68   drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,        drctg06_0,
69   drctg06_1,     drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,
70   drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,
71   drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,
72   drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,        drctg06_1,
73//#define THUMB_LSOP_L        ((UINT16)0x0800)
74   drctg07_0,     drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,
75   drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,
76   drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,
77   drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,        drctg07_0,
78   drctg07_1,     drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,
79   drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,
80   drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,
81   drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,        drctg07_1,
82// #define THUMB_HALFOP_L      ((UINT16)0x0800)
83   drctg08_0,     drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,
84   drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,
85   drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,
86   drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,        drctg08_0,
87   drctg08_1,     drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,
88   drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,
89   drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,
90   drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,        drctg08_1,
91// #define THUMB_STACKOP_L     ((UINT16)0x0800)
92   drctg09_0,     drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,
93   drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,
94   drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,
95   drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,        drctg09_0,
96   drctg09_1,     drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,
97   drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,
98   drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,
99   drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,        drctg09_1,
100// #define THUMB_RELADDR_SP    ((UINT16)0x0800)
101   drctg0a_0,     drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,
102   drctg0a_0,     drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,
103   drctg0a_0,     drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,
104   drctg0a_0,     drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,        drctg0a_0,
105   drctg0a_1,     drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,
106   drctg0a_1,     drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,
107   drctg0a_1,     drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,
108   drctg0a_1,     drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,        drctg0a_1,
109// #define THUMB_STACKOP_TYPE  ((UINT16)0x0f00)
110   drctg0b_0,     drctg0b_0,        drctg0b_0,        drctg0b_0,        drctg0b_1,        drctg0b_1,        drctg0b_1,        drctg0b_1,
111   drctg0b_2,        drctg0b_2,        drctg0b_2,        drctg0b_2,        drctg0b_3,        drctg0b_3,        drctg0b_3,        drctg0b_3,
112   drctg0b_4,        drctg0b_4,        drctg0b_4,        drctg0b_4,        drctg0b_5,        drctg0b_5,        drctg0b_5,        drctg0b_5,
113   drctg0b_6,        drctg0b_6,        drctg0b_6,        drctg0b_6,        drctg0b_7,        drctg0b_7,        drctg0b_7,        drctg0b_7,
114   drctg0b_8,     drctg0b_8,        drctg0b_8,        drctg0b_8,        drctg0b_9,        drctg0b_9,        drctg0b_9,        drctg0b_9,
115   drctg0b_a,        drctg0b_a,        drctg0b_a,        drctg0b_a,        drctg0b_b,        drctg0b_b,        drctg0b_b,        drctg0b_b,
116   drctg0b_c,        drctg0b_c,        drctg0b_c,        drctg0b_c,        drctg0b_d,        drctg0b_d,        drctg0b_d,        drctg0b_d,
117   drctg0b_e,        drctg0b_e,        drctg0b_e,        drctg0b_e,        drctg0b_f,        drctg0b_f,        drctg0b_f,        drctg0b_f,
118// #define THUMB_MULTLS        ((UINT16)0x0800)
119   drctg0c_0,     drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,
120   drctg0c_0,     drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,
121   drctg0c_0,     drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,
122   drctg0c_0,     drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,        drctg0c_0,
123   drctg0c_1,     drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,
124   drctg0c_1,     drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,
125   drctg0c_1,     drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,
126   drctg0c_1,     drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,        drctg0c_1,
127// #define THUMB_COND_TYPE     ((UINT16)0x0f00)
128   drctg0d_0,     drctg0d_0,        drctg0d_0,        drctg0d_0,        drctg0d_1,        drctg0d_1,        drctg0d_1,        drctg0d_1,
129   drctg0d_2,        drctg0d_2,        drctg0d_2,        drctg0d_2,        drctg0d_3,        drctg0d_3,        drctg0d_3,        drctg0d_3,
130   drctg0d_4,        drctg0d_4,        drctg0d_4,        drctg0d_4,        drctg0d_5,        drctg0d_5,        drctg0d_5,        drctg0d_5,
131   drctg0d_6,        drctg0d_6,        drctg0d_6,        drctg0d_6,        drctg0d_7,        drctg0d_7,        drctg0d_7,        drctg0d_7,
132   drctg0d_8,     drctg0d_8,        drctg0d_8,        drctg0d_8,        drctg0d_9,        drctg0d_9,        drctg0d_9,        drctg0d_9,
133   drctg0d_a,        drctg0d_a,        drctg0d_a,        drctg0d_a,        drctg0d_b,        drctg0d_b,        drctg0d_b,        drctg0d_b,
134   drctg0d_c,        drctg0d_c,        drctg0d_c,        drctg0d_c,        drctg0d_d,        drctg0d_d,        drctg0d_d,        drctg0d_d,
135   drctg0d_e,        drctg0d_e,        drctg0d_e,        drctg0d_e,        drctg0d_f,        drctg0d_f,        drctg0d_f,        drctg0d_f,
136// #define THUMB_BLOP_LO       ((UINT16)0x0800)
137   drctg0e_0,     drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,
138   drctg0e_0,     drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,
139   drctg0e_0,     drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,
140   drctg0e_0,     drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,        drctg0e_0,
141   drctg0e_1,     drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,
142   drctg0e_1,     drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,
143   drctg0e_1,     drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,
144   drctg0e_1,     drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,        drctg0e_1,
145// #define THUMB_BLOP_LO       ((UINT16)0x0800)
146   drctg0f_0,     drctg0f_0,       drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,
147   drctg0f_0,     drctg0f_0,       drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,
148   drctg0f_0,     drctg0f_0,       drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,
149   drctg0f_0,     drctg0f_0,       drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,        drctg0f_0,
150   drctg0f_1,     drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,
151   drctg0f_1,     drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,
152   drctg0f_1,     drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,
153   drctg0f_1,     drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,        drctg0f_1,
154};
155
156   /* Shift operations */
157
158const void drctg00_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Shift left */
159{
160   UINT32 op = desc->opptr.l[0];
161   UINT32 pc = desc->pc;
162   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
163   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
164   INT32 offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
165
166   UML_MOV(block, I0, DRC_RS); // rrs
167   if (offs != 0)
168   {
169      UML_SHL(block, DRC_RD, DRC_RS, offs);
170      UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK);
171      UML_TEST(block, I0, 1 << (31 - (offs - 1)));
172      UML_MOVc(block, COND_NZ, I1, C_MASK);
173      UML_MOVc(block, COND_Z, I1, 0);
174      UML_OR(block, DRC_CPSR, I1);
175   }
176   else
177   {
178      UML_MOV(block, DRC_RD, DRC_RS);
179   }
180   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
181   DRCHandleALUNZFlags(DRC_RD);
182   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
183   UML_ADD(block, DRC_PC, DRC_PC, 2);
184}
185
186const void drctg00_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Shift right */
187{
188   UINT32 op = desc->opptr.l[0];
189   UINT32 pc = desc->pc;
190   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
191   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
192   INT32 offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
193
194   UML_MOV(block, I0, DRC_RS); // rrs
195   if (offs != 0)
196   {
197      UML_SHR(block, DRC_RD, DRC_RS, offs);
198      UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK);
199      UML_TEST(block, I0, 1 << (31 - (offs - 1)));
200      UML_MOVc(block, COND_NZ, I1, C_MASK);
201      UML_MOVc(block, COND_Z, I1, 0);
202      UML_OR(block, DRC_CPSR, I1);
203   }
204   else
205   {
206      UML_MOV(block, DRC_RD, 0);
207      UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK);
208      UML_TEST(block, I0, 0x80000000);
209      UML_MOVc(block, COND_NZ, I1, C_MASK);
210      UML_MOVc(block, COND_Z, I1, 0);
211      UML_OR(block, DRC_CPSR, I1);
212   }
213   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
214   DRCHandleALUNZFlags(DRC_RD);
215   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
216   UML_ADD(block, DRC_PC, DRC_PC, 2);
217}
218
219   /* Arithmetic */
220
221const void drctg01_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
222{
223   UINT32 op = desc->opptr.l[0];
224   UINT32 pc = desc->pc;
225   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
226   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
227   INT32 offs = (op & THUMB_SHIFT_AMT) >> THUMB_SHIFT_AMT_SHIFT;
228
229   /* ASR.. */
230   UML_MOV(block, I0, DRC_RS);
231   if (offs == 0)
232   {
233      offs = 32;
234   }
235   if (offs >= 32)
236   {
237      UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK);
238      UML_SHR(block, I1, I0, 31);
239      UML_TEST(block, I1, ~0);
240      UML_MOVc(block, COND_NZ, I1, C_MASK);
241      UML_MOVc(block, COND_Z, I1, 0);
242      UML_OR(block, DRC_CPSR, DRC_CPSR, I1);
243      UML_TEST(block, I0, 0x80000000);
244      UML_MOVc(block, COND_NZ, DRC_RD, ~0);
245      UML_MOVc(block, COND_Z, DRC_RD, 0);
246   }
247   else
248   {
249      UML_AND(block, DRC_CPSR, DRC_CPSR, ~C_MASK);
250      UML_TEST(block, I0, 1 << (offs - 1));
251      UML_MOVc(block, COND_NZ, I1, C_MASK);
252      UML_MOVc(block, COND_Z, I1, 0);
253      UML_OR(block, DRC_CPSR, DRC_CPSR, I1);
254      UML_SHR(block, I1, I0, offs);
255      UML_SHL(block, I2, ~0, 32 - offs);
256      UML_TEST(block, I0, 0x80000000);
257      UML_MOVc(block, COND_Z, I2, 0);
258      UML_OR(block, DRC_RD, I1, I2);
259   }
260   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
261   DRCHandleALUNZFlags(DRC_RD);
262   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
263   UML_ADD(block, DRC_PC, DRC_PC, 2);
264}
265
266const void drctg01_10(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
267{
268   UINT32 op = desc->opptr.l[0];
269   UINT32 rn = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
270   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
271   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
272   UML_ADD(block, DRC_REG(rd), DRC_REG(rs), DRC_REG(rn));
273   DRCHandleThumbALUAddFlags(DRC_REG(rd), DRC_REG(rs), DRC_REG(rn));
274}
275
276const void drctg01_11(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* SUB Rd, Rs, Rn */
277{
278   UINT32 op = desc->opptr.l[0];
279   UINT32 rn = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
280   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
281   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
282   UML_SUB(block, DRC_REG(rd), DRC_REG(rs), DRC_REG(rn));
283   DRCHandleThumbALUSubFlags(DRC_REG(rd), DRC_REG(rs), DRC_REG(rn));
284}
285
286const void drctg01_12(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ADD Rd, Rs, #imm */
287{
288   UINT32 op = desc->opptr.l[0];
289   UINT32 imm = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
290   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
291   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
292   UML_ADD(block, DRC_REG(rd), DRC_REG(rs), imm);
293   DRCHandleThumbALUAddFlags(DRC_REG(rd), DRC_REG(rs), imm);
294}
295
296const void drctg01_13(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* SUB Rd, Rs, #imm */
297{
298   UINT32 op = desc->opptr.l[0];
299   UINT32 imm = (op & THUMB_ADDSUB_RNIMM) >> THUMB_ADDSUB_RNIMM_SHIFT;
300   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
301   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
302   UML_SUB(block, DRC_REG(rd), DRC_REG(rs), imm);
303   DRCHandleThumbALUSubFlags(DRC_REG(rd), DRC_REG(rs), imm);
304}
305
306   /* CMP / MOV */
307
308const void drctg02_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
309{
310   UINT32 op = desc->opptr.l[0];
311   UINT32 rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
312   UINT32 op2 = (op & THUMB_INSN_IMM);
313   UML_MOV(block, DRC_REG(rd), op2);
314   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
315   DRCHandleALUNZFlags(DRC_REG(rd));
316   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
317   UML_ADD(block, DRC_PC, DRC_PC, 2);
318}
319
320const void drctg02_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
321{
322   UINT32 op = desc->opptr.l[0];
323   UINT32 rn = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
324   UINT32 op2 = op & THUMB_INSN_IMM;
325
326   UML_SUB(block, I3, DRC_REG(rn), op2);
327   DRCHandleThumbALUSubFlags(I3, DRC_REG(rn), op2);
328}
329
330   /* ADD/SUB immediate */
331
332const void drctg03_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ADD Rd, #Offset8 */
333{
334   UINT32 op = desc->opptr.l[0];
335   UINT32 rn = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
336   UINT32 op2 = op & THUMB_INSN_IMM;
337   UINT32 rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
338   UML_ADD(block, DRC_REG(rd), DRC_REG(rn), op2);
339   DRCHandleThumbALUAddFlags(DRC_REG(rd), DRC_REG(rn), op2);
340}
341
342const void drctg03_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* SUB Rd, #Offset8 */
343{
344   UINT32 op = desc->opptr.l[0];
345   UINT32 rn = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
346   UINT32 op2 = op & THUMB_INSN_IMM;
347   UINT32 rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
348   UML_SUB(block, DRC_REG(rd), DRC_REG(rn), op2);
349   DRCHandleThumbALUSubFlags(DRC_REG(rd), DRC_REG(rn), op2);
350}
351
352   /* Rd & Rm instructions */
353
354const void drctg04_00_00(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* AND Rd, Rs */
355{
356   UINT32 op = desc->opptr.l[0];
357   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
358   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
359   UML_AND(block, DRC_REG(rd), DRC_REG(rd), DRC_REG(rs));
360   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
361   DRCHandleALUNZFlags(DRC_REG(rd));
362   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
363   UML_ADD(block, DRC_PC, DRC_PC, 2);
364}
365
366const void drctg04_00_01(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* EOR Rd, Rs */
367{
368   UINT32 op = desc->opptr.l[0];
369   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
370   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
371   UML_XOR(block, DRC_REG(rd), DRC_REG(rd), DRC_REG(rs));
372   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
373   DRCHandleALUNZFlags(DRC_REG(rd));
374   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
375   UML_ADD(block, DRC_PC, DRC_PC, 2);
376}
377
378const void drctg04_00_02(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* LSL Rd, Rs */
379{
380   UINT32 op = desc->opptr.l[0];
381   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
382   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
383   code_label skip;
384   code_label offsg32;
385   code_label offs32;
386
387   UML_AND(block, I1, DRC_REG(rs), 0xff);
388   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK | C_MASK));
389
390   UML_CMP(block, I1, 0);
391   UML_JMPc(block, COND_E, skip = compiler->labelnum++);
392
393   UML_CMP(block, I1, 32);
394   UML_JMPc(block, COND_A, offsg32 = compiler->labelnum++);
395   UML_JMPc(block, COND_E, offs32 = compiler->labelnum++);
396
397   UML_SHL(block, DRC_REG(rd), DRC_REG(rd), I1);
398   UML_SUB(block, I1, I1, 1);
399   UML_SUB(block, I1, 31, I1);
400   UML_SHL(block, I1, 1, I1);
401   UML_TEST(block, DRC_REG(rd), I1);
402   UML_MOVc(block, COND_NZ, I0, C_MASK);
403   UML_MOVc(block, COND_Z, I0, 0);
404   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
405   UML_JMP(block, skip);
406
407   UML_LABEL(block, offs32);
408   UML_TEST(block, DRC_REG(rd), 1);
409   UML_MOVc(block, COND_NZ, I0, C_MASK);
410   UML_MOVc(block, COND_Z, I0, 0);
411   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
412   UML_MOV(block, DRC_REG(rd), 0);
413   UML_JMP(block, skip);
414
415   UML_LABEL(block, offsg32);
416   UML_MOV(block, DRC_REG(rd), 0);
417
418   UML_LABEL(block, skip);
419
420   DRCHandleALUNZFlags(DRC_REG(rd));
421   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
422   UML_ADD(block, DRC_PC, DRC_PC, 2);
423}
424
425const void drctg04_00_03(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* LSR Rd, Rs */
426{
427   UINT32 op = desc->opptr.l[0];
428   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
429   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
430   code_label skip;
431   code_label offsg32;
432   code_label offs32;
433
434   UML_AND(block, I1, DRC_REG(rs), 0xff);
435   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK | C_MASK));
436   UML_CMP(block, I1, 0);
437   UML_JMPc(block, COND_E, skip = compiler->labelnum++);
438
439   UML_CMP(block, I1, 32);
440   UML_JMPc(block, COND_A, offsg32 = compiler->labelnum++);
441   UML_JMPc(block, COND_E, offs32 = compiler->labelnum++);
442
443   UML_SHR(block, DRC_REG(rd), DRC_REG(rd), I1);
444   UML_SUB(block, I1, 1);
445   UML_SHL(block, I1, 1, I1);
446   UML_TEST(block, DRC_REG(rd), I1);
447   UML_MOVc(block, COND_NZ, I0, C_MASK);
448   UML_MOVc(block, COND_Z, I0, 0);
449   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
450   UML_JMP(block, skip);
451
452   UML_LABEL(block, offs32);
453   UML_TEST(block, DRC_REG(rd), 0x80000000);
454   UML_MOVc(block, COND_NZ, I0, C_MASK);
455   UML_MOVc(block, COND_Z, I0, 0);
456   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
457   UML_MOV(block, DRC_REG(rd), 0);
458   UML_JMP(block, skip);
459
460   UML_LABEL(block, offsg32);
461   UML_MOV(block, DRC_REG(rd), 0);
462
463   UML_LABEL(block, skip);
464
465   DRCHandleALUNZFlags(DRC_REG(rd));
466   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
467   UML_ADD(block, DRC_PC, DRC_PC, 2);
468}
469
470const void drctg04_00_04(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ASR Rd, Rs */
471{
472   UINT32 op = desc->opptr.l[0];
473   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
474   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
475   code_label skip;
476   code_label offsg32;
477   code_label offs32;
478
479   UML_MOV(block, I0, DRC_REG(rd));
480   UML_AND(block, I1, DRC_REG(rs), 0xff);
481   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK | C_MASK));
482   UML_CMP(block, I1, 0);
483   UML_JMPc(block, COND_E, skip = compiler->labelnum++);
484
485   UML_SHR(block, I2, I0, I1);
486   UML_SUB(block, I1, 32, I1);
487   UML_SHL(block, I1, ~0, I1);
488   UML_TEST(block, I0, 0x80000000);
489   UML_MOVc(block, COND_NZ, DRC_REG(RD), I1);
490   UML_MOVc(block, COND_Z, DRC_REG(RD), 0);
491   UML_OR(block, DRC_REG(rd), DRC_REG(RD), I2);
492   UML_JMPc(block, COND_B, offsl32 = compiler->labelnum++);
493
494   UML_TEST(block, I0, 0x80000000);
495   UML_MOVc(block, COND_NZ, DRC_REG(rd), ~0);
496   UML_MOVc(block, COND_Z, DRC_REG(rd), 0);
497   UML_MOVc(block, COND_NZ, I1, C_MASK);
498   UML_MOVc(block, COND_Z, I1, 0);
499   UML_OR(block, DRC_CPSR, DRC_CPSR, I1);
500   UML_JMP(block, skip);
501
502   UML_LABEL(block, offsl32);
503   UML_SUB(block, I1, I1, 1);
504   UML_SHL(block, I1, 1, I1);
505   UML_TEST(block, I0, I1);
506   UML_MOVc(block, COND_NZ, I1, C_MASK);
507   UML_MOVc(block, COND_Z, I1, 0);
508   UML_OR(block, DRC_CPSR, DRC_CPSR, I1);
509   UML_JMP(block, skip);
510
511   UML_LABEL(block, skip);
512   DRCHandleALUNZFlags(DRC_REG(rd));
513   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
514   UML_ADD(block, DRC_PC, DRC_PC, 2);
515
516}
517
518const void drctg04_00_05(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ADC Rd, Rs */
519{
520   UINT32 op = desc->opptr.l[0];
521   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
522   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
523   UML_TEST(block, DRC_CPSR, C_MASK);
524   UML_MOVc(block, COND_NZ, I3, 1);
525   UML_MOVc(block, COND_Z, I3, 0);
526   UML_ADD(block, I3, I3, DRC_REG(rd);
527   UML_ADD(block, I3, I3, DRC_REG(rs);
528   DRCHandleThumbALUAddFlags(I3, DRC_REG(rd), DRC_REG(rs));
529   UML_MOV(block, DRC_REG(rd), I3);
530}
531
532const void drctg04_00_06(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* SBC Rd, Rs */
533{
534   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
535   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
536   UML_TEST(block, DRC_CPSR, C_MASK);
537   UML_MOVc(block, COND_NZ, I3, 0);
538   UML_MOVc(block, COND_Z, I3, 1);
539   UML_SUB(block, I3, DRC_REG(rs), I3);
540   UML_ADD(block, I3, DRC_REG(rd), I3);
541   DRCHandleThumbALUSubFlags(I3, DRC_REG(rd), DRC_REG(rs));
542   UML_MOV(block, DRC_REG(rd), I3);
543}
544
545const void drctg04_00_07(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ROR Rd, Rs */
546{
547   UINT32 op = desc->opptr.l[0];
548   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
549   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
550   UML_MOV(block, I0, DRC_REG(rd));
551   UML_AND(block, I1, DRC_REG(rs), 0x1f);
552   UML_SHR(block, DRC_REG(rd), I0, I1);
553   UML_SUB(block, I2, 32, I1);
554   UML_SHL(block( I2, I0, I2);
555   UML_OR(block, DRC_REG(rd), DRC_REG(rd), I2);
556   UML_SUB(block, I1, I1, 1);
557   UML_SHL(block, I1, 1, I1);
558   UML_TEST(block, I0, I1);
559   UML_MOVc(block, COND_NZ, I0, C_MASK);
560   UML_MOVc(block, COND_Z, I0, 0);
561   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK | C_MASK));
562   DRCHandleALUNZFlags(DRC_REG(rd));
563   UML_OR(block, DRC_CSPR, DRC_CPSR, I0);
564   UML_ADD(block, DRC_PC, DRC_PC, 2);
565}
566
567const void drctg04_00_08(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* TST Rd, Rs */
568{
569   UINT32 op = desc->opptr.l[0];
570   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
571   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
572   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
573   UML_AND(block, I2, DRC_REG(rd), DRC_REG(rs));
574   DRCHandleALUNZFlags(I2);
575   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
576   UML_ADD(block, DRC_PC, DRC_PC, 2);
577}
578
579const void drctg04_00_09(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* NEG Rd, Rs */
580{
581   UINT32 op = desc->opptr.l[0];
582   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
583   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
584   UML_MOV(block, I3, DRC_REG(rs));
585   UML_SUB(block, DRC_REG(rd), 0, I3);
586   DRCHandleThumbALUSubFlags(DRC_REG(rd), 0, I3);
587}
588
589const void drctg04_00_0a(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* CMP Rd, Rs */
590{
591   UINT32 op = desc->opptr.l[0];
592   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
593   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
594   UML_SUB(block, I3, DRC_REG(rd), DRC_REG(rs));
595   DRCHandleThumbALUSubFlags(I3, DRC_REG(rd), DRC_REG(rs));
596}
597
598const void drctg04_00_0b(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* CMN Rd, Rs - check flags, add dasm */
599{
600   UINT32 op = desc->opptr.l[0];
601   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
602   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
603   UML_ADD(block, I3, DRC_REG(rd), DRC_REG(rs));
604   DRCHandleThumbALUAddFlags(I3, DRC_REG(rd), DRC_REG(rs));
605}
606
607const void drctg04_00_0c(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ORR Rd, Rs */
608{
609   UINT32 op = desc->opptr.l[0];
610   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
611   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
612   UML_OR(block, DRC_REG(rd), DRC_REG(rd), DRC_REG(rs));
613   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
614   DRCHandleALUNZFlags(DRC_REG(rd));
615   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
616   UML_ADD(block, DRC_PC, DRC_PC, 2);
617}
618
619const void drctg04_00_0d(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* MUL Rd, Rs */
620{
621   UINT32 op = desc->opptr.l[0];
622   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
623   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
624   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
625   UML_MULU(block, DRC_REG(rd), I1, DRC_REG(rd), DRC_REG(rs));
626   DRCHandleALUNZFlags(DRC_REG(rd));
627   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
628   UML_ADD(block, DRC_PC, DRC_PC, 2);
629}
630
631const void drctg04_00_0e(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* BIC Rd, Rs */
632{
633   UINT32 op = desc->opptr.l[0];
634   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
635   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
636   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
637   UML_XOR(block, I0, DRC_REG(rs), ~0);
638   UML_AND(block, DRC_REG(rd), DRC_REG(rd), I0);
639   DRCHandleALUNZFlags(DRC_REG(rd));
640   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
641   UML_ADD(block, DRC_PC, DRC_PC, 2);
642}
643
644const void drctg04_00_0f(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* MVN Rd, Rs */
645{
646   UINT32 op = desc->opptr.l[0];
647   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
648   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
649   UML_XOR(block, I0, DRC_REG(rs), ~0);
650   UML_MOV(block, DRC_REG(rd), I0);
651   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(Z_MASK | N_MASK));
652   DRCHandleALUNZFlags(DRC_REG(rd));
653   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);
654   UML_ADD(block, DRC_PC, DRC_PC, 2);
655}
656
657   /* ADD Rd, Rs group */
658
659const void drctg04_01_00(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
660{
661   UINT32 op = desc->opptr.l[0];
662   fatalerror("%08x: G4-1-0 Undefined Thumb instruction: %04x %x\n", pc, op, (op & THUMB_HIREG_H) >> THUMB_HIREG_H_SHIFT);
663}
664
665const void drctg04_01_01(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ADD Rd, HRs */
666{
667   UINT32 op = desc->opptr.l[0];
668   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
669   UINT32 rd = op & THUMB_HIREG_RD;
670   UML_ADD(block, DRC_REG(rd), DRC_REG(rd), DRC_REG(rs+8));
671   if (rs == 7)
672   {
673      UML_ADD(block, DRC_REG(rd), DRC_REG(rd), 4);
674   }
675   UML_ADD(block, DRC_PC, DRC_PC, 2);
676}
677
678const void drctg04_01_02(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ADD HRd, Rs */
679{
680   UINT32 op = desc->opptr.l[0];
681   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
682   UINT32 rd = op & THUMB_HIREG_RD;
683   UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), DRC_REG(rs));
684   if (rd == 7)
685   {
686      UML_ADD(block, DRC_REG(rd), DRC_REG(rd), 4);
687   }
688   UML_ADD(block, DRC_PC, DRC_PC, 2);
689}
690
691const void drctg04_01_03(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Add HRd, HRs */
692{
693   UINT32 op = desc->opptr.l[0];
694   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
695   UINT32 rd = op & THUMB_HIREG_RD;
696   UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), DRC_REG(rs+8));
697   // emulate the effects of pre-fetch
698   if (rs == 7)
699   {
700      UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), 4);
701   }
702   if (rd == 7)
703   {
704      UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), 2);
705   }
706   UML_ADD(block, DRC_PC, DRC_PC, 2);
707}
708
709const void drctg04_01_10(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* CMP Rd, Rs */
710{
711   UINT32 op = desc->opptr.l[0];
712   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
713   UINT32 rd = op & THUMB_HIREG_RD;
714   UML_SUB(block, I3, DRC_REG(rd), DRC_REG(rs));
715   DRCHandleThumbALUSubFlags(I3, DRC_REG(rd), DRC_REG(rs));
716}
717
718const void drctg04_01_11(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* CMP Rd, Hs */
719{
720   UINT32 op = desc->opptr.l[0];
721   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
722   UINT32 rd = op & THUMB_HIREG_RD;
723   UML_SUB(block, I3, DRC_REG(rd), DRC_REG(rs+8));
724   DRCHandleThumbALUSubFlags(I3, DRC_REG(rd), DRC_REG(rs+8));
725}
726
727const void drctg04_01_12(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* CMP Hd, Rs */
728{
729   UINT32 op = desc->opptr.l[0];
730   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
731   UINT32 rd = op & THUMB_HIREG_RD;
732   UML_SUB(block, I3, DRC_REG(rd+8), DRC_REG(rs));
733   DRCHandleThumbALUSubFlags(I3, DRC_REG(rd+8), DRC_REG(rs));
734}
735
736const void drctg04_01_13(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* CMP Hd, Hs */
737{
738   UINT32 op = desc->opptr.l[0];
739   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT));
740   UINT32 rd = op & THUMB_HIREG_RD;
741   UML_SUB(block, I3, DRC_REG(rd+8), DRC_REG(rs+8));
742   DRCHandleThumbALUSubFlags(I3, DRC_REG(rd+8), DRC_REG(rs+8));
743}
744
745   /* MOV group */
746
747const void drctg04_01_20(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* MOV Rd, Rs (undefined) */
748{
749   UINT32 op = desc->opptr.l[0];
750   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
751   UINT32 rd = op & THUMB_HIREG_RD;
752   UML_MOV(block, DRC_REG(rd), DRC_REG(rs));
753   UML_ADD(block, DRC_PC, DRC_PC, 2);
754}
755
756const void drctg04_01_21(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* MOV Rd, Hs */
757{
758   UINT32 op = desc->opptr.l[0];
759   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
760   UINT32 rd = op & THUMB_HIREG_RD;
761   UML_MOV(block, DRC_REG(rd), DRC_REG(rs+8));
762   if (rs == 7)
763   {
764      UML_ADD(block, DRC_REG(rd), DRC_REG(rd), 4);
765   }
766   UML_ADD(block, DRC_PC, DRC_PC, 2);
767}
768
769const void drctg04_01_22(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* MOV Hd, Rs */
770{
771   UINT32 op = desc->opptr.l[0];
772   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
773   UINT32 rd = op & THUMB_HIREG_RD;
774   UML_MOV(block, DRC_REG(rd+8), DRC_REG(rs));
775   // CHECKME
776   if (rd != 7)
777   {
778      UML_ADD(block, DRC_PC, DRC_PC, 2);
779   }
780   else
781   {
782      UML_AND(block, DRC_PC, DRC_PC, ~1);
783   }
784}
785
786const void drctg04_01_23(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* MOV Hd, Hs */
787{
788   UINT32 op = desc->opptr.l[0];
789   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
790   UINT32 rd = op & THUMB_HIREG_RD;
791   UML_MOV(block, DRC_REG(rd+8), DRC_REG(rs+8));
792   if (rs == 7)
793   {
794      UML_ADD(block, DRC_REG(rd+8), DRC_REG(rd+8), 4);
795   }
796   if (rd != 7)
797   {
798      UML_ADD(block, DRC_PC, DRC_PC, 2);
799   }
800   else
801   {
802      UML_AND(block, DRC_PC, DRC_PC, ~1);
803   }
804
805}
806
807const void drctg04_01_30(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
808{
809   UINT32 op = desc->opptr.l[0];
810   code_label switch_state;
811   code_label done;
812   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
813   UML_MOV(block, I0, DRC_REG(rs);
814   UML_TEST(block, I0, 1);
815   UML_JMPc(block, COND_Z, switch_state = compiler->labelnum++);
816   UML_AND(block, I0, I0, ~1);
817   UML_JMP(block, done = compiler->labelnum++);
818
819   UML_LABEL(block, switch_state);
820   UML_AND(block, DRC_CPSR, DRC_CPSR, ~T_MASK);
821   UML_TEST(block, I0, 2);
822   UML_MOVc(block, COND_NZ, I1, 2);
823   UML_MOVc(block, COND_Z, I1, 0);
824   UML_ADD(block, I0, I0, I1);
825
826   UML_LABEL(block, done);
827   UML_MOV(block, DRC_PC, I0);
828}
829
830const void drctg04_01_31(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
831{
832   UINT32 op = desc->opptr.l[0];
833   code_label switch_state;
834   code_label done;
835   UINT32 rs = (op & THUMB_HIREG_RS) >> THUMB_HIREG_RS_SHIFT;
836   UML_MOV(block, I0, DRC_REG(rs+8);
837   if(rs == 7)
838   {
839      UML_ADD(block, I0, I0, 2);
840   }
841   UML_TEST(block, I0, 1);
842   UML_JMPc(block, COND_Z, switch_state = compiler->labelnum++);
843   UML_AND(block, I0, I0, ~1);
844   UML_JMP(block, done = compiler->labelnum++);
845
846   UML_LABEL(block, switch_state);
847   UML_AND(block, DRC_CPSR, DRC_CPSR, ~T_MASK);
848   UML_TEST(block, I0, 2);
849   UML_MOVc(block, COND_NZ, I1, 2);
850   UML_MOVc(block, COND_Z, I1, 0);
851   UML_ADD(block, I0, I0, I1);
852
853   UML_LABEL(block, done);
854   UML_MOV(block, DRC_PC, I0);
855}
856
857const void drctg04_01_32(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
858{
859   UINT32 op = desc->opptr.l[0];
860   fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, op);
861}
862
863const void drctg04_01_33(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
864{
865   UINT32 op = desc->opptr.l[0];
866   fatalerror("%08x: G4-3 Undefined Thumb instruction: %04x\n", pc, op);
867}
868
869const void drctg04_0203(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
870{
871   UINT32 op = desc->opptr.l[0];
872   UINT32 rd = (op & THUMB_INSN_IMM_RD) >> THUMB_INSN_IMM_RD_SHIFT;
873   UINT32 imm = 4 + ((op & THUMB_INSN_IMM) << 2);
874   UML_AND(block, I0, DRC_PC, ~2);
875   UML_ADD(block, I0, I0, imm);
876   UML_CALLH(block, *arm->impstate->read32);
877   UML_MOV(block, DRC_REG(rd), I0);
878   UML_ADD(block, DRC_PC, DRC_PC, 2);
879}
880
881   /* LDR* STR* group */
882
883const void drctg05_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* STR Rd, [Rn, Rm] */
884{
885   UINT32 op = desc->opptr.l[0];
886   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
887   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
888   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
889   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
890   UML_MOV(block, I1, DRC_REG(rd));
891   UML_ADD(block, I0, DRC_REG(rn), DRC_REG(rm));
892   UML_CALLH(block, *arm->impstate->write32);
893   UML_ADD(block, DRC_PC, DRC_PC, 2);
894}
895
896const void drctg05_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* STRH Rd, [Rn, Rm] */
897{
898   UINT32 op = desc->opptr.l[0];
899   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
900   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
901   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
902   UML_MOV(block, I1, DRC_REG(rd));
903   UML_ADD(block, I0, DRC_REG(rn), DRC_REG(rm));
904   UML_CALLH(block, *arm->impstate->write16);
905   UML_ADD(block, DRC_PC, DRC_PC, 2);
906}
907
908const void drctg05_2(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* STRB Rd, [Rn, Rm] */
909{
910   UINT32 op = desc->opptr.l[0];
911   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
912   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
913   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
914   UINT32 addr = GET_REGISTER(arm, rn) + GET_REGISTER(arm, rm);
915   UML_MOV(block, I1, DRC_REG(rd));
916   UML_ADD(block, I0, DRC_REG(rn), DRC_REG(rm));
917   UML_CALLH(block, *arm->impstate->write16);
918   UML_ADD(block, DRC_PC, DRC_PC, 2);
919}
920
921const void drctg05_3(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* LDSB Rd, [Rn, Rm] todo, add dasm */
922{
923   UINT32 op = desc->opptr.l[0];
924   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
925   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
926   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
927   UML_ADD(block, I0, DRC_REG(rn), DRC_REG(rm));
928   UML_CALLH(block, *arm->impstate->read8);
929   UML_SEXT(block, DRC_REG(rd), I0, SIZE_BYTE);
930   UML_ADD(block, DRC_PC, DRC_PC, 2);
931}
932
933const void drctg05_4(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* LDR Rd, [Rn, Rm] */
934{
935   UINT32 op = desc->opptr.l[0];
936   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
937   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
938   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
939   UML_ADD(block, I0, DRC_REG(rn), DRC_REG(rm));
940   UML_CALLH(block, *arm->impstate->read32);
941   UML_MOV(block, DRC_REG(rd), I0);
942   UML_ADD(block, DRC_PC, DRC_PC, 2);
943}
944
945const void drctg05_5(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* LDRH Rd, [Rn, Rm] */
946{
947   UINT32 op = desc->opptr.l[0];
948   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
949   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
950   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
951   UML_ADD(block, I0, DRC_REG(rn), DRC_REG(rm));
952   UML_CALLH(block, *arm->impstate->read16);
953   UML_MOV(block, DRC_REG(rd), I0);
954   UML_ADD(block, DRC_PC, DRC_PC, 2);
955}
956
957const void drctg05_6(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* LDRB Rd, [Rn, Rm] */
958{
959   UINT32 op = desc->opptr.l[0];
960   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
961   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
962   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
963   UML_ADD(block, I0, DRC_REG(rn), DRC_REG(rm));
964   UML_CALLH(block, *arm->impstate->read8);
965   UML_MOV(block, DRC_REG(rd), I0);
966   UML_ADD(block, DRC_PC, DRC_PC, 2);
967}
968
969const void drctg05_7(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* LDSH Rd, [Rn, Rm] */
970{
971   UINT32 op = desc->opptr.l[0];
972   UINT32 rm = (op & THUMB_GROUP5_RM) >> THUMB_GROUP5_RM_SHIFT;
973   UINT32 rn = (op & THUMB_GROUP5_RN) >> THUMB_GROUP5_RN_SHIFT;
974   UINT32 rd = (op & THUMB_GROUP5_RD) >> THUMB_GROUP5_RD_SHIFT;
975   UML_ADD(block, I0, DRC_REG(rn), DRC_REG(rm));
976   UML_CALLH(block, *arm->impstate->read16);
977   UML_SEXT(block, DRC_REG(rd), I0, SIZE_WORD);
978   UML_ADD(block, DRC_PC, DRC_PC, 2);
979}
980
981   /* Word Store w/ Immediate Offset */
982
983const void drctg06_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Store */
984{
985   UINT32 op = desc->opptr.l[0];
986   UINT32 rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
987   UINT32 rd = op & THUMB_ADDSUB_RD;
988   INT32 offs = ((op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
989   UML_ADD(block, I0, DRC_REG(rn), offs);
990   UML_MOV(block, I1, DRC_REG(rd));
991   UML_CALLH(block, *arm->impstate->write32);
992   UML_ADD(block, DRC_PC, DRC_PC, 2);
993}
994
995const void drctg06_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Load */
996{
997   UINT32 op = desc->opptr.l[0];
998   UINT32 rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
999   UINT32 rd = op & THUMB_ADDSUB_RD;
1000   INT32 offs = ((op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT) << 2;
1001   UML_ADD(block, I0, DRC_REG(rn), offs);
1002   UML_CALLH(block, *arm->impstate->read32);
1003   UML_MOV(block, DRC_REG(rd), I0);
1004   UML_ADD(block, DRC_PC, DRC_PC, 2);
1005}
1006
1007   /* Byte Store w/ Immeidate Offset */
1008
1009const void drctg07_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Store */
1010{
1011   UINT32 op = desc->opptr.l[0];
1012   UINT32 rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1013   UINT32 rd = op & THUMB_ADDSUB_RD;
1014   INT32 offs = (op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
1015   UML_ADD(block, I0, DRC_REG(rn), offs);
1016   UML_MOV(block, I1, DRC_REG(rd));
1017   UML_CALLH(block, *arm->impstate->write8);
1018   UML_ADD(block, DRC_PC, DRC_PC, 2);
1019}
1020
1021const void drctg07_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* Load */
1022{
1023   UINT32 op = desc->opptr.l[0];
1024   UINT32 rn = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1025   UINT32 rd = op & THUMB_ADDSUB_RD;
1026   INT32 offs = (op & THUMB_LSOP_OFFS) >> THUMB_LSOP_OFFS_SHIFT;
1027   UML_ADD(block, I0, DRC_REG(rn), offs);
1028   UML_CALLH(block, *arm->impstate->read8);
1029   UML_MOV(block, DRC_REG(rd), I0);
1030   UML_ADD(block, DRC_PC, DRC_PC, 2);
1031}
1032
1033   /* Load/Store Halfword */
1034
1035const void drctg08_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Store */
1036{
1037   UINT32 op = desc->opptr.l[0];
1038   UINT32 offs = (op & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
1039   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1040   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
1041   UML_ADD(block, I0, DRC_REG(rn), offs << 1);
1042   UML_MOV(block, I1, DRC_REG(rd));
1043   UML_CALLH(block, *arm->impstate->write16);
1044   UML_ADD(block, DRC_PC, DRC_PC, 2);
1045}
1046
1047const void drctg08_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Load */
1048{
1049   UINT32 op = desc->opptr.l[0];
1050   UINT32 offs = (op & THUMB_HALFOP_OFFS) >> THUMB_HALFOP_OFFS_SHIFT;
1051   UINT32 rs = (op & THUMB_ADDSUB_RS) >> THUMB_ADDSUB_RS_SHIFT;
1052   UINT32 rd = (op & THUMB_ADDSUB_RD) >> THUMB_ADDSUB_RD_SHIFT;
1053   UML_ADD(block, I0, DRC_REG(rn), offs << 1);
1054   UML_CALLH(block, *arm->impstate->read16);
1055   UML_MOV(block, DRC_REG(rd), I0);
1056   UML_ADD(block, DRC_PC, DRC_PC, 2);
1057}
1058
1059   /* Stack-Relative Load/Store */
1060
1061const void drctg09_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Store */
1062{
1063   UINT32 op = desc->opptr.l[0];
1064   UINT32 rd = (op & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
1065   INT32 offs = (UINT8)(op & THUMB_INSN_IMM) << 2;
1066   UML_ADD(block, I0, DRC_REG(13), offs);
1067   UML_MOV(block, I1, DRC_REG(rd));
1068   UML_CALLH(block, *arm->impstate->write32);
1069   UML_ADD(block, DRC_PC, DRC_PC, 2);
1070}
1071
1072const void drctg09_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Load */
1073{
1074   UINT32 op = desc->opptr.l[0];
1075   UINT32 rd = (op & THUMB_STACKOP_RD) >> THUMB_STACKOP_RD_SHIFT;
1076   UINT32 offs = (UINT8)(op & THUMB_INSN_IMM) << 2;
1077   UML_ADD(block, I0, DRC_REG(13), offs);
1078   UML_CALLH(block, *arm->impstate->read32);
1079   UML_MOV(block, DRC_REG(rd), I0);
1080   UML_ADD(block, DRC_PC, DRC_PC, 2);
1081}
1082
1083   /* Get relative address */
1084
1085const void drctg0a_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)  /* ADD Rd, PC, #nn */
1086{
1087   UINT32 op = desc->opptr.l[0];
1088   UINT32 rd = (op & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
1089   INT32 offs = (UINT8)(op & THUMB_INSN_IMM) << 2;
1090   UML_ADD(block, I0, DRC_PC, 4);
1091   UML_AND(block, I0, I0, ~2);
1092   UML_ADD(block, DRC_REG(rd), I0, offs);
1093   UML_ADD(block, DRC_PC, DRC_PC, 2);
1094}
1095
1096const void drctg0a_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ADD Rd, SP, #nn */
1097{
1098   UINT32 op = desc->opptr.l[0];
1099   UINT32 rd = (op & THUMB_RELADDR_RD) >> THUMB_RELADDR_RD_SHIFT;
1100   INT32 offs = (UINT8)(op & THUMB_INSN_IMM) << 2;
1101   UML_ADD(block, DRC_REG(rd), DRC_REG(13), offs);
1102   UML_ADD(block, DRC_PC, DRC_PC, 2);
1103}
1104
1105   /* Stack-Related Opcodes */
1106
1107const void drctg0b_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* ADD SP, #imm */
1108{
1109   UINT32 op = desc->opptr.l[0];
1110   INT32 addr = (op & THUMB_INSN_IMM);
1111   addr &= ~THUMB_INSN_IMM_S;
1112   addr = ((op & THUMB_INSN_IMM_S) ? -(addr << 2) : (addr << 2));
1113   UML_ADD(block, DRC_REG(13), DRC_REG(13), addr);
1114   UML_ADD(block, DRC_PC, DRC_PC, 2);
1115}
1116
1117const void drctg0b_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1118{
1119   UINT32 op = desc->opptr.l[0];
1120   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1121}
1122
1123const void drctg0b_2(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1124{
1125   UINT32 op = desc->opptr.l[0];
1126   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1127}
1128
1129const void drctg0b_3(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1130{
1131   UINT32 op = desc->opptr.l[0];
1132   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1133}
1134
1135const void drctg0b_4(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* PUSH {Rlist} */
1136{
1137   UINT32 op = desc->opptr.l[0];
1138   for (INT32 offs = 7; offs >= 0; offs--)
1139   {
1140      if (op & (1 << offs))
1141      {
1142         UML_SUB(block, DRC_REG(13), DRC_REG(13), 4);
1143         UML_MOV(block, I0, DRC_REG(13));
1144         UML_MOV(block, I1, DRC_REG(offs));
1145         UML_CALLH(block, *arm->impstate->write32);
1146      }
1147   }
1148   UML_ADD(block, DRC_PC, DRC_PC, 2);
1149}
1150
1151const void drctg0b_5(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* PUSH {Rlist}{LR} */
1152{
1153   UINT32 op = desc->opptr.l[0];
1154   UML_SUB(block, DRC_REG(13), DRC_REG(13), 4);
1155   UML_MOV(block, I0, DRC_REG(13));
1156   UML_MOV(block, I1, DRC_REG(14));
1157   UML_CALLH(block, *arm->impstate->write32);
1158   for (INT32 offs = 7; offs >= 0; offs--)
1159   {
1160      if (op & (1 << offs))
1161      {
1162         UML_SUB(block, DRC_REG(13), DRC_REG(13), 4);
1163         UML_MOV(block, I0, DRC_REG(13));
1164         UML_MOV(block, I1, DRC_REG(offs));
1165         UML_CALLH(block, *arm->impstate->write32);
1166      }
1167   }
1168   UML_ADD(block, DRC_PC, DRC_PC, 2);
1169}
1170
1171const void drctg0b_6(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1172{
1173   UINT32 op = desc->opptr.l[0];
1174   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1175}
1176
1177const void drctg0b_7(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1178{
1179   UINT32 op = desc->opptr.l[0];
1180   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1181}
1182
1183const void drctg0b_8(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1184{
1185   UINT32 op = desc->opptr.l[0];
1186   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1187}
1188
1189const void drctg0b_9(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1190{
1191   UINT32 op = desc->opptr.l[0];
1192   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1193}
1194
1195const void drctg0b_a(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1196{
1197   UINT32 op = desc->opptr.l[0];
1198   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1199}
1200
1201const void drctg0b_b(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1202{
1203   UINT32 op = desc->opptr.l[0];
1204   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1205}
1206
1207const void tg0b_c(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* POP {Rlist} */
1208{
1209   UINT32 op = desc->opptr.l[0];
1210   for (INT32 offs = 0; offs < 8; offs++)
1211   {
1212      if (op & (1 << offs))
1213      {
1214         UML_MOV(block, I0, DRC_REG(13));
1215         UML_CALLH(block, *arm->impstate->read32);
1216         UML_MOV(block, DRC_REG(offs), I0);
1217         UML_ADD(block, DRC_REG(13), DRC_REG(13), 4);
1218      }
1219   }
1220   UML_ADD(block, DRC_PC, DRC_PC, 2);
1221}
1222
1223const void drctg0b_d(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* POP {Rlist}{PC} */
1224{
1225   UINT32 op = desc->opptr.l[0];
1226   code_label arch5up;
1227   code_label done;
1228   code_label switch_mode;
1229   for (INT32 offs = 0; offs < 8; offs++)
1230   {
1231      if (op & (1 << offs))
1232      {
1233         UML_MOV(block, I0, DRC_REG(13));
1234         UML_CALLH(block, *arm->impstate->read32);
1235         UML_MOV(block, DRC_REG(offs), I0);
1236         UML_ADD(block, DRC_REG(13), DRC_REG(13), 4);
1237      }
1238   }
1239   UML_MOV(block, I0, DRC_REG(13));
1240   UML_CALLH(block, *arm->impstate->read32);
1241   UML_CMP(block, mem(&arm->archRev), 4);
1242   UML_JMPc(block, COND_A, arch5up = compiler->labelnum++);
1243   UML_AND(block, DRC_PC, I0, ~1);
1244
1245   UML_LABEL(block, arch5up);
1246
1247   UML_TEST(block, I0, 1);
1248   UML_JMPc(block, COND_Z, switch_mode = compiler->labelnum++);
1249
1250   UML_AND(block, I0, I0, ~1);
1251   UML_MOV(block, DRC_PC, I0);
1252   UML_JMP(block done);
1253
1254   UML_LABEL(block, switch_mode);
1255   UML_AND(block, DRC_CPSR, DRC_CPSR, ~T_MASK);
1256   UML_TEST(block, I0, 2);
1257   UML_MOVc(block, COND_NZ, I1, 2);
1258   UML_MOVc(block, COND_Z, I1, 0);
1259   UML_ADD(block, I0, I0, I1);
1260   UML_MOV(block, DRC_PC, I0);
1261
1262   UML_LABEL(block, done);
1263   UML_ADD(block, DRC_REG(13), DRC_REG(13), 4);
1264}
1265
1266const void drctg0b_e(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1267{
1268   UINT32 op = desc->opptr.l[0];
1269   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1270}
1271
1272const void drctg0b_f(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1273{
1274   UINT32 op = desc->opptr.l[0];
1275   fatalerror("%08x: Gb Undefined Thumb instruction: %04x\n", pc, op);
1276}
1277
1278/* Multiple Load/Store */
1279
1280// "The address should normally be a word aligned quantity and non-word aligned addresses do not affect the instruction."
1281// "However, the bottom 2 bits of the address will appear on A[1:0] and might be interpreted by the memory system."
1282
1283// GBA "BB Ball" performs an unaligned read with A[1:0] = 2 and expects A[1] not to be ignored [BP 800B90A,(R4&3)!=0]
1284// GBA "Gadget Racers" performs an unaligned read with A[1:0] = 1 and expects A[0] to be ignored [BP B72,(R0&3)!=0]
1285
1286const void drctg0c_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Store */
1287{
1288   UINT32 op = desc->opptr.l[0];
1289   UINT32 rd = (op & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
1290   UML_MOV(block, I2, DRC_REG(rd));
1291   for (INT32 offs = 0; offs < 8; offs++)
1292   {
1293      if (op & (1 << offs))
1294      {
1295         UML_AND(block, I0, I2, ~3);
1296         UML_MOV(block, I1, DRC_REG(offs));
1297         UML_CALLH(block, *arm->impstate->write32);
1298         UML_ADD(block, I2, I2, 4);
1299      }
1300   }
1301   UML_MOV(block, DRC_REG(rd), I2);
1302   UML_ADD(block, DRC_PC, DRC_PC, 2);
1303}
1304
1305const void drctg0c_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* Load */
1306{
1307   UINT32 op = desc->opptr.l[0];
1308   UINT32 rd = (op & THUMB_MULTLS_BASE) >> THUMB_MULTLS_BASE_SHIFT;
1309   int rd_in_list = op & (1 << rd);
1310   UML_MOV(block, I2, DRC_REG(rd));
1311   for (INT32 offs = 0; offs < 8; offs++)
1312   {
1313      if (op & (1 << offs))
1314      {
1315         UML_AND(block, I0, I2, ~1);
1316         UML_CALLH(block, *arm->impstate->read32);
1317         UML_ADD(block, I2, I2, 4);
1318      }
1319   }
1320   if (!rd_in_list)
1321   {
1322      UML_MOV(block, DRC_REG(rd), I2);
1323   }
1324   UML_ADD(block, DRC_PC, DRC_PC, 2);
1325}
1326
1327   /* Conditional Branch */
1328
1329const void drctg0d_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_EQ:
1330{
1331   UINT32 op = desc->opptr.l[0];
1332   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1333   UML_TEST(block, DRC_CPSR, Z_MASK);
1334   UML_MOVc(block, COND_NZ, I0, offs);
1335   UML_MOVc(block, COND_Z, I0, 2);
1336   UML_ADD(block, COND_PC, COND_PC, I0);
1337}
1338
1339const void drctg0d_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_NE:
1340{
1341   UINT32 op = desc->opptr.l[0];
1342   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1343   UML_TEST(block, DRC_CPSR, Z_MASK);
1344   UML_MOVc(block, COND_Z, I0, offs);
1345   UML_MOVc(block, COND_NZ, I0, 2);
1346   UML_ADD(block, COND_PC, COND_PC, I0);
1347}
1348
1349const void drctg0d_2(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_CS:
1350{
1351   UINT32 op = desc->opptr.l[0];
1352   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1353   UML_TEST(block, DRC_CPSR, C_MASK);
1354   UML_MOVc(block, COND_NZ, I0, offs);
1355   UML_MOVc(block, COND_Z, I0, 2);
1356   UML_ADD(block, COND_PC, COND_PC, I0);
1357}
1358
1359const void drctg0d_3(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_CC:
1360{
1361   UINT32 op = desc->opptr.l[0];
1362   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1363   UML_TEST(block, DRC_CPSR, C_MASK);
1364   UML_MOVc(block, COND_Z, I0, offs);
1365   UML_MOVc(block, COND_NZ, I0, 2);
1366   UML_ADD(block, COND_PC, COND_PC, I0);
1367}
1368
1369const void drctg0d_4(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_MI:
1370{
1371   UINT32 op = desc->opptr.l[0];
1372   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1373   UML_TEST(block, DRC_CPSR, N_MASK);
1374   UML_MOVc(block, COND_NZ, I0, offs);
1375   UML_MOVc(block, COND_Z, I0, 2);
1376   UML_ADD(block, COND_PC, COND_PC, I0);
1377}
1378
1379const void drctg0d_5(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_PL:
1380{
1381   UINT32 op = desc->opptr.l[0];
1382   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1383   UML_TEST(block, DRC_CPSR, N_MASK);
1384   UML_MOVc(block, COND_Z, I0, offs);
1385   UML_MOVc(block, COND_NZ, I0, 2);
1386   UML_ADD(block, COND_PC, COND_PC, I0);
1387}
1388
1389const void drctg0d_6(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_VS:
1390{
1391   UINT32 op = desc->opptr.l[0];
1392   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1393   UML_TEST(block, DRC_CPSR, V_MASK);
1394   UML_MOVc(block, COND_NZ, I0, offs);
1395   UML_MOVc(block, COND_Z, I0, 2);
1396   UML_ADD(block, COND_PC, COND_PC, I0);
1397}
1398
1399const void drctg0d_7(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_VC:
1400{
1401   UINT32 op = desc->opptr.l[0];
1402   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1403   UML_TEST(block, DRC_CPSR, V_MASK);
1404   UML_MOVc(block, COND_Z, I0, offs);
1405   UML_MOVc(block, COND_NZ, I0, 2);
1406   UML_ADD(block, COND_PC, COND_PC, I0);
1407}
1408
1409const void drctg0d_8(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_HI:
1410{
1411   UINT32 op = desc->opptr.l[0];
1412   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1413   UML_TEST(block, DRC_CPSR, C_MASK);
1414   UML_MOVc(block, COND_NZ, I0, 1);
1415   UML_MOVc(block, COND_Z, I0, 0);
1416   UML_TEST(block, DRC_CPSR, Z_MASK);
1417   UML_MOVc(block, COND_NZ, I1, 0);
1418   UML_MOVc(block, COND_Z, I1, 1);
1419   UML_AND(block, I0, I0, I1);
1420   UML_TEST(block, I0, 1);
1421   UML_MOVc(block, COND_NZ, I0, offs);
1422   UML_MOVc(block, COND_Z, I0, 2);
1423   UML_ADD(block, COND_PC, COND_PC, I0);
1424}
1425
1426const void drctg0d_9(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_LS:
1427{
1428   UINT32 op = desc->opptr.l[0];
1429   INT32 offs = ((INT8)(op & THUMB_INSN_IMM) << 1) + 4;
1430   UML_TEST(block, DRC_CPSR, C_MASK);
1431   UML_MOVc(block, COND_Z, I0, 1);
1432   UML_MOVc(block, COND_NZ, I0, 0);
1433   UML_TEST(block, DRC_CPSR, Z_MASK);
1434   UML_MOVc(block, COND_Z, I1, 0);
1435   UML_MOVc(block, COND_NZ, I1, 1);
1436   UML_AND(block, I0, I0, I1);
1437   UML_TEST(block, I0, 1);
1438   UML_MOVc(block, COND_NZ, I0, offs);
1439   UML_MOVc(block, COND_Z, I0, 2);
1440   UML_ADD(block, COND_PC, COND_PC, I0);
1441}
1442
1443const void drctg0d_a(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_GE:
1444{
1445   UINT32 op = desc->opptr.l[0];
1446   UML_TEST(block, DRC_CPSR, N_MASK);
1447   UML_MOVc(block, COND_Z, I0, 1);
1448   UML_MOVc(block, COND_NZ, I0, 0);
1449   UML_TEST(block, DRC_CPSR, V_MASK);
1450   UML_MOVc(block, COND_Z, I1, 0);
1451   UML_MOVc(block, COND_NZ, I1, 1);
1452   UML_CMP(block, I0, I1);
1453   UML_MOVc(block, COND_E, I0, offs);
1454   UML_MOVc(block, COND_NE, I0, 2);
1455   UML_ADD(block, COND_PC, COND_PC, I0);
1456}
1457
1458const void drctg0d_b(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_LT:
1459{
1460   UINT32 op = desc->opptr.l[0];
1461   UML_TEST(block, DRC_CPSR, N_MASK);
1462   UML_MOVc(block, COND_Z, I0, 1);
1463   UML_MOVc(block, COND_NZ, I0, 0);
1464   UML_TEST(block, DRC_CPSR, V_MASK);
1465   UML_MOVc(block, COND_Z, I1, 0);
1466   UML_MOVc(block, COND_NZ, I1, 1);
1467   UML_CMP(block, I0, I1);
1468   UML_MOVc(block, COND_NE, I0, offs);
1469   UML_MOVc(block, COND_E, I0, 2);
1470   UML_ADD(block, COND_PC, COND_PC, I0);
1471}
1472
1473const void drctg0d_c(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_GT:
1474{
1475   UINT32 op = desc->opptr.l[0];
1476   UML_TEST(block, DRC_CPSR, N_MASK);
1477   UML_MOVc(block, COND_Z, I0, 1);
1478   UML_MOVc(block, COND_NZ, I0, 0);
1479   UML_TEST(block, DRC_CPSR, V_MASK);
1480   UML_MOVc(block, COND_Z, I1, 0);
1481   UML_MOVc(block, COND_NZ, I1, 1);
1482   UML_CMP(block, I0, I1);
1483   UML_MOVc(block, COND_E, I0, 1);
1484   UML_MOVc(block, COND_NE, I0, 0);
1485   UML_TEST(block, DRC_CPSR, Z_MASK);
1486   UML_MOVc(block, COND_NZ, I1, 1);
1487   UML_MOVc(block, COND_Z, I1, 0);
1488   UML_AND(block, I0, I0, I1);
1489   UML_TEST(block, I0, 1);
1490   UML_MOVc(block, COND_NZ, I0, offs);
1491   UML_MOVc(block, COND_Z, I0, 2);
1492   UML_ADD(block, COND_PC, COND_PC, I0);
1493}
1494
1495const void drctg0d_d(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_LE:
1496{
1497   UINT32 op = desc->opptr.l[0];
1498   UML_TEST(block, DRC_CPSR, N_MASK);
1499   UML_MOVc(block, COND_Z, I0, 1);
1500   UML_MOVc(block, COND_NZ, I0, 0);
1501   UML_TEST(block, DRC_CPSR, V_MASK);
1502   UML_MOVc(block, COND_Z, I1, 0);
1503   UML_MOVc(block, COND_NZ, I1, 1);
1504   UML_CMP(block, I0, I1);
1505   UML_MOVc(block, COND_NE, I0, 1);
1506   UML_MOVc(block, COND_E, I0, 0);
1507   UML_TEST(block, DRC_CPSR, Z_MASK);
1508   UML_MOVc(block, COND_NZ, I1, 0);
1509   UML_MOVc(block, COND_Z, I1, 1);
1510   UML_AND(block, I0, I0, I1);
1511   UML_TEST(block, I0, 1);
1512   UML_MOVc(block, COND_NZ, I0, offs);
1513   UML_MOVc(block, COND_Z, I0, 2);
1514   UML_ADD(block, COND_PC, COND_PC, I0);
1515}
1516
1517const void drctg0d_e(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // COND_AL:
1518{
1519   UINT32 op = desc->opptr.l[0];
1520   fatalerror("%08x: Undefined Thumb instruction: %04x (ARM9 reserved)\n", pc, op);
1521}
1522
1523const void drctg0d_f(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) // SWI (this is sort of a "hole" in the opcode encoding)
1524{
1525   UINT32 op = desc->opptr.l[0];
1526   UML_MOV(block, mem(&arm->pendingSwi), 1);
1527   UML_CALLH(block, *arm->impstate->check_irq);
1528}
1529
1530   /* B #offs */
1531
1532const void drctg0e_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1533{
1534   UINT32 op = desc->opptr.l[0];
1535   INT32 offs = (op & THUMB_BRANCH_OFFS) << 1;
1536   if (offs & 0x00000800)
1537   {
1538      offs |= 0xfffff800;
1539   }
1540   UML_ADD(block, DRC_PC, DRC_PC, offs + 4);
1541}
1542
1543const void drctg0e_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1544{
1545   UINT32 op = desc->opptr.l[0];
1546   UINT32 offs = (op & THUMB_BLOP_OFFS) << 1;
1547   UML_MOV(block, I0, DRC_REG(14));
1548   UML_ADD(block, I0, I0, offs);
1549   UML_AND(block, I0, I0, ~3);
1550   UML_ADD(block, DRC_REG(14), DRC_PC, 4);
1551   UML_OR(block, DRC_REG(14), DRC_REG(14), 1);
1552   UML_MOV(block, DRC_PC, I0);
1553}
1554
1555   /* BL */
1556
1557const void drctg0f_0(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc)
1558{
1559   UINT32 op = desc->opptr.l[0];
1560   UINT32 addr = (op & THUMB_BLOP_OFFS) << 12;
1561   if (addr & (1 << 22))
1562   {
1563      addr |= 0xff800000;
1564   }
1565   addr += 4;
1566   UML_ADD(block, DRC_REG(14), DRC_PC, addr);
1567   UML_ADD(block, DRC_PC, DRC_PC, 2);
1568}
1569
1570const void drctg0f_1(arm_state *arm, drcuml_block *block, compiler_state *compiler, const opcode_desc *desc) /* BL */
1571{
1572   UINT32 op = desc->opptr.l[0];
1573   UINT32 addr = (op & THUMB_BLOP_OFFS) << 1;
1574   UML_AND(block, I0, DRC_REG(14), ~1);
1575   UML_ADD(block, I0, I0, addr);
1576   UML_ADD(block, DRC_REG(14), DRC_PC, 2);
1577   UML_OR(block, DRC_REG(14), DRC_REG(14), 1);
1578   UML_MOV(block, DRC_PC, I0);
1579}
1580
1581#endif // ARM7_USE_DRC
No newline at end of file
Property changes on: trunk/src/emu/cpu/arm7/arm7tdrc.c
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/emu/cpu/arm7/arm7help.h
r20737r20738
4242            | HandleALUNZFlags(rd)));                                                           \
4343   R15 += 2;
4444
45#define DRCHandleThumbALUAddFlags(rd, rn, op2)                                       \
46   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(N_MASK | Z_MASK | V_MASK | C_MASK));               \
47   DRCHandleALUNZFlags(rd);                                                   \
48   UML_XOR(block, I1, rn, ~0);                                                   \
49   UML_CMP(block, I1, op2);                                                   \
50   UML_MOVc(block, COND_B, I1, C_BIT);                                             \
51   UML_MOVc(block, COND_AE, I1, 0);                                             \
52   UML_OR(block, I0, I0, I1);                                                   \
53   UML_XOR(block, I1, rn, op2);                                                \
54   UML_XOR(block, I2, rn, rd);                                                   \
55   UML_AND(block, I1, I1, I2);                                                   \
56   UML_TEST(block, I1, 1 << 31);                                                \
57   UML_MOVc(block, COND_NZ, I1, V_BIT);                                          \
58   UML_MOVc(block, COND_Z, I1, 0);                                                \
59   UML_OR(block, I0, I0, I1);                                                   \
60   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);                                          \
61   UML_ADD(block, DRC_PC, DRC_PC, 2);
62
4563#define HandleALUSubFlags(rd, rn, op2)                                                                         \
4664   if (insn & INSN_S)                                                                                           \
4765   SET_CPSR(((GET_CPSR & ~(N_MASK | Z_MASK | V_MASK | C_MASK))                                                \
r20737r20738
5775            | HandleALUNZFlags(rd)));                                                                        \
5876   R15 += 2;
5977
78#define DRCHandleThumbALUSubFlags(rd, rn, op2)                                       \
79   UML_AND(block, DRC_CPSR, DRC_CPSR, ~(N_MASK | Z_MASK | V_MASK | C_MASK));               \
80   DRCHandleALUNZFlags(rd);                                                   \
81   UML_XOR(block, I1, rn, op2);                                                \
82   UML_XOR(block, I2, rn, rd);                                                   \
83   UML_AND(block, I1, I1, I2);                                                   \
84   UML_TEST(block, I1, 1 << 31);                                                \
85   UML_MOVc(block, COND_NZ, I1, V_BIT);                                          \
86   UML_MOVc(block, COND_Z, I1, 0);                                                \
87   UML_OR(block, I0, I0, I1);                                                   \
88   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);                                          \
89   UML_AND(block, I0, rd, 1 << 31);                                             \
90   UML_AND(block, I1, op2, 1 << 31);                                             \
91   UML_AND(block, I2, rn, 1 << 31);                                             \
92   UML_XOR(block, I2, I2, ~0);                                                   \
93   UML_AND(block, I1, I1, I2);                                                   \
94   UML_AND(block, I2, I2, I0);                                                   \
95   UML_OR(block, I1, I1, I2);                                                   \
96   UML_AND(block, I2, op2, 1 << 31);                                             \
97   UML_AND(block, I2, I2, I0);                                                   \
98   UML_OR(block, I1, I1, I2);                                                   \
99   UML_TEST(block, I1, 1 << 31);                                                \
100   UML_MOVc(block, COND_NZ, I0, C_MASK);                                          \
101   UML_MOVc(block, COND_Z, I0, 0);                                                \
102   UML_OR(block, DRC_CPSR, DRC_CPSR, I0);                                          \
103   UML_ADD(block, DRC_PC, DRC_PC, 2);
104
60105/* Set NZC flags for logical operations. */
61106
62107// This macro (which I didn't write) - doesn't make it obvious that the SIGN BIT = 31, just as the N Bit does,
r20737r20738
64109#define HandleALUNZFlags(rd)               \
65110   (((rd) & SIGN_BIT) | ((!(rd)) << Z_BIT))
66111
112#define DRCHandleALUNZFlags(rd)               \
113   UML_AND(block, I0, rd, SIGN_BIT);         \
114   UML_CMP(block, rd, 0);                  \
115   UML_MOVc(block, COND_E, I1, 1);            \
116   UML_MOVc(block, COND_NE, I1, 0);         \
117   UML_ROLINS(block, I0, I1, Z_BIT, 1 << Z_BIT);
67118
68119// Long ALU Functions use bit 63
69120#define HandleLongALUNZFlags(rd)                            \
r20737r20738
76127            | (((sc) != 0) << C_BIT)));              \
77128   R15 += 4;
78129
130#define DRC_RD      mem(&GET_REGISTER(arm, rd))
131#define DRC_RS      mem(&GET_REGISTER(arm, rs))
132#define DRC_CPSR   mem(&GET_CPSR)
133#define DRC_PC      mem(&R15)
134#define DRC_REG(i)   mem(&arm->r[(i)]);
135
136#define DRCHandleALULogicalFlags(rd, sc)                        \
137   if (insn & INSN_S)                                       \
138   {                                                   \
139      UML_AND(block, DRC_CPSR, DRC_CPSR, ~(N_MASK | Z_MASK | C_MASK);   \
140      DRCHandleALUNZFlags(rd);                              \
141      UML_TEST(block, sc, ~0);                              \
142      UML_MOVc(block, COND_Z, I1, C_BIT);                        \
143      UML_MOVc(block, COND_NZ, I1, 0);                        \
144      UML_OR(block, I0, I0, I1);                              \
145      UML_OR(block, DRC_CPSR, DRC_CPSR, I0);                     \
146   }                                                   \
147   UML_ADD(block, DRC_PC, DRC_PC, 4);
148
79149void set_cpsr( arm_state *arm, UINT32 val);
80150
81151// used to be functions, but no longer a need, so we'll use define for better speed.
r20737r20738
89159void arm7_check_irq_state(arm_state *arm);
90160
91161typedef const void (*arm7thumb_ophandler)(arm_state*, UINT32, UINT32);
92
93162extern arm7thumb_ophandler thumb_handler[0x40*0x10];
94163
95164typedef const void (*arm7ops_ophandler)(arm_state*, UINT32);
trunk/src/emu/cpu/arm7/arm7.h
r20737r20738
5454   CPUINFO_PTR_ARM7_FASTRAM_BASE = CPUINFO_PTR_CPU_SPECIFIC
5555};
5656
57/***************************************************************************
58    COMPILER-SPECIFIC OPTIONS
59***************************************************************************/
60
61#define ARM7DRC_STRICT_VERIFY      0x0001          /* verify all instructions */
62#define ARM7DRC_FLUSH_PC           0x0008          /* flush the PC value before each memory access */
63
64#define ARM7DRC_COMPATIBLE_OPTIONS (ARM7DRC_STRICT_VERIFY | ARM7DRC_FLUSH_PC)
65#define ARM7DRC_FASTEST_OPTIONS    (0)
66
5767/****************************************************************************************************
5868 *  PUBLIC FUNCTIONS
5969 ***************************************************************************************************/

Previous 199869 Revisions Next


© 1997-2024 The MAME Team