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