Home | History | Annotate | Line # | Download | only in arm
      1 /*  armemu.c -- Main instruction emulation:  ARM7 Instruction Emulator.
      2     Copyright (C) 1994 Advanced RISC Machines Ltd.
      3     Modifications to add arch. v4 support by <jsmith (at) cygnus.com>.
      4 
      5     This program is free software; you can redistribute it and/or modify
      6     it under the terms of the GNU General Public License as published by
      7     the Free Software Foundation; either version 3 of the License, or
      8     (at your option) any later version.
      9 
     10     This program is distributed in the hope that it will be useful,
     11     but WITHOUT ANY WARRANTY; without even the implied warranty of
     12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13     GNU General Public License for more details.
     14 
     15     You should have received a copy of the GNU General Public License
     16     along with this program; if not, see <http://www.gnu.org/licenses/>.  */
     17 
     18 /* This must come before any other includes.  */
     19 #include "defs.h"
     20 
     21 #include "armdefs.h"
     22 #include "armemu.h"
     23 #include "armos.h"
     24 #include "iwmmxt.h"
     25 
     26 static ARMword  GetDPRegRHS         (ARMul_State *, ARMword);
     27 static ARMword  GetDPSRegRHS        (ARMul_State *, ARMword);
     28 static void     WriteR15            (ARMul_State *, ARMword);
     29 static void     WriteSR15           (ARMul_State *, ARMword);
     30 static void     WriteR15Branch      (ARMul_State *, ARMword);
     31 static void     WriteR15Load        (ARMul_State *, ARMword);
     32 static ARMword  GetLSRegRHS         (ARMul_State *, ARMword);
     33 static ARMword  GetLS7RHS           (ARMul_State *, ARMword);
     34 static unsigned LoadWord            (ARMul_State *, ARMword, ARMword);
     35 static unsigned LoadHalfWord        (ARMul_State *, ARMword, ARMword, int);
     36 static unsigned LoadByte            (ARMul_State *, ARMword, ARMword, int);
     37 static unsigned StoreWord           (ARMul_State *, ARMword, ARMword);
     38 static unsigned StoreHalfWord       (ARMul_State *, ARMword, ARMword);
     39 static unsigned StoreByte           (ARMul_State *, ARMword, ARMword);
     40 static void     LoadMult            (ARMul_State *, ARMword, ARMword, ARMword);
     41 static void     StoreMult           (ARMul_State *, ARMword, ARMword, ARMword);
     42 static void     LoadSMult           (ARMul_State *, ARMword, ARMword, ARMword);
     43 static void     StoreSMult          (ARMul_State *, ARMword, ARMword, ARMword);
     44 static unsigned Multiply64          (ARMul_State *, ARMword, int, int);
     45 static unsigned MultiplyAdd64       (ARMul_State *, ARMword, int, int);
     46 static void     Handle_Load_Double  (ARMul_State *, ARMword);
     47 static void     Handle_Store_Double (ARMul_State *, ARMword);
     48 
     49 #define LUNSIGNED (0)		/* unsigned operation */
     50 #define LSIGNED   (1)		/* signed operation */
     51 #define LDEFAULT  (0)		/* default : do nothing */
     52 #define LSCC      (1)		/* set condition codes on result */
     53 
     54 extern int stop_simulator;
     55 
     56 /* Short-hand macros for LDR/STR.  */
     57 
     58 /* Store post decrement writeback.  */
     59 #define SHDOWNWB()                                      \
     60   lhs = LHS ;                                           \
     61   if (StoreHalfWord (state, instr, lhs))                \
     62      LSBase = lhs - GetLS7RHS (state, instr);
     63 
     64 /* Store post increment writeback.  */
     65 #define SHUPWB()                                        \
     66   lhs = LHS ;                                           \
     67   if (StoreHalfWord (state, instr, lhs))                \
     68      LSBase = lhs + GetLS7RHS (state, instr);
     69 
     70 /* Store pre decrement.  */
     71 #define SHPREDOWN()                                     \
     72   (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr));
     73 
     74 /* Store pre decrement writeback.  */
     75 #define SHPREDOWNWB()                                   \
     76   temp = LHS - GetLS7RHS (state, instr);                \
     77   if (StoreHalfWord (state, instr, temp))               \
     78      LSBase = temp;
     79 
     80 /* Store pre increment.  */
     81 #define SHPREUP()                                       \
     82   (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr));
     83 
     84 /* Store pre increment writeback.  */
     85 #define SHPREUPWB()                                     \
     86   temp = LHS + GetLS7RHS (state, instr);                \
     87   if (StoreHalfWord (state, instr, temp))               \
     88      LSBase = temp;
     89 
     90 /* Load post decrement writeback.  */
     91 #define LHPOSTDOWN()                                    \
     92 {                                                       \
     93   int done = 1;                                        	\
     94   lhs = LHS;						\
     95   temp = lhs - GetLS7RHS (state, instr);		\
     96   							\
     97   switch (BITS (5, 6))					\
     98     {                                  			\
     99     case 1: /* H */                                     \
    100       if (LoadHalfWord (state, instr, lhs, LUNSIGNED))  \
    101          LSBase = temp;        				\
    102       break;                                           	\
    103     case 2: /* SB */                                    \
    104       if (LoadByte (state, instr, lhs, LSIGNED))        \
    105          LSBase = temp;        				\
    106       break;                                           	\
    107     case 3: /* SH */                                    \
    108       if (LoadHalfWord (state, instr, lhs, LSIGNED))    \
    109          LSBase = temp;        				\
    110       break;                                           	\
    111     case 0: /* SWP handled elsewhere.  */               \
    112     default:                                            \
    113       done = 0;                                        	\
    114       break;                                           	\
    115     }                                                   \
    116   if (done)                                             \
    117      break;                                            	\
    118 }
    119 
    120 /* Load post increment writeback.  */
    121 #define LHPOSTUP()                                      \
    122 {                                                       \
    123   int done = 1;                                        	\
    124   lhs = LHS;                                           	\
    125   temp = lhs + GetLS7RHS (state, instr);		\
    126   							\
    127   switch (BITS (5, 6))					\
    128     {                                  			\
    129     case 1: /* H */                                     \
    130       if (LoadHalfWord (state, instr, lhs, LUNSIGNED))  \
    131          LSBase = temp;        				\
    132       break;                                           	\
    133     case 2: /* SB */                                    \
    134       if (LoadByte (state, instr, lhs, LSIGNED))        \
    135          LSBase = temp;        				\
    136       break;                                           	\
    137     case 3: /* SH */                                    \
    138       if (LoadHalfWord (state, instr, lhs, LSIGNED))    \
    139          LSBase = temp;        				\
    140       break;                                           	\
    141     case 0: /* SWP handled elsewhere.  */               \
    142     default:                                            \
    143       done = 0;                                        	\
    144       break;                                           	\
    145     }                                                   \
    146   if (done)                                             \
    147      break;                                            	\
    148 }
    149 
    150 /* Load pre decrement.  */
    151 #define LHPREDOWN()                                     	\
    152 {                                                       	\
    153   int done = 1;                                        		\
    154 								\
    155   temp = LHS - GetLS7RHS (state, instr);                 	\
    156   switch (BITS (5, 6))						\
    157     {                                  				\
    158     case 1: /* H */                                     	\
    159       (void) LoadHalfWord (state, instr, temp, LUNSIGNED);  	\
    160       break;                                           		\
    161     case 2: /* SB */                                    	\
    162       (void) LoadByte (state, instr, temp, LSIGNED);        	\
    163       break;                                           		\
    164     case 3: /* SH */                                    	\
    165       (void) LoadHalfWord (state, instr, temp, LSIGNED);    	\
    166       break;                                           		\
    167     case 0:							\
    168       /* SWP handled elsewhere.  */                 		\
    169     default:                                            	\
    170       done = 0;                                        		\
    171       break;                                           		\
    172     }                                                   	\
    173   if (done)                                             	\
    174      break;                                            		\
    175 }
    176 
    177 /* Load pre decrement writeback.  */
    178 #define LHPREDOWNWB()                                   	\
    179 {                                                       	\
    180   int done = 1;                                        		\
    181 								\
    182   temp = LHS - GetLS7RHS (state, instr);                	\
    183   switch (BITS (5, 6))						\
    184     {                                  				\
    185     case 1: /* H */                                     	\
    186       if (LoadHalfWord (state, instr, temp, LUNSIGNED))     	\
    187          LSBase = temp;                                		\
    188       break;                                           		\
    189     case 2: /* SB */                                    	\
    190       if (LoadByte (state, instr, temp, LSIGNED))           	\
    191          LSBase = temp;                                		\
    192       break;                                           		\
    193     case 3: /* SH */                                    	\
    194       if (LoadHalfWord (state, instr, temp, LSIGNED))       	\
    195          LSBase = temp;                                		\
    196       break;                                           		\
    197     case 0:							\
    198       /* SWP handled elsewhere.  */                 		\
    199     default:                                            	\
    200       done = 0;                                        		\
    201       break;                                           		\
    202     }                                                   	\
    203   if (done)                                             	\
    204      break;                                            		\
    205 }
    206 
    207 /* Load pre increment.  */
    208 #define LHPREUP()                                       	\
    209 {                                                       	\
    210   int done = 1;                                        		\
    211 								\
    212   temp = LHS + GetLS7RHS (state, instr);                 	\
    213   switch (BITS (5, 6))						\
    214     {                                  				\
    215     case 1: /* H */                                     	\
    216       (void) LoadHalfWord (state, instr, temp, LUNSIGNED);  	\
    217       break;                                           		\
    218     case 2: /* SB */                                    	\
    219       (void) LoadByte (state, instr, temp, LSIGNED);        	\
    220       break;                                           		\
    221     case 3: /* SH */                                    	\
    222       (void) LoadHalfWord (state, instr, temp, LSIGNED);    	\
    223       break;                                           		\
    224     case 0:							\
    225       /* SWP handled elsewhere.  */                 		\
    226     default:                                            	\
    227       done = 0;                                        		\
    228       break;                                           		\
    229     }                                                   	\
    230   if (done)                                             	\
    231      break;                                            		\
    232 }
    233 
    234 /* Load pre increment writeback.  */
    235 #define LHPREUPWB()                                     	\
    236 {                                                       	\
    237   int done = 1;                                        		\
    238 								\
    239   temp = LHS + GetLS7RHS (state, instr);                	\
    240   switch (BITS (5, 6))						\
    241     {                                  				\
    242     case 1: /* H */                                     	\
    243       if (LoadHalfWord (state, instr, temp, LUNSIGNED))     	\
    244 	LSBase = temp;                                		\
    245       break;                                           		\
    246     case 2: /* SB */                                    	\
    247       if (LoadByte (state, instr, temp, LSIGNED))           	\
    248 	LSBase = temp;                                		\
    249       break;                                           		\
    250     case 3: /* SH */                                    	\
    251       if (LoadHalfWord (state, instr, temp, LSIGNED))       	\
    252 	LSBase = temp;                                		\
    253       break;                                           		\
    254     case 0:							\
    255       /* SWP handled elsewhere.  */                 		\
    256     default:                                            	\
    257       done = 0;                                        		\
    258       break;                                           		\
    259     }                                                   	\
    260   if (done)                                             	\
    261      break;                                            		\
    262 }
    263 
    264 /* Attempt to emulate an ARMv6 instruction.
    265    Returns non-zero upon success.  */
    266 
    267 #ifdef MODE32
    268 static int
    269 handle_v6_insn (ARMul_State * state, ARMword instr)
    270 {
    271   ARMword val;
    272   ARMword Rd;
    273   ARMword Rm;
    274   ARMword Rn;
    275 
    276   switch (BITS (20, 27))
    277     {
    278 #if 0
    279     case 0x03: printf ("Unhandled v6 insn: ldr\n"); break;
    280     case 0x04: printf ("Unhandled v6 insn: umaal\n"); break;
    281     case 0x06: printf ("Unhandled v6 insn: mls/str\n"); break;
    282     case 0x16: printf ("Unhandled v6 insn: smi\n"); break;
    283     case 0x18: printf ("Unhandled v6 insn: strex\n"); break;
    284     case 0x19: printf ("Unhandled v6 insn: ldrex\n"); break;
    285     case 0x1a: printf ("Unhandled v6 insn: strexd\n"); break;
    286     case 0x1b: printf ("Unhandled v6 insn: ldrexd\n"); break;
    287     case 0x1c: printf ("Unhandled v6 insn: strexb\n"); break;
    288     case 0x1d: printf ("Unhandled v6 insn: ldrexb\n"); break;
    289     case 0x1e: printf ("Unhandled v6 insn: strexh\n"); break;
    290     case 0x1f: printf ("Unhandled v6 insn: ldrexh\n"); break;
    291     case 0x32: printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n"); break;
    292     case 0x3f: printf ("Unhandled v6 insn: rbit\n"); break;
    293 #endif
    294     case 0x61: printf ("Unhandled v6 insn: sadd/ssub\n"); break;
    295     case 0x63: printf ("Unhandled v6 insn: shadd/shsub\n"); break;
    296     case 0x6c: printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); break;
    297     case 0x70: printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); break;
    298     case 0x74: printf ("Unhandled v6 insn: smlald/smlsld\n"); break;
    299     case 0x75: printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); break;
    300     case 0x78: printf ("Unhandled v6 insn: usad/usada8\n"); break;
    301 
    302     case 0x30:
    303       {
    304 	/* MOVW<c> <Rd>,#<imm16>
    305 	   instr[31,28] = cond
    306 	   instr[27,20] = 0011 0000
    307 	   instr[19,16] = imm4
    308 	   instr[15,12] = Rd
    309 	   instr[11, 0] = imm12.  */
    310 	Rd = BITS (12, 15);
    311 	val = (BITS (16, 19) << 12) | BITS (0, 11);
    312 	state->Reg[Rd] = val;
    313 	return 1;
    314       }
    315 
    316     case 0x34:
    317       {
    318 	/* MOVT<c> <Rd>,#<imm16>
    319 	   instr[31,28] = cond
    320 	   instr[27,20] = 0011 0100
    321 	   instr[19,16] = imm4
    322 	   instr[15,12] = Rd
    323 	   instr[11, 0] = imm12.  */
    324 	Rd = BITS (12, 15);
    325 	val = (BITS (16, 19) << 12) | BITS (0, 11);
    326 	state->Reg[Rd] &= 0xFFFF;
    327 	state->Reg[Rd] |= val << 16;
    328 	return 1;
    329       }
    330 
    331     case 0x62:
    332       {
    333 	ARMword val1;
    334 	ARMword val2;
    335 	ARMsword n, m, r;
    336 	int i;
    337 
    338 	Rd = BITS (12, 15);
    339 	Rn = BITS (16, 19);
    340 	Rm = BITS (0, 3);
    341 
    342 	if (Rd == 15 || Rn == 15 || Rm == 15)
    343 	  break;
    344 
    345 	val1 = state->Reg[Rn];
    346 	val2 = state->Reg[Rm];
    347 
    348 	switch (BITS (4, 11))
    349 	  {
    350 	  case 0xF1: /* QADD16<c> <Rd>,<Rn>,<Rm>.  */
    351 	    state->Reg[Rd] = 0;
    352 
    353 	    for (i = 0; i < 32; i+= 16)
    354 	      {
    355 		n = (val1 >> i) & 0xFFFF;
    356 		if (n & 0x8000)
    357 		  n |= -(1 << 16);
    358 
    359 		m = (val2 >> i) & 0xFFFF;
    360 		if (m & 0x8000)
    361 		  m |= -(1 << 16);
    362 
    363 		r = n + m;
    364 
    365 		if (r > 0x7FFF)
    366 		  r = 0x7FFF;
    367 		else if (r < -(0x8000))
    368 		  r = - 0x8000;
    369 
    370 		state->Reg[Rd] |= (r & 0xFFFF) << i;
    371 	      }
    372 	    return 1;
    373 
    374 	  case 0xF3: /* QASX<c> <Rd>,<Rn>,<Rm>.  */
    375 	    n = val1 & 0xFFFF;
    376 	    if (n & 0x8000)
    377 	      n |= -(1 << 16);
    378 
    379 	    m = (val2 >> 16) & 0xFFFF;
    380 	    if (m & 0x8000)
    381 	      m |= -(1 << 16);
    382 
    383 	    r = n - m;
    384 
    385 	    if (r > 0x7FFF)
    386 	      r = 0x7FFF;
    387 	    else if (r < -(0x8000))
    388 	      r = - 0x8000;
    389 
    390 	    state->Reg[Rd] = (r & 0xFFFF);
    391 
    392 	    n = (val1 >> 16) & 0xFFFF;
    393 	    if (n & 0x8000)
    394 	      n |= -(1 << 16);
    395 
    396 	    m = val2 & 0xFFFF;
    397 	    if (m & 0x8000)
    398 	      m |= -(1 << 16);
    399 
    400 	    r = n + m;
    401 
    402 	    if (r > 0x7FFF)
    403 	      r = 0x7FFF;
    404 	    else if (r < -(0x8000))
    405 	      r = - 0x8000;
    406 
    407 	    state->Reg[Rd] |= (r & 0xFFFF) << 16;
    408 	    return 1;
    409 
    410 	  case 0xF5: /* QSAX<c> <Rd>,<Rn>,<Rm>.  */
    411 	    n = val1 & 0xFFFF;
    412 	    if (n & 0x8000)
    413 	      n |= -(1 << 16);
    414 
    415 	    m = (val2 >> 16) & 0xFFFF;
    416 	    if (m & 0x8000)
    417 	      m |= -(1 << 16);
    418 
    419 	    r = n + m;
    420 
    421 	    if (r > 0x7FFF)
    422 	      r = 0x7FFF;
    423 	    else if (r < -(0x8000))
    424 	      r = - 0x8000;
    425 
    426 	    state->Reg[Rd] = (r & 0xFFFF);
    427 
    428 	    n = (val1 >> 16) & 0xFFFF;
    429 	    if (n & 0x8000)
    430 	      n |= -(1 << 16);
    431 
    432 	    m = val2 & 0xFFFF;
    433 	    if (m & 0x8000)
    434 	      m |= -(1 << 16);
    435 
    436 	    r = n - m;
    437 
    438 	    if (r > 0x7FFF)
    439 	      r = 0x7FFF;
    440 	    else if (r < -(0x8000))
    441 	      r = - 0x8000;
    442 
    443 	    state->Reg[Rd] |= (r & 0xFFFF) << 16;
    444 	    return 1;
    445 
    446 	  case 0xF7: /* QSUB16<c> <Rd>,<Rn>,<Rm>.  */
    447 	    state->Reg[Rd] = 0;
    448 
    449 	    for (i = 0; i < 32; i+= 16)
    450 	      {
    451 		n = (val1 >> i) & 0xFFFF;
    452 		if (n & 0x8000)
    453 		  n |= -(1 << 16);
    454 
    455 		m = (val2 >> i) & 0xFFFF;
    456 		if (m & 0x8000)
    457 		  m |= -(1 << 16);
    458 
    459 		r = n - m;
    460 
    461 		if (r > 0x7FFF)
    462 		  r = 0x7FFF;
    463 		else if (r < -(0x8000))
    464 		  r = - 0x8000;
    465 
    466 		state->Reg[Rd] |= (r & 0xFFFF) << i;
    467 	      }
    468 	    return 1;
    469 
    470 	  case 0xF9: /* QADD8<c> <Rd>,<Rn>,<Rm>.  */
    471 	    state->Reg[Rd] = 0;
    472 
    473 	    for (i = 0; i < 32; i+= 8)
    474 	      {
    475 		n = (val1 >> i) & 0xFF;
    476 		if (n & 0x80)
    477 		  n |= - (1 << 8);
    478 
    479 		m = (val2 >> i) & 0xFF;
    480 		if (m & 0x80)
    481 		  m |= - (1 << 8);
    482 
    483 		r = n + m;
    484 
    485 		if (r > 127)
    486 		  r = 127;
    487 		else if (r < -128)
    488 		  r = -128;
    489 
    490 		state->Reg[Rd] |= (r & 0xFF) << i;
    491 	      }
    492 	    return 1;
    493 
    494 	  case 0xFF: /* QSUB8<c> <Rd>,<Rn>,<Rm>.  */
    495 	    state->Reg[Rd] = 0;
    496 
    497 	    for (i = 0; i < 32; i+= 8)
    498 	      {
    499 		n = (val1 >> i) & 0xFF;
    500 		if (n & 0x80)
    501 		  n |= - (1 << 8);
    502 
    503 		m = (val2 >> i) & 0xFF;
    504 		if (m & 0x80)
    505 		  m |= - (1 << 8);
    506 
    507 		r = n - m;
    508 
    509 		if (r > 127)
    510 		  r = 127;
    511 		else if (r < -128)
    512 		  r = -128;
    513 
    514 		state->Reg[Rd] |= (r & 0xFF) << i;
    515 	      }
    516 	    return 1;
    517 
    518 	  default:
    519 	    break;
    520 	  }
    521 	break;
    522       }
    523 
    524     case 0x65:
    525       {
    526 	ARMword valn;
    527 	ARMword valm;
    528 	ARMword res1, res2, res3, res4;
    529 
    530 	/* U{ADD|SUB}{8|16}<c> <Rd>, <Rn>, <Rm>
    531 	   instr[31,28] = cond
    532 	   instr[27,20] = 0110 0101
    533 	   instr[19,16] = Rn
    534 	   instr[15,12] = Rd
    535 	   instr[11, 8] = 1111
    536 	   instr[ 7, 4] = opcode: UADD8 (1001), UADD16 (0001), USUB8 (1111), USUB16 (0111)
    537 	   instr[ 3, 0] = Rm.  */
    538 	if (BITS (8, 11) != 0xF)
    539 	  break;
    540 
    541 	Rn = BITS (16, 19);
    542 	Rd = BITS (12, 15);
    543 	Rm = BITS (0, 3);
    544 
    545 	if (Rn == 15 || Rd == 15 || Rm == 15)
    546 	  {
    547 	    ARMul_UndefInstr (state, instr);
    548 	    state->Emulate = FALSE;
    549 	    break;
    550 	  }
    551 
    552 	valn = state->Reg[Rn];
    553 	valm = state->Reg[Rm];
    554 
    555 	switch (BITS (4, 7))
    556 	  {
    557 	  case 1:  /* UADD16.  */
    558 	    res1 = (valn & 0xFFFF) + (valm & 0xFFFF);
    559 	    if (res1 > 0xFFFF)
    560 	      state->Cpsr |= (GE0 | GE1);
    561 	    else
    562 	      state->Cpsr &= ~ (GE0 | GE1);
    563 
    564 	    res2 = (valn >> 16) + (valm >> 16);
    565 	    if (res2 > 0xFFFF)
    566 	      state->Cpsr |= (GE2 | GE3);
    567 	    else
    568 	      state->Cpsr &= ~ (GE2 | GE3);
    569 
    570 	    state->Reg[Rd] = (res1 & 0xFFFF) | (res2 << 16);
    571 	    return 1;
    572 
    573 	  case 7:  /* USUB16.  */
    574 	    res1 = (valn & 0xFFFF) - (valm & 0xFFFF);
    575 	    if (res1 & 0x800000)
    576 	      state->Cpsr |= (GE0 | GE1);
    577 	    else
    578 	      state->Cpsr &= ~ (GE0 | GE1);
    579 
    580 	    res2 = (valn >> 16) - (valm >> 16);
    581 	    if (res2 & 0x800000)
    582 	      state->Cpsr |= (GE2 | GE3);
    583 	    else
    584 	      state->Cpsr &= ~ (GE2 | GE3);
    585 
    586 	    state->Reg[Rd] = (res1 & 0xFFFF) | (res2 << 16);
    587 	    return 1;
    588 
    589 	  case 9:  /* UADD8.  */
    590 	    res1 = (valn & 0xFF) + (valm & 0xFF);
    591 	    if (res1 > 0xFF)
    592 	      state->Cpsr |= GE0;
    593 	    else
    594 	      state->Cpsr &= ~ GE0;
    595 
    596 	    res2 = ((valn >> 8) & 0xFF) + ((valm >> 8) & 0xFF);
    597 	    if (res2 > 0xFF)
    598 	      state->Cpsr |= GE1;
    599 	    else
    600 	      state->Cpsr &= ~ GE1;
    601 
    602 	    res3 = ((valn >> 16) & 0xFF) + ((valm >> 16) & 0xFF);
    603 	    if (res3 > 0xFF)
    604 	      state->Cpsr |= GE2;
    605 	    else
    606 	      state->Cpsr &= ~ GE2;
    607 
    608 	    res4 = (valn >> 24) + (valm >> 24);
    609 	    if (res4 > 0xFF)
    610 	      state->Cpsr |= GE3;
    611 	    else
    612 	      state->Cpsr &= ~ GE3;
    613 
    614 	    state->Reg[Rd] = (res1 & 0xFF) | ((res2 << 8) & 0xFF00)
    615 	      | ((res3 << 16) & 0xFF0000) | (res4 << 24);
    616 	    return 1;
    617 
    618 	  case 15: /* USUB8.  */
    619 	    res1 = (valn & 0xFF) - (valm & 0xFF);
    620 	    if (res1 & 0x800000)
    621 	      state->Cpsr |= GE0;
    622 	    else
    623 	      state->Cpsr &= ~ GE0;
    624 
    625 	    res2 = ((valn >> 8) & 0XFF) - ((valm >> 8) & 0xFF);
    626 	    if (res2 & 0x800000)
    627 	      state->Cpsr |= GE1;
    628 	    else
    629 	      state->Cpsr &= ~ GE1;
    630 
    631 	    res3 = ((valn >> 16) & 0XFF) - ((valm >> 16) & 0xFF);
    632 	    if (res3 & 0x800000)
    633 	      state->Cpsr |= GE2;
    634 	    else
    635 	      state->Cpsr &= ~ GE2;
    636 
    637 	    res4 = (valn >> 24) - (valm >> 24) ;
    638 	    if (res4 & 0x800000)
    639 	      state->Cpsr |= GE3;
    640 	    else
    641 	      state->Cpsr &= ~ GE3;
    642 
    643 	    state->Reg[Rd] = (res1 & 0xFF) | ((res2 << 8) & 0xFF00)
    644 	      | ((res3 << 16) & 0xFF0000) | (res4 << 24);
    645 	    return 1;
    646 
    647 	  default:
    648 	    break;
    649 	  }
    650 	break;
    651       }
    652 
    653     case 0x68:
    654       {
    655 	ARMword res;
    656 
    657 	/* PKHBT<c> <Rd>,<Rn>,<Rm>{,LSL #<imm>}
    658 	   PKHTB<c> <Rd>,<Rn>,<Rm>{,ASR #<imm>}
    659 	   SXTAB16<c> <Rd>,<Rn>,<Rm>{,<rotation>}
    660 	   SXTB16<c> <Rd>,<Rm>{,<rotation>}
    661 	   SEL<c> <Rd>,<Rn>,<Rm>
    662 
    663 	   instr[31,28] = cond
    664 	   instr[27,20] = 0110 1000
    665 	   instr[19,16] = Rn
    666 	   instr[15,12] = Rd
    667 	   instr[11, 7] = imm5 (PKH), 11111 (SEL), rr000 (SXTAB16 & SXTB16),
    668 	   instr[6]     = tb (PKH), 0 (SEL), 1 (SXT)
    669 	   instr[5]     = opcode: PKH (0), SEL/SXT (1)
    670 	   instr[4]     = 1
    671 	   instr[ 3, 0] = Rm.  */
    672 
    673 	if (BIT (4) != 1)
    674 	  break;
    675 
    676 	if (BIT (5) == 0)
    677 	  {
    678 	    /* FIXME: Add implementation of PKH.  */
    679 	    fprintf (stderr, "PKH: NOT YET IMPLEMENTED\n");
    680 	    ARMul_UndefInstr (state, instr);
    681 	    break;
    682 	  }
    683 
    684 	if (BIT (6) == 1)
    685 	  {
    686 	    /* FIXME: Add implementation of SXT.  */
    687 	    fprintf (stderr, "SXT: NOT YET IMPLEMENTED\n");
    688 	    ARMul_UndefInstr (state, instr);
    689 	    break;
    690 	  }
    691 
    692 	Rn = BITS (16, 19);
    693 	Rd = BITS (12, 15);
    694 	Rm = BITS (0, 3);
    695 	if (Rn == 15 || Rm == 15 || Rd == 15)
    696 	  {
    697 	    ARMul_UndefInstr (state, instr);
    698 	    state->Emulate = FALSE;
    699 	    break;
    700 	  }
    701 
    702 	res  = (state->Reg[(state->Cpsr & GE0) ? Rn : Rm]) & 0xFF;
    703 	res |= (state->Reg[(state->Cpsr & GE1) ? Rn : Rm]) & 0xFF00;
    704 	res |= (state->Reg[(state->Cpsr & GE2) ? Rn : Rm]) & 0xFF0000;
    705 	res |= (state->Reg[(state->Cpsr & GE3) ? Rn : Rm]) & 0xFF000000;
    706 	state->Reg[Rd] = res;
    707 	return 1;
    708       }
    709 
    710     case 0x6a:
    711       {
    712 	int ror = -1;
    713 
    714 	switch (BITS (4, 11))
    715 	  {
    716 	  case 0x07: ror = 0; break;
    717 	  case 0x47: ror = 8; break;
    718 	  case 0x87: ror = 16; break;
    719 	  case 0xc7: ror = 24; break;
    720 
    721 	  case 0x01:
    722 	  case 0xf3:
    723 	    printf ("Unhandled v6 insn: ssat\n");
    724 	    return 0;
    725 
    726 	  default:
    727 	    break;
    728 	  }
    729 
    730 	if (ror == -1)
    731 	  {
    732 	    if (BITS (4, 6) == 0x7)
    733 	      {
    734 		printf ("Unhandled v6 insn: ssat\n");
    735 		return 0;
    736 	      }
    737 	    break;
    738 	  }
    739 
    740 	Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
    741 	if (Rm & 0x80)
    742 	  Rm |= 0xffffff00;
    743 
    744 	if (BITS (16, 19) == 0xf)
    745 	   /* SXTB */
    746 	  state->Reg[BITS (12, 15)] = Rm;
    747 	else
    748 	  /* SXTAB */
    749 	  state->Reg[BITS (12, 15)] += Rm;
    750       }
    751       return 1;
    752 
    753     case 0x6b:
    754       {
    755 	int ror = -1;
    756 
    757 	switch (BITS (4, 11))
    758 	  {
    759 	  case 0x07: ror = 0; break;
    760 	  case 0x47: ror = 8; break;
    761 	  case 0x87: ror = 16; break;
    762 	  case 0xc7: ror = 24; break;
    763 
    764 	  case 0xf3:
    765 	    {
    766 	      /* REV<c> <Rd>,<Rm>
    767 	         instr[31,28] = cond
    768 	         instr[27,20] = 0110 1011
    769 	         instr[19,16] = 1111
    770 	         instr[15,12] = Rd
    771 	         instr[11, 4] = 1111 0011
    772 	         instr[ 3, 0] = Rm.  */
    773 	      if (BITS (16, 19) != 0xF)
    774 		break;
    775 
    776 	      Rd = BITS (12, 15);
    777 	      Rm = BITS (0, 3);
    778 	      if (Rd == 15 || Rm == 15)
    779 		{
    780 		  ARMul_UndefInstr (state, instr);
    781 		  state->Emulate = FALSE;
    782 		  break;
    783 		}
    784 
    785 	      val = state->Reg[Rm] << 24;
    786 	      val |= ((state->Reg[Rm] << 8) & 0xFF0000);
    787 	      val |= ((state->Reg[Rm] >> 8) & 0xFF00);
    788 	      val |= ((state->Reg[Rm] >> 24));
    789 	      state->Reg[Rd] = val;
    790 	      return 1;
    791 	    }
    792 
    793 	  case 0xfb:
    794 	    {
    795 	      /* REV16<c> <Rd>,<Rm>.  */
    796 	      if (BITS (16, 19) != 0xF)
    797 		break;
    798 
    799 	      Rd = BITS (12, 15);
    800 	      Rm = BITS (0, 3);
    801 	      if (Rd == 15 || Rm == 15)
    802 		{
    803 		  ARMul_UndefInstr (state, instr);
    804 		  state->Emulate = FALSE;
    805 		  break;
    806 		}
    807 
    808 	      val = 0;
    809 	      val |= ((state->Reg[Rm] >> 8) & 0x00FF00FF);
    810 	      val |= ((state->Reg[Rm] << 8) & 0xFF00FF00);
    811 	      state->Reg[Rd] = val;
    812 	      return 1;
    813 	    }
    814 
    815 	  default:
    816 	    break;
    817 	  }
    818 
    819 	if (ror == -1)
    820 	  break;
    821 
    822 	Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
    823 	if (Rm & 0x8000)
    824 	  Rm |= 0xffff0000;
    825 
    826 	if (BITS (16, 19) == 0xf)
    827 	  /* SXTH */
    828 	  state->Reg[BITS (12, 15)] = Rm;
    829 	else
    830 	  /* SXTAH */
    831 	  state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
    832       }
    833       return 1;
    834 
    835     case 0x6e:
    836       {
    837 	int ror = -1;
    838 
    839 	switch (BITS (4, 11))
    840 	  {
    841 	  case 0x07: ror = 0; break;
    842 	  case 0x47: ror = 8; break;
    843 	  case 0x87: ror = 16; break;
    844 	  case 0xc7: ror = 24; break;
    845 
    846 	  case 0x01:
    847 	  case 0xf3:
    848 	    printf ("Unhandled v6 insn: usat\n");
    849 	    return 0;
    850 
    851 	  default:
    852 	    break;
    853 	  }
    854 
    855 	if (ror == -1)
    856 	  {
    857 	    if (BITS (4, 6) == 0x7)
    858 	      {
    859 		printf ("Unhandled v6 insn: usat\n");
    860 		return 0;
    861 	      }
    862 	    break;
    863 	  }
    864 
    865 	Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
    866 
    867 	if (BITS (16, 19) == 0xf)
    868 	  /* UXTB */
    869 	  state->Reg[BITS (12, 15)] = Rm;
    870 	else
    871 	  /* UXTAB */
    872 	  state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
    873       }
    874       return 1;
    875 
    876     case 0x6f:
    877       {
    878 	int i;
    879 	int ror = -1;
    880 
    881 	switch (BITS (4, 11))
    882 	  {
    883 	  case 0x07: ror = 0; break;
    884 	  case 0x47: ror = 8; break;
    885 	  case 0x87: ror = 16; break;
    886 	  case 0xc7: ror = 24; break;
    887 
    888 	  case 0xf3: /* RBIT */
    889 	    if (BITS (16, 19) != 0xF)
    890 	      break;
    891 	    Rd = BITS (12, 15);
    892 	    state->Reg[Rd] = 0;
    893 	    Rm = state->Reg[BITS (0, 3)];
    894 	    for (i = 0; i < 32; i++)
    895 	      if (Rm & (1 << i))
    896 		state->Reg[Rd] |= (1 << (31 - i));
    897 	    return 1;
    898 
    899 	  case 0xfb:
    900 	    printf ("Unhandled v6 insn: revsh\n");
    901 	    return 0;
    902 
    903 	  default:
    904 	    break;
    905 	  }
    906 
    907 	if (ror == -1)
    908 	  break;
    909 
    910 	Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
    911 
    912 	if (BITS (16, 19) == 0xf)
    913 	  /* UXT */
    914 	  state->Reg[BITS (12, 15)] = Rm;
    915 	else
    916 	  /* UXTAH */
    917 	  state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm;
    918       }
    919       return 1;
    920 
    921     case 0x71:
    922     case 0x73:
    923       {
    924 	ARMword valn, valm;
    925 	/* SDIV<c> <Rd>,<Rn>,<Rm>
    926 	   UDIV<c> <Rd>,<Rn>,<Rm>
    927 	   instr[31,28] = cond
    928 	   instr[27,20] = 0111 0001 (SDIV), 0111 0011 (UDIV)
    929 	   instr[21,21] = sign
    930 	   instr[19,16] = Rn
    931 	   instr[15,12] = 1111
    932 	   instr[11, 8] = Rd
    933 	   instr[ 7, 4] = 1111
    934 	   instr[ 3, 0] = Rm	*/
    935 	/* These bit-positions are confusing!
    936            instr[15,12] = Rd
    937 	   instr[11, 8] = 1111	*/
    938 
    939 #if 0	/* This is what I would expect:  */
    940 	Rn = BITS (16, 19);
    941 	Rd = BITS (8, 11);
    942 	Rm = BITS (0, 3);
    943 #else	/* This seem to work:  */
    944 	Rd = BITS (16, 19);
    945 	Rm = BITS (8, 11);
    946 	Rn = BITS (0, 3);
    947 #endif
    948 	if (Rn == 15 || Rd == 15 || Rm == 15
    949 	    || Rn == 13 || Rd == 13 || Rm == 13)
    950 	  {
    951 	    ARMul_UndefInstr (state, instr);
    952 	    state->Emulate = FALSE;
    953 	    break;
    954 	  }
    955 
    956 	valn = state->Reg[Rn];
    957 	valm = state->Reg[Rm];
    958 
    959 	if (valm == 0)
    960 	  {
    961 #if 0
    962 	    /* Exceptions: UsageFault, address 20
    963 	       Note: UsageFault is for Cortex-M; I don't know what it would be on non-Cortex-M.  */
    964 	    ARMul_Abort (state, address);
    965 #endif
    966 	    printf ("Unhandled v6 insn: %cDIV divide by zero exception\n", "SU"[BIT(21)]);
    967 	  }
    968 	else
    969 	  {
    970 	    if(BIT(21))
    971 	      {
    972 		val = valn / valm;
    973 	      }
    974 	    else
    975 	      {
    976 		val = ((ARMsword)valn / (ARMsword)valm);
    977 	      }
    978 	    state->Reg[Rd] = val;
    979 	  }
    980 	return 1;
    981       }
    982 
    983     case 0x7c:
    984     case 0x7d:
    985       {
    986 	int lsb;
    987 	int msb;
    988 	ARMword mask;
    989 
    990 	/* BFC<c> <Rd>,#<lsb>,#<width>
    991 	   BFI<c> <Rd>,<Rn>,#<lsb>,#<width>
    992 
    993 	   instr[31,28] = cond
    994 	   instr[27,21] = 0111 110
    995 	   instr[20,16] = msb
    996 	   instr[15,12] = Rd
    997 	   instr[11, 7] = lsb
    998 	   instr[ 6, 4] = 001 1111
    999 	   instr[ 3, 0] = Rn (BFI) / 1111 (BFC).  */
   1000 
   1001 	if (BITS (4, 6) != 0x1)
   1002 	  break;
   1003 
   1004 	Rd = BITS (12, 15);
   1005 	if (Rd == 15)
   1006 	  {
   1007 	    ARMul_UndefInstr (state, instr);
   1008 	    state->Emulate = FALSE;
   1009 	  }
   1010 
   1011 	lsb = BITS (7, 11);
   1012 	msb = BITS (16, 20);
   1013 	if (lsb > msb)
   1014 	  {
   1015 	    ARMul_UndefInstr (state, instr);
   1016 	    state->Emulate = FALSE;
   1017 	  }
   1018 
   1019 	mask = -(1 << lsb);
   1020 	mask &= ~(-(1 << (msb + 1)));
   1021 	state->Reg[Rd] &= ~ mask;
   1022 
   1023 	Rn = BITS (0, 3);
   1024 	if (Rn != 0xF)
   1025 	  {
   1026 	    val = state->Reg[Rn] & ~(-(1 << ((msb + 1) - lsb)));
   1027 	    state->Reg[Rd] |= val << lsb;
   1028 	  }
   1029 	return 1;
   1030       }
   1031     case 0x7b:
   1032     case 0x7a: /* SBFX<c> <Rd>,<Rn>,#<lsb>,#<width>.  */
   1033       {
   1034 	int lsb;
   1035 	int widthm1;
   1036 	ARMsword sval;
   1037 
   1038 	if (BITS (4, 6) != 0x5)
   1039 	  break;
   1040 
   1041 	Rd = BITS (12, 15);
   1042 	if (Rd == 15)
   1043 	  {
   1044 	    ARMul_UndefInstr (state, instr);
   1045 	    state->Emulate = FALSE;
   1046 	  }
   1047 
   1048 	Rn = BITS (0, 3);
   1049 	if (Rn == 15)
   1050 	  {
   1051 	    ARMul_UndefInstr (state, instr);
   1052 	    state->Emulate = FALSE;
   1053 	  }
   1054 
   1055 	lsb = BITS (7, 11);
   1056 	widthm1 = BITS (16, 20);
   1057 
   1058 	sval = state->Reg[Rn];
   1059 	sval <<= (31 - (lsb + widthm1));
   1060 	sval >>= (31 - widthm1);
   1061 	state->Reg[Rd] = sval;
   1062 
   1063 	return 1;
   1064       }
   1065 
   1066     case 0x7f:
   1067     case 0x7e:
   1068       {
   1069 	int lsb;
   1070 	int widthm1;
   1071 
   1072 	/* UBFX<c> <Rd>,<Rn>,#<lsb>,#<width>
   1073 	   instr[31,28] = cond
   1074 	   instr[27,21] = 0111 111
   1075 	   instr[20,16] = widthm1
   1076 	   instr[15,12] = Rd
   1077 	   instr[11, 7] = lsb
   1078 	   instr[ 6, 4] = 101
   1079 	   instr[ 3, 0] = Rn.  */
   1080 
   1081 	if (BITS (4, 6) != 0x5)
   1082 	  break;
   1083 
   1084 	Rd = BITS (12, 15);
   1085 	if (Rd == 15)
   1086 	  {
   1087 	    ARMul_UndefInstr (state, instr);
   1088 	    state->Emulate = FALSE;
   1089 	  }
   1090 
   1091 	Rn = BITS (0, 3);
   1092 	if (Rn == 15)
   1093 	  {
   1094 	    ARMul_UndefInstr (state, instr);
   1095 	    state->Emulate = FALSE;
   1096 	  }
   1097 
   1098 	lsb = BITS (7, 11);
   1099 	widthm1 = BITS (16, 20);
   1100 
   1101 	val = state->Reg[Rn];
   1102 	val >>= lsb;
   1103 	val &= ~(-(1 << (widthm1 + 1)));
   1104 
   1105 	state->Reg[Rd] = val;
   1106 
   1107 	return 1;
   1108       }
   1109 #if 0
   1110     case 0x84: printf ("Unhandled v6 insn: srs\n"); break;
   1111 #endif
   1112     default:
   1113       break;
   1114     }
   1115   printf ("Unhandled v6 insn: UNKNOWN: %08x\n", instr);
   1116   return 0;
   1117 }
   1118 #endif
   1119 
   1120 static void
   1121 handle_VFP_move (ARMul_State * state, ARMword instr)
   1122 {
   1123   switch (BITS (20, 27))
   1124     {
   1125     case 0xC4:
   1126     case 0xC5:
   1127       switch (BITS (4, 11))
   1128 	{
   1129 	case 0xA1:
   1130 	case 0xA3:
   1131 	  {
   1132 	    /* VMOV two core <-> two VFP single precision.  */
   1133 	    int sreg = (BITS (0, 3) << 1) | BIT (5);
   1134 
   1135 	    if (BIT (20))
   1136 	      {
   1137 		state->Reg[BITS (12, 15)] = VFP_uword (sreg);
   1138 		state->Reg[BITS (16, 19)] = VFP_uword (sreg + 1);
   1139 	      }
   1140 	    else
   1141 	      {
   1142 		VFP_uword (sreg)     = state->Reg[BITS (12, 15)];
   1143 		VFP_uword (sreg + 1) = state->Reg[BITS (16, 19)];
   1144 	      }
   1145 	  }
   1146 	  break;
   1147 
   1148 	case 0xB1:
   1149 	case 0xB3:
   1150 	  {
   1151 	    /* VMOV two core <-> VFP double precision.  */
   1152 	    int dreg = BITS (0, 3) | (BIT (5) << 4);
   1153 
   1154 	    if (BIT (20))
   1155 	      {
   1156 		if (trace)
   1157 		  fprintf (stderr, " VFP: VMOV: r%d r%d <= d%d\n",
   1158 			   BITS (12, 15), BITS (16, 19), dreg);
   1159 
   1160 		state->Reg[BITS (12, 15)] = VFP_dword (dreg);
   1161 		state->Reg[BITS (16, 19)] = VFP_dword (dreg) >> 32;
   1162 	      }
   1163 	    else
   1164 	      {
   1165 		VFP_dword (dreg) = state->Reg[BITS (16, 19)];
   1166 		VFP_dword (dreg) <<= 32;
   1167 		VFP_dword (dreg) |= state->Reg[BITS (12, 15)];
   1168 
   1169 		if (trace)
   1170 		  fprintf (stderr, " VFP: VMOV: d%d <= r%d r%d : %g\n",
   1171 			   dreg, BITS (16, 19), BITS (12, 15),
   1172 			   VFP_dval (dreg));
   1173 	      }
   1174 	  }
   1175 	  break;
   1176 
   1177 	default:
   1178 	  fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
   1179 	  break;
   1180 	}
   1181       break;
   1182 
   1183     case 0xe0:
   1184     case 0xe1:
   1185       /* VMOV single core <-> VFP single precision.  */
   1186       if (BITS (0, 6) != 0x10 || BITS (8, 11) != 0xA)
   1187 	fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
   1188       else
   1189 	{
   1190 	  int sreg = (BITS (16, 19) << 1) | BIT (7);
   1191 
   1192 	  if (BIT (20))
   1193 	    state->Reg[DESTReg] = VFP_uword (sreg);
   1194 	  else
   1195 	    VFP_uword (sreg) = state->Reg[DESTReg];
   1196 	}
   1197       break;
   1198 
   1199     default:
   1200       fprintf (stderr, "SIM: VFP: Unimplemented move insn %x\n", BITS (20, 27));
   1201       return;
   1202     }
   1203 }
   1204 
   1205 /* EMULATION of ARM6.  */
   1206 
   1207 ARMword
   1208 #ifdef MODE32
   1209 ARMul_Emulate32 (ARMul_State * state)
   1210 #else
   1211 ARMul_Emulate26 (ARMul_State * state)
   1212 #endif
   1213 {
   1214   ARMword instr;	/* The current instruction.  */
   1215   ARMword dest = 0;	/* Almost the DestBus.  */
   1216   ARMword temp;		/* Ubiquitous third hand.  */
   1217   ARMword pc = 0;	/* The address of the current instruction.  */
   1218   ARMword lhs;		/* Almost the ABus and BBus.  */
   1219   ARMword rhs;
   1220   ARMword decoded = 0;	/* Instruction pipeline.  */
   1221   ARMword loaded = 0;
   1222 
   1223   /* Execute the next instruction.  */
   1224 
   1225   if (state->NextInstr < PRIMEPIPE)
   1226     {
   1227       decoded = state->decoded;
   1228       loaded = state->loaded;
   1229       pc = state->pc;
   1230     }
   1231 
   1232   do
   1233     {
   1234       /* Just keep going.  */
   1235       isize = INSN_SIZE;
   1236 
   1237       switch (state->NextInstr)
   1238 	{
   1239 	case SEQ:
   1240 	  /* Advance the pipeline, and an S cycle.  */
   1241 	  state->Reg[15] += isize;
   1242 	  pc += isize;
   1243 	  instr = decoded;
   1244 	  decoded = loaded;
   1245 	  loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
   1246 	  break;
   1247 
   1248 	case NONSEQ:
   1249 	  /* Advance the pipeline, and an N cycle.  */
   1250 	  state->Reg[15] += isize;
   1251 	  pc += isize;
   1252 	  instr = decoded;
   1253 	  decoded = loaded;
   1254 	  loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
   1255 	  NORMALCYCLE;
   1256 	  break;
   1257 
   1258 	case PCINCEDSEQ:
   1259 	  /* Program counter advanced, and an S cycle.  */
   1260 	  pc += isize;
   1261 	  instr = decoded;
   1262 	  decoded = loaded;
   1263 	  loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
   1264 	  NORMALCYCLE;
   1265 	  break;
   1266 
   1267 	case PCINCEDNONSEQ:
   1268 	  /* Program counter advanced, and an N cycle.  */
   1269 	  pc += isize;
   1270 	  instr = decoded;
   1271 	  decoded = loaded;
   1272 	  loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
   1273 	  NORMALCYCLE;
   1274 	  break;
   1275 
   1276 	case RESUME:
   1277 	  /* The program counter has been changed.  */
   1278 	  pc = state->Reg[15];
   1279 #ifndef MODE32
   1280 	  pc = pc & R15PCBITS;
   1281 #endif
   1282 	  state->Reg[15] = pc + (isize * 2);
   1283 	  state->Aborted = 0;
   1284 	  instr   = ARMul_ReLoadInstr (state, pc, isize);
   1285 	  decoded = ARMul_ReLoadInstr (state, pc + isize, isize);
   1286 	  loaded  = ARMul_ReLoadInstr (state, pc + isize * 2, isize);
   1287 	  NORMALCYCLE;
   1288 	  break;
   1289 
   1290 	default:
   1291 	  /* The program counter has been changed.  */
   1292 	  pc = state->Reg[15];
   1293 #ifndef MODE32
   1294 	  pc = pc & R15PCBITS;
   1295 #endif
   1296 	  state->Reg[15] = pc + (isize * 2);
   1297 	  state->Aborted = 0;
   1298 	  instr   = ARMul_LoadInstrN (state, pc, isize);
   1299 	  decoded = ARMul_LoadInstrS (state, pc + (isize), isize);
   1300 	  loaded  = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
   1301 	  NORMALCYCLE;
   1302 	  break;
   1303 	}
   1304 
   1305       if (state->EventSet)
   1306 	ARMul_EnvokeEvent (state);
   1307 
   1308       if (! TFLAG && trace)
   1309 	{
   1310 	  fprintf (stderr, "pc: %x, ", pc & ~1);
   1311 	  if (! disas)
   1312 	    fprintf (stderr, "instr: %x\n", instr);
   1313 	}
   1314 
   1315       if (instr == 0 || pc < 0x10)
   1316 	{
   1317 	  ARMul_Abort (state, ARMUndefinedInstrV);
   1318 	  state->Emulate = FALSE;
   1319 	}
   1320 
   1321 #if 0 /* Enable this code to help track down stack alignment bugs.  */
   1322       {
   1323 	static ARMword old_sp = -1;
   1324 
   1325 	if (old_sp != state->Reg[13])
   1326 	  {
   1327 	    old_sp = state->Reg[13];
   1328 	    fprintf (stderr, "pc: %08x: SP set to %08x%s\n",
   1329 		     pc & ~1, old_sp, (old_sp % 8) ? " [UNALIGNED!]" : "");
   1330 	  }
   1331       }
   1332 #endif
   1333 
   1334       if (state->Exception)
   1335 	{
   1336 	  /* Any exceptions ?  */
   1337 	  if (state->NresetSig == LOW)
   1338 	    {
   1339 	      ARMul_Abort (state, ARMul_ResetV);
   1340 	      break;
   1341 	    }
   1342 	  else if (!state->NfiqSig && !FFLAG)
   1343 	    {
   1344 	      ARMul_Abort (state, ARMul_FIQV);
   1345 	      break;
   1346 	    }
   1347 	  else if (!state->NirqSig && !IFLAG)
   1348 	    {
   1349 	      ARMul_Abort (state, ARMul_IRQV);
   1350 	      break;
   1351 	    }
   1352 	}
   1353 
   1354       if (state->CallDebug > 0)
   1355 	{
   1356 	  if (state->Emulate < ONCE)
   1357 	    {
   1358 	      state->NextInstr = RESUME;
   1359 	      break;
   1360 	    }
   1361 	  if (state->Debug)
   1362 	    {
   1363 	      fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n",
   1364 		       (long) pc, (long) instr, (long) state->Mode);
   1365 	      (void) fgetc (stdin);
   1366 	    }
   1367 	}
   1368       else if (state->Emulate < ONCE)
   1369 	{
   1370 	  state->NextInstr = RESUME;
   1371 	  break;
   1372 	}
   1373 
   1374       state->NumInstrs++;
   1375 
   1376 #ifdef MODET
   1377       /* Provide Thumb instruction decoding. If the processor is in Thumb
   1378          mode, then we can simply decode the Thumb instruction, and map it
   1379          to the corresponding ARM instruction (by directly loading the
   1380          instr variable, and letting the normal ARM simulator
   1381          execute). There are some caveats to ensure that the correct
   1382          pipelined PC value is used when executing Thumb code, and also for
   1383          dealing with the BL instruction.  */
   1384       if (TFLAG)
   1385 	{
   1386 	  ARMword new;
   1387 
   1388 	  /* Check if in Thumb mode.  */
   1389 	  switch (ARMul_ThumbDecode (state, pc, instr, &new))
   1390 	    {
   1391 	    case t_undefined:
   1392 	      /* This is a Thumb instruction.  */
   1393 	      ARMul_UndefInstr (state, instr);
   1394 	      goto donext;
   1395 
   1396 	    case t_branch:
   1397 	      /* Already processed.  */
   1398 	      goto donext;
   1399 
   1400 	    case t_decoded:
   1401 	      /* ARM instruction available.  */
   1402 	      if (disas || trace)
   1403 		{
   1404 		  fprintf (stderr, "  emulate as: ");
   1405 		  if (trace)
   1406 		    fprintf (stderr, "%08x ", new);
   1407 		  if (! disas)
   1408 		    fprintf (stderr, "\n");
   1409 		}
   1410 	      instr = new;
   1411 	      /* So continue instruction decoding.  */
   1412 	      break;
   1413 	    default:
   1414 	      break;
   1415 	    }
   1416 	}
   1417 #endif
   1418       if (disas)
   1419 	print_insn (instr);
   1420 
   1421       /* Check the condition codes.  */
   1422       if ((temp = TOPBITS (28)) == AL)
   1423 	/* Vile deed in the need for speed.  */
   1424 	goto mainswitch;
   1425 
   1426       /* Check the condition code.  */
   1427       switch ((int) TOPBITS (28))
   1428 	{
   1429 	case AL:
   1430 	  temp = TRUE;
   1431 	  break;
   1432 	case NV:
   1433 	  if (state->is_v5)
   1434 	    {
   1435 	      if (BITS (25, 27) == 5) /* BLX(1) */
   1436 		{
   1437 		  state->Reg[14] = pc + 4;
   1438 
   1439 		  /* Force entry into Thumb mode.  */
   1440 		  dest = pc + 8 + 1;
   1441 		  if (BIT (23))
   1442 		    dest += (NEGBRANCH + (BIT (24) << 1));
   1443 		  else
   1444 		    dest += POSBRANCH + (BIT (24) << 1);
   1445 
   1446 		  WriteR15Branch (state, dest);
   1447 		  goto donext;
   1448 		}
   1449 	      else if ((instr & 0xFC70F000) == 0xF450F000)
   1450 		/* The PLD instruction.  Ignored.  */
   1451 		goto donext;
   1452 	      else if (   ((instr & 0xfe500f00) == 0xfc100100)
   1453 		       || ((instr & 0xfe500f00) == 0xfc000100))
   1454 		/* wldrw and wstrw are unconditional.  */
   1455 		goto mainswitch;
   1456 	      else
   1457 		/* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2.  */
   1458 		ARMul_UndefInstr (state, instr);
   1459 	    }
   1460 	  temp = FALSE;
   1461 	  break;
   1462 	case EQ:
   1463 	  temp = ZFLAG;
   1464 	  break;
   1465 	case NE:
   1466 	  temp = !ZFLAG;
   1467 	  break;
   1468 	case VS:
   1469 	  temp = VFLAG;
   1470 	  break;
   1471 	case VC:
   1472 	  temp = !VFLAG;
   1473 	  break;
   1474 	case MI:
   1475 	  temp = NFLAG;
   1476 	  break;
   1477 	case PL:
   1478 	  temp = !NFLAG;
   1479 	  break;
   1480 	case CS:
   1481 	  temp = CFLAG;
   1482 	  break;
   1483 	case CC:
   1484 	  temp = !CFLAG;
   1485 	  break;
   1486 	case HI:
   1487 	  temp = (CFLAG && !ZFLAG);
   1488 	  break;
   1489 	case LS:
   1490 	  temp = (!CFLAG || ZFLAG);
   1491 	  break;
   1492 	case GE:
   1493 	  temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
   1494 	  break;
   1495 	case LT:
   1496 	  temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
   1497 	  break;
   1498 	case GT:
   1499 	  temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
   1500 	  break;
   1501 	case LE:
   1502 	  temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
   1503 	  break;
   1504 	}			/* cc check */
   1505 
   1506       /* Handle the Clock counter here.  */
   1507       if (state->is_XScale)
   1508 	{
   1509 	  ARMword cp14r0;
   1510 	  int ok;
   1511 
   1512 	  ok = state->CPRead[14] (state, 0, & cp14r0);
   1513 
   1514 	  if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE))
   1515 	    {
   1516 	      unsigned long newcycles, nowtime = ARMul_Time (state);
   1517 
   1518 	      newcycles = nowtime - state->LastTime;
   1519 	      state->LastTime = nowtime;
   1520 
   1521 	      if (cp14r0 & ARMul_CP14_R0_CCD)
   1522 	        {
   1523 		  if (state->CP14R0_CCD == -1)
   1524 		    state->CP14R0_CCD = newcycles;
   1525 		  else
   1526 		    state->CP14R0_CCD += newcycles;
   1527 
   1528 		  if (state->CP14R0_CCD >= 64)
   1529 		    {
   1530 		      newcycles = 0;
   1531 
   1532 		      while (state->CP14R0_CCD >= 64)
   1533 		        state->CP14R0_CCD -= 64, newcycles++;
   1534 
   1535 		      goto check_PMUintr;
   1536 		    }
   1537 		}
   1538 	      else
   1539 		{
   1540 		  ARMword cp14r1;
   1541 		  int do_int;
   1542 
   1543 		  state->CP14R0_CCD = -1;
   1544 check_PMUintr:
   1545 		  do_int = 0;
   1546 		  cp14r0 |= ARMul_CP14_R0_FLAG2;
   1547 		  (void) state->CPWrite[14] (state, 0, cp14r0);
   1548 
   1549 		  ok = state->CPRead[14] (state, 1, & cp14r1);
   1550 
   1551 		  /* Coded like this for portability.  */
   1552 		  while (ok && newcycles)
   1553 		    {
   1554 		      if (cp14r1 == 0xffffffff)
   1555 			{
   1556 			  cp14r1 = 0;
   1557 			  do_int = 1;
   1558 			}
   1559 		      else
   1560 			cp14r1 ++;
   1561 
   1562 		      newcycles --;
   1563 		    }
   1564 
   1565 		  (void) state->CPWrite[14] (state, 1, cp14r1);
   1566 
   1567 		  if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2))
   1568 		    {
   1569 		      ARMword cp;
   1570 
   1571 		      if (state->CPRead[13] (state, 8, & cp)
   1572 			  && (cp & ARMul_CP13_R8_PMUS))
   1573 		        ARMul_Abort (state, ARMul_FIQV);
   1574 		      else
   1575 		        ARMul_Abort (state, ARMul_IRQV);
   1576 		    }
   1577 		}
   1578 	    }
   1579 	}
   1580 
   1581       /* Handle hardware instructions breakpoints here.  */
   1582       if (state->is_XScale)
   1583 	{
   1584 	  if (   (pc | 3) == (read_cp15_reg (14, 0, 8) | 2)
   1585 	      || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2))
   1586 	    {
   1587 	      if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB))
   1588 	        ARMul_OSHandleSWI (state, SWI_Breakpoint);
   1589 	    }
   1590 	}
   1591 
   1592       /* Actual execution of instructions begins here.  */
   1593       /* If the condition codes don't match, stop here.  */
   1594       if (temp)
   1595 	{
   1596 	mainswitch:
   1597 
   1598 	  if (state->is_XScale)
   1599 	    {
   1600 	      if (BIT (20) == 0 && BITS (25, 27) == 0)
   1601 		{
   1602 		  if (BITS (4, 7) == 0xD)
   1603 		    {
   1604 		      /* XScale Load Consecutive insn.  */
   1605 		      ARMword temp1 = GetLS7RHS (state, instr);
   1606 		      ARMword temp2 = BIT (23) ? LHS + temp1 : LHS - temp1;
   1607 		      ARMword addr = BIT (24) ? temp2 : LHS;
   1608 
   1609 		      if (BIT (12))
   1610 			ARMul_UndefInstr (state, instr);
   1611 		      else if (addr & 7)
   1612 			/* Alignment violation.  */
   1613 			ARMul_Abort (state, ARMul_DataAbortV);
   1614 		      else
   1615 			{
   1616 			  int wb = BIT (21) || (! BIT (24));
   1617 
   1618 			  state->Reg[BITS (12, 15)] =
   1619 			    ARMul_LoadWordN (state, addr);
   1620 			  state->Reg[BITS (12, 15) + 1] =
   1621 			    ARMul_LoadWordN (state, addr + 4);
   1622 			  if (wb)
   1623 			    LSBase = temp2;
   1624 			}
   1625 
   1626 		      goto donext;
   1627 		    }
   1628 		  else if (BITS (4, 7) == 0xF)
   1629 		    {
   1630 		      /* XScale Store Consecutive insn.  */
   1631 		      ARMword temp1 = GetLS7RHS (state, instr);
   1632 		      ARMword temp2 = BIT (23) ? LHS + temp1 : LHS - temp1;
   1633 		      ARMword addr = BIT (24) ? temp2 : LHS;
   1634 
   1635 		      if (BIT (12))
   1636 			ARMul_UndefInstr (state, instr);
   1637 		      else if (addr & 7)
   1638 			/* Alignment violation.  */
   1639 			ARMul_Abort (state, ARMul_DataAbortV);
   1640 		      else
   1641 			{
   1642 			  ARMul_StoreWordN (state, addr,
   1643 					    state->Reg[BITS (12, 15)]);
   1644 			  ARMul_StoreWordN (state, addr + 4,
   1645 					    state->Reg[BITS (12, 15) + 1]);
   1646 
   1647 			  if (BIT (21)|| ! BIT (24))
   1648 			    LSBase = temp2;
   1649 			}
   1650 
   1651 		      goto donext;
   1652 		    }
   1653 		}
   1654 
   1655 	      if (ARMul_HandleIwmmxt (state, instr))
   1656 		goto donext;
   1657 	    }
   1658 
   1659 	  switch ((int) BITS (20, 27))
   1660 	    {
   1661 	      /* Data Processing Register RHS Instructions.  */
   1662 
   1663 	    case 0x00:		/* AND reg and MUL */
   1664 #ifdef MODET
   1665 	      if (BITS (4, 11) == 0xB)
   1666 		{
   1667 		  /* STRH register offset, no write-back, down, post indexed.  */
   1668 		  SHDOWNWB ();
   1669 		  break;
   1670 		}
   1671 	      if (BITS (4, 7) == 0xD)
   1672 		{
   1673 		  Handle_Load_Double (state, instr);
   1674 		  break;
   1675 		}
   1676 	      if (BITS (4, 7) == 0xF)
   1677 		{
   1678 		  Handle_Store_Double (state, instr);
   1679 		  break;
   1680 		}
   1681 #endif
   1682 	      if (BITS (4, 7) == 9)
   1683 		{
   1684 		  /* MUL */
   1685 		  rhs = state->Reg[MULRHSReg];
   1686 		  if (MULLHSReg == MULDESTReg)
   1687 		    {
   1688 		      UNDEF_MULDestEQOp1;
   1689 		      state->Reg[MULDESTReg] = 0;
   1690 		    }
   1691 		  else if (MULDESTReg != 15)
   1692 		    state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
   1693 		  else
   1694 		    UNDEF_MULPCDest;
   1695 
   1696 		  for (dest = 0, temp = 0; dest < 32; dest ++)
   1697 		    if (rhs & (1L << dest))
   1698 		      temp = dest;
   1699 
   1700 		  /* Mult takes this many/2 I cycles.  */
   1701 		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
   1702 		}
   1703 	      else
   1704 		{
   1705 		  /* AND reg.  */
   1706 		  rhs = DPRegRHS;
   1707 		  dest = LHS & rhs;
   1708 		  WRITEDEST (dest);
   1709 		}
   1710 	      break;
   1711 
   1712 	    case 0x01:		/* ANDS reg and MULS */
   1713 #ifdef MODET
   1714 	      if ((BITS (4, 11) & 0xF9) == 0x9)
   1715 		/* LDR register offset, no write-back, down, post indexed.  */
   1716 		LHPOSTDOWN ();
   1717 	      /* Fall through to rest of decoding.  */
   1718 #endif
   1719 	      if (BITS (4, 7) == 9)
   1720 		{
   1721 		  /* MULS */
   1722 		  rhs = state->Reg[MULRHSReg];
   1723 
   1724 		  if (MULLHSReg == MULDESTReg)
   1725 		    {
   1726 		      UNDEF_MULDestEQOp1;
   1727 		      state->Reg[MULDESTReg] = 0;
   1728 		      CLEARN;
   1729 		      SETZ;
   1730 		    }
   1731 		  else if (MULDESTReg != 15)
   1732 		    {
   1733 		      dest = state->Reg[MULLHSReg] * rhs;
   1734 		      ARMul_NegZero (state, dest);
   1735 		      state->Reg[MULDESTReg] = dest;
   1736 		    }
   1737 		  else
   1738 		    UNDEF_MULPCDest;
   1739 
   1740 		  for (dest = 0, temp = 0; dest < 32; dest ++)
   1741 		    if (rhs & (1L << dest))
   1742 		      temp = dest;
   1743 
   1744 		  /* Mult takes this many/2 I cycles.  */
   1745 		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
   1746 		}
   1747 	      else
   1748 		{
   1749 		  /* ANDS reg.  */
   1750 		  rhs = DPSRegRHS;
   1751 		  dest = LHS & rhs;
   1752 		  WRITESDEST (dest);
   1753 		}
   1754 	      break;
   1755 
   1756 	    case 0x02:		/* EOR reg and MLA */
   1757 #ifdef MODET
   1758 	      if (BITS (4, 11) == 0xB)
   1759 		{
   1760 		  /* STRH register offset, write-back, down, post indexed.  */
   1761 		  SHDOWNWB ();
   1762 		  break;
   1763 		}
   1764 #endif
   1765 	      if (BITS (4, 7) == 9)
   1766 		{		/* MLA */
   1767 		  rhs = state->Reg[MULRHSReg];
   1768 		  if (MULLHSReg == MULDESTReg)
   1769 		    {
   1770 		      UNDEF_MULDestEQOp1;
   1771 		      state->Reg[MULDESTReg] = state->Reg[MULACCReg];
   1772 		    }
   1773 		  else if (MULDESTReg != 15)
   1774 		    state->Reg[MULDESTReg] =
   1775 		      state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
   1776 		  else
   1777 		    UNDEF_MULPCDest;
   1778 
   1779 		  for (dest = 0, temp = 0; dest < 32; dest ++)
   1780 		    if (rhs & (1L << dest))
   1781 		      temp = dest;
   1782 
   1783 		  /* Mult takes this many/2 I cycles.  */
   1784 		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
   1785 		}
   1786 	      else
   1787 		{
   1788 		  rhs = DPRegRHS;
   1789 		  dest = LHS ^ rhs;
   1790 		  WRITEDEST (dest);
   1791 		}
   1792 	      break;
   1793 
   1794 	    case 0x03:		/* EORS reg and MLAS */
   1795 #ifdef MODET
   1796 	      if ((BITS (4, 11) & 0xF9) == 0x9)
   1797 		/* LDR register offset, write-back, down, post-indexed.  */
   1798 		LHPOSTDOWN ();
   1799 	      /* Fall through to rest of the decoding.  */
   1800 #endif
   1801 	      if (BITS (4, 7) == 9)
   1802 		{
   1803 		  /* MLAS */
   1804 		  rhs = state->Reg[MULRHSReg];
   1805 
   1806 		  if (MULLHSReg == MULDESTReg)
   1807 		    {
   1808 		      UNDEF_MULDestEQOp1;
   1809 		      dest = state->Reg[MULACCReg];
   1810 		      ARMul_NegZero (state, dest);
   1811 		      state->Reg[MULDESTReg] = dest;
   1812 		    }
   1813 		  else if (MULDESTReg != 15)
   1814 		    {
   1815 		      dest =
   1816 			state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
   1817 		      ARMul_NegZero (state, dest);
   1818 		      state->Reg[MULDESTReg] = dest;
   1819 		    }
   1820 		  else
   1821 		    UNDEF_MULPCDest;
   1822 
   1823 		  for (dest = 0, temp = 0; dest < 32; dest ++)
   1824 		    if (rhs & (1L << dest))
   1825 		      temp = dest;
   1826 
   1827 		  /* Mult takes this many/2 I cycles.  */
   1828 		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
   1829 		}
   1830 	      else
   1831 		{
   1832 		  /* EORS Reg.  */
   1833 		  rhs = DPSRegRHS;
   1834 		  dest = LHS ^ rhs;
   1835 		  WRITESDEST (dest);
   1836 		}
   1837 	      break;
   1838 
   1839 	    case 0x04:		/* SUB reg */
   1840 #ifdef MODET
   1841 	      if (BITS (4, 7) == 0xB)
   1842 		{
   1843 		  /* STRH immediate offset, no write-back, down, post indexed.  */
   1844 		  SHDOWNWB ();
   1845 		  break;
   1846 		}
   1847 	      if (BITS (4, 7) == 0xD)
   1848 		{
   1849 		  Handle_Load_Double (state, instr);
   1850 		  break;
   1851 		}
   1852 	      if (BITS (4, 7) == 0xF)
   1853 		{
   1854 		  Handle_Store_Double (state, instr);
   1855 		  break;
   1856 		}
   1857 #endif
   1858 	      rhs = DPRegRHS;
   1859 	      dest = LHS - rhs;
   1860 	      WRITEDEST (dest);
   1861 	      break;
   1862 
   1863 	    case 0x05:		/* SUBS reg */
   1864 #ifdef MODET
   1865 	      if ((BITS (4, 7) & 0x9) == 0x9)
   1866 		/* LDR immediate offset, no write-back, down, post indexed.  */
   1867 		LHPOSTDOWN ();
   1868 	      /* Fall through to the rest of the instruction decoding.  */
   1869 #endif
   1870 	      lhs = LHS;
   1871 	      rhs = DPRegRHS;
   1872 	      dest = lhs - rhs;
   1873 
   1874 	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))
   1875 		{
   1876 		  ARMul_SubCarry (state, lhs, rhs, dest);
   1877 		  ARMul_SubOverflow (state, lhs, rhs, dest);
   1878 		}
   1879 	      else
   1880 		{
   1881 		  CLEARC;
   1882 		  CLEARV;
   1883 		}
   1884 	      WRITESDEST (dest);
   1885 	      break;
   1886 
   1887 	    case 0x06:		/* RSB reg */
   1888 #ifdef MODET
   1889 	      if (BITS (4, 7) == 0xB)
   1890 		{
   1891 		  /* STRH immediate offset, write-back, down, post indexed.  */
   1892 		  SHDOWNWB ();
   1893 		  break;
   1894 		}
   1895 #endif
   1896 	      rhs = DPRegRHS;
   1897 	      dest = rhs - LHS;
   1898 	      WRITEDEST (dest);
   1899 	      break;
   1900 
   1901 	    case 0x07:		/* RSBS reg */
   1902 #ifdef MODET
   1903 	      if ((BITS (4, 7) & 0x9) == 0x9)
   1904 		/* LDR immediate offset, write-back, down, post indexed.  */
   1905 		LHPOSTDOWN ();
   1906 	      /* Fall through to remainder of instruction decoding.  */
   1907 #endif
   1908 	      lhs = LHS;
   1909 	      rhs = DPRegRHS;
   1910 	      dest = rhs - lhs;
   1911 
   1912 	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))
   1913 		{
   1914 		  ARMul_SubCarry (state, rhs, lhs, dest);
   1915 		  ARMul_SubOverflow (state, rhs, lhs, dest);
   1916 		}
   1917 	      else
   1918 		{
   1919 		  CLEARC;
   1920 		  CLEARV;
   1921 		}
   1922 	      WRITESDEST (dest);
   1923 	      break;
   1924 
   1925 	    case 0x08:		/* ADD reg */
   1926 #ifdef MODET
   1927 	      if (BITS (4, 11) == 0xB)
   1928 		{
   1929 		  /* STRH register offset, no write-back, up, post indexed.  */
   1930 		  SHUPWB ();
   1931 		  break;
   1932 		}
   1933 	      if (BITS (4, 7) == 0xD)
   1934 		{
   1935 		  Handle_Load_Double (state, instr);
   1936 		  break;
   1937 		}
   1938 	      if (BITS (4, 7) == 0xF)
   1939 		{
   1940 		  Handle_Store_Double (state, instr);
   1941 		  break;
   1942 		}
   1943 #endif
   1944 #ifdef MODET
   1945 	      if (BITS (4, 7) == 0x9)
   1946 		{
   1947 		  /* MULL */
   1948 		  /* 32x32 = 64 */
   1949 		  ARMul_Icycles (state,
   1950 				 Multiply64 (state, instr, LUNSIGNED,
   1951 					     LDEFAULT), 0L);
   1952 		  break;
   1953 		}
   1954 #endif
   1955 	      rhs = DPRegRHS;
   1956 	      dest = LHS + rhs;
   1957 	      WRITEDEST (dest);
   1958 	      break;
   1959 
   1960 	    case 0x09:		/* ADDS reg */
   1961 #ifdef MODET
   1962 	      if ((BITS (4, 11) & 0xF9) == 0x9)
   1963 		/* LDR register offset, no write-back, up, post indexed.  */
   1964 		LHPOSTUP ();
   1965 	      /* Fall through to remaining instruction decoding.  */
   1966 #endif
   1967 #ifdef MODET
   1968 	      if (BITS (4, 7) == 0x9)
   1969 		{
   1970 		  /* MULL */
   1971 		  /* 32x32=64 */
   1972 		  ARMul_Icycles (state,
   1973 				 Multiply64 (state, instr, LUNSIGNED, LSCC),
   1974 				 0L);
   1975 		  break;
   1976 		}
   1977 #endif
   1978 	      lhs = LHS;
   1979 	      rhs = DPRegRHS;
   1980 	      dest = lhs + rhs;
   1981 	      ASSIGNZ (dest == 0);
   1982 	      if ((lhs | rhs) >> 30)
   1983 		{
   1984 		  /* Possible C,V,N to set.  */
   1985 		  ASSIGNN (NEG (dest));
   1986 		  ARMul_AddCarry (state, lhs, rhs, dest);
   1987 		  ARMul_AddOverflow (state, lhs, rhs, dest);
   1988 		}
   1989 	      else
   1990 		{
   1991 		  CLEARN;
   1992 		  CLEARC;
   1993 		  CLEARV;
   1994 		}
   1995 	      WRITESDEST (dest);
   1996 	      break;
   1997 
   1998 	    case 0x0a:		/* ADC reg */
   1999 #ifdef MODET
   2000 	      if (BITS (4, 11) == 0xB)
   2001 		{
   2002 		  /* STRH register offset, write-back, up, post-indexed.  */
   2003 		  SHUPWB ();
   2004 		  break;
   2005 		}
   2006 	      if (BITS (4, 7) == 0x9)
   2007 		{
   2008 		  /* MULL */
   2009 		  /* 32x32=64 */
   2010 		  ARMul_Icycles (state,
   2011 				 MultiplyAdd64 (state, instr, LUNSIGNED,
   2012 						LDEFAULT), 0L);
   2013 		  break;
   2014 		}
   2015 #endif
   2016 	      rhs = DPRegRHS;
   2017 	      dest = LHS + rhs + CFLAG;
   2018 	      WRITEDEST (dest);
   2019 	      break;
   2020 
   2021 	    case 0x0b:		/* ADCS reg */
   2022 #ifdef MODET
   2023 	      if ((BITS (4, 11) & 0xF9) == 0x9)
   2024 		/* LDR register offset, write-back, up, post indexed.  */
   2025 		LHPOSTUP ();
   2026 	      /* Fall through to remaining instruction decoding.  */
   2027 	      if (BITS (4, 7) == 0x9)
   2028 		{
   2029 		  /* MULL */
   2030 		  /* 32x32=64 */
   2031 		  ARMul_Icycles (state,
   2032 				 MultiplyAdd64 (state, instr, LUNSIGNED,
   2033 						LSCC), 0L);
   2034 		  break;
   2035 		}
   2036 #endif
   2037 	      lhs = LHS;
   2038 	      rhs = DPRegRHS;
   2039 	      dest = lhs + rhs + CFLAG;
   2040 	      ASSIGNZ (dest == 0);
   2041 	      if ((lhs | rhs) >> 30)
   2042 		{
   2043 		  /* Possible C,V,N to set.  */
   2044 		  ASSIGNN (NEG (dest));
   2045 		  ARMul_AddCarry (state, lhs, rhs, dest);
   2046 		  ARMul_AddOverflow (state, lhs, rhs, dest);
   2047 		}
   2048 	      else
   2049 		{
   2050 		  CLEARN;
   2051 		  CLEARC;
   2052 		  CLEARV;
   2053 		}
   2054 	      WRITESDEST (dest);
   2055 	      break;
   2056 
   2057 	    case 0x0c:		/* SBC reg */
   2058 #ifdef MODET
   2059 	      if (BITS (4, 7) == 0xB)
   2060 		{
   2061 		  /* STRH immediate offset, no write-back, up post indexed.  */
   2062 		  SHUPWB ();
   2063 		  break;
   2064 		}
   2065 	      if (BITS (4, 7) == 0xD)
   2066 		{
   2067 		  Handle_Load_Double (state, instr);
   2068 		  break;
   2069 		}
   2070 	      if (BITS (4, 7) == 0xF)
   2071 		{
   2072 		  Handle_Store_Double (state, instr);
   2073 		  break;
   2074 		}
   2075 	      if (BITS (4, 7) == 0x9)
   2076 		{
   2077 		  /* MULL */
   2078 		  /* 32x32=64 */
   2079 		  ARMul_Icycles (state,
   2080 				 Multiply64 (state, instr, LSIGNED, LDEFAULT),
   2081 				 0L);
   2082 		  break;
   2083 		}
   2084 #endif
   2085 	      rhs = DPRegRHS;
   2086 	      dest = LHS - rhs - !CFLAG;
   2087 	      WRITEDEST (dest);
   2088 	      break;
   2089 
   2090 	    case 0x0d:		/* SBCS reg */
   2091 #ifdef MODET
   2092 	      if ((BITS (4, 7) & 0x9) == 0x9)
   2093 		/* LDR immediate offset, no write-back, up, post indexed.  */
   2094 		LHPOSTUP ();
   2095 
   2096 	      if (BITS (4, 7) == 0x9)
   2097 		{
   2098 		  /* MULL */
   2099 		  /* 32x32=64 */
   2100 		  ARMul_Icycles (state,
   2101 				 Multiply64 (state, instr, LSIGNED, LSCC),
   2102 				 0L);
   2103 		  break;
   2104 		}
   2105 #endif
   2106 	      lhs = LHS;
   2107 	      rhs = DPRegRHS;
   2108 	      dest = lhs - rhs - !CFLAG;
   2109 	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))
   2110 		{
   2111 		  ARMul_SubCarry (state, lhs, rhs, dest);
   2112 		  ARMul_SubOverflow (state, lhs, rhs, dest);
   2113 		}
   2114 	      else
   2115 		{
   2116 		  CLEARC;
   2117 		  CLEARV;
   2118 		}
   2119 	      WRITESDEST (dest);
   2120 	      break;
   2121 
   2122 	    case 0x0e:		/* RSC reg */
   2123 #ifdef MODET
   2124 	      if (BITS (4, 7) == 0xB)
   2125 		{
   2126 		  /* STRH immediate offset, write-back, up, post indexed.  */
   2127 		  SHUPWB ();
   2128 		  break;
   2129 		}
   2130 
   2131 	      if (BITS (4, 7) == 0x9)
   2132 		{
   2133 		  /* MULL */
   2134 		  /* 32x32=64 */
   2135 		  ARMul_Icycles (state,
   2136 				 MultiplyAdd64 (state, instr, LSIGNED,
   2137 						LDEFAULT), 0L);
   2138 		  break;
   2139 		}
   2140 #endif
   2141 	      rhs = DPRegRHS;
   2142 	      dest = rhs - LHS - !CFLAG;
   2143 	      WRITEDEST (dest);
   2144 	      break;
   2145 
   2146 	    case 0x0f:		/* RSCS reg */
   2147 #ifdef MODET
   2148 	      if ((BITS (4, 7) & 0x9) == 0x9)
   2149 		/* LDR immediate offset, write-back, up, post indexed.  */
   2150 		LHPOSTUP ();
   2151 	      /* Fall through to remaining instruction decoding.  */
   2152 
   2153 	      if (BITS (4, 7) == 0x9)
   2154 		{
   2155 		  /* MULL */
   2156 		  /* 32x32=64 */
   2157 		  ARMul_Icycles (state,
   2158 				 MultiplyAdd64 (state, instr, LSIGNED, LSCC),
   2159 				 0L);
   2160 		  break;
   2161 		}
   2162 #endif
   2163 	      lhs = LHS;
   2164 	      rhs = DPRegRHS;
   2165 	      dest = rhs - lhs - !CFLAG;
   2166 
   2167 	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))
   2168 		{
   2169 		  ARMul_SubCarry (state, rhs, lhs, dest);
   2170 		  ARMul_SubOverflow (state, rhs, lhs, dest);
   2171 		}
   2172 	      else
   2173 		{
   2174 		  CLEARC;
   2175 		  CLEARV;
   2176 		}
   2177 	      WRITESDEST (dest);
   2178 	      break;
   2179 
   2180 	    case 0x10:		/* TST reg and MRS CPSR and SWP word.  */
   2181 	      if (state->is_v5e)
   2182 		{
   2183 		  if (BIT (4) == 0 && BIT (7) == 1)
   2184 		    {
   2185 		      /* ElSegundo SMLAxy insn.  */
   2186 		      ARMword op1 = state->Reg[BITS (0, 3)];
   2187 		      ARMword op2 = state->Reg[BITS (8, 11)];
   2188 		      ARMword Rn = state->Reg[BITS (12, 15)];
   2189 
   2190 		      if (BIT (5))
   2191 			op1 >>= 16;
   2192 		      if (BIT (6))
   2193 			op2 >>= 16;
   2194 		      op1 &= 0xFFFF;
   2195 		      op2 &= 0xFFFF;
   2196 		      if (op1 & 0x8000)
   2197 			op1 -= 65536;
   2198 		      if (op2 & 0x8000)
   2199 			op2 -= 65536;
   2200 		      op1 *= op2;
   2201 
   2202 		      if (AddOverflow (op1, Rn, op1 + Rn))
   2203 			SETS;
   2204 		      state->Reg[BITS (16, 19)] = op1 + Rn;
   2205 		      break;
   2206 		    }
   2207 
   2208 		  if (BITS (4, 11) == 5)
   2209 		    {
   2210 		      /* ElSegundo QADD insn.  */
   2211 		      ARMword op1 = state->Reg[BITS (0, 3)];
   2212 		      ARMword op2 = state->Reg[BITS (16, 19)];
   2213 		      ARMword result = op1 + op2;
   2214 		      if (AddOverflow (op1, op2, result))
   2215 			{
   2216 			  result = POS (result) ? 0x80000000 : 0x7fffffff;
   2217 			  SETS;
   2218 			}
   2219 		      state->Reg[BITS (12, 15)] = result;
   2220 		      break;
   2221 		    }
   2222 		}
   2223 #ifdef MODET
   2224 	      if (BITS (4, 11) == 0xB)
   2225 		{
   2226 		  /* STRH register offset, no write-back, down, pre indexed.  */
   2227 		  SHPREDOWN ();
   2228 		  break;
   2229 		}
   2230 	      if (BITS (4, 7) == 0xD)
   2231 		{
   2232 		  Handle_Load_Double (state, instr);
   2233 		  break;
   2234 		}
   2235 	      if (BITS (4, 7) == 0xF)
   2236 		{
   2237 		  Handle_Store_Double (state, instr);
   2238 		  break;
   2239 		}
   2240 #endif
   2241 	      if (BITS (4, 11) == 9)
   2242 		{
   2243 		  /* SWP */
   2244 		  UNDEF_SWPPC;
   2245 		  temp = LHS;
   2246 		  BUSUSEDINCPCS;
   2247 #ifndef MODE32
   2248 		  if (VECTORACCESS (temp) || ADDREXCEPT (temp))
   2249 		    {
   2250 		      INTERNALABORT (temp);
   2251 		      (void) ARMul_LoadWordN (state, temp);
   2252 		      (void) ARMul_LoadWordN (state, temp);
   2253 		    }
   2254 		  else
   2255 #endif
   2256 		    dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]);
   2257 		  if (temp & 3)
   2258 		    DEST = ARMul_Align (state, temp, dest);
   2259 		  else
   2260 		    DEST = dest;
   2261 		  if (state->abortSig || state->Aborted)
   2262 		    TAKEABORT;
   2263 		}
   2264 	      else if ((BITS (0, 11) == 0) && (LHSReg == 15))
   2265 		{		/* MRS CPSR */
   2266 		  UNDEF_MRSPC;
   2267 		  DEST = ECC | EINT | EMODE;
   2268 		}
   2269 	      else
   2270 		{
   2271 #ifdef MODE32
   2272 		  if (state->is_v6
   2273 		      && handle_v6_insn (state, instr))
   2274 		    break;
   2275 #endif
   2276 		  UNDEF_Test;
   2277 		}
   2278 	      break;
   2279 
   2280 	    case 0x11:		/* TSTP reg */
   2281 #ifdef MODET
   2282 	      if ((BITS (4, 11) & 0xF9) == 0x9)
   2283 		/* LDR register offset, no write-back, down, pre indexed.  */
   2284 		LHPREDOWN ();
   2285 	      /* Continue with remaining instruction decode.  */
   2286 #endif
   2287 	      if (DESTReg == 15)
   2288 		{
   2289 		  /* TSTP reg */
   2290 #ifdef MODE32
   2291 		  state->Cpsr = GETSPSR (state->Bank);
   2292 		  ARMul_CPSRAltered (state);
   2293 #else
   2294 		  rhs = DPRegRHS;
   2295 		  temp = LHS & rhs;
   2296 		  SETR15PSR (temp);
   2297 #endif
   2298 		}
   2299 	      else
   2300 		{
   2301 		  /* TST reg */
   2302 		  rhs = DPSRegRHS;
   2303 		  dest = LHS & rhs;
   2304 		  ARMul_NegZero (state, dest);
   2305 		}
   2306 	      break;
   2307 
   2308 	    case 0x12:		/* TEQ reg and MSR reg to CPSR (ARM6).  */
   2309 	      if (state->is_v5)
   2310 		{
   2311 		  if (BITS (4, 7) == 3)
   2312 		    {
   2313 		      /* BLX(2) */
   2314 		      if (TFLAG)
   2315 			dest = (pc + 2) | 1;
   2316 		      else
   2317 			dest = pc + 4;
   2318 
   2319 		      WriteR15Branch (state, state->Reg[RHSReg]);
   2320 		      state->Reg[14] = dest;
   2321 		      break;
   2322 		    }
   2323 		}
   2324 
   2325 	      if (state->is_v5e)
   2326 		{
   2327 		  if (BIT (4) == 0 && BIT (7) == 1
   2328 		      && (BIT (5) == 0 || BITS (12, 15) == 0))
   2329 		    {
   2330 		      /* ElSegundo SMLAWy/SMULWy insn.  */
   2331 		      ARMdword op1 = state->Reg[BITS (0, 3)];
   2332 		      ARMdword op2 = state->Reg[BITS (8, 11)];
   2333 		      ARMdword result;
   2334 
   2335 		      if (BIT (6))
   2336 			op2 >>= 16;
   2337 		      if (op1 & 0x80000000)
   2338 			op1 -= 1ULL << 32;
   2339 		      op2 &= 0xFFFF;
   2340 		      if (op2 & 0x8000)
   2341 			op2 -= 65536;
   2342 		      result = (op1 * op2) >> 16;
   2343 
   2344 		      if (BIT (5) == 0)
   2345 			{
   2346 			  ARMword Rn = state->Reg[BITS (12, 15)];
   2347 
   2348 			  if (AddOverflow (result, Rn, result + Rn))
   2349 			    SETS;
   2350 			  result += Rn;
   2351 			}
   2352 		      state->Reg[BITS (16, 19)] = result;
   2353 		      break;
   2354 		    }
   2355 
   2356 		  if (BITS (4, 11) == 5)
   2357 		    {
   2358 		      /* ElSegundo QSUB insn.  */
   2359 		      ARMword op1 = state->Reg[BITS (0, 3)];
   2360 		      ARMword op2 = state->Reg[BITS (16, 19)];
   2361 		      ARMword result = op1 - op2;
   2362 
   2363 		      if (SubOverflow (op1, op2, result))
   2364 			{
   2365 			  result = POS (result) ? 0x80000000 : 0x7fffffff;
   2366 			  SETS;
   2367 			}
   2368 
   2369 		      state->Reg[BITS (12, 15)] = result;
   2370 		      break;
   2371 		    }
   2372 		}
   2373 #ifdef MODET
   2374 	      if (BITS (4, 11) == 0xB)
   2375 		{
   2376 		  /* STRH register offset, write-back, down, pre indexed.  */
   2377 		  SHPREDOWNWB ();
   2378 		  break;
   2379 		}
   2380 	      if (BITS (4, 27) == 0x12FFF1)
   2381 		{
   2382 		  /* BX */
   2383 		  WriteR15Branch (state, state->Reg[RHSReg]);
   2384 		  break;
   2385 		}
   2386 	      if (BITS (4, 7) == 0xD)
   2387 		{
   2388 		  Handle_Load_Double (state, instr);
   2389 		  break;
   2390 		}
   2391 	      if (BITS (4, 7) == 0xF)
   2392 		{
   2393 		  Handle_Store_Double (state, instr);
   2394 		  break;
   2395 		}
   2396 #endif
   2397 	      if (state->is_v5)
   2398 		{
   2399 		  if (BITS (4, 7) == 0x7)
   2400 		    {
   2401 		      extern int SWI_vector_installed;
   2402 
   2403 		      /* Hardware is allowed to optionally override this
   2404 			 instruction and treat it as a breakpoint.  Since
   2405 			 this is a simulator not hardware, we take the position
   2406 			 that if a SWI vector was not installed, then an Abort
   2407 			 vector was probably not installed either, and so
   2408 			 normally this instruction would be ignored, even if an
   2409 			 Abort is generated.  This is a bad thing, since GDB
   2410 			 uses this instruction for its breakpoints (at least in
   2411 			 Thumb mode it does).  So intercept the instruction here
   2412 			 and generate a breakpoint SWI instead.  */
   2413 		      if (! SWI_vector_installed)
   2414 			ARMul_OSHandleSWI (state, SWI_Breakpoint);
   2415 		      else
   2416 			{
   2417 			  /* BKPT - normally this will cause an abort, but on the
   2418 			     XScale we must check the DCSR.  */
   2419 			  XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
   2420 	                  if (!XScale_debug_moe (state, ARMul_CP14_R10_MOE_BT))
   2421 			    break;
   2422 			}
   2423 
   2424 		      /* Force the next instruction to be refetched.  */
   2425 		      state->NextInstr = RESUME;
   2426 		      break;
   2427 		    }
   2428 		}
   2429 	      if (DESTReg == 15)
   2430 		{
   2431 		  /* MSR reg to CPSR.  */
   2432 		  UNDEF_MSRPC;
   2433 		  temp = DPRegRHS;
   2434 #ifdef MODET
   2435 		  /* Don't allow TBIT to be set by MSR.  */
   2436 		  temp &= ~ TBIT;
   2437 #endif
   2438 		  ARMul_FixCPSR (state, instr, temp);
   2439 		}
   2440 #ifdef MODE32
   2441 	      else if (state->is_v6
   2442 		       && handle_v6_insn (state, instr))
   2443 		break;
   2444 #endif
   2445 	      else
   2446 		UNDEF_Test;
   2447 
   2448 	      break;
   2449 
   2450 	    case 0x13:		/* TEQP reg */
   2451 #ifdef MODET
   2452 	      if ((BITS (4, 11) & 0xF9) == 0x9)
   2453 		/* LDR register offset, write-back, down, pre indexed.  */
   2454 		LHPREDOWNWB ();
   2455 	      /* Continue with remaining instruction decode.  */
   2456 #endif
   2457 	      if (DESTReg == 15)
   2458 		{
   2459 		  /* TEQP reg */
   2460 #ifdef MODE32
   2461 		  state->Cpsr = GETSPSR (state->Bank);
   2462 		  ARMul_CPSRAltered (state);
   2463 #else
   2464 		  rhs = DPRegRHS;
   2465 		  temp = LHS ^ rhs;
   2466 		  SETR15PSR (temp);
   2467 #endif
   2468 		}
   2469 	      else
   2470 		{
   2471 		  /* TEQ Reg.  */
   2472 		  rhs = DPSRegRHS;
   2473 		  dest = LHS ^ rhs;
   2474 		  ARMul_NegZero (state, dest);
   2475 		}
   2476 	      break;
   2477 
   2478 	    case 0x14:		/* CMP reg and MRS SPSR and SWP byte.  */
   2479 	      if (state->is_v5e)
   2480 		{
   2481 		  if (BIT (4) == 0 && BIT (7) == 1)
   2482 		    {
   2483 		      /* ElSegundo SMLALxy insn.  */
   2484 		      ARMdword op1 = state->Reg[BITS (0, 3)];
   2485 		      ARMdword op2 = state->Reg[BITS (8, 11)];
   2486 		      ARMdword result;
   2487 
   2488 		      if (BIT (5))
   2489 			op1 >>= 16;
   2490 		      if (BIT (6))
   2491 			op2 >>= 16;
   2492 		      op1 &= 0xFFFF;
   2493 		      if (op1 & 0x8000)
   2494 			op1 -= 65536;
   2495 		      op2 &= 0xFFFF;
   2496 		      if (op2 & 0x8000)
   2497 			op2 -= 65536;
   2498 
   2499 		      result = (ARMdword) state->Reg[BITS (16, 19)] << 32;
   2500 		      result |= state->Reg[BITS (12, 15)];
   2501 		      result += op1 * op2;
   2502 		      state->Reg[BITS (12, 15)] = result;
   2503 		      state->Reg[BITS (16, 19)] = result >> 32;
   2504 		      break;
   2505 		    }
   2506 
   2507 		  if (BITS (4, 11) == 5)
   2508 		    {
   2509 		      /* ElSegundo QDADD insn.  */
   2510 		      ARMword op1 = state->Reg[BITS (0, 3)];
   2511 		      ARMword op2 = state->Reg[BITS (16, 19)];
   2512 		      ARMword op2d = op2 + op2;
   2513 		      ARMword result;
   2514 
   2515 		      if (AddOverflow (op2, op2, op2d))
   2516 			{
   2517 			  SETS;
   2518 			  op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
   2519 			}
   2520 
   2521 		      result = op1 + op2d;
   2522 		      if (AddOverflow (op1, op2d, result))
   2523 			{
   2524 			  SETS;
   2525 			  result = POS (result) ? 0x80000000 : 0x7fffffff;
   2526 			}
   2527 
   2528 		      state->Reg[BITS (12, 15)] = result;
   2529 		      break;
   2530 		    }
   2531 		}
   2532 #ifdef MODET
   2533 	      if (BITS (4, 7) == 0xB)
   2534 		{
   2535 		  /* STRH immediate offset, no write-back, down, pre indexed.  */
   2536 		  SHPREDOWN ();
   2537 		  break;
   2538 		}
   2539 	      if (BITS (4, 7) == 0xD)
   2540 		{
   2541 		  Handle_Load_Double (state, instr);
   2542 		  break;
   2543 		}
   2544 	      if (BITS (4, 7) == 0xF)
   2545 		{
   2546 		  Handle_Store_Double (state, instr);
   2547 		  break;
   2548 		}
   2549 #endif
   2550 	      if (BITS (4, 11) == 9)
   2551 		{
   2552 		  /* SWP */
   2553 		  UNDEF_SWPPC;
   2554 		  temp = LHS;
   2555 		  BUSUSEDINCPCS;
   2556 #ifndef MODE32
   2557 		  if (VECTORACCESS (temp) || ADDREXCEPT (temp))
   2558 		    {
   2559 		      INTERNALABORT (temp);
   2560 		      (void) ARMul_LoadByte (state, temp);
   2561 		      (void) ARMul_LoadByte (state, temp);
   2562 		    }
   2563 		  else
   2564 #endif
   2565 		    DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
   2566 		  if (state->abortSig || state->Aborted)
   2567 		    TAKEABORT;
   2568 		}
   2569 	      else if ((BITS (0, 11) == 0) && (LHSReg == 15))
   2570 		{
   2571 		  /* MRS SPSR */
   2572 		  UNDEF_MRSPC;
   2573 		  DEST = GETSPSR (state->Bank);
   2574 		}
   2575 #ifdef MODE32
   2576 	      else if (state->is_v6
   2577 		       && handle_v6_insn (state, instr))
   2578 		break;
   2579 #endif
   2580 	      else
   2581 		UNDEF_Test;
   2582 
   2583 	      break;
   2584 
   2585 	    case 0x15:		/* CMPP reg.  */
   2586 #ifdef MODET
   2587 	      if ((BITS (4, 7) & 0x9) == 0x9)
   2588 		/* LDR immediate offset, no write-back, down, pre indexed.  */
   2589 		LHPREDOWN ();
   2590 	      /* Continue with remaining instruction decode.  */
   2591 #endif
   2592 	      if (DESTReg == 15)
   2593 		{
   2594 		  /* CMPP reg.  */
   2595 #ifdef MODE32
   2596 		  state->Cpsr = GETSPSR (state->Bank);
   2597 		  ARMul_CPSRAltered (state);
   2598 #else
   2599 		  rhs = DPRegRHS;
   2600 		  temp = LHS - rhs;
   2601 		  SETR15PSR (temp);
   2602 #endif
   2603 		}
   2604 	      else
   2605 		{
   2606 		  /* CMP reg.  */
   2607 		  lhs = LHS;
   2608 		  rhs = DPRegRHS;
   2609 		  dest = lhs - rhs;
   2610 		  ARMul_NegZero (state, dest);
   2611 		  if ((lhs >= rhs) || ((rhs | lhs) >> 31))
   2612 		    {
   2613 		      ARMul_SubCarry (state, lhs, rhs, dest);
   2614 		      ARMul_SubOverflow (state, lhs, rhs, dest);
   2615 		    }
   2616 		  else
   2617 		    {
   2618 		      CLEARC;
   2619 		      CLEARV;
   2620 		    }
   2621 		}
   2622 	      break;
   2623 
   2624 	    case 0x16:		/* CMN reg and MSR reg to SPSR */
   2625 	      if (state->is_v5e)
   2626 		{
   2627 		  if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0)
   2628 		    {
   2629 		      /* ElSegundo SMULxy insn.  */
   2630 		      ARMword op1 = state->Reg[BITS (0, 3)];
   2631 		      ARMword op2 = state->Reg[BITS (8, 11)];
   2632 
   2633 		      if (BIT (5))
   2634 			op1 >>= 16;
   2635 		      if (BIT (6))
   2636 			op2 >>= 16;
   2637 		      op1 &= 0xFFFF;
   2638 		      op2 &= 0xFFFF;
   2639 		      if (op1 & 0x8000)
   2640 			op1 -= 65536;
   2641 		      if (op2 & 0x8000)
   2642 			op2 -= 65536;
   2643 
   2644 		      state->Reg[BITS (16, 19)] = op1 * op2;
   2645 		      break;
   2646 		    }
   2647 
   2648 		  if (BITS (4, 11) == 5)
   2649 		    {
   2650 		      /* ElSegundo QDSUB insn.  */
   2651 		      ARMword op1 = state->Reg[BITS (0, 3)];
   2652 		      ARMword op2 = state->Reg[BITS (16, 19)];
   2653 		      ARMword op2d = op2 + op2;
   2654 		      ARMword result;
   2655 
   2656 		      if (AddOverflow (op2, op2, op2d))
   2657 			{
   2658 			  SETS;
   2659 			  op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
   2660 			}
   2661 
   2662 		      result = op1 - op2d;
   2663 		      if (SubOverflow (op1, op2d, result))
   2664 			{
   2665 			  SETS;
   2666 			  result = POS (result) ? 0x80000000 : 0x7fffffff;
   2667 			}
   2668 
   2669 		      state->Reg[BITS (12, 15)] = result;
   2670 		      break;
   2671 		    }
   2672 		}
   2673 
   2674 	      if (state->is_v5)
   2675 		{
   2676 		  if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF)
   2677 		    {
   2678 		      /* ARM5 CLZ insn.  */
   2679 		      ARMword op1 = state->Reg[BITS (0, 3)];
   2680 		      int result = 32;
   2681 
   2682 		      if (op1)
   2683 			for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
   2684 			  result++;
   2685 
   2686 		      state->Reg[BITS (12, 15)] = result;
   2687 		      break;
   2688 		    }
   2689 		}
   2690 #ifdef MODET
   2691 	      if (BITS (4, 7) == 0xB)
   2692 		{
   2693 		  /* STRH immediate offset, write-back, down, pre indexed.  */
   2694 		  SHPREDOWNWB ();
   2695 		  break;
   2696 		}
   2697 	      if (BITS (4, 7) == 0xD)
   2698 		{
   2699 		  Handle_Load_Double (state, instr);
   2700 		  break;
   2701 		}
   2702 	      if (BITS (4, 7) == 0xF)
   2703 		{
   2704 		  Handle_Store_Double (state, instr);
   2705 		  break;
   2706 		}
   2707 #endif
   2708 	      if (DESTReg == 15)
   2709 		{
   2710 		  /* MSR */
   2711 		  UNDEF_MSRPC;
   2712 		  ARMul_FixSPSR (state, instr, DPRegRHS);
   2713 		}
   2714 	      else
   2715 		{
   2716 #ifdef MODE32
   2717 		  if (state->is_v6
   2718 		      && handle_v6_insn (state, instr))
   2719 		    break;
   2720 #endif
   2721 		  UNDEF_Test;
   2722 		}
   2723 	      break;
   2724 
   2725 	    case 0x17:		/* CMNP reg */
   2726 #ifdef MODET
   2727 	      if ((BITS (4, 7) & 0x9) == 0x9)
   2728 		/* LDR immediate offset, write-back, down, pre indexed.  */
   2729 		LHPREDOWNWB ();
   2730 	      /* Continue with remaining instruction decoding.  */
   2731 #endif
   2732 	      if (DESTReg == 15)
   2733 		{
   2734 #ifdef MODE32
   2735 		  state->Cpsr = GETSPSR (state->Bank);
   2736 		  ARMul_CPSRAltered (state);
   2737 #else
   2738 		  rhs = DPRegRHS;
   2739 		  temp = LHS + rhs;
   2740 		  SETR15PSR (temp);
   2741 #endif
   2742 		  break;
   2743 		}
   2744 	      else
   2745 		{
   2746 		  /* CMN reg.  */
   2747 		  lhs = LHS;
   2748 		  rhs = DPRegRHS;
   2749 		  dest = lhs + rhs;
   2750 		  ASSIGNZ (dest == 0);
   2751 		  if ((lhs | rhs) >> 30)
   2752 		    {
   2753 		      /* Possible C,V,N to set.  */
   2754 		      ASSIGNN (NEG (dest));
   2755 		      ARMul_AddCarry (state, lhs, rhs, dest);
   2756 		      ARMul_AddOverflow (state, lhs, rhs, dest);
   2757 		    }
   2758 		  else
   2759 		    {
   2760 		      CLEARN;
   2761 		      CLEARC;
   2762 		      CLEARV;
   2763 		    }
   2764 		}
   2765 	      break;
   2766 
   2767 	    case 0x18:		/* ORR reg */
   2768 #ifdef MODET
   2769 	      if (BITS (4, 11) == 0xB)
   2770 		{
   2771 		  /* STRH register offset, no write-back, up, pre indexed.  */
   2772 		  SHPREUP ();
   2773 		  break;
   2774 		}
   2775 	      if (BITS (4, 7) == 0xD)
   2776 		{
   2777 		  Handle_Load_Double (state, instr);
   2778 		  break;
   2779 		}
   2780 	      if (BITS (4, 7) == 0xF)
   2781 		{
   2782 		  Handle_Store_Double (state, instr);
   2783 		  break;
   2784 		}
   2785 #endif
   2786 	      rhs = DPRegRHS;
   2787 	      dest = LHS | rhs;
   2788 	      WRITEDEST (dest);
   2789 	      break;
   2790 
   2791 	    case 0x19:		/* ORRS reg */
   2792 #ifdef MODET
   2793 	      if ((BITS (4, 11) & 0xF9) == 0x9)
   2794 		/* LDR register offset, no write-back, up, pre indexed.  */
   2795 		LHPREUP ();
   2796 	      /* Continue with remaining instruction decoding.  */
   2797 #endif
   2798 	      rhs = DPSRegRHS;
   2799 	      dest = LHS | rhs;
   2800 	      WRITESDEST (dest);
   2801 	      break;
   2802 
   2803 	    case 0x1a:		/* MOV reg */
   2804 #ifdef MODET
   2805 	      if (BITS (4, 11) == 0xB)
   2806 		{
   2807 		  /* STRH register offset, write-back, up, pre indexed.  */
   2808 		  SHPREUPWB ();
   2809 		  break;
   2810 		}
   2811 	      if (BITS (4, 7) == 0xD)
   2812 		{
   2813 		  Handle_Load_Double (state, instr);
   2814 		  break;
   2815 		}
   2816 	      if (BITS (4, 7) == 0xF)
   2817 		{
   2818 		  Handle_Store_Double (state, instr);
   2819 		  break;
   2820 		}
   2821 #endif
   2822 	      dest = DPRegRHS;
   2823 	      WRITEDEST (dest);
   2824 	      break;
   2825 
   2826 	    case 0x1b:		/* MOVS reg */
   2827 #ifdef MODET
   2828 	      if ((BITS (4, 11) & 0xF9) == 0x9)
   2829 		/* LDR register offset, write-back, up, pre indexed.  */
   2830 		LHPREUPWB ();
   2831 	      /* Continue with remaining instruction decoding.  */
   2832 #endif
   2833 	      dest = DPSRegRHS;
   2834 	      WRITESDEST (dest);
   2835 	      break;
   2836 
   2837 	    case 0x1c:		/* BIC reg */
   2838 #ifdef MODET
   2839 	      if (BITS (4, 7) == 0xB)
   2840 		{
   2841 		  /* STRH immediate offset, no write-back, up, pre indexed.  */
   2842 		  SHPREUP ();
   2843 		  break;
   2844 		}
   2845 	      if (BITS (4, 7) == 0xD)
   2846 		{
   2847 		  Handle_Load_Double (state, instr);
   2848 		  break;
   2849 		}
   2850 	      else if (BITS (4, 7) == 0xF)
   2851 		{
   2852 		  Handle_Store_Double (state, instr);
   2853 		  break;
   2854 		}
   2855 #endif
   2856 	      rhs = DPRegRHS;
   2857 	      dest = LHS & ~rhs;
   2858 	      WRITEDEST (dest);
   2859 	      break;
   2860 
   2861 	    case 0x1d:		/* BICS reg */
   2862 #ifdef MODET
   2863 	      if ((BITS (4, 7) & 0x9) == 0x9)
   2864 		/* LDR immediate offset, no write-back, up, pre indexed.  */
   2865 		LHPREUP ();
   2866 	      /* Continue with instruction decoding.  */
   2867 #endif
   2868 	      rhs = DPSRegRHS;
   2869 	      dest = LHS & ~rhs;
   2870 	      WRITESDEST (dest);
   2871 	      break;
   2872 
   2873 	    case 0x1e:		/* MVN reg */
   2874 #ifdef MODET
   2875 	      if (BITS (4, 7) == 0xB)
   2876 		{
   2877 		  /* STRH immediate offset, write-back, up, pre indexed.  */
   2878 		  SHPREUPWB ();
   2879 		  break;
   2880 		}
   2881 	      if (BITS (4, 7) == 0xD)
   2882 		{
   2883 		  Handle_Load_Double (state, instr);
   2884 		  break;
   2885 		}
   2886 	      if (BITS (4, 7) == 0xF)
   2887 		{
   2888 		  Handle_Store_Double (state, instr);
   2889 		  break;
   2890 		}
   2891 #endif
   2892 	      dest = ~DPRegRHS;
   2893 	      WRITEDEST (dest);
   2894 	      break;
   2895 
   2896 	    case 0x1f:		/* MVNS reg */
   2897 #ifdef MODET
   2898 	      if ((BITS (4, 7) & 0x9) == 0x9)
   2899 		/* LDR immediate offset, write-back, up, pre indexed.  */
   2900 		LHPREUPWB ();
   2901 	      /* Continue instruction decoding.  */
   2902 #endif
   2903 	      dest = ~DPSRegRHS;
   2904 	      WRITESDEST (dest);
   2905 	      break;
   2906 
   2907 
   2908 	      /* Data Processing Immediate RHS Instructions.  */
   2909 
   2910 	    case 0x20:		/* AND immed */
   2911 	      dest = LHS & DPImmRHS;
   2912 	      WRITEDEST (dest);
   2913 	      break;
   2914 
   2915 	    case 0x21:		/* ANDS immed */
   2916 	      DPSImmRHS;
   2917 	      dest = LHS & rhs;
   2918 	      WRITESDEST (dest);
   2919 	      break;
   2920 
   2921 	    case 0x22:		/* EOR immed */
   2922 	      dest = LHS ^ DPImmRHS;
   2923 	      WRITEDEST (dest);
   2924 	      break;
   2925 
   2926 	    case 0x23:		/* EORS immed */
   2927 	      DPSImmRHS;
   2928 	      dest = LHS ^ rhs;
   2929 	      WRITESDEST (dest);
   2930 	      break;
   2931 
   2932 	    case 0x24:		/* SUB immed */
   2933 	      dest = LHS - DPImmRHS;
   2934 	      WRITEDEST (dest);
   2935 	      break;
   2936 
   2937 	    case 0x25:		/* SUBS immed */
   2938 	      lhs = LHS;
   2939 	      rhs = DPImmRHS;
   2940 	      dest = lhs - rhs;
   2941 
   2942 	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))
   2943 		{
   2944 		  ARMul_SubCarry (state, lhs, rhs, dest);
   2945 		  ARMul_SubOverflow (state, lhs, rhs, dest);
   2946 		}
   2947 	      else
   2948 		{
   2949 		  CLEARC;
   2950 		  CLEARV;
   2951 		}
   2952 	      WRITESDEST (dest);
   2953 	      break;
   2954 
   2955 	    case 0x26:		/* RSB immed */
   2956 	      dest = DPImmRHS - LHS;
   2957 	      WRITEDEST (dest);
   2958 	      break;
   2959 
   2960 	    case 0x27:		/* RSBS immed */
   2961 	      lhs = LHS;
   2962 	      rhs = DPImmRHS;
   2963 	      dest = rhs - lhs;
   2964 
   2965 	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))
   2966 		{
   2967 		  ARMul_SubCarry (state, rhs, lhs, dest);
   2968 		  ARMul_SubOverflow (state, rhs, lhs, dest);
   2969 		}
   2970 	      else
   2971 		{
   2972 		  CLEARC;
   2973 		  CLEARV;
   2974 		}
   2975 	      WRITESDEST (dest);
   2976 	      break;
   2977 
   2978 	    case 0x28:		/* ADD immed */
   2979 	      dest = LHS + DPImmRHS;
   2980 	      WRITEDEST (dest);
   2981 	      break;
   2982 
   2983 	    case 0x29:		/* ADDS immed */
   2984 	      lhs = LHS;
   2985 	      rhs = DPImmRHS;
   2986 	      dest = lhs + rhs;
   2987 	      ASSIGNZ (dest == 0);
   2988 
   2989 	      if ((lhs | rhs) >> 30)
   2990 		{
   2991 		  /* Possible C,V,N to set.  */
   2992 		  ASSIGNN (NEG (dest));
   2993 		  ARMul_AddCarry (state, lhs, rhs, dest);
   2994 		  ARMul_AddOverflow (state, lhs, rhs, dest);
   2995 		}
   2996 	      else
   2997 		{
   2998 		  CLEARN;
   2999 		  CLEARC;
   3000 		  CLEARV;
   3001 		}
   3002 	      WRITESDEST (dest);
   3003 	      break;
   3004 
   3005 	    case 0x2a:		/* ADC immed */
   3006 	      dest = LHS + DPImmRHS + CFLAG;
   3007 	      WRITEDEST (dest);
   3008 	      break;
   3009 
   3010 	    case 0x2b:		/* ADCS immed */
   3011 	      lhs = LHS;
   3012 	      rhs = DPImmRHS;
   3013 	      dest = lhs + rhs + CFLAG;
   3014 	      ASSIGNZ (dest == 0);
   3015 	      if ((lhs | rhs) >> 30)
   3016 		{
   3017 		  /* Possible C,V,N to set.  */
   3018 		  ASSIGNN (NEG (dest));
   3019 		  ARMul_AddCarry (state, lhs, rhs, dest);
   3020 		  ARMul_AddOverflow (state, lhs, rhs, dest);
   3021 		}
   3022 	      else
   3023 		{
   3024 		  CLEARN;
   3025 		  CLEARC;
   3026 		  CLEARV;
   3027 		}
   3028 	      WRITESDEST (dest);
   3029 	      break;
   3030 
   3031 	    case 0x2c:		/* SBC immed */
   3032 	      dest = LHS - DPImmRHS - !CFLAG;
   3033 	      WRITEDEST (dest);
   3034 	      break;
   3035 
   3036 	    case 0x2d:		/* SBCS immed */
   3037 	      lhs = LHS;
   3038 	      rhs = DPImmRHS;
   3039 	      dest = lhs - rhs - !CFLAG;
   3040 	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))
   3041 		{
   3042 		  ARMul_SubCarry (state, lhs, rhs, dest);
   3043 		  ARMul_SubOverflow (state, lhs, rhs, dest);
   3044 		}
   3045 	      else
   3046 		{
   3047 		  CLEARC;
   3048 		  CLEARV;
   3049 		}
   3050 	      WRITESDEST (dest);
   3051 	      break;
   3052 
   3053 	    case 0x2e:		/* RSC immed */
   3054 	      dest = DPImmRHS - LHS - !CFLAG;
   3055 	      WRITEDEST (dest);
   3056 	      break;
   3057 
   3058 	    case 0x2f:		/* RSCS immed */
   3059 	      lhs = LHS;
   3060 	      rhs = DPImmRHS;
   3061 	      dest = rhs - lhs - !CFLAG;
   3062 	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))
   3063 		{
   3064 		  ARMul_SubCarry (state, rhs, lhs, dest);
   3065 		  ARMul_SubOverflow (state, rhs, lhs, dest);
   3066 		}
   3067 	      else
   3068 		{
   3069 		  CLEARC;
   3070 		  CLEARV;
   3071 		}
   3072 	      WRITESDEST (dest);
   3073 	      break;
   3074 
   3075 	    case 0x30:		/* MOVW immed */
   3076 #ifdef MODE32
   3077 	      if (state->is_v6
   3078 		  && handle_v6_insn (state, instr))
   3079 		break;
   3080 #endif
   3081 	      dest = BITS (0, 11);
   3082 	      dest |= (BITS (16, 19) << 12);
   3083 	      WRITEDEST (dest);
   3084 	      break;
   3085 
   3086 	    case 0x31:		/* TSTP immed */
   3087 	      if (DESTReg == 15)
   3088 		{
   3089 		  /* TSTP immed.  */
   3090 #ifdef MODE32
   3091 		  state->Cpsr = GETSPSR (state->Bank);
   3092 		  ARMul_CPSRAltered (state);
   3093 #else
   3094 		  temp = LHS & DPImmRHS;
   3095 		  SETR15PSR (temp);
   3096 #endif
   3097 		}
   3098 	      else
   3099 		{
   3100 		  /* TST immed.  */
   3101 		  DPSImmRHS;
   3102 		  dest = LHS & rhs;
   3103 		  ARMul_NegZero (state, dest);
   3104 		}
   3105 	      break;
   3106 
   3107 	    case 0x32:		/* TEQ immed and MSR immed to CPSR */
   3108 	      if (DESTReg == 15)
   3109 		/* MSR immed to CPSR.  */
   3110 		ARMul_FixCPSR (state, instr, DPImmRHS);
   3111 #ifdef MODE32
   3112 	      else if (state->is_v6
   3113 		       && handle_v6_insn (state, instr))
   3114 		break;
   3115 #endif
   3116 	      else
   3117 		UNDEF_Test;
   3118 	      break;
   3119 
   3120 	    case 0x33:		/* TEQP immed */
   3121 	      if (DESTReg == 15)
   3122 		{
   3123 		  /* TEQP immed.  */
   3124 #ifdef MODE32
   3125 		  state->Cpsr = GETSPSR (state->Bank);
   3126 		  ARMul_CPSRAltered (state);
   3127 #else
   3128 		  temp = LHS ^ DPImmRHS;
   3129 		  SETR15PSR (temp);
   3130 #endif
   3131 		}
   3132 	      else
   3133 		{
   3134 		  DPSImmRHS;	/* TEQ immed */
   3135 		  dest = LHS ^ rhs;
   3136 		  ARMul_NegZero (state, dest);
   3137 		}
   3138 	      break;
   3139 
   3140 	    case 0x34:		/* MOVT immed */
   3141 #ifdef MODE32
   3142 	      if (state->is_v6
   3143 		  && handle_v6_insn (state, instr))
   3144 		break;
   3145 #endif
   3146 	      DEST &= 0xFFFF;
   3147 	      dest  = BITS (0, 11);
   3148 	      dest |= (BITS (16, 19) << 12);
   3149 	      DEST |= (dest << 16);
   3150 	      break;
   3151 
   3152 	    case 0x35:		/* CMPP immed */
   3153 	      if (DESTReg == 15)
   3154 		{
   3155 		  /* CMPP immed.  */
   3156 #ifdef MODE32
   3157 		  state->Cpsr = GETSPSR (state->Bank);
   3158 		  ARMul_CPSRAltered (state);
   3159 #else
   3160 		  temp = LHS - DPImmRHS;
   3161 		  SETR15PSR (temp);
   3162 #endif
   3163 		  break;
   3164 		}
   3165 	      else
   3166 		{
   3167 		  /* CMP immed.  */
   3168 		  lhs = LHS;
   3169 		  rhs = DPImmRHS;
   3170 		  dest = lhs - rhs;
   3171 		  ARMul_NegZero (state, dest);
   3172 
   3173 		  if ((lhs >= rhs) || ((rhs | lhs) >> 31))
   3174 		    {
   3175 		      ARMul_SubCarry (state, lhs, rhs, dest);
   3176 		      ARMul_SubOverflow (state, lhs, rhs, dest);
   3177 		    }
   3178 		  else
   3179 		    {
   3180 		      CLEARC;
   3181 		      CLEARV;
   3182 		    }
   3183 		}
   3184 	      break;
   3185 
   3186 	    case 0x36:		/* CMN immed and MSR immed to SPSR */
   3187 	      if (DESTReg == 15)
   3188 		ARMul_FixSPSR (state, instr, DPImmRHS);
   3189 #ifdef MODE32
   3190 	      else if (state->is_v6
   3191 		       && handle_v6_insn (state, instr))
   3192 		break;
   3193 #endif
   3194 	      else
   3195 		UNDEF_Test;
   3196 	      break;
   3197 
   3198 	    case 0x37:		/* CMNP immed.  */
   3199 	      if (DESTReg == 15)
   3200 		{
   3201 		  /* CMNP immed.  */
   3202 #ifdef MODE32
   3203 		  state->Cpsr = GETSPSR (state->Bank);
   3204 		  ARMul_CPSRAltered (state);
   3205 #else
   3206 		  temp = LHS + DPImmRHS;
   3207 		  SETR15PSR (temp);
   3208 #endif
   3209 		  break;
   3210 		}
   3211 	      else
   3212 		{
   3213 		  /* CMN immed.  */
   3214 		  lhs = LHS;
   3215 		  rhs = DPImmRHS;
   3216 		  dest = lhs + rhs;
   3217 		  ASSIGNZ (dest == 0);
   3218 		  if ((lhs | rhs) >> 30)
   3219 		    {
   3220 		      /* Possible C,V,N to set.  */
   3221 		      ASSIGNN (NEG (dest));
   3222 		      ARMul_AddCarry (state, lhs, rhs, dest);
   3223 		      ARMul_AddOverflow (state, lhs, rhs, dest);
   3224 		    }
   3225 		  else
   3226 		    {
   3227 		      CLEARN;
   3228 		      CLEARC;
   3229 		      CLEARV;
   3230 		    }
   3231 		}
   3232 	      break;
   3233 
   3234 	    case 0x38:		/* ORR immed.  */
   3235 	      dest = LHS | DPImmRHS;
   3236 	      WRITEDEST (dest);
   3237 	      break;
   3238 
   3239 	    case 0x39:		/* ORRS immed.  */
   3240 	      DPSImmRHS;
   3241 	      dest = LHS | rhs;
   3242 	      WRITESDEST (dest);
   3243 	      break;
   3244 
   3245 	    case 0x3a:		/* MOV immed.  */
   3246 	      dest = DPImmRHS;
   3247 	      WRITEDEST (dest);
   3248 	      break;
   3249 
   3250 	    case 0x3b:		/* MOVS immed.  */
   3251 	      DPSImmRHS;
   3252 	      WRITESDEST (rhs);
   3253 	      break;
   3254 
   3255 	    case 0x3c:		/* BIC immed.  */
   3256 	      dest = LHS & ~DPImmRHS;
   3257 	      WRITEDEST (dest);
   3258 	      break;
   3259 
   3260 	    case 0x3d:		/* BICS immed.  */
   3261 	      DPSImmRHS;
   3262 	      dest = LHS & ~rhs;
   3263 	      WRITESDEST (dest);
   3264 	      break;
   3265 
   3266 	    case 0x3e:		/* MVN immed.  */
   3267 	      dest = ~DPImmRHS;
   3268 	      WRITEDEST (dest);
   3269 	      break;
   3270 
   3271 	    case 0x3f:		/* MVNS immed.  */
   3272 	      DPSImmRHS;
   3273 	      WRITESDEST (~rhs);
   3274 	      break;
   3275 
   3276 
   3277 	      /* Single Data Transfer Immediate RHS Instructions.  */
   3278 
   3279 	    case 0x40:		/* Store Word, No WriteBack, Post Dec, Immed.  */
   3280 	      lhs = LHS;
   3281 	      if (StoreWord (state, instr, lhs))
   3282 		LSBase = lhs - LSImmRHS;
   3283 	      break;
   3284 
   3285 	    case 0x41:		/* Load Word, No WriteBack, Post Dec, Immed.  */
   3286 	      lhs = LHS;
   3287 	      if (LoadWord (state, instr, lhs))
   3288 		LSBase = lhs - LSImmRHS;
   3289 	      break;
   3290 
   3291 	    case 0x42:		/* Store Word, WriteBack, Post Dec, Immed.  */
   3292 	      UNDEF_LSRBaseEQDestWb;
   3293 	      UNDEF_LSRPCBaseWb;
   3294 	      lhs = LHS;
   3295 	      temp = lhs - LSImmRHS;
   3296 	      state->NtransSig = LOW;
   3297 	      if (StoreWord (state, instr, lhs))
   3298 		LSBase = temp;
   3299 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3300 	      break;
   3301 
   3302 	    case 0x43:		/* Load Word, WriteBack, Post Dec, Immed.  */
   3303 	      UNDEF_LSRBaseEQDestWb;
   3304 	      UNDEF_LSRPCBaseWb;
   3305 	      lhs = LHS;
   3306 	      state->NtransSig = LOW;
   3307 	      if (LoadWord (state, instr, lhs))
   3308 		LSBase = lhs - LSImmRHS;
   3309 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3310 	      break;
   3311 
   3312 	    case 0x44:		/* Store Byte, No WriteBack, Post Dec, Immed.  */
   3313 	      lhs = LHS;
   3314 	      if (StoreByte (state, instr, lhs))
   3315 		LSBase = lhs - LSImmRHS;
   3316 	      break;
   3317 
   3318 	    case 0x45:		/* Load Byte, No WriteBack, Post Dec, Immed.  */
   3319 	      lhs = LHS;
   3320 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
   3321 		LSBase = lhs - LSImmRHS;
   3322 	      break;
   3323 
   3324 	    case 0x46:		/* Store Byte, WriteBack, Post Dec, Immed.  */
   3325 	      UNDEF_LSRBaseEQDestWb;
   3326 	      UNDEF_LSRPCBaseWb;
   3327 	      lhs = LHS;
   3328 	      state->NtransSig = LOW;
   3329 	      if (StoreByte (state, instr, lhs))
   3330 		LSBase = lhs - LSImmRHS;
   3331 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3332 	      break;
   3333 
   3334 	    case 0x47:		/* Load Byte, WriteBack, Post Dec, Immed.  */
   3335 	      UNDEF_LSRBaseEQDestWb;
   3336 	      UNDEF_LSRPCBaseWb;
   3337 	      lhs = LHS;
   3338 	      state->NtransSig = LOW;
   3339 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
   3340 		LSBase = lhs - LSImmRHS;
   3341 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3342 	      break;
   3343 
   3344 	    case 0x48:		/* Store Word, No WriteBack, Post Inc, Immed.  */
   3345 	      lhs = LHS;
   3346 	      if (StoreWord (state, instr, lhs))
   3347 		LSBase = lhs + LSImmRHS;
   3348 	      break;
   3349 
   3350 	    case 0x49:		/* Load Word, No WriteBack, Post Inc, Immed.  */
   3351 	      lhs = LHS;
   3352 	      if (LoadWord (state, instr, lhs))
   3353 		LSBase = lhs + LSImmRHS;
   3354 	      break;
   3355 
   3356 	    case 0x4a:		/* Store Word, WriteBack, Post Inc, Immed.  */
   3357 	      UNDEF_LSRBaseEQDestWb;
   3358 	      UNDEF_LSRPCBaseWb;
   3359 	      lhs = LHS;
   3360 	      state->NtransSig = LOW;
   3361 	      if (StoreWord (state, instr, lhs))
   3362 		LSBase = lhs + LSImmRHS;
   3363 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3364 	      break;
   3365 
   3366 	    case 0x4b:		/* Load Word, WriteBack, Post Inc, Immed.  */
   3367 	      UNDEF_LSRBaseEQDestWb;
   3368 	      UNDEF_LSRPCBaseWb;
   3369 	      lhs = LHS;
   3370 	      state->NtransSig = LOW;
   3371 	      if (LoadWord (state, instr, lhs))
   3372 		LSBase = lhs + LSImmRHS;
   3373 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3374 	      break;
   3375 
   3376 	    case 0x4c:		/* Store Byte, No WriteBack, Post Inc, Immed.  */
   3377 	      lhs = LHS;
   3378 	      if (StoreByte (state, instr, lhs))
   3379 		LSBase = lhs + LSImmRHS;
   3380 	      break;
   3381 
   3382 	    case 0x4d:		/* Load Byte, No WriteBack, Post Inc, Immed.  */
   3383 	      lhs = LHS;
   3384 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
   3385 		LSBase = lhs + LSImmRHS;
   3386 	      break;
   3387 
   3388 	    case 0x4e:		/* Store Byte, WriteBack, Post Inc, Immed.  */
   3389 	      UNDEF_LSRBaseEQDestWb;
   3390 	      UNDEF_LSRPCBaseWb;
   3391 	      lhs = LHS;
   3392 	      state->NtransSig = LOW;
   3393 	      if (StoreByte (state, instr, lhs))
   3394 		LSBase = lhs + LSImmRHS;
   3395 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3396 	      break;
   3397 
   3398 	    case 0x4f:		/* Load Byte, WriteBack, Post Inc, Immed.  */
   3399 	      UNDEF_LSRBaseEQDestWb;
   3400 	      UNDEF_LSRPCBaseWb;
   3401 	      lhs = LHS;
   3402 	      state->NtransSig = LOW;
   3403 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
   3404 		LSBase = lhs + LSImmRHS;
   3405 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3406 	      break;
   3407 
   3408 
   3409 	    case 0x50:		/* Store Word, No WriteBack, Pre Dec, Immed.  */
   3410 	      (void) StoreWord (state, instr, LHS - LSImmRHS);
   3411 	      break;
   3412 
   3413 	    case 0x51:		/* Load Word, No WriteBack, Pre Dec, Immed.  */
   3414 	      (void) LoadWord (state, instr, LHS - LSImmRHS);
   3415 	      break;
   3416 
   3417 	    case 0x52:		/* Store Word, WriteBack, Pre Dec, Immed.  */
   3418 	      UNDEF_LSRBaseEQDestWb;
   3419 	      UNDEF_LSRPCBaseWb;
   3420 	      temp = LHS - LSImmRHS;
   3421 	      if (StoreWord (state, instr, temp))
   3422 		LSBase = temp;
   3423 	      break;
   3424 
   3425 	    case 0x53:		/* Load Word, WriteBack, Pre Dec, Immed.  */
   3426 	      UNDEF_LSRBaseEQDestWb;
   3427 	      UNDEF_LSRPCBaseWb;
   3428 	      temp = LHS - LSImmRHS;
   3429 	      if (LoadWord (state, instr, temp))
   3430 		LSBase = temp;
   3431 	      break;
   3432 
   3433 	    case 0x54:		/* Store Byte, No WriteBack, Pre Dec, Immed.  */
   3434 	      (void) StoreByte (state, instr, LHS - LSImmRHS);
   3435 	      break;
   3436 
   3437 	    case 0x55:		/* Load Byte, No WriteBack, Pre Dec, Immed.  */
   3438 	      (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED);
   3439 	      break;
   3440 
   3441 	    case 0x56:		/* Store Byte, WriteBack, Pre Dec, Immed.  */
   3442 	      UNDEF_LSRBaseEQDestWb;
   3443 	      UNDEF_LSRPCBaseWb;
   3444 	      temp = LHS - LSImmRHS;
   3445 	      if (StoreByte (state, instr, temp))
   3446 		LSBase = temp;
   3447 	      break;
   3448 
   3449 	    case 0x57:		/* Load Byte, WriteBack, Pre Dec, Immed.  */
   3450 	      UNDEF_LSRBaseEQDestWb;
   3451 	      UNDEF_LSRPCBaseWb;
   3452 	      temp = LHS - LSImmRHS;
   3453 	      if (LoadByte (state, instr, temp, LUNSIGNED))
   3454 		LSBase = temp;
   3455 	      break;
   3456 
   3457 	    case 0x58:		/* Store Word, No WriteBack, Pre Inc, Immed.  */
   3458 	      (void) StoreWord (state, instr, LHS + LSImmRHS);
   3459 	      break;
   3460 
   3461 	    case 0x59:		/* Load Word, No WriteBack, Pre Inc, Immed.  */
   3462 	      (void) LoadWord (state, instr, LHS + LSImmRHS);
   3463 	      break;
   3464 
   3465 	    case 0x5a:		/* Store Word, WriteBack, Pre Inc, Immed.  */
   3466 	      UNDEF_LSRBaseEQDestWb;
   3467 	      UNDEF_LSRPCBaseWb;
   3468 	      temp = LHS + LSImmRHS;
   3469 	      if (StoreWord (state, instr, temp))
   3470 		LSBase = temp;
   3471 	      break;
   3472 
   3473 	    case 0x5b:		/* Load Word, WriteBack, Pre Inc, Immed.  */
   3474 	      UNDEF_LSRBaseEQDestWb;
   3475 	      UNDEF_LSRPCBaseWb;
   3476 	      temp = LHS + LSImmRHS;
   3477 	      if (LoadWord (state, instr, temp))
   3478 		LSBase = temp;
   3479 	      break;
   3480 
   3481 	    case 0x5c:		/* Store Byte, No WriteBack, Pre Inc, Immed.  */
   3482 	      (void) StoreByte (state, instr, LHS + LSImmRHS);
   3483 	      break;
   3484 
   3485 	    case 0x5d:		/* Load Byte, No WriteBack, Pre Inc, Immed.  */
   3486 	      (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED);
   3487 	      break;
   3488 
   3489 	    case 0x5e:		/* Store Byte, WriteBack, Pre Inc, Immed.  */
   3490 	      UNDEF_LSRBaseEQDestWb;
   3491 	      UNDEF_LSRPCBaseWb;
   3492 	      temp = LHS + LSImmRHS;
   3493 	      if (StoreByte (state, instr, temp))
   3494 		LSBase = temp;
   3495 	      break;
   3496 
   3497 	    case 0x5f:		/* Load Byte, WriteBack, Pre Inc, Immed.  */
   3498 	      UNDEF_LSRBaseEQDestWb;
   3499 	      UNDEF_LSRPCBaseWb;
   3500 	      temp = LHS + LSImmRHS;
   3501 	      if (LoadByte (state, instr, temp, LUNSIGNED))
   3502 		LSBase = temp;
   3503 	      break;
   3504 
   3505 
   3506 	      /* Single Data Transfer Register RHS Instructions.  */
   3507 
   3508 	    case 0x60:		/* Store Word, No WriteBack, Post Dec, Reg.  */
   3509 	      if (BIT (4))
   3510 		{
   3511 #ifdef MODE32
   3512 		  if (state->is_v6
   3513 		      && handle_v6_insn (state, instr))
   3514 		    break;
   3515 #endif
   3516 		  ARMul_UndefInstr (state, instr);
   3517 		  break;
   3518 		}
   3519 	      UNDEF_LSRBaseEQOffWb;
   3520 	      UNDEF_LSRBaseEQDestWb;
   3521 	      UNDEF_LSRPCBaseWb;
   3522 	      UNDEF_LSRPCOffWb;
   3523 	      lhs = LHS;
   3524 	      if (StoreWord (state, instr, lhs))
   3525 		LSBase = lhs - LSRegRHS;
   3526 	      break;
   3527 
   3528 	    case 0x61:		/* Load Word, No WriteBack, Post Dec, Reg.  */
   3529 	      if (BIT (4))
   3530 		{
   3531 #ifdef MODE32
   3532 		  if (state->is_v6
   3533 		      && handle_v6_insn (state, instr))
   3534 		    break;
   3535 #endif
   3536 		  ARMul_UndefInstr (state, instr);
   3537 		  break;
   3538 		}
   3539 	      UNDEF_LSRBaseEQOffWb;
   3540 	      UNDEF_LSRBaseEQDestWb;
   3541 	      UNDEF_LSRPCBaseWb;
   3542 	      UNDEF_LSRPCOffWb;
   3543 	      lhs = LHS;
   3544 	      temp = lhs - LSRegRHS;
   3545 	      if (LoadWord (state, instr, lhs))
   3546 		LSBase = temp;
   3547 	      break;
   3548 
   3549 	    case 0x62:		/* Store Word, WriteBack, Post Dec, Reg.  */
   3550 	      if (BIT (4))
   3551 		{
   3552 #ifdef MODE32
   3553 		  if (state->is_v6
   3554 		      && handle_v6_insn (state, instr))
   3555 		    break;
   3556 #endif
   3557 		  ARMul_UndefInstr (state, instr);
   3558 		  break;
   3559 		}
   3560 	      UNDEF_LSRBaseEQOffWb;
   3561 	      UNDEF_LSRBaseEQDestWb;
   3562 	      UNDEF_LSRPCBaseWb;
   3563 	      UNDEF_LSRPCOffWb;
   3564 	      lhs = LHS;
   3565 	      state->NtransSig = LOW;
   3566 	      if (StoreWord (state, instr, lhs))
   3567 		LSBase = lhs - LSRegRHS;
   3568 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3569 	      break;
   3570 
   3571 	    case 0x63:		/* Load Word, WriteBack, Post Dec, Reg.  */
   3572 	      if (BIT (4))
   3573 		{
   3574 #ifdef MODE32
   3575 		  if (state->is_v6
   3576 		      && handle_v6_insn (state, instr))
   3577 		    break;
   3578 #endif
   3579 		  ARMul_UndefInstr (state, instr);
   3580 		  break;
   3581 		}
   3582 	      UNDEF_LSRBaseEQOffWb;
   3583 	      UNDEF_LSRBaseEQDestWb;
   3584 	      UNDEF_LSRPCBaseWb;
   3585 	      UNDEF_LSRPCOffWb;
   3586 	      lhs = LHS;
   3587 	      temp = lhs - LSRegRHS;
   3588 	      state->NtransSig = LOW;
   3589 	      if (LoadWord (state, instr, lhs))
   3590 		LSBase = temp;
   3591 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3592 	      break;
   3593 
   3594 	    case 0x64:		/* Store Byte, No WriteBack, Post Dec, Reg.  */
   3595 	      if (BIT (4))
   3596 		{
   3597 #ifdef MODE32
   3598 		  if (state->is_v6
   3599 		      && handle_v6_insn (state, instr))
   3600 		    break;
   3601 #endif
   3602 		  ARMul_UndefInstr (state, instr);
   3603 		  break;
   3604 		}
   3605 	      UNDEF_LSRBaseEQOffWb;
   3606 	      UNDEF_LSRBaseEQDestWb;
   3607 	      UNDEF_LSRPCBaseWb;
   3608 	      UNDEF_LSRPCOffWb;
   3609 	      lhs = LHS;
   3610 	      if (StoreByte (state, instr, lhs))
   3611 		LSBase = lhs - LSRegRHS;
   3612 	      break;
   3613 
   3614 	    case 0x65:		/* Load Byte, No WriteBack, Post Dec, Reg.  */
   3615 	      if (BIT (4))
   3616 		{
   3617 #ifdef MODE32
   3618 		  if (state->is_v6
   3619 		      && handle_v6_insn (state, instr))
   3620 		    break;
   3621 #endif
   3622 		  ARMul_UndefInstr (state, instr);
   3623 		  break;
   3624 		}
   3625 	      UNDEF_LSRBaseEQOffWb;
   3626 	      UNDEF_LSRBaseEQDestWb;
   3627 	      UNDEF_LSRPCBaseWb;
   3628 	      UNDEF_LSRPCOffWb;
   3629 	      lhs = LHS;
   3630 	      temp = lhs - LSRegRHS;
   3631 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
   3632 		LSBase = temp;
   3633 	      break;
   3634 
   3635 	    case 0x66:		/* Store Byte, WriteBack, Post Dec, Reg.  */
   3636 	      if (BIT (4))
   3637 		{
   3638 #ifdef MODE32
   3639 		  if (state->is_v6
   3640 		      && handle_v6_insn (state, instr))
   3641 		    break;
   3642 #endif
   3643 		  ARMul_UndefInstr (state, instr);
   3644 		  break;
   3645 		}
   3646 	      UNDEF_LSRBaseEQOffWb;
   3647 	      UNDEF_LSRBaseEQDestWb;
   3648 	      UNDEF_LSRPCBaseWb;
   3649 	      UNDEF_LSRPCOffWb;
   3650 	      lhs = LHS;
   3651 	      state->NtransSig = LOW;
   3652 	      if (StoreByte (state, instr, lhs))
   3653 		LSBase = lhs - LSRegRHS;
   3654 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3655 	      break;
   3656 
   3657 	    case 0x67:		/* Load Byte, WriteBack, Post Dec, Reg.  */
   3658 	      if (BIT (4))
   3659 		{
   3660 #ifdef MODE32
   3661 		  if (state->is_v6
   3662 		      && handle_v6_insn (state, instr))
   3663 		    break;
   3664 #endif
   3665 		  ARMul_UndefInstr (state, instr);
   3666 		  break;
   3667 		}
   3668 	      UNDEF_LSRBaseEQOffWb;
   3669 	      UNDEF_LSRBaseEQDestWb;
   3670 	      UNDEF_LSRPCBaseWb;
   3671 	      UNDEF_LSRPCOffWb;
   3672 	      lhs = LHS;
   3673 	      temp = lhs - LSRegRHS;
   3674 	      state->NtransSig = LOW;
   3675 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
   3676 		LSBase = temp;
   3677 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3678 	      break;
   3679 
   3680 	    case 0x68:		/* Store Word, No WriteBack, Post Inc, Reg.  */
   3681 	      if (BIT (4))
   3682 		{
   3683 #ifdef MODE32
   3684 		  if (state->is_v6
   3685 		      && handle_v6_insn (state, instr))
   3686 		    break;
   3687 #endif
   3688 		  ARMul_UndefInstr (state, instr);
   3689 		  break;
   3690 		}
   3691 	      UNDEF_LSRBaseEQOffWb;
   3692 	      UNDEF_LSRBaseEQDestWb;
   3693 	      UNDEF_LSRPCBaseWb;
   3694 	      UNDEF_LSRPCOffWb;
   3695 	      lhs = LHS;
   3696 	      if (StoreWord (state, instr, lhs))
   3697 		LSBase = lhs + LSRegRHS;
   3698 	      break;
   3699 
   3700 	    case 0x69:		/* Load Word, No WriteBack, Post Inc, Reg.  */
   3701 	      if (BIT (4))
   3702 		{
   3703 #ifdef MODE32
   3704 		  if (state->is_v6
   3705 		      && handle_v6_insn (state, instr))
   3706 		    break;
   3707 #endif
   3708 		  ARMul_UndefInstr (state, instr);
   3709 		  break;
   3710 		}
   3711 	      UNDEF_LSRBaseEQOffWb;
   3712 	      UNDEF_LSRBaseEQDestWb;
   3713 	      UNDEF_LSRPCBaseWb;
   3714 	      UNDEF_LSRPCOffWb;
   3715 	      lhs = LHS;
   3716 	      temp = lhs + LSRegRHS;
   3717 	      if (LoadWord (state, instr, lhs))
   3718 		LSBase = temp;
   3719 	      break;
   3720 
   3721 	    case 0x6a:		/* Store Word, WriteBack, Post Inc, Reg.  */
   3722 	      if (BIT (4))
   3723 		{
   3724 #ifdef MODE32
   3725 		  if (state->is_v6
   3726 		      && handle_v6_insn (state, instr))
   3727 		    break;
   3728 #endif
   3729 		  ARMul_UndefInstr (state, instr);
   3730 		  break;
   3731 		}
   3732 	      UNDEF_LSRBaseEQOffWb;
   3733 	      UNDEF_LSRBaseEQDestWb;
   3734 	      UNDEF_LSRPCBaseWb;
   3735 	      UNDEF_LSRPCOffWb;
   3736 	      lhs = LHS;
   3737 	      state->NtransSig = LOW;
   3738 	      if (StoreWord (state, instr, lhs))
   3739 		LSBase = lhs + LSRegRHS;
   3740 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3741 	      break;
   3742 
   3743 	    case 0x6b:		/* Load Word, WriteBack, Post Inc, Reg.  */
   3744 	      if (BIT (4))
   3745 		{
   3746 #ifdef MODE32
   3747 		  if (state->is_v6
   3748 		      && handle_v6_insn (state, instr))
   3749 		    break;
   3750 #endif
   3751 		  ARMul_UndefInstr (state, instr);
   3752 		  break;
   3753 		}
   3754 	      UNDEF_LSRBaseEQOffWb;
   3755 	      UNDEF_LSRBaseEQDestWb;
   3756 	      UNDEF_LSRPCBaseWb;
   3757 	      UNDEF_LSRPCOffWb;
   3758 	      lhs = LHS;
   3759 	      temp = lhs + LSRegRHS;
   3760 	      state->NtransSig = LOW;
   3761 	      if (LoadWord (state, instr, lhs))
   3762 		LSBase = temp;
   3763 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3764 	      break;
   3765 
   3766 	    case 0x6c:		/* Store Byte, No WriteBack, Post Inc, Reg.  */
   3767 	      if (BIT (4))
   3768 		{
   3769 #ifdef MODE32
   3770 		  if (state->is_v6
   3771 		      && handle_v6_insn (state, instr))
   3772 		    break;
   3773 #endif
   3774 		  ARMul_UndefInstr (state, instr);
   3775 		  break;
   3776 		}
   3777 	      UNDEF_LSRBaseEQOffWb;
   3778 	      UNDEF_LSRBaseEQDestWb;
   3779 	      UNDEF_LSRPCBaseWb;
   3780 	      UNDEF_LSRPCOffWb;
   3781 	      lhs = LHS;
   3782 	      if (StoreByte (state, instr, lhs))
   3783 		LSBase = lhs + LSRegRHS;
   3784 	      break;
   3785 
   3786 	    case 0x6d:		/* Load Byte, No WriteBack, Post Inc, Reg.  */
   3787 	      if (BIT (4))
   3788 		{
   3789 #ifdef MODE32
   3790 		  if (state->is_v6
   3791 		      && handle_v6_insn (state, instr))
   3792 		    break;
   3793 #endif
   3794 		  ARMul_UndefInstr (state, instr);
   3795 		  break;
   3796 		}
   3797 	      UNDEF_LSRBaseEQOffWb;
   3798 	      UNDEF_LSRBaseEQDestWb;
   3799 	      UNDEF_LSRPCBaseWb;
   3800 	      UNDEF_LSRPCOffWb;
   3801 	      lhs = LHS;
   3802 	      temp = lhs + LSRegRHS;
   3803 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
   3804 		LSBase = temp;
   3805 	      break;
   3806 
   3807 	    case 0x6e:		/* Store Byte, WriteBack, Post Inc, Reg.  */
   3808 	      if (BIT (4))
   3809 		{
   3810 #ifdef MODE32
   3811 		  if (state->is_v6
   3812 		      && handle_v6_insn (state, instr))
   3813 		    break;
   3814 #endif
   3815 		  ARMul_UndefInstr (state, instr);
   3816 		  break;
   3817 		}
   3818 	      UNDEF_LSRBaseEQOffWb;
   3819 	      UNDEF_LSRBaseEQDestWb;
   3820 	      UNDEF_LSRPCBaseWb;
   3821 	      UNDEF_LSRPCOffWb;
   3822 	      lhs = LHS;
   3823 	      state->NtransSig = LOW;
   3824 	      if (StoreByte (state, instr, lhs))
   3825 		LSBase = lhs + LSRegRHS;
   3826 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3827 	      break;
   3828 
   3829 	    case 0x6f:		/* Load Byte, WriteBack, Post Inc, Reg.  */
   3830 	      if (BIT (4))
   3831 		{
   3832 #ifdef MODE32
   3833 		  if (state->is_v6
   3834 		      && handle_v6_insn (state, instr))
   3835 		    break;
   3836 #endif
   3837 		  ARMul_UndefInstr (state, instr);
   3838 		  break;
   3839 		}
   3840 	      UNDEF_LSRBaseEQOffWb;
   3841 	      UNDEF_LSRBaseEQDestWb;
   3842 	      UNDEF_LSRPCBaseWb;
   3843 	      UNDEF_LSRPCOffWb;
   3844 	      lhs = LHS;
   3845 	      temp = lhs + LSRegRHS;
   3846 	      state->NtransSig = LOW;
   3847 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
   3848 		LSBase = temp;
   3849 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
   3850 	      break;
   3851 
   3852 
   3853 	    case 0x70:		/* Store Word, No WriteBack, Pre Dec, Reg.  */
   3854 	      if (BIT (4))
   3855 		{
   3856 #ifdef MODE32
   3857 		  if (state->is_v6
   3858 		      && handle_v6_insn (state, instr))
   3859 		    break;
   3860 #endif
   3861 		  ARMul_UndefInstr (state, instr);
   3862 		  break;
   3863 		}
   3864 	      (void) StoreWord (state, instr, LHS - LSRegRHS);
   3865 	      break;
   3866 
   3867 	    case 0x71:		/* Load Word, No WriteBack, Pre Dec, Reg.  */
   3868 	      if (BIT (4))
   3869 		{
   3870 #ifdef MODE32
   3871 		  if (state->is_v6
   3872 		      && handle_v6_insn (state, instr))
   3873 		    break;
   3874 #endif
   3875 		  ARMul_UndefInstr (state, instr);
   3876 		  break;
   3877 		}
   3878 	      (void) LoadWord (state, instr, LHS - LSRegRHS);
   3879 	      break;
   3880 
   3881 	    case 0x72:		/* Store Word, WriteBack, Pre Dec, Reg.  */
   3882 	      if (BIT (4))
   3883 		{
   3884 #ifdef MODE32
   3885 		  if (state->is_v6
   3886 		      && handle_v6_insn (state, instr))
   3887 		    break;
   3888 #endif
   3889 		  ARMul_UndefInstr (state, instr);
   3890 		  break;
   3891 		}
   3892 	      UNDEF_LSRBaseEQOffWb;
   3893 	      UNDEF_LSRBaseEQDestWb;
   3894 	      UNDEF_LSRPCBaseWb;
   3895 	      UNDEF_LSRPCOffWb;
   3896 	      temp = LHS - LSRegRHS;
   3897 	      if (StoreWord (state, instr, temp))
   3898 		LSBase = temp;
   3899 	      break;
   3900 
   3901 	    case 0x73:		/* Load Word, WriteBack, Pre Dec, Reg.  */
   3902 	      if (BIT (4))
   3903 		{
   3904 #ifdef MODE32
   3905 		  if (state->is_v6
   3906 		      && handle_v6_insn (state, instr))
   3907 		    break;
   3908 #endif
   3909 		  ARMul_UndefInstr (state, instr);
   3910 		  break;
   3911 		}
   3912 	      UNDEF_LSRBaseEQOffWb;
   3913 	      UNDEF_LSRBaseEQDestWb;
   3914 	      UNDEF_LSRPCBaseWb;
   3915 	      UNDEF_LSRPCOffWb;
   3916 	      temp = LHS - LSRegRHS;
   3917 	      if (LoadWord (state, instr, temp))
   3918 		LSBase = temp;
   3919 	      break;
   3920 
   3921 	    case 0x74:		/* Store Byte, No WriteBack, Pre Dec, Reg.  */
   3922 	      if (BIT (4))
   3923 		{
   3924 #ifdef MODE32
   3925 		  if (state->is_v6
   3926 		      && handle_v6_insn (state, instr))
   3927 		    break;
   3928 #endif
   3929 		  ARMul_UndefInstr (state, instr);
   3930 		  break;
   3931 		}
   3932 	      (void) StoreByte (state, instr, LHS - LSRegRHS);
   3933 	      break;
   3934 
   3935 	    case 0x75:		/* Load Byte, No WriteBack, Pre Dec, Reg.  */
   3936 	      if (BIT (4))
   3937 		{
   3938 #ifdef MODE32
   3939 		  if (state->is_v6
   3940 		      && handle_v6_insn (state, instr))
   3941 		    break;
   3942 #endif
   3943 		  ARMul_UndefInstr (state, instr);
   3944 		  break;
   3945 		}
   3946 	      (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED);
   3947 	      break;
   3948 
   3949 	    case 0x76:		/* Store Byte, WriteBack, Pre Dec, Reg.  */
   3950 	      if (BIT (4))
   3951 		{
   3952 #ifdef MODE32
   3953 		  if (state->is_v6
   3954 		      && handle_v6_insn (state, instr))
   3955 		    break;
   3956 #endif
   3957 		  ARMul_UndefInstr (state, instr);
   3958 		  break;
   3959 		}
   3960 	      UNDEF_LSRBaseEQOffWb;
   3961 	      UNDEF_LSRBaseEQDestWb;
   3962 	      UNDEF_LSRPCBaseWb;
   3963 	      UNDEF_LSRPCOffWb;
   3964 	      temp = LHS - LSRegRHS;
   3965 	      if (StoreByte (state, instr, temp))
   3966 		LSBase = temp;
   3967 	      break;
   3968 
   3969 	    case 0x77:		/* Load Byte, WriteBack, Pre Dec, Reg.  */
   3970 	      if (BIT (4))
   3971 		{
   3972 #ifdef MODE32
   3973 		  if (state->is_v6
   3974 		      && handle_v6_insn (state, instr))
   3975 		    break;
   3976 #endif
   3977 		  ARMul_UndefInstr (state, instr);
   3978 		  break;
   3979 		}
   3980 	      UNDEF_LSRBaseEQOffWb;
   3981 	      UNDEF_LSRBaseEQDestWb;
   3982 	      UNDEF_LSRPCBaseWb;
   3983 	      UNDEF_LSRPCOffWb;
   3984 	      temp = LHS - LSRegRHS;
   3985 	      if (LoadByte (state, instr, temp, LUNSIGNED))
   3986 		LSBase = temp;
   3987 	      break;
   3988 
   3989 	    case 0x78:		/* Store Word, No WriteBack, Pre Inc, Reg.  */
   3990 	      if (BIT (4))
   3991 		{
   3992 #ifdef MODE32
   3993 		  if (state->is_v6
   3994 		      && handle_v6_insn (state, instr))
   3995 		    break;
   3996 #endif
   3997 		  ARMul_UndefInstr (state, instr);
   3998 		  break;
   3999 		}
   4000 	      (void) StoreWord (state, instr, LHS + LSRegRHS);
   4001 	      break;
   4002 
   4003 	    case 0x79:		/* Load Word, No WriteBack, Pre Inc, Reg.  */
   4004 	      if (BIT (4))
   4005 		{
   4006 #ifdef MODE32
   4007 		  if (state->is_v6
   4008 		      && handle_v6_insn (state, instr))
   4009 		    break;
   4010 #endif
   4011 		  ARMul_UndefInstr (state, instr);
   4012 		  break;
   4013 		}
   4014 	      (void) LoadWord (state, instr, LHS + LSRegRHS);
   4015 	      break;
   4016 
   4017 	    case 0x7a:		/* Store Word, WriteBack, Pre Inc, Reg.  */
   4018 	      if (BIT (4))
   4019 		{
   4020 #ifdef MODE32
   4021 		  if (state->is_v6
   4022 		      && handle_v6_insn (state, instr))
   4023 		    break;
   4024 #endif
   4025 		  ARMul_UndefInstr (state, instr);
   4026 		  break;
   4027 		}
   4028 	      UNDEF_LSRBaseEQOffWb;
   4029 	      UNDEF_LSRBaseEQDestWb;
   4030 	      UNDEF_LSRPCBaseWb;
   4031 	      UNDEF_LSRPCOffWb;
   4032 	      temp = LHS + LSRegRHS;
   4033 	      if (StoreWord (state, instr, temp))
   4034 		LSBase = temp;
   4035 	      break;
   4036 
   4037 	    case 0x7b:		/* Load Word, WriteBack, Pre Inc, Reg.  */
   4038 	      if (BIT (4))
   4039 		{
   4040 #ifdef MODE32
   4041 		  if (state->is_v6
   4042 		      && handle_v6_insn (state, instr))
   4043 		    break;
   4044 #endif
   4045 		  ARMul_UndefInstr (state, instr);
   4046 		  break;
   4047 		}
   4048 	      UNDEF_LSRBaseEQOffWb;
   4049 	      UNDEF_LSRBaseEQDestWb;
   4050 	      UNDEF_LSRPCBaseWb;
   4051 	      UNDEF_LSRPCOffWb;
   4052 	      temp = LHS + LSRegRHS;
   4053 	      if (LoadWord (state, instr, temp))
   4054 		LSBase = temp;
   4055 	      break;
   4056 
   4057 	    case 0x7c:		/* Store Byte, No WriteBack, Pre Inc, Reg.  */
   4058 	      if (BIT (4))
   4059 		{
   4060 #ifdef MODE32
   4061 		  if (state->is_v6
   4062 		      && handle_v6_insn (state, instr))
   4063 		    break;
   4064 #endif
   4065 		  ARMul_UndefInstr (state, instr);
   4066 		  break;
   4067 		}
   4068 	      (void) StoreByte (state, instr, LHS + LSRegRHS);
   4069 	      break;
   4070 
   4071 	    case 0x7d:		/* Load Byte, No WriteBack, Pre Inc, Reg.  */
   4072 	      if (BIT (4))
   4073 		{
   4074 #ifdef MODE32
   4075 		  if (state->is_v6
   4076 		      && handle_v6_insn (state, instr))
   4077 		    break;
   4078 #endif
   4079 		  ARMul_UndefInstr (state, instr);
   4080 		  break;
   4081 		}
   4082 	      (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED);
   4083 	      break;
   4084 
   4085 	    case 0x7e:		/* Store Byte, WriteBack, Pre Inc, Reg.  */
   4086 	      if (BIT (4))
   4087 		{
   4088 #ifdef MODE32
   4089 		  if (state->is_v6
   4090 		      && handle_v6_insn (state, instr))
   4091 		    break;
   4092 #endif
   4093 		  ARMul_UndefInstr (state, instr);
   4094 		  break;
   4095 		}
   4096 	      UNDEF_LSRBaseEQOffWb;
   4097 	      UNDEF_LSRBaseEQDestWb;
   4098 	      UNDEF_LSRPCBaseWb;
   4099 	      UNDEF_LSRPCOffWb;
   4100 	      temp = LHS + LSRegRHS;
   4101 	      if (StoreByte (state, instr, temp))
   4102 		LSBase = temp;
   4103 	      break;
   4104 
   4105 	    case 0x7f:		/* Load Byte, WriteBack, Pre Inc, Reg.  */
   4106 	      if (BIT (4))
   4107 		{
   4108 		  /* Check for the special breakpoint opcode.
   4109 		     This value should correspond to the value defined
   4110 		     as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h.  */
   4111 		  if (BITS (0, 19) == 0xfdefe)
   4112 		    {
   4113 		      if (!ARMul_OSHandleSWI (state, SWI_Breakpoint))
   4114 			ARMul_Abort (state, ARMul_SWIV);
   4115 		    }
   4116 #ifdef MODE32
   4117 		  else if (state->is_v6
   4118 			   && handle_v6_insn (state, instr))
   4119 		    break;
   4120 #endif
   4121 		  else
   4122 		    ARMul_UndefInstr (state, instr);
   4123 		  break;
   4124 		}
   4125 	      UNDEF_LSRBaseEQOffWb;
   4126 	      UNDEF_LSRBaseEQDestWb;
   4127 	      UNDEF_LSRPCBaseWb;
   4128 	      UNDEF_LSRPCOffWb;
   4129 	      temp = LHS + LSRegRHS;
   4130 	      if (LoadByte (state, instr, temp, LUNSIGNED))
   4131 		LSBase = temp;
   4132 	      break;
   4133 
   4134 
   4135 	      /* Multiple Data Transfer Instructions.  */
   4136 
   4137 	    case 0x80:		/* Store, No WriteBack, Post Dec.  */
   4138 	      STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
   4139 	      break;
   4140 
   4141 	    case 0x81:		/* Load, No WriteBack, Post Dec.  */
   4142 	      LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
   4143 	      break;
   4144 
   4145 	    case 0x82:		/* Store, WriteBack, Post Dec.  */
   4146 	      temp = LSBase - LSMNumRegs;
   4147 	      STOREMULT (instr, temp + 4L, temp);
   4148 	      break;
   4149 
   4150 	    case 0x83:		/* Load, WriteBack, Post Dec.  */
   4151 	      temp = LSBase - LSMNumRegs;
   4152 	      LOADMULT (instr, temp + 4L, temp);
   4153 	      break;
   4154 
   4155 	    case 0x84:		/* Store, Flags, No WriteBack, Post Dec.  */
   4156 	      STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
   4157 	      break;
   4158 
   4159 	    case 0x85:		/* Load, Flags, No WriteBack, Post Dec.  */
   4160 	      LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
   4161 	      break;
   4162 
   4163 	    case 0x86:		/* Store, Flags, WriteBack, Post Dec.  */
   4164 	      temp = LSBase - LSMNumRegs;
   4165 	      STORESMULT (instr, temp + 4L, temp);
   4166 	      break;
   4167 
   4168 	    case 0x87:		/* Load, Flags, WriteBack, Post Dec.  */
   4169 	      temp = LSBase - LSMNumRegs;
   4170 	      LOADSMULT (instr, temp + 4L, temp);
   4171 	      break;
   4172 
   4173 	    case 0x88:		/* Store, No WriteBack, Post Inc.  */
   4174 	      STOREMULT (instr, LSBase, 0L);
   4175 	      break;
   4176 
   4177 	    case 0x89:		/* Load, No WriteBack, Post Inc.  */
   4178 	      LOADMULT (instr, LSBase, 0L);
   4179 	      break;
   4180 
   4181 	    case 0x8a:		/* Store, WriteBack, Post Inc.  */
   4182 	      temp = LSBase;
   4183 	      STOREMULT (instr, temp, temp + LSMNumRegs);
   4184 	      break;
   4185 
   4186 	    case 0x8b:		/* Load, WriteBack, Post Inc.  */
   4187 	      temp = LSBase;
   4188 	      LOADMULT (instr, temp, temp + LSMNumRegs);
   4189 	      break;
   4190 
   4191 	    case 0x8c:		/* Store, Flags, No WriteBack, Post Inc.  */
   4192 	      STORESMULT (instr, LSBase, 0L);
   4193 	      break;
   4194 
   4195 	    case 0x8d:		/* Load, Flags, No WriteBack, Post Inc.  */
   4196 	      LOADSMULT (instr, LSBase, 0L);
   4197 	      break;
   4198 
   4199 	    case 0x8e:		/* Store, Flags, WriteBack, Post Inc.  */
   4200 	      temp = LSBase;
   4201 	      STORESMULT (instr, temp, temp + LSMNumRegs);
   4202 	      break;
   4203 
   4204 	    case 0x8f:		/* Load, Flags, WriteBack, Post Inc.  */
   4205 	      temp = LSBase;
   4206 	      LOADSMULT (instr, temp, temp + LSMNumRegs);
   4207 	      break;
   4208 
   4209 	    case 0x90:		/* Store, No WriteBack, Pre Dec.  */
   4210 	      STOREMULT (instr, LSBase - LSMNumRegs, 0L);
   4211 	      break;
   4212 
   4213 	    case 0x91:		/* Load, No WriteBack, Pre Dec.  */
   4214 	      LOADMULT (instr, LSBase - LSMNumRegs, 0L);
   4215 	      break;
   4216 
   4217 	    case 0x92:		/* Store, WriteBack, Pre Dec.  */
   4218 	      temp = LSBase - LSMNumRegs;
   4219 	      STOREMULT (instr, temp, temp);
   4220 	      break;
   4221 
   4222 	    case 0x93:		/* Load, WriteBack, Pre Dec.  */
   4223 	      temp = LSBase - LSMNumRegs;
   4224 	      LOADMULT (instr, temp, temp);
   4225 	      break;
   4226 
   4227 	    case 0x94:		/* Store, Flags, No WriteBack, Pre Dec.  */
   4228 	      STORESMULT (instr, LSBase - LSMNumRegs, 0L);
   4229 	      break;
   4230 
   4231 	    case 0x95:		/* Load, Flags, No WriteBack, Pre Dec.  */
   4232 	      LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
   4233 	      break;
   4234 
   4235 	    case 0x96:		/* Store, Flags, WriteBack, Pre Dec.  */
   4236 	      temp = LSBase - LSMNumRegs;
   4237 	      STORESMULT (instr, temp, temp);
   4238 	      break;
   4239 
   4240 	    case 0x97:		/* Load, Flags, WriteBack, Pre Dec.  */
   4241 	      temp = LSBase - LSMNumRegs;
   4242 	      LOADSMULT (instr, temp, temp);
   4243 	      break;
   4244 
   4245 	    case 0x98:		/* Store, No WriteBack, Pre Inc.  */
   4246 	      STOREMULT (instr, LSBase + 4L, 0L);
   4247 	      break;
   4248 
   4249 	    case 0x99:		/* Load, No WriteBack, Pre Inc.  */
   4250 	      LOADMULT (instr, LSBase + 4L, 0L);
   4251 	      break;
   4252 
   4253 	    case 0x9a:		/* Store, WriteBack, Pre Inc.  */
   4254 	      temp = LSBase;
   4255 	      STOREMULT (instr, temp + 4L, temp + LSMNumRegs);
   4256 	      break;
   4257 
   4258 	    case 0x9b:		/* Load, WriteBack, Pre Inc.  */
   4259 	      temp = LSBase;
   4260 	      LOADMULT (instr, temp + 4L, temp + LSMNumRegs);
   4261 	      break;
   4262 
   4263 	    case 0x9c:		/* Store, Flags, No WriteBack, Pre Inc.  */
   4264 	      STORESMULT (instr, LSBase + 4L, 0L);
   4265 	      break;
   4266 
   4267 	    case 0x9d:		/* Load, Flags, No WriteBack, Pre Inc.  */
   4268 	      LOADSMULT (instr, LSBase + 4L, 0L);
   4269 	      break;
   4270 
   4271 	    case 0x9e:		/* Store, Flags, WriteBack, Pre Inc.  */
   4272 	      temp = LSBase;
   4273 	      STORESMULT (instr, temp + 4L, temp + LSMNumRegs);
   4274 	      break;
   4275 
   4276 	    case 0x9f:		/* Load, Flags, WriteBack, Pre Inc.  */
   4277 	      temp = LSBase;
   4278 	      LOADSMULT (instr, temp + 4L, temp + LSMNumRegs);
   4279 	      break;
   4280 
   4281 
   4282 	      /* Branch forward.  */
   4283 	    case 0xa0:
   4284 	    case 0xa1:
   4285 	    case 0xa2:
   4286 	    case 0xa3:
   4287 	    case 0xa4:
   4288 	    case 0xa5:
   4289 	    case 0xa6:
   4290 	    case 0xa7:
   4291 	      state->Reg[15] = pc + 8 + POSBRANCH;
   4292 	      FLUSHPIPE;
   4293 	      break;
   4294 
   4295 
   4296 	      /* Branch backward.  */
   4297 	    case 0xa8:
   4298 	    case 0xa9:
   4299 	    case 0xaa:
   4300 	    case 0xab:
   4301 	    case 0xac:
   4302 	    case 0xad:
   4303 	    case 0xae:
   4304 	    case 0xaf:
   4305 	      state->Reg[15] = pc + 8 + NEGBRANCH;
   4306 	      FLUSHPIPE;
   4307 	      break;
   4308 
   4309 	      /* Branch and Link forward.  */
   4310 	    case 0xb0:
   4311 	    case 0xb1:
   4312 	    case 0xb2:
   4313 	    case 0xb3:
   4314 	    case 0xb4:
   4315 	    case 0xb5:
   4316 	    case 0xb6:
   4317 	    case 0xb7:
   4318 	      /* Put PC into Link.  */
   4319 #ifdef MODE32
   4320 	      state->Reg[14] = pc + 4;
   4321 #else
   4322 	      state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
   4323 #endif
   4324 	      state->Reg[15] = pc + 8 + POSBRANCH;
   4325 	      FLUSHPIPE;
   4326 	      if (trace_funcs)
   4327 		fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
   4328 	      break;
   4329 
   4330 	      /* Branch and Link backward.  */
   4331 	    case 0xb8:
   4332 	    case 0xb9:
   4333 	    case 0xba:
   4334 	    case 0xbb:
   4335 	    case 0xbc:
   4336 	    case 0xbd:
   4337 	    case 0xbe:
   4338 	    case 0xbf:
   4339 	      /* Put PC into Link.  */
   4340 #ifdef MODE32
   4341 	      state->Reg[14] = pc + 4;
   4342 #else
   4343 	      state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
   4344 #endif
   4345 	      state->Reg[15] = pc + 8 + NEGBRANCH;
   4346 	      FLUSHPIPE;
   4347 	      if (trace_funcs)
   4348 		fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
   4349 	      break;
   4350 
   4351 	      /* Co-Processor Data Transfers.  */
   4352 	    case 0xc4:
   4353 	      if (state->is_v5)
   4354 		{
   4355 		  if (CPNum == 10 || CPNum == 11)
   4356 		    handle_VFP_move (state, instr);
   4357 		  /* Reading from R15 is UNPREDICTABLE.  */
   4358 		  else if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
   4359 		    ARMul_UndefInstr (state, instr);
   4360 		  /* Is access to coprocessor 0 allowed ?  */
   4361 		  else if (! CP_ACCESS_ALLOWED (state, CPNum))
   4362 		    ARMul_UndefInstr (state, instr);
   4363 		  /* Special treatment for XScale coprocessors.  */
   4364 		  else if (state->is_XScale)
   4365 		    {
   4366 		      /* Only opcode 0 is supported.  */
   4367 		      if (BITS (4, 7) != 0x00)
   4368 			ARMul_UndefInstr (state, instr);
   4369 		      /* Only coporcessor 0 is supported.  */
   4370 		      else if (CPNum != 0x00)
   4371 			ARMul_UndefInstr (state, instr);
   4372 		      /* Only accumulator 0 is supported.  */
   4373 		      else if (BITS (0, 3) != 0x00)
   4374 			ARMul_UndefInstr (state, instr);
   4375 		      else
   4376 			{
   4377 			  /* XScale MAR insn.  Move two registers into accumulator.  */
   4378 			  state->Accumulator = state->Reg[BITS (12, 15)];
   4379 			  state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32;
   4380 			}
   4381 		    }
   4382 		  else
   4383 		    /* FIXME: Not sure what to do for other v5 processors.  */
   4384 		    ARMul_UndefInstr (state, instr);
   4385 		  break;
   4386 		}
   4387 	      ATTRIBUTE_FALLTHROUGH;
   4388 
   4389 	    case 0xc0:		/* Store , No WriteBack , Post Dec.  */
   4390 	      ARMul_STC (state, instr, LHS);
   4391 	      break;
   4392 
   4393 	    case 0xc5:
   4394 	      if (state->is_v5)
   4395 		{
   4396 		  if (CPNum == 10 || CPNum == 11)
   4397 		    handle_VFP_move (state, instr);
   4398 		  /* Writes to R15 are UNPREDICATABLE.  */
   4399 		  else if (DESTReg == 15 || LHSReg == 15)
   4400 		    ARMul_UndefInstr (state, instr);
   4401 		  /* Is access to the coprocessor allowed ?  */
   4402 		  else if (! CP_ACCESS_ALLOWED (state, CPNum))
   4403 		    ARMul_UndefInstr (state, instr);
   4404 		  /* Special handling for XScale coprcoessors.  */
   4405 		  else if (state->is_XScale)
   4406 		    {
   4407 		      /* Only opcode 0 is supported.  */
   4408 		      if (BITS (4, 7) != 0x00)
   4409 			ARMul_UndefInstr (state, instr);
   4410 		      /* Only coprocessor 0 is supported.  */
   4411 		      else if (CPNum != 0x00)
   4412 			ARMul_UndefInstr (state, instr);
   4413 		      /* Only accumulator 0 is supported.  */
   4414 		      else if (BITS (0, 3) != 0x00)
   4415 			ARMul_UndefInstr (state, instr);
   4416 		      else
   4417 			{
   4418 			  /* XScale MRA insn.  Move accumulator into two registers.  */
   4419 			  ARMword t1 = (state->Accumulator >> 32) & 255;
   4420 
   4421 			  if (t1 & 128)
   4422 			    t1 -= 256;
   4423 
   4424 			  state->Reg[BITS (12, 15)] = state->Accumulator;
   4425 			  state->Reg[BITS (16, 19)] = t1;
   4426 			  break;
   4427 			}
   4428 		    }
   4429 		  else
   4430 		    /* FIXME: Not sure what to do for other v5 processors.  */
   4431 		    ARMul_UndefInstr (state, instr);
   4432 		  break;
   4433 		}
   4434 	      ATTRIBUTE_FALLTHROUGH;
   4435 
   4436 	    case 0xc1:		/* Load , No WriteBack , Post Dec.  */
   4437 	      ARMul_LDC (state, instr, LHS);
   4438 	      break;
   4439 
   4440 	    case 0xc2:
   4441 	    case 0xc6:		/* Store , WriteBack , Post Dec.  */
   4442 	      lhs = LHS;
   4443 	      state->Base = lhs - LSCOff;
   4444 	      ARMul_STC (state, instr, lhs);
   4445 	      break;
   4446 
   4447 	    case 0xc3:
   4448 	    case 0xc7:		/* Load , WriteBack , Post Dec.  */
   4449 	      lhs = LHS;
   4450 	      state->Base = lhs - LSCOff;
   4451 	      ARMul_LDC (state, instr, lhs);
   4452 	      break;
   4453 
   4454 	    case 0xc8:
   4455 	    case 0xcc:		/* Store , No WriteBack , Post Inc.  */
   4456 	      ARMul_STC (state, instr, LHS);
   4457 	      break;
   4458 
   4459 	    case 0xc9:
   4460 	    case 0xcd:		/* Load , No WriteBack , Post Inc.  */
   4461 	      ARMul_LDC (state, instr, LHS);
   4462 	      break;
   4463 
   4464 	    case 0xca:
   4465 	    case 0xce:		/* Store , WriteBack , Post Inc.  */
   4466 	      lhs = LHS;
   4467 	      state->Base = lhs + LSCOff;
   4468 	      ARMul_STC (state, instr, LHS);
   4469 	      break;
   4470 
   4471 	    case 0xcb:
   4472 	    case 0xcf:		/* Load , WriteBack , Post Inc.  */
   4473 	      lhs = LHS;
   4474 	      state->Base = lhs + LSCOff;
   4475 	      ARMul_LDC (state, instr, LHS);
   4476 	      break;
   4477 
   4478 	    case 0xd0:
   4479 	    case 0xd4:		/* Store , No WriteBack , Pre Dec.  */
   4480 	      ARMul_STC (state, instr, LHS - LSCOff);
   4481 	      break;
   4482 
   4483 	    case 0xd1:
   4484 	    case 0xd5:		/* Load , No WriteBack , Pre Dec.  */
   4485 	      ARMul_LDC (state, instr, LHS - LSCOff);
   4486 	      break;
   4487 
   4488 	    case 0xd2:
   4489 	    case 0xd6:		/* Store , WriteBack , Pre Dec.  */
   4490 	      lhs = LHS - LSCOff;
   4491 	      state->Base = lhs;
   4492 	      ARMul_STC (state, instr, lhs);
   4493 	      break;
   4494 
   4495 	    case 0xd3:
   4496 	    case 0xd7:		/* Load , WriteBack , Pre Dec.  */
   4497 	      lhs = LHS - LSCOff;
   4498 	      state->Base = lhs;
   4499 	      ARMul_LDC (state, instr, lhs);
   4500 	      break;
   4501 
   4502 	    case 0xd8:
   4503 	    case 0xdc:		/* Store , No WriteBack , Pre Inc.  */
   4504 	      ARMul_STC (state, instr, LHS + LSCOff);
   4505 	      break;
   4506 
   4507 	    case 0xd9:
   4508 	    case 0xdd:		/* Load , No WriteBack , Pre Inc.  */
   4509 	      ARMul_LDC (state, instr, LHS + LSCOff);
   4510 	      break;
   4511 
   4512 	    case 0xda:
   4513 	    case 0xde:		/* Store , WriteBack , Pre Inc.  */
   4514 	      lhs = LHS + LSCOff;
   4515 	      state->Base = lhs;
   4516 	      ARMul_STC (state, instr, lhs);
   4517 	      break;
   4518 
   4519 	    case 0xdb:
   4520 	    case 0xdf:		/* Load , WriteBack , Pre Inc.  */
   4521 	      lhs = LHS + LSCOff;
   4522 	      state->Base = lhs;
   4523 	      ARMul_LDC (state, instr, lhs);
   4524 	      break;
   4525 
   4526 
   4527 	      /* Co-Processor Register Transfers (MCR) and Data Ops.  */
   4528 
   4529 	    case 0xe2:
   4530 	      if (! CP_ACCESS_ALLOWED (state, CPNum))
   4531 		{
   4532 		  ARMul_UndefInstr (state, instr);
   4533 		  break;
   4534 		}
   4535 	      if (state->is_XScale)
   4536 		switch (BITS (18, 19))
   4537 		  {
   4538 		  case 0x0:
   4539 		    if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
   4540 		      {
   4541 			/* XScale MIA instruction.  Signed multiplication of
   4542 			   two 32 bit values and addition to 40 bit accumulator.  */
   4543 			ARMsdword Rm = state->Reg[MULLHSReg];
   4544 			ARMsdword Rs = state->Reg[MULACCReg];
   4545 
   4546 			if (Rm & (1 << 31))
   4547 			  Rm -= 1ULL << 32;
   4548 			if (Rs & (1 << 31))
   4549 			  Rs -= 1ULL << 32;
   4550 			state->Accumulator += Rm * Rs;
   4551 			goto donext;
   4552 		      }
   4553 		    break;
   4554 
   4555 		  case 0x2:
   4556 		    if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
   4557 		      {
   4558 			/* XScale MIAPH instruction.  */
   4559 			ARMword t1 = state->Reg[MULLHSReg] >> 16;
   4560 			ARMword t2 = state->Reg[MULACCReg] >> 16;
   4561 			ARMword t3 = state->Reg[MULLHSReg] & 0xffff;
   4562 			ARMword t4 = state->Reg[MULACCReg] & 0xffff;
   4563 			ARMsdword t5;
   4564 
   4565 			if (t1 & (1 << 15))
   4566 			  t1 -= 1 << 16;
   4567 			if (t2 & (1 << 15))
   4568 			  t2 -= 1 << 16;
   4569 			if (t3 & (1 << 15))
   4570 			  t3 -= 1 << 16;
   4571 			if (t4 & (1 << 15))
   4572 			  t4 -= 1 << 16;
   4573 			t1 *= t2;
   4574 			t5 = t1;
   4575 			if (t5 & (1 << 31))
   4576 			  t5 -= 1ULL << 32;
   4577 			state->Accumulator += t5;
   4578 			t3 *= t4;
   4579 			t5 = t3;
   4580 			if (t5 & (1 << 31))
   4581 			  t5 -= 1ULL << 32;
   4582 			state->Accumulator += t5;
   4583 			goto donext;
   4584 		      }
   4585 		    break;
   4586 
   4587 		  case 0x3:
   4588 		    if (BITS (4, 11) == 1)
   4589 		      {
   4590 			/* XScale MIAxy instruction.  */
   4591 			ARMword t1;
   4592 			ARMword t2;
   4593 			ARMsdword t5;
   4594 
   4595 			if (BIT (17))
   4596 			  t1 = state->Reg[MULLHSReg] >> 16;
   4597 			else
   4598 			  t1 = state->Reg[MULLHSReg] & 0xffff;
   4599 
   4600 			if (BIT (16))
   4601 			  t2 = state->Reg[MULACCReg] >> 16;
   4602 			else
   4603 			  t2 = state->Reg[MULACCReg] & 0xffff;
   4604 
   4605 			if (t1 & (1 << 15))
   4606 			  t1 -= 1 << 16;
   4607 			if (t2 & (1 << 15))
   4608 			  t2 -= 1 << 16;
   4609 			t1 *= t2;
   4610 			t5 = t1;
   4611 			if (t5 & (1 << 31))
   4612 			  t5 -= 1ULL << 32;
   4613 			state->Accumulator += t5;
   4614 			goto donext;
   4615 		      }
   4616 		    break;
   4617 
   4618 		  default:
   4619 		    break;
   4620 		  }
   4621 	      ATTRIBUTE_FALLTHROUGH;
   4622 
   4623 	    case 0xe0:
   4624 	    case 0xe4:
   4625 	    case 0xe6:
   4626 	    case 0xe8:
   4627 	    case 0xea:
   4628 	    case 0xec:
   4629 	    case 0xee:
   4630 	      if (BIT (4))
   4631 		{
   4632 		  if (CPNum == 10 || CPNum == 11)
   4633 		    handle_VFP_move (state, instr);
   4634 		  /* MCR.  */
   4635 		  else if (DESTReg == 15)
   4636 		    {
   4637 		      UNDEF_MCRPC;
   4638 #ifdef MODE32
   4639 		      ARMul_MCR (state, instr, state->Reg[15] + isize);
   4640 #else
   4641 		      ARMul_MCR (state, instr, ECC | ER15INT | EMODE |
   4642 				 ((state->Reg[15] + isize) & R15PCBITS));
   4643 #endif
   4644 		    }
   4645 		  else
   4646 		    ARMul_MCR (state, instr, DEST);
   4647 		}
   4648 	      else
   4649 		/* CDP Part 1.  */
   4650 		ARMul_CDP (state, instr);
   4651 	      break;
   4652 
   4653 
   4654 	      /* Co-Processor Register Transfers (MRC) and Data Ops.  */
   4655 	    case 0xe1:
   4656 	    case 0xe3:
   4657 	    case 0xe5:
   4658 	    case 0xe7:
   4659 	    case 0xe9:
   4660 	    case 0xeb:
   4661 	    case 0xed:
   4662 	    case 0xef:
   4663 	      if (BIT (4))
   4664 		{
   4665 		  if (CPNum == 10 || CPNum == 11)
   4666 		    {
   4667 		      switch (BITS (20, 27))
   4668 			{
   4669 			case 0xEF:
   4670 			  if (BITS (16, 19) == 0x1
   4671 			      && BITS (0, 11) == 0xA10)
   4672 			    {
   4673 			      /* VMRS  */
   4674 			      if (DESTReg == 15)
   4675 				{
   4676 				  ARMul_SetCPSR (state, (state->FPSCR & 0xF0000000)
   4677 						 | (ARMul_GetCPSR (state) & 0x0FFFFFFF));
   4678 
   4679 				  if (trace)
   4680 				    fprintf (stderr, " VFP: VMRS: set flags to %c%c%c%c\n",
   4681 					     ARMul_GetCPSR (state) & NBIT ? 'N' : '-',
   4682 					     ARMul_GetCPSR (state) & ZBIT ? 'Z' : '-',
   4683 					     ARMul_GetCPSR (state) & CBIT ? 'C' : '-',
   4684 					     ARMul_GetCPSR (state) & VBIT ? 'V' : '-');
   4685 				}
   4686 			      else
   4687 				{
   4688 				  state->Reg[DESTReg] = state->FPSCR;
   4689 
   4690 				  if (trace)
   4691 				    fprintf (stderr, " VFP: VMRS: r%d = %x\n", DESTReg, state->Reg[DESTReg]);
   4692 				}
   4693 			    }
   4694 			  else
   4695 			    fprintf (stderr, "SIM: VFP: Unimplemented: Compare op\n");
   4696 			  break;
   4697 
   4698 			case 0xE0:
   4699 			case 0xE1:
   4700 			  /* VMOV reg <-> single precision.  */
   4701 			  if (BITS (0,6) != 0x10 || BITS (8,11) != 0xA)
   4702 			    fprintf (stderr, "SIM: VFP: Unimplemented: move op\n");
   4703 			  else if (BIT (20))
   4704 			    state->Reg[BITS (12, 15)] = VFP_uword (BITS (16, 19) << 1 | BIT (7));
   4705 			  else
   4706 			    VFP_uword (BITS (16, 19) << 1 | BIT (7)) = state->Reg[BITS (12, 15)];
   4707 			  break;
   4708 
   4709 			default:
   4710 			  fprintf (stderr, "SIM: VFP: Unimplemented: CDP op\n");
   4711 			  break;
   4712 			}
   4713 		    }
   4714 		  else
   4715 		    {
   4716 		      /* MRC */
   4717 		      temp = ARMul_MRC (state, instr);
   4718 		      if (DESTReg == 15)
   4719 			{
   4720 			  ASSIGNN ((temp & NBIT) != 0);
   4721 			  ASSIGNZ ((temp & ZBIT) != 0);
   4722 			  ASSIGNC ((temp & CBIT) != 0);
   4723 			  ASSIGNV ((temp & VBIT) != 0);
   4724 			}
   4725 		      else
   4726 			DEST = temp;
   4727 		    }
   4728 		}
   4729 	      else
   4730 		/* CDP Part 2.  */
   4731 		ARMul_CDP (state, instr);
   4732 	      break;
   4733 
   4734 
   4735 	      /* SWI instruction.  */
   4736 	    case 0xf0:
   4737 	    case 0xf1:
   4738 	    case 0xf2:
   4739 	    case 0xf3:
   4740 	    case 0xf4:
   4741 	    case 0xf5:
   4742 	    case 0xf6:
   4743 	    case 0xf7:
   4744 	    case 0xf8:
   4745 	    case 0xf9:
   4746 	    case 0xfa:
   4747 	    case 0xfb:
   4748 	    case 0xfc:
   4749 	    case 0xfd:
   4750 	    case 0xfe:
   4751 	    case 0xff:
   4752 	      if (instr == ARMul_ABORTWORD && state->AbortAddr == pc)
   4753 		{
   4754 		  /* A prefetch abort.  */
   4755 		  XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
   4756 		  ARMul_Abort (state, ARMul_PrefetchAbortV);
   4757 		  break;
   4758 		}
   4759 
   4760 	      if (!ARMul_OSHandleSWI (state, BITS (0, 23)))
   4761 		ARMul_Abort (state, ARMul_SWIV);
   4762 
   4763 	      break;
   4764 	    }
   4765 	}
   4766 
   4767 #ifdef MODET
   4768     donext:
   4769 #endif
   4770 
   4771       if (state->Emulate == ONCE)
   4772 	state->Emulate = STOP;
   4773       /* If we have changed mode, allow the PC to advance before stopping.  */
   4774       else if (state->Emulate == CHANGEMODE)
   4775 	continue;
   4776       else if (state->Emulate != RUN)
   4777 	break;
   4778     }
   4779   while (!stop_simulator);
   4780 
   4781   state->decoded = decoded;
   4782   state->loaded = loaded;
   4783   state->pc = pc;
   4784 
   4785   return pc;
   4786 }
   4787 
   4788 /* This routine evaluates most Data Processing register RHS's with the S
   4789    bit clear.  It is intended to be called from the macro DPRegRHS, which
   4790    filters the common case of an unshifted register with in line code.  */
   4791 
   4792 static ARMword
   4793 GetDPRegRHS (ARMul_State * state, ARMword instr)
   4794 {
   4795   ARMword shamt, base;
   4796 
   4797   base = RHSReg;
   4798   if (BIT (4))
   4799     {
   4800       /* Shift amount in a register.  */
   4801       UNDEF_Shift;
   4802       INCPC;
   4803 #ifndef MODE32
   4804       if (base == 15)
   4805 	base = ECC | ER15INT | R15PC | EMODE;
   4806       else
   4807 #endif
   4808 	base = state->Reg[base];
   4809       ARMul_Icycles (state, 1, 0L);
   4810       shamt = state->Reg[BITS (8, 11)] & 0xff;
   4811       switch ((int) BITS (5, 6))
   4812 	{
   4813 	case LSL:
   4814 	  if (shamt == 0)
   4815 	    return (base);
   4816 	  else if (shamt >= 32)
   4817 	    return (0);
   4818 	  else
   4819 	    return (base << shamt);
   4820 	case LSR:
   4821 	  if (shamt == 0)
   4822 	    return (base);
   4823 	  else if (shamt >= 32)
   4824 	    return (0);
   4825 	  else
   4826 	    return (base >> shamt);
   4827 	case ASR:
   4828 	  if (shamt == 0)
   4829 	    return (base);
   4830 	  else if (shamt >= 32)
   4831 	    return ((ARMword) ((ARMsword) base >> 31L));
   4832 	  else
   4833 	    return ((ARMword) ((ARMsword) base >> (int) shamt));
   4834 	case ROR:
   4835 	  shamt &= 0x1f;
   4836 	  if (shamt == 0)
   4837 	    return (base);
   4838 	  else
   4839 	    return ((base << (32 - shamt)) | (base >> shamt));
   4840 	}
   4841     }
   4842   else
   4843     {
   4844       /* Shift amount is a constant.  */
   4845 #ifndef MODE32
   4846       if (base == 15)
   4847 	base = ECC | ER15INT | R15PC | EMODE;
   4848       else
   4849 #endif
   4850 	base = state->Reg[base];
   4851       shamt = BITS (7, 11);
   4852       switch ((int) BITS (5, 6))
   4853 	{
   4854 	case LSL:
   4855 	  return (base << shamt);
   4856 	case LSR:
   4857 	  if (shamt == 0)
   4858 	    return (0);
   4859 	  else
   4860 	    return (base >> shamt);
   4861 	case ASR:
   4862 	  if (shamt == 0)
   4863 	    return ((ARMword) ((ARMsword) base >> 31L));
   4864 	  else
   4865 	    return ((ARMword) ((ARMsword) base >> (int) shamt));
   4866 	case ROR:
   4867 	  if (shamt == 0)
   4868 	    /* It's an RRX.  */
   4869 	    return ((base >> 1) | (CFLAG << 31));
   4870 	  else
   4871 	    return ((base << (32 - shamt)) | (base >> shamt));
   4872 	}
   4873     }
   4874 
   4875   return 0;
   4876 }
   4877 
   4878 /* This routine evaluates most Logical Data Processing register RHS's
   4879    with the S bit set.  It is intended to be called from the macro
   4880    DPSRegRHS, which filters the common case of an unshifted register
   4881    with in line code.  */
   4882 
   4883 static ARMword
   4884 GetDPSRegRHS (ARMul_State * state, ARMword instr)
   4885 {
   4886   ARMword shamt, base;
   4887 
   4888   base = RHSReg;
   4889   if (BIT (4))
   4890     {
   4891       /* Shift amount in a register.  */
   4892       UNDEF_Shift;
   4893       INCPC;
   4894 #ifndef MODE32
   4895       if (base == 15)
   4896 	base = ECC | ER15INT | R15PC | EMODE;
   4897       else
   4898 #endif
   4899 	base = state->Reg[base];
   4900       ARMul_Icycles (state, 1, 0L);
   4901       shamt = state->Reg[BITS (8, 11)] & 0xff;
   4902       switch ((int) BITS (5, 6))
   4903 	{
   4904 	case LSL:
   4905 	  if (shamt == 0)
   4906 	    return (base);
   4907 	  else if (shamt == 32)
   4908 	    {
   4909 	      ASSIGNC (base & 1);
   4910 	      return (0);
   4911 	    }
   4912 	  else if (shamt > 32)
   4913 	    {
   4914 	      CLEARC;
   4915 	      return (0);
   4916 	    }
   4917 	  else
   4918 	    {
   4919 	      ASSIGNC ((base >> (32 - shamt)) & 1);
   4920 	      return (base << shamt);
   4921 	    }
   4922 	case LSR:
   4923 	  if (shamt == 0)
   4924 	    return (base);
   4925 	  else if (shamt == 32)
   4926 	    {
   4927 	      ASSIGNC (base >> 31);
   4928 	      return (0);
   4929 	    }
   4930 	  else if (shamt > 32)
   4931 	    {
   4932 	      CLEARC;
   4933 	      return (0);
   4934 	    }
   4935 	  else
   4936 	    {
   4937 	      ASSIGNC ((base >> (shamt - 1)) & 1);
   4938 	      return (base >> shamt);
   4939 	    }
   4940 	case ASR:
   4941 	  if (shamt == 0)
   4942 	    return (base);
   4943 	  else if (shamt >= 32)
   4944 	    {
   4945 	      ASSIGNC (base >> 31L);
   4946 	      return ((ARMword) ((ARMsword) base >> 31L));
   4947 	    }
   4948 	  else
   4949 	    {
   4950 	      ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1);
   4951 	      return ((ARMword) ((ARMsword) base >> (int) shamt));
   4952 	    }
   4953 	case ROR:
   4954 	  if (shamt == 0)
   4955 	    return (base);
   4956 	  shamt &= 0x1f;
   4957 	  if (shamt == 0)
   4958 	    {
   4959 	      ASSIGNC (base >> 31);
   4960 	      return (base);
   4961 	    }
   4962 	  else
   4963 	    {
   4964 	      ASSIGNC ((base >> (shamt - 1)) & 1);
   4965 	      return ((base << (32 - shamt)) | (base >> shamt));
   4966 	    }
   4967 	}
   4968     }
   4969   else
   4970     {
   4971       /* Shift amount is a constant.  */
   4972 #ifndef MODE32
   4973       if (base == 15)
   4974 	base = ECC | ER15INT | R15PC | EMODE;
   4975       else
   4976 #endif
   4977 	base = state->Reg[base];
   4978       shamt = BITS (7, 11);
   4979 
   4980       switch ((int) BITS (5, 6))
   4981 	{
   4982 	case LSL:
   4983 	  ASSIGNC ((base >> (32 - shamt)) & 1);
   4984 	  return (base << shamt);
   4985 	case LSR:
   4986 	  if (shamt == 0)
   4987 	    {
   4988 	      ASSIGNC (base >> 31);
   4989 	      return (0);
   4990 	    }
   4991 	  else
   4992 	    {
   4993 	      ASSIGNC ((base >> (shamt - 1)) & 1);
   4994 	      return (base >> shamt);
   4995 	    }
   4996 	case ASR:
   4997 	  if (shamt == 0)
   4998 	    {
   4999 	      ASSIGNC (base >> 31L);
   5000 	      return ((ARMword) ((ARMsword) base >> 31L));
   5001 	    }
   5002 	  else
   5003 	    {
   5004 	      ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1);
   5005 	      return ((ARMword) ((ARMsword) base >> (int) shamt));
   5006 	    }
   5007 	case ROR:
   5008 	  if (shamt == 0)
   5009 	    {
   5010 	      /* It's an RRX.  */
   5011 	      shamt = CFLAG;
   5012 	      ASSIGNC (base & 1);
   5013 	      return ((base >> 1) | (shamt << 31));
   5014 	    }
   5015 	  else
   5016 	    {
   5017 	      ASSIGNC ((base >> (shamt - 1)) & 1);
   5018 	      return ((base << (32 - shamt)) | (base >> shamt));
   5019 	    }
   5020 	}
   5021     }
   5022 
   5023   return 0;
   5024 }
   5025 
   5026 /* This routine handles writes to register 15 when the S bit is not set.  */
   5027 
   5028 static void
   5029 WriteR15 (ARMul_State * state, ARMword src)
   5030 {
   5031   /* The ARM documentation states that the two least significant bits
   5032      are discarded when setting PC, except in the cases handled by
   5033      WriteR15Branch() below.  It's probably an oversight: in THUMB
   5034      mode, the second least significant bit should probably not be
   5035      discarded.  */
   5036 #ifdef MODET
   5037   if (TFLAG)
   5038     src &= 0xfffffffe;
   5039   else
   5040 #endif
   5041     src &= 0xfffffffc;
   5042 
   5043 #ifdef MODE32
   5044   state->Reg[15] = src & PCBITS;
   5045 #else
   5046   state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
   5047   ARMul_R15Altered (state);
   5048 #endif
   5049 
   5050   FLUSHPIPE;
   5051   if (trace_funcs)
   5052     fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
   5053 }
   5054 
   5055 /* This routine handles writes to register 15 when the S bit is set.  */
   5056 
   5057 static void
   5058 WriteSR15 (ARMul_State * state, ARMword src)
   5059 {
   5060 #ifdef MODE32
   5061   if (state->Bank > 0)
   5062     {
   5063       state->Cpsr = state->Spsr[state->Bank];
   5064       ARMul_CPSRAltered (state);
   5065     }
   5066 #ifdef MODET
   5067   if (TFLAG)
   5068     src &= 0xfffffffe;
   5069   else
   5070 #endif
   5071     src &= 0xfffffffc;
   5072   state->Reg[15] = src & PCBITS;
   5073 #else
   5074 #ifdef MODET
   5075   if (TFLAG)
   5076     /* ARMul_R15Altered would have to support it.  */
   5077     abort ();
   5078   else
   5079 #endif
   5080     src &= 0xfffffffc;
   5081 
   5082   if (state->Bank == USERBANK)
   5083     state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
   5084   else
   5085     state->Reg[15] = src;
   5086 
   5087   ARMul_R15Altered (state);
   5088 #endif
   5089   FLUSHPIPE;
   5090   if (trace_funcs)
   5091     fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
   5092 }
   5093 
   5094 /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
   5095    will switch to Thumb mode if the least significant bit is set.  */
   5096 
   5097 static void
   5098 WriteR15Branch (ARMul_State * state, ARMword src)
   5099 {
   5100 #ifdef MODET
   5101   if (src & 1)
   5102     {
   5103       /* Thumb bit.  */
   5104       SETT;
   5105       state->Reg[15] = src & 0xfffffffe;
   5106     }
   5107   else
   5108     {
   5109       CLEART;
   5110       state->Reg[15] = src & 0xfffffffc;
   5111     }
   5112   FLUSHPIPE;
   5113   if (trace_funcs)
   5114     fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
   5115 #else
   5116   WriteR15 (state, src);
   5117 #endif
   5118 }
   5119 
   5120 /* Before ARM_v5 LDR and LDM of pc did not change mode.  */
   5121 
   5122 static void
   5123 WriteR15Load (ARMul_State * state, ARMword src)
   5124 {
   5125   if (state->is_v5)
   5126     WriteR15Branch (state, src);
   5127   else
   5128     WriteR15 (state, src);
   5129 }
   5130 
   5131 /* This routine evaluates most Load and Store register RHS's.  It is
   5132    intended to be called from the macro LSRegRHS, which filters the
   5133    common case of an unshifted register with in line code.  */
   5134 
   5135 static ARMword
   5136 GetLSRegRHS (ARMul_State * state, ARMword instr)
   5137 {
   5138   ARMword shamt, base;
   5139 
   5140   base = RHSReg;
   5141 #ifndef MODE32
   5142   if (base == 15)
   5143     /* Now forbidden, but ...  */
   5144     base = ECC | ER15INT | R15PC | EMODE;
   5145   else
   5146 #endif
   5147     base = state->Reg[base];
   5148 
   5149   shamt = BITS (7, 11);
   5150   switch ((int) BITS (5, 6))
   5151     {
   5152     case LSL:
   5153       return (base << shamt);
   5154     case LSR:
   5155       if (shamt == 0)
   5156 	return (0);
   5157       else
   5158 	return (base >> shamt);
   5159     case ASR:
   5160       if (shamt == 0)
   5161 	return ((ARMword) ((ARMsword) base >> 31L));
   5162       else
   5163 	return ((ARMword) ((ARMsword) base >> (int) shamt));
   5164     case ROR:
   5165       if (shamt == 0)
   5166 	/* It's an RRX.  */
   5167 	return ((base >> 1) | (CFLAG << 31));
   5168       else
   5169 	return ((base << (32 - shamt)) | (base >> shamt));
   5170     default:
   5171       break;
   5172     }
   5173   return 0;
   5174 }
   5175 
   5176 /* This routine evaluates the ARM7T halfword and signed transfer RHS's.  */
   5177 
   5178 static ARMword
   5179 GetLS7RHS (ARMul_State * state, ARMword instr)
   5180 {
   5181   if (BIT (22) == 0)
   5182     {
   5183       /* Register.  */
   5184 #ifndef MODE32
   5185       if (RHSReg == 15)
   5186 	/* Now forbidden, but ...  */
   5187 	return ECC | ER15INT | R15PC | EMODE;
   5188 #endif
   5189       return state->Reg[RHSReg];
   5190     }
   5191 
   5192   /* Immediate.  */
   5193   return BITS (0, 3) | (BITS (8, 11) << 4);
   5194 }
   5195 
   5196 /* This function does the work of loading a word for a LDR instruction.  */
   5197 
   5198 static unsigned
   5199 LoadWord (ARMul_State * state, ARMword instr, ARMword address)
   5200 {
   5201   ARMword dest;
   5202 
   5203   BUSUSEDINCPCS;
   5204 #ifndef MODE32
   5205   if (ADDREXCEPT (address))
   5206     INTERNALABORT (address);
   5207 #endif
   5208 
   5209   dest = ARMul_LoadWordN (state, address);
   5210 
   5211   if (state->Aborted)
   5212     {
   5213       TAKEABORT;
   5214       return state->lateabtSig;
   5215     }
   5216   if (address & 3)
   5217     dest = ARMul_Align (state, address, dest);
   5218   WRITEDESTB (dest);
   5219   ARMul_Icycles (state, 1, 0L);
   5220 
   5221   return (DESTReg != LHSReg);
   5222 }
   5223 
   5224 #ifdef MODET
   5225 /* This function does the work of loading a halfword.  */
   5226 
   5227 static unsigned
   5228 LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
   5229 	      int signextend)
   5230 {
   5231   ARMword dest;
   5232 
   5233   BUSUSEDINCPCS;
   5234 #ifndef MODE32
   5235   if (ADDREXCEPT (address))
   5236     INTERNALABORT (address);
   5237 #endif
   5238   dest = ARMul_LoadHalfWord (state, address);
   5239   if (state->Aborted)
   5240     {
   5241       TAKEABORT;
   5242       return state->lateabtSig;
   5243     }
   5244   UNDEF_LSRBPC;
   5245   if (signextend)
   5246     if (dest & 1 << (16 - 1))
   5247       dest = (dest & ((1 << 16) - 1)) - (1 << 16);
   5248 
   5249   WRITEDEST (dest);
   5250   ARMul_Icycles (state, 1, 0L);
   5251   return (DESTReg != LHSReg);
   5252 }
   5253 
   5254 #endif /* MODET */
   5255 
   5256 /* This function does the work of loading a byte for a LDRB instruction.  */
   5257 
   5258 static unsigned
   5259 LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend)
   5260 {
   5261   ARMword dest;
   5262 
   5263   BUSUSEDINCPCS;
   5264 #ifndef MODE32
   5265   if (ADDREXCEPT (address))
   5266     INTERNALABORT (address);
   5267 #endif
   5268   dest = ARMul_LoadByte (state, address);
   5269   if (state->Aborted)
   5270     {
   5271       TAKEABORT;
   5272       return state->lateabtSig;
   5273     }
   5274   UNDEF_LSRBPC;
   5275   if (signextend)
   5276     if (dest & 1 << (8 - 1))
   5277       dest = (dest & ((1 << 8) - 1)) - (1 << 8);
   5278 
   5279   WRITEDEST (dest);
   5280   ARMul_Icycles (state, 1, 0L);
   5281 
   5282   return (DESTReg != LHSReg);
   5283 }
   5284 
   5285 /* This function does the work of loading two words for a LDRD instruction.  */
   5286 
   5287 static void
   5288 Handle_Load_Double (ARMul_State * state, ARMword instr)
   5289 {
   5290   ARMword dest_reg;
   5291   ARMword addr_reg;
   5292   ARMword write_back  = BIT (21);
   5293   ARMword immediate   = BIT (22);
   5294   ARMword add_to_base = BIT (23);
   5295   ARMword pre_indexed = BIT (24);
   5296   ARMword offset;
   5297   ARMword addr;
   5298   ARMword sum;
   5299   ARMword base;
   5300   ARMword value1;
   5301   ARMword value2;
   5302 
   5303   BUSUSEDINCPCS;
   5304 
   5305   /* If the writeback bit is set, the pre-index bit must be clear.  */
   5306   if (write_back && ! pre_indexed)
   5307     {
   5308       ARMul_UndefInstr (state, instr);
   5309       return;
   5310     }
   5311 
   5312   /* Extract the base address register.  */
   5313   addr_reg = LHSReg;
   5314 
   5315   /* Extract the destination register and check it.  */
   5316   dest_reg = DESTReg;
   5317 
   5318   /* Destination register must be even.  */
   5319   if ((dest_reg & 1)
   5320     /* Destination register cannot be LR.  */
   5321       || (dest_reg == 14))
   5322     {
   5323       ARMul_UndefInstr (state, instr);
   5324       return;
   5325     }
   5326 
   5327   /* Compute the base address.  */
   5328   base = state->Reg[addr_reg];
   5329 
   5330   /* Compute the offset.  */
   5331   offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
   5332 
   5333   /* Compute the sum of the two.  */
   5334   if (add_to_base)
   5335     sum = base + offset;
   5336   else
   5337     sum = base - offset;
   5338 
   5339   /* If this is a pre-indexed mode use the sum.  */
   5340   if (pre_indexed)
   5341     addr = sum;
   5342   else
   5343     addr = base;
   5344 
   5345   if (state->is_v6 && (addr & 0x3) == 0)
   5346     /* Word alignment is enough for v6.  */
   5347     ;
   5348   /* The address must be aligned on a 8 byte boundary.  */
   5349   else if (addr & 0x7)
   5350     {
   5351 #ifdef ABORTS
   5352       ARMul_DATAABORT (addr);
   5353 #else
   5354       ARMul_UndefInstr (state, instr);
   5355 #endif
   5356       return;
   5357     }
   5358 
   5359   /* For pre indexed or post indexed addressing modes,
   5360      check that the destination registers do not overlap
   5361      the address registers.  */
   5362   if ((! pre_indexed || write_back)
   5363       && (   addr_reg == dest_reg
   5364 	  || addr_reg == dest_reg + 1))
   5365     {
   5366       ARMul_UndefInstr (state, instr);
   5367       return;
   5368     }
   5369 
   5370   /* Load the words.  */
   5371   value1 = ARMul_LoadWordN (state, addr);
   5372   value2 = ARMul_LoadWordN (state, addr + 4);
   5373 
   5374   /* Check for data aborts.  */
   5375   if (state->Aborted)
   5376     {
   5377       TAKEABORT;
   5378       return;
   5379     }
   5380 
   5381   ARMul_Icycles (state, 2, 0L);
   5382 
   5383   /* Store the values.  */
   5384   state->Reg[dest_reg] = value1;
   5385   state->Reg[dest_reg + 1] = value2;
   5386 
   5387   /* Do the post addressing and writeback.  */
   5388   if (! pre_indexed)
   5389     addr = sum;
   5390 
   5391   if (! pre_indexed || write_back)
   5392     state->Reg[addr_reg] = addr;
   5393 }
   5394 
   5395 /* This function does the work of storing two words for a STRD instruction.  */
   5396 
   5397 static void
   5398 Handle_Store_Double (ARMul_State * state, ARMword instr)
   5399 {
   5400   ARMword src_reg;
   5401   ARMword addr_reg;
   5402   ARMword write_back  = BIT (21);
   5403   ARMword immediate   = BIT (22);
   5404   ARMword add_to_base = BIT (23);
   5405   ARMword pre_indexed = BIT (24);
   5406   ARMword offset;
   5407   ARMword addr;
   5408   ARMword sum;
   5409   ARMword base;
   5410 
   5411   BUSUSEDINCPCS;
   5412 
   5413   /* If the writeback bit is set, the pre-index bit must be clear.  */
   5414   if (write_back && ! pre_indexed)
   5415     {
   5416       ARMul_UndefInstr (state, instr);
   5417       return;
   5418     }
   5419 
   5420   /* Extract the base address register.  */
   5421   addr_reg = LHSReg;
   5422 
   5423   /* Base register cannot be PC.  */
   5424   if (addr_reg == 15)
   5425     {
   5426       ARMul_UndefInstr (state, instr);
   5427       return;
   5428     }
   5429 
   5430   /* Extract the source register.  */
   5431   src_reg = DESTReg;
   5432 
   5433   /* Source register must be even.  */
   5434   if (src_reg & 1)
   5435     {
   5436       ARMul_UndefInstr (state, instr);
   5437       return;
   5438     }
   5439 
   5440   /* Compute the base address.  */
   5441   base = state->Reg[addr_reg];
   5442 
   5443   /* Compute the offset.  */
   5444   offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
   5445 
   5446   /* Compute the sum of the two.  */
   5447   if (add_to_base)
   5448     sum = base + offset;
   5449   else
   5450     sum = base - offset;
   5451 
   5452   /* If this is a pre-indexed mode use the sum.  */
   5453   if (pre_indexed)
   5454     addr = sum;
   5455   else
   5456     addr = base;
   5457 
   5458   /* The address must be aligned on a 8 byte boundary.  */
   5459   if (state->is_v6 && (addr & 0x3) == 0)
   5460     /* Word alignment is enough for v6.  */
   5461     ;
   5462   else if (addr & 0x7)
   5463     {
   5464 #ifdef ABORTS
   5465       ARMul_DATAABORT (addr);
   5466 #else
   5467       ARMul_UndefInstr (state, instr);
   5468 #endif
   5469       return;
   5470     }
   5471 
   5472   /* For pre indexed or post indexed addressing modes,
   5473      check that the destination registers do not overlap
   5474      the address registers.  */
   5475   if ((! pre_indexed || write_back)
   5476       && (   addr_reg == src_reg
   5477 	  || addr_reg == src_reg + 1))
   5478     {
   5479       ARMul_UndefInstr (state, instr);
   5480       return;
   5481     }
   5482 
   5483   /* Load the words.  */
   5484   ARMul_StoreWordN (state, addr, state->Reg[src_reg]);
   5485   ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]);
   5486 
   5487   if (state->Aborted)
   5488     {
   5489       TAKEABORT;
   5490       return;
   5491     }
   5492 
   5493   /* Do the post addressing and writeback.  */
   5494   if (! pre_indexed)
   5495     addr = sum;
   5496 
   5497   if (! pre_indexed || write_back)
   5498     state->Reg[addr_reg] = addr;
   5499 }
   5500 
   5501 /* This function does the work of storing a word from a STR instruction.  */
   5502 
   5503 static unsigned
   5504 StoreWord (ARMul_State * state, ARMword instr, ARMword address)
   5505 {
   5506   BUSUSEDINCPCN;
   5507 #ifndef MODE32
   5508   if (DESTReg == 15)
   5509     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
   5510 #endif
   5511 #ifdef MODE32
   5512   ARMul_StoreWordN (state, address, DEST);
   5513 #else
   5514   if (VECTORACCESS (address) || ADDREXCEPT (address))
   5515     {
   5516       INTERNALABORT (address);
   5517       (void) ARMul_LoadWordN (state, address);
   5518     }
   5519   else
   5520     ARMul_StoreWordN (state, address, DEST);
   5521 #endif
   5522   if (state->Aborted)
   5523     {
   5524       TAKEABORT;
   5525       return state->lateabtSig;
   5526     }
   5527   return TRUE;
   5528 }
   5529 
   5530 #ifdef MODET
   5531 /* This function does the work of storing a byte for a STRH instruction.  */
   5532 
   5533 static unsigned
   5534 StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
   5535 {
   5536   BUSUSEDINCPCN;
   5537 
   5538 #ifndef MODE32
   5539   if (DESTReg == 15)
   5540     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
   5541 #endif
   5542 
   5543 #ifdef MODE32
   5544   ARMul_StoreHalfWord (state, address, DEST);
   5545 #else
   5546   if (VECTORACCESS (address) || ADDREXCEPT (address))
   5547     {
   5548       INTERNALABORT (address);
   5549       (void) ARMul_LoadHalfWord (state, address);
   5550     }
   5551   else
   5552     ARMul_StoreHalfWord (state, address, DEST);
   5553 #endif
   5554 
   5555   if (state->Aborted)
   5556     {
   5557       TAKEABORT;
   5558       return state->lateabtSig;
   5559     }
   5560   return TRUE;
   5561 }
   5562 
   5563 #endif /* MODET */
   5564 
   5565 /* This function does the work of storing a byte for a STRB instruction.  */
   5566 
   5567 static unsigned
   5568 StoreByte (ARMul_State * state, ARMword instr, ARMword address)
   5569 {
   5570   BUSUSEDINCPCN;
   5571 #ifndef MODE32
   5572   if (DESTReg == 15)
   5573     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
   5574 #endif
   5575 #ifdef MODE32
   5576   ARMul_StoreByte (state, address, DEST);
   5577 #else
   5578   if (VECTORACCESS (address) || ADDREXCEPT (address))
   5579     {
   5580       INTERNALABORT (address);
   5581       (void) ARMul_LoadByte (state, address);
   5582     }
   5583   else
   5584     ARMul_StoreByte (state, address, DEST);
   5585 #endif
   5586   if (state->Aborted)
   5587     {
   5588       TAKEABORT;
   5589       return state->lateabtSig;
   5590     }
   5591   UNDEF_LSRBPC;
   5592   return TRUE;
   5593 }
   5594 
   5595 /* This function does the work of loading the registers listed in an LDM
   5596    instruction, when the S bit is clear.  The code here is always increment
   5597    after, it's up to the caller to get the input address correct and to
   5598    handle base register modification.  */
   5599 
   5600 static void
   5601 LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
   5602 {
   5603   ARMword dest, temp;
   5604 
   5605   UNDEF_LSMNoRegs;
   5606   UNDEF_LSMPCBase;
   5607   UNDEF_LSMBaseInListWb;
   5608   BUSUSEDINCPCS;
   5609 #ifndef MODE32
   5610   if (ADDREXCEPT (address))
   5611     INTERNALABORT (address);
   5612 #endif
   5613   if (BIT (21) && LHSReg != 15)
   5614     LSBase = WBBase;
   5615 
   5616   /* N cycle first.  */
   5617   for (temp = 0; !BIT (temp); temp++)
   5618     ;
   5619 
   5620   dest = ARMul_LoadWordN (state, address);
   5621 
   5622   if (!state->abortSig && !state->Aborted)
   5623     state->Reg[temp++] = dest;
   5624   else if (!state->Aborted)
   5625     {
   5626       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
   5627       state->Aborted = ARMul_DataAbortV;
   5628     }
   5629 
   5630   /* S cycles from here on.  */
   5631   for (; temp < 16; temp ++)
   5632     if (BIT (temp))
   5633       {
   5634 	/* Load this register.  */
   5635 	address += 4;
   5636 	dest = ARMul_LoadWordS (state, address);
   5637 
   5638 	if (!state->abortSig && !state->Aborted)
   5639 	  state->Reg[temp] = dest;
   5640 	else if (!state->Aborted)
   5641 	  {
   5642             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
   5643 	    state->Aborted = ARMul_DataAbortV;
   5644 	  }
   5645       }
   5646 
   5647   if (BIT (15) && !state->Aborted)
   5648     /* PC is in the reg list.  */
   5649     WriteR15Load (state, PC);
   5650 
   5651   /* To write back the final register.  */
   5652   ARMul_Icycles (state, 1, 0L);
   5653 
   5654   if (state->Aborted)
   5655     {
   5656       if (BIT (21) && LHSReg != 15)
   5657 	LSBase = WBBase;
   5658       TAKEABORT;
   5659     }
   5660 }
   5661 
   5662 /* This function does the work of loading the registers listed in an LDM
   5663    instruction, when the S bit is set. The code here is always increment
   5664    after, it's up to the caller to get the input address correct and to
   5665    handle base register modification.  */
   5666 
   5667 static void
   5668 LoadSMult (ARMul_State * state,
   5669 	   ARMword       instr,
   5670 	   ARMword       address,
   5671 	   ARMword       WBBase)
   5672 {
   5673   ARMword dest, temp;
   5674 
   5675   UNDEF_LSMNoRegs;
   5676   UNDEF_LSMPCBase;
   5677   UNDEF_LSMBaseInListWb;
   5678 
   5679   BUSUSEDINCPCS;
   5680 
   5681 #ifndef MODE32
   5682   if (ADDREXCEPT (address))
   5683     INTERNALABORT (address);
   5684 #endif
   5685 
   5686   if (BIT (21) && LHSReg != 15)
   5687     LSBase = WBBase;
   5688 
   5689   if (!BIT (15) && state->Bank != USERBANK)
   5690     {
   5691       /* Temporary reg bank switch.  */
   5692       (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
   5693       UNDEF_LSMUserBankWb;
   5694     }
   5695 
   5696   /* N cycle first.  */
   5697   for (temp = 0; !BIT (temp); temp ++)
   5698     ;
   5699 
   5700   dest = ARMul_LoadWordN (state, address);
   5701 
   5702   if (!state->abortSig)
   5703     state->Reg[temp++] = dest;
   5704   else if (!state->Aborted)
   5705     {
   5706       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
   5707       state->Aborted = ARMul_DataAbortV;
   5708     }
   5709 
   5710   /* S cycles from here on.  */
   5711   for (; temp < 16; temp++)
   5712     if (BIT (temp))
   5713       {
   5714 	/* Load this register.  */
   5715 	address += 4;
   5716 	dest = ARMul_LoadWordS (state, address);
   5717 
   5718 	if (!state->abortSig && !state->Aborted)
   5719 	  state->Reg[temp] = dest;
   5720 	else if (!state->Aborted)
   5721 	  {
   5722             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
   5723 	    state->Aborted = ARMul_DataAbortV;
   5724 	  }
   5725       }
   5726 
   5727   if (BIT (15) && !state->Aborted)
   5728     {
   5729       /* PC is in the reg list.  */
   5730 #ifdef MODE32
   5731       if (state->Mode != USER26MODE && state->Mode != USER32MODE)
   5732 	{
   5733 	  state->Cpsr = GETSPSR (state->Bank);
   5734 	  ARMul_CPSRAltered (state);
   5735 	}
   5736 
   5737       WriteR15 (state, PC);
   5738 #else
   5739       if (state->Mode == USER26MODE || state->Mode == USER32MODE)
   5740 	{
   5741 	  /* Protect bits in user mode.  */
   5742 	  ASSIGNN ((state->Reg[15] & NBIT) != 0);
   5743 	  ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
   5744 	  ASSIGNC ((state->Reg[15] & CBIT) != 0);
   5745 	  ASSIGNV ((state->Reg[15] & VBIT) != 0);
   5746 	}
   5747       else
   5748 	ARMul_R15Altered (state);
   5749 
   5750       FLUSHPIPE;
   5751 #endif
   5752     }
   5753 
   5754   if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE)
   5755     /* Restore the correct bank.  */
   5756     (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
   5757 
   5758   /* To write back the final register.  */
   5759   ARMul_Icycles (state, 1, 0L);
   5760 
   5761   if (state->Aborted)
   5762     {
   5763       if (BIT (21) && LHSReg != 15)
   5764 	LSBase = WBBase;
   5765 
   5766       TAKEABORT;
   5767     }
   5768 }
   5769 
   5770 /* This function does the work of storing the registers listed in an STM
   5771    instruction, when the S bit is clear.  The code here is always increment
   5772    after, it's up to the caller to get the input address correct and to
   5773    handle base register modification.  */
   5774 
   5775 static void
   5776 StoreMult (ARMul_State * state,
   5777 	   ARMword instr,
   5778 	   ARMword address,
   5779 	   ARMword WBBase)
   5780 {
   5781   ARMword temp;
   5782 
   5783   UNDEF_LSMNoRegs;
   5784   UNDEF_LSMPCBase;
   5785   UNDEF_LSMBaseInListWb;
   5786 
   5787   if (!TFLAG)
   5788     /* N-cycle, increment the PC and update the NextInstr state.  */
   5789     BUSUSEDINCPCN;
   5790 
   5791 #ifndef MODE32
   5792   if (VECTORACCESS (address) || ADDREXCEPT (address))
   5793     INTERNALABORT (address);
   5794 
   5795   if (BIT (15))
   5796     PATCHR15;
   5797 #endif
   5798 
   5799   /* N cycle first.  */
   5800   for (temp = 0; !BIT (temp); temp ++)
   5801     ;
   5802 
   5803 #ifdef MODE32
   5804   ARMul_StoreWordN (state, address, state->Reg[temp++]);
   5805 #else
   5806   if (state->Aborted)
   5807     {
   5808       (void) ARMul_LoadWordN (state, address);
   5809 
   5810       /* Fake the Stores as Loads.  */
   5811       for (; temp < 16; temp++)
   5812 	if (BIT (temp))
   5813 	  {
   5814 	    /* Save this register.  */
   5815 	    address += 4;
   5816 	    (void) ARMul_LoadWordS (state, address);
   5817 	  }
   5818 
   5819       if (BIT (21) && LHSReg != 15)
   5820 	LSBase = WBBase;
   5821       TAKEABORT;
   5822       return;
   5823     }
   5824   else
   5825     ARMul_StoreWordN (state, address, state->Reg[temp++]);
   5826 #endif
   5827 
   5828   if (state->abortSig && !state->Aborted)
   5829     {
   5830       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
   5831       state->Aborted = ARMul_DataAbortV;
   5832     }
   5833 
   5834   if (BIT (21) && LHSReg != 15)
   5835     LSBase = WBBase;
   5836 
   5837   /* S cycles from here on.  */
   5838   for (; temp < 16; temp ++)
   5839     if (BIT (temp))
   5840       {
   5841 	/* Save this register.  */
   5842 	address += 4;
   5843 
   5844 	ARMul_StoreWordS (state, address, state->Reg[temp]);
   5845 
   5846 	if (state->abortSig && !state->Aborted)
   5847 	  {
   5848             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
   5849 	    state->Aborted = ARMul_DataAbortV;
   5850 	  }
   5851       }
   5852 
   5853   if (state->Aborted)
   5854     TAKEABORT;
   5855 }
   5856 
   5857 /* This function does the work of storing the registers listed in an STM
   5858    instruction when the S bit is set.  The code here is always increment
   5859    after, it's up to the caller to get the input address correct and to
   5860    handle base register modification.  */
   5861 
   5862 static void
   5863 StoreSMult (ARMul_State * state,
   5864 	    ARMword       instr,
   5865 	    ARMword       address,
   5866 	    ARMword       WBBase)
   5867 {
   5868   ARMword temp;
   5869 
   5870   UNDEF_LSMNoRegs;
   5871   UNDEF_LSMPCBase;
   5872   UNDEF_LSMBaseInListWb;
   5873 
   5874   BUSUSEDINCPCN;
   5875 
   5876 #ifndef MODE32
   5877   if (VECTORACCESS (address) || ADDREXCEPT (address))
   5878     INTERNALABORT (address);
   5879 
   5880   if (BIT (15))
   5881     PATCHR15;
   5882 #endif
   5883 
   5884   if (state->Bank != USERBANK)
   5885     {
   5886       /* Force User Bank.  */
   5887       (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
   5888       UNDEF_LSMUserBankWb;
   5889     }
   5890 
   5891   for (temp = 0; !BIT (temp); temp++)
   5892     ;	/* N cycle first.  */
   5893 
   5894 #ifdef MODE32
   5895   ARMul_StoreWordN (state, address, state->Reg[temp++]);
   5896 #else
   5897   if (state->Aborted)
   5898     {
   5899       (void) ARMul_LoadWordN (state, address);
   5900 
   5901       for (; temp < 16; temp++)
   5902 	/* Fake the Stores as Loads.  */
   5903 	if (BIT (temp))
   5904 	  {
   5905 	    /* Save this register.  */
   5906 	    address += 4;
   5907 
   5908 	    (void) ARMul_LoadWordS (state, address);
   5909 	  }
   5910 
   5911       if (BIT (21) && LHSReg != 15)
   5912 	LSBase = WBBase;
   5913 
   5914       TAKEABORT;
   5915       return;
   5916     }
   5917   else
   5918     ARMul_StoreWordN (state, address, state->Reg[temp++]);
   5919 #endif
   5920 
   5921   if (state->abortSig && !state->Aborted)
   5922     {
   5923       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
   5924       state->Aborted = ARMul_DataAbortV;
   5925     }
   5926 
   5927   /* S cycles from here on.  */
   5928   for (; temp < 16; temp++)
   5929     if (BIT (temp))
   5930       {
   5931 	/* Save this register.  */
   5932 	address += 4;
   5933 
   5934 	ARMul_StoreWordS (state, address, state->Reg[temp]);
   5935 
   5936 	if (state->abortSig && !state->Aborted)
   5937 	  {
   5938             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
   5939 	    state->Aborted = ARMul_DataAbortV;
   5940 	  }
   5941       }
   5942 
   5943   if (state->Mode != USER26MODE && state->Mode != USER32MODE)
   5944     /* Restore the correct bank.  */
   5945     (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
   5946 
   5947   if (BIT (21) && LHSReg != 15)
   5948     LSBase = WBBase;
   5949 
   5950   if (state->Aborted)
   5951     TAKEABORT;
   5952 }
   5953 
   5954 /* This function does the work of adding two 32bit values
   5955    together, and calculating if a carry has occurred.  */
   5956 
   5957 static ARMword
   5958 Add32 (ARMword a1, ARMword a2, int *carry)
   5959 {
   5960   ARMword result = (a1 + a2);
   5961   unsigned int uresult = (unsigned int) result;
   5962   unsigned int ua1 = (unsigned int) a1;
   5963 
   5964   /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
   5965      or (result > RdLo) then we have no carry.  */
   5966   if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
   5967     *carry = 1;
   5968   else
   5969     *carry = 0;
   5970 
   5971   return result;
   5972 }
   5973 
   5974 /* This function does the work of multiplying
   5975    two 32bit values to give a 64bit result.  */
   5976 
   5977 static unsigned
   5978 Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
   5979 {
   5980   /* Operand register numbers.  */
   5981   int nRdHi, nRdLo, nRs, nRm;
   5982   ARMword RdHi = 0, RdLo = 0, Rm;
   5983   /* Cycle count.  */
   5984   int scount;
   5985 
   5986   nRdHi = BITS (16, 19);
   5987   nRdLo = BITS (12, 15);
   5988   nRs = BITS (8, 11);
   5989   nRm = BITS (0, 3);
   5990 
   5991   /* Needed to calculate the cycle count.  */
   5992   Rm = state->Reg[nRm];
   5993 
   5994   /* Check for illegal operand combinations first.  */
   5995   if (   nRdHi != 15
   5996       && nRdLo != 15
   5997       && nRs   != 15
   5998       && nRm   != 15
   5999       && nRdHi != nRdLo)
   6000     {
   6001       /* Intermediate results.  */
   6002       ARMword lo, mid1, mid2, hi;
   6003       int carry;
   6004       ARMword Rs = state->Reg[nRs];
   6005       int sign = 0;
   6006 
   6007 #ifdef MODE32
   6008       if (state->is_v6)
   6009 	;
   6010       else
   6011 #endif
   6012 	/* BAD code can trigger this result.  So only complain if debugging.  */
   6013 	if (state->Debug && (nRdHi == nRm || nRdLo == nRm))
   6014 	  fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS: %d %d %d\n",
   6015 		   nRdHi, nRdLo, nRm);
   6016       if (msigned)
   6017 	{
   6018 	  /* Compute sign of result and adjust operands if necessary.  */
   6019 	  sign = (Rm ^ Rs) & 0x80000000;
   6020 
   6021 	  if (((ARMsword) Rm) < 0)
   6022 	    Rm = -Rm;
   6023 
   6024 	  if (((ARMsword) Rs) < 0)
   6025 	    Rs = -Rs;
   6026 	}
   6027 
   6028       /* We can split the 32x32 into four 16x16 operations. This
   6029 	 ensures that we do not lose precision on 32bit only hosts.  */
   6030       lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
   6031       mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
   6032       mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
   6033       hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
   6034 
   6035       /* We now need to add all of these results together, taking
   6036 	 care to propagate the carries from the additions.  */
   6037       RdLo = Add32 (lo, (mid1 << 16), &carry);
   6038       RdHi = carry;
   6039       RdLo = Add32 (RdLo, (mid2 << 16), &carry);
   6040       RdHi +=
   6041 	(carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
   6042 
   6043       if (sign)
   6044 	{
   6045 	  /* Negate result if necessary.  */
   6046 	  RdLo = ~RdLo;
   6047 	  RdHi = ~RdHi;
   6048 	  if (RdLo == 0xFFFFFFFF)
   6049 	    {
   6050 	      RdLo = 0;
   6051 	      RdHi += 1;
   6052 	    }
   6053 	  else
   6054 	    RdLo += 1;
   6055 	}
   6056 
   6057       state->Reg[nRdLo] = RdLo;
   6058       state->Reg[nRdHi] = RdHi;
   6059     }
   6060   else if (state->Debug)
   6061     fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS\n");
   6062 
   6063   if (scc)
   6064     /* Ensure that both RdHi and RdLo are used to compute Z,
   6065        but don't let RdLo's sign bit make it to N.  */
   6066     ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
   6067 
   6068   /* The cycle count depends on whether the instruction is a signed or
   6069      unsigned multiply, and what bits are clear in the multiplier.  */
   6070   if (msigned && (Rm & ((unsigned) 1 << 31)))
   6071     /* Invert the bits to make the check against zero.  */
   6072     Rm = ~Rm;
   6073 
   6074   if ((Rm & 0xFFFFFF00) == 0)
   6075     scount = 1;
   6076   else if ((Rm & 0xFFFF0000) == 0)
   6077     scount = 2;
   6078   else if ((Rm & 0xFF000000) == 0)
   6079     scount = 3;
   6080   else
   6081     scount = 4;
   6082 
   6083   return 2 + scount;
   6084 }
   6085 
   6086 /* This function does the work of multiplying two 32bit
   6087    values and adding a 64bit value to give a 64bit result.  */
   6088 
   6089 static unsigned
   6090 MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc)
   6091 {
   6092   unsigned scount;
   6093   ARMword RdLo, RdHi;
   6094   int nRdHi, nRdLo;
   6095   int carry = 0;
   6096 
   6097   nRdHi = BITS (16, 19);
   6098   nRdLo = BITS (12, 15);
   6099 
   6100   RdHi = state->Reg[nRdHi];
   6101   RdLo = state->Reg[nRdLo];
   6102 
   6103   scount = Multiply64 (state, instr, msigned, LDEFAULT);
   6104 
   6105   RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry);
   6106   RdHi = (RdHi + state->Reg[nRdHi]) + carry;
   6107 
   6108   state->Reg[nRdLo] = RdLo;
   6109   state->Reg[nRdHi] = RdHi;
   6110 
   6111   if (scc)
   6112     /* Ensure that both RdHi and RdLo are used to compute Z,
   6113        but don't let RdLo's sign bit make it to N.  */
   6114     ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
   6115 
   6116   /* Extra cycle for addition.  */
   6117   return scount + 1;
   6118 }
   6119