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