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