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