xref: /netbsd-src/external/gpl3/gdb/dist/sim/arm/armemu.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
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 	    ARMword 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 		  ARMword dest;
1438 
1439 		  state->Reg[14] = pc + 4;
1440 
1441 		  /* Force entry into Thumb mode.  */
1442 		  dest = pc + 8 + 1;
1443 		  if (BIT (23))
1444 		    dest += (NEGBRANCH + (BIT (24) << 1));
1445 		  else
1446 		    dest += POSBRANCH + (BIT (24) << 1);
1447 
1448 		  WriteR15Branch (state, dest);
1449 		  goto donext;
1450 		}
1451 	      else if ((instr & 0xFC70F000) == 0xF450F000)
1452 		/* The PLD instruction.  Ignored.  */
1453 		goto donext;
1454 	      else if (   ((instr & 0xfe500f00) == 0xfc100100)
1455 		       || ((instr & 0xfe500f00) == 0xfc000100))
1456 		/* wldrw and wstrw are unconditional.  */
1457 		goto mainswitch;
1458 	      else
1459 		/* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2.  */
1460 		ARMul_UndefInstr (state, instr);
1461 	    }
1462 	  temp = FALSE;
1463 	  break;
1464 	case EQ:
1465 	  temp = ZFLAG;
1466 	  break;
1467 	case NE:
1468 	  temp = !ZFLAG;
1469 	  break;
1470 	case VS:
1471 	  temp = VFLAG;
1472 	  break;
1473 	case VC:
1474 	  temp = !VFLAG;
1475 	  break;
1476 	case MI:
1477 	  temp = NFLAG;
1478 	  break;
1479 	case PL:
1480 	  temp = !NFLAG;
1481 	  break;
1482 	case CS:
1483 	  temp = CFLAG;
1484 	  break;
1485 	case CC:
1486 	  temp = !CFLAG;
1487 	  break;
1488 	case HI:
1489 	  temp = (CFLAG && !ZFLAG);
1490 	  break;
1491 	case LS:
1492 	  temp = (!CFLAG || ZFLAG);
1493 	  break;
1494 	case GE:
1495 	  temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
1496 	  break;
1497 	case LT:
1498 	  temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
1499 	  break;
1500 	case GT:
1501 	  temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
1502 	  break;
1503 	case LE:
1504 	  temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
1505 	  break;
1506 	}			/* cc check */
1507 
1508       /* Handle the Clock counter here.  */
1509       if (state->is_XScale)
1510 	{
1511 	  ARMword cp14r0;
1512 	  int ok;
1513 
1514 	  ok = state->CPRead[14] (state, 0, & cp14r0);
1515 
1516 	  if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE))
1517 	    {
1518 	      unsigned long newcycles, nowtime = ARMul_Time (state);
1519 
1520 	      newcycles = nowtime - state->LastTime;
1521 	      state->LastTime = nowtime;
1522 
1523 	      if (cp14r0 & ARMul_CP14_R0_CCD)
1524 	        {
1525 		  if (state->CP14R0_CCD == -1)
1526 		    state->CP14R0_CCD = newcycles;
1527 		  else
1528 		    state->CP14R0_CCD += newcycles;
1529 
1530 		  if (state->CP14R0_CCD >= 64)
1531 		    {
1532 		      newcycles = 0;
1533 
1534 		      while (state->CP14R0_CCD >= 64)
1535 		        state->CP14R0_CCD -= 64, newcycles++;
1536 
1537 		      goto check_PMUintr;
1538 		    }
1539 		}
1540 	      else
1541 		{
1542 		  ARMword cp14r1;
1543 		  int do_int;
1544 
1545 		  state->CP14R0_CCD = -1;
1546 check_PMUintr:
1547 		  do_int = 0;
1548 		  cp14r0 |= ARMul_CP14_R0_FLAG2;
1549 		  (void) state->CPWrite[14] (state, 0, cp14r0);
1550 
1551 		  ok = state->CPRead[14] (state, 1, & cp14r1);
1552 
1553 		  /* Coded like this for portability.  */
1554 		  while (ok && newcycles)
1555 		    {
1556 		      if (cp14r1 == 0xffffffff)
1557 			{
1558 			  cp14r1 = 0;
1559 			  do_int = 1;
1560 			}
1561 		      else
1562 			cp14r1 ++;
1563 
1564 		      newcycles --;
1565 		    }
1566 
1567 		  (void) state->CPWrite[14] (state, 1, cp14r1);
1568 
1569 		  if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2))
1570 		    {
1571 		      ARMword temp;
1572 
1573 		      if (state->CPRead[13] (state, 8, & temp)
1574 			  && (temp & ARMul_CP13_R8_PMUS))
1575 		        ARMul_Abort (state, ARMul_FIQV);
1576 		      else
1577 		        ARMul_Abort (state, ARMul_IRQV);
1578 		    }
1579 		}
1580 	    }
1581 	}
1582 
1583       /* Handle hardware instructions breakpoints here.  */
1584       if (state->is_XScale)
1585 	{
1586 	  if (   (pc | 3) == (read_cp15_reg (14, 0, 8) | 2)
1587 	      || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2))
1588 	    {
1589 	      if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB))
1590 	        ARMul_OSHandleSWI (state, SWI_Breakpoint);
1591 	    }
1592 	}
1593 
1594       /* Actual execution of instructions begins here.  */
1595       /* If the condition codes don't match, stop here.  */
1596       if (temp)
1597 	{
1598 	mainswitch:
1599 
1600 	  if (state->is_XScale)
1601 	    {
1602 	      if (BIT (20) == 0 && BITS (25, 27) == 0)
1603 		{
1604 		  if (BITS (4, 7) == 0xD)
1605 		    {
1606 		      /* XScale Load Consecutive insn.  */
1607 		      ARMword temp = GetLS7RHS (state, instr);
1608 		      ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
1609 		      ARMword addr = BIT (24) ? temp2 : LHS;
1610 
1611 		      if (BIT (12))
1612 			ARMul_UndefInstr (state, instr);
1613 		      else if (addr & 7)
1614 			/* Alignment violation.  */
1615 			ARMul_Abort (state, ARMul_DataAbortV);
1616 		      else
1617 			{
1618 			  int wb = BIT (21) || (! BIT (24));
1619 
1620 			  state->Reg[BITS (12, 15)] =
1621 			    ARMul_LoadWordN (state, addr);
1622 			  state->Reg[BITS (12, 15) + 1] =
1623 			    ARMul_LoadWordN (state, addr + 4);
1624 			  if (wb)
1625 			    LSBase = temp2;
1626 			}
1627 
1628 		      goto donext;
1629 		    }
1630 		  else if (BITS (4, 7) == 0xF)
1631 		    {
1632 		      /* XScale Store Consecutive insn.  */
1633 		      ARMword temp = GetLS7RHS (state, instr);
1634 		      ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
1635 		      ARMword addr = BIT (24) ? temp2 : LHS;
1636 
1637 		      if (BIT (12))
1638 			ARMul_UndefInstr (state, instr);
1639 		      else if (addr & 7)
1640 			/* Alignment violation.  */
1641 			ARMul_Abort (state, ARMul_DataAbortV);
1642 		      else
1643 			{
1644 			  ARMul_StoreWordN (state, addr,
1645 					    state->Reg[BITS (12, 15)]);
1646 			  ARMul_StoreWordN (state, addr + 4,
1647 					    state->Reg[BITS (12, 15) + 1]);
1648 
1649 			  if (BIT (21)|| ! BIT (24))
1650 			    LSBase = temp2;
1651 			}
1652 
1653 		      goto donext;
1654 		    }
1655 		}
1656 
1657 	      if (ARMul_HandleIwmmxt (state, instr))
1658 		goto donext;
1659 	    }
1660 
1661 	  switch ((int) BITS (20, 27))
1662 	    {
1663 	      /* Data Processing Register RHS Instructions.  */
1664 
1665 	    case 0x00:		/* AND reg and MUL */
1666 #ifdef MODET
1667 	      if (BITS (4, 11) == 0xB)
1668 		{
1669 		  /* STRH register offset, no write-back, down, post indexed.  */
1670 		  SHDOWNWB ();
1671 		  break;
1672 		}
1673 	      if (BITS (4, 7) == 0xD)
1674 		{
1675 		  Handle_Load_Double (state, instr);
1676 		  break;
1677 		}
1678 	      if (BITS (4, 7) == 0xF)
1679 		{
1680 		  Handle_Store_Double (state, instr);
1681 		  break;
1682 		}
1683 #endif
1684 	      if (BITS (4, 7) == 9)
1685 		{
1686 		  /* MUL */
1687 		  rhs = state->Reg[MULRHSReg];
1688 		  if (MULLHSReg == MULDESTReg)
1689 		    {
1690 		      UNDEF_MULDestEQOp1;
1691 		      state->Reg[MULDESTReg] = 0;
1692 		    }
1693 		  else if (MULDESTReg != 15)
1694 		    state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
1695 		  else
1696 		    UNDEF_MULPCDest;
1697 
1698 		  for (dest = 0, temp = 0; dest < 32; dest ++)
1699 		    if (rhs & (1L << dest))
1700 		      temp = dest;
1701 
1702 		  /* Mult takes this many/2 I cycles.  */
1703 		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
1704 		}
1705 	      else
1706 		{
1707 		  /* AND reg.  */
1708 		  rhs = DPRegRHS;
1709 		  dest = LHS & rhs;
1710 		  WRITEDEST (dest);
1711 		}
1712 	      break;
1713 
1714 	    case 0x01:		/* ANDS reg and MULS */
1715 #ifdef MODET
1716 	      if ((BITS (4, 11) & 0xF9) == 0x9)
1717 		/* LDR register offset, no write-back, down, post indexed.  */
1718 		LHPOSTDOWN ();
1719 	      /* Fall through to rest of decoding.  */
1720 #endif
1721 	      if (BITS (4, 7) == 9)
1722 		{
1723 		  /* MULS */
1724 		  rhs = state->Reg[MULRHSReg];
1725 
1726 		  if (MULLHSReg == MULDESTReg)
1727 		    {
1728 		      UNDEF_MULDestEQOp1;
1729 		      state->Reg[MULDESTReg] = 0;
1730 		      CLEARN;
1731 		      SETZ;
1732 		    }
1733 		  else if (MULDESTReg != 15)
1734 		    {
1735 		      dest = state->Reg[MULLHSReg] * rhs;
1736 		      ARMul_NegZero (state, dest);
1737 		      state->Reg[MULDESTReg] = dest;
1738 		    }
1739 		  else
1740 		    UNDEF_MULPCDest;
1741 
1742 		  for (dest = 0, temp = 0; dest < 32; dest ++)
1743 		    if (rhs & (1L << dest))
1744 		      temp = dest;
1745 
1746 		  /* Mult takes this many/2 I cycles.  */
1747 		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
1748 		}
1749 	      else
1750 		{
1751 		  /* ANDS reg.  */
1752 		  rhs = DPSRegRHS;
1753 		  dest = LHS & rhs;
1754 		  WRITESDEST (dest);
1755 		}
1756 	      break;
1757 
1758 	    case 0x02:		/* EOR reg and MLA */
1759 #ifdef MODET
1760 	      if (BITS (4, 11) == 0xB)
1761 		{
1762 		  /* STRH register offset, write-back, down, post indexed.  */
1763 		  SHDOWNWB ();
1764 		  break;
1765 		}
1766 #endif
1767 	      if (BITS (4, 7) == 9)
1768 		{		/* MLA */
1769 		  rhs = state->Reg[MULRHSReg];
1770 		  if (MULLHSReg == MULDESTReg)
1771 		    {
1772 		      UNDEF_MULDestEQOp1;
1773 		      state->Reg[MULDESTReg] = state->Reg[MULACCReg];
1774 		    }
1775 		  else if (MULDESTReg != 15)
1776 		    state->Reg[MULDESTReg] =
1777 		      state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
1778 		  else
1779 		    UNDEF_MULPCDest;
1780 
1781 		  for (dest = 0, temp = 0; dest < 32; dest ++)
1782 		    if (rhs & (1L << dest))
1783 		      temp = dest;
1784 
1785 		  /* Mult takes this many/2 I cycles.  */
1786 		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
1787 		}
1788 	      else
1789 		{
1790 		  rhs = DPRegRHS;
1791 		  dest = LHS ^ rhs;
1792 		  WRITEDEST (dest);
1793 		}
1794 	      break;
1795 
1796 	    case 0x03:		/* EORS reg and MLAS */
1797 #ifdef MODET
1798 	      if ((BITS (4, 11) & 0xF9) == 0x9)
1799 		/* LDR register offset, write-back, down, post-indexed.  */
1800 		LHPOSTDOWN ();
1801 	      /* Fall through to rest of the decoding.  */
1802 #endif
1803 	      if (BITS (4, 7) == 9)
1804 		{
1805 		  /* MLAS */
1806 		  rhs = state->Reg[MULRHSReg];
1807 
1808 		  if (MULLHSReg == MULDESTReg)
1809 		    {
1810 		      UNDEF_MULDestEQOp1;
1811 		      dest = state->Reg[MULACCReg];
1812 		      ARMul_NegZero (state, dest);
1813 		      state->Reg[MULDESTReg] = dest;
1814 		    }
1815 		  else if (MULDESTReg != 15)
1816 		    {
1817 		      dest =
1818 			state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
1819 		      ARMul_NegZero (state, dest);
1820 		      state->Reg[MULDESTReg] = dest;
1821 		    }
1822 		  else
1823 		    UNDEF_MULPCDest;
1824 
1825 		  for (dest = 0, temp = 0; dest < 32; dest ++)
1826 		    if (rhs & (1L << dest))
1827 		      temp = dest;
1828 
1829 		  /* Mult takes this many/2 I cycles.  */
1830 		  ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
1831 		}
1832 	      else
1833 		{
1834 		  /* EORS Reg.  */
1835 		  rhs = DPSRegRHS;
1836 		  dest = LHS ^ rhs;
1837 		  WRITESDEST (dest);
1838 		}
1839 	      break;
1840 
1841 	    case 0x04:		/* SUB reg */
1842 #ifdef MODET
1843 	      if (BITS (4, 7) == 0xB)
1844 		{
1845 		  /* STRH immediate offset, no write-back, down, post indexed.  */
1846 		  SHDOWNWB ();
1847 		  break;
1848 		}
1849 	      if (BITS (4, 7) == 0xD)
1850 		{
1851 		  Handle_Load_Double (state, instr);
1852 		  break;
1853 		}
1854 	      if (BITS (4, 7) == 0xF)
1855 		{
1856 		  Handle_Store_Double (state, instr);
1857 		  break;
1858 		}
1859 #endif
1860 	      rhs = DPRegRHS;
1861 	      dest = LHS - rhs;
1862 	      WRITEDEST (dest);
1863 	      break;
1864 
1865 	    case 0x05:		/* SUBS reg */
1866 #ifdef MODET
1867 	      if ((BITS (4, 7) & 0x9) == 0x9)
1868 		/* LDR immediate offset, no write-back, down, post indexed.  */
1869 		LHPOSTDOWN ();
1870 	      /* Fall through to the rest of the instruction decoding.  */
1871 #endif
1872 	      lhs = LHS;
1873 	      rhs = DPRegRHS;
1874 	      dest = lhs - rhs;
1875 
1876 	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))
1877 		{
1878 		  ARMul_SubCarry (state, lhs, rhs, dest);
1879 		  ARMul_SubOverflow (state, lhs, rhs, dest);
1880 		}
1881 	      else
1882 		{
1883 		  CLEARC;
1884 		  CLEARV;
1885 		}
1886 	      WRITESDEST (dest);
1887 	      break;
1888 
1889 	    case 0x06:		/* RSB reg */
1890 #ifdef MODET
1891 	      if (BITS (4, 7) == 0xB)
1892 		{
1893 		  /* STRH immediate offset, write-back, down, post indexed.  */
1894 		  SHDOWNWB ();
1895 		  break;
1896 		}
1897 #endif
1898 	      rhs = DPRegRHS;
1899 	      dest = rhs - LHS;
1900 	      WRITEDEST (dest);
1901 	      break;
1902 
1903 	    case 0x07:		/* RSBS reg */
1904 #ifdef MODET
1905 	      if ((BITS (4, 7) & 0x9) == 0x9)
1906 		/* LDR immediate offset, write-back, down, post indexed.  */
1907 		LHPOSTDOWN ();
1908 	      /* Fall through to remainder of instruction decoding.  */
1909 #endif
1910 	      lhs = LHS;
1911 	      rhs = DPRegRHS;
1912 	      dest = rhs - lhs;
1913 
1914 	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))
1915 		{
1916 		  ARMul_SubCarry (state, rhs, lhs, dest);
1917 		  ARMul_SubOverflow (state, rhs, lhs, dest);
1918 		}
1919 	      else
1920 		{
1921 		  CLEARC;
1922 		  CLEARV;
1923 		}
1924 	      WRITESDEST (dest);
1925 	      break;
1926 
1927 	    case 0x08:		/* ADD reg */
1928 #ifdef MODET
1929 	      if (BITS (4, 11) == 0xB)
1930 		{
1931 		  /* STRH register offset, no write-back, up, post indexed.  */
1932 		  SHUPWB ();
1933 		  break;
1934 		}
1935 	      if (BITS (4, 7) == 0xD)
1936 		{
1937 		  Handle_Load_Double (state, instr);
1938 		  break;
1939 		}
1940 	      if (BITS (4, 7) == 0xF)
1941 		{
1942 		  Handle_Store_Double (state, instr);
1943 		  break;
1944 		}
1945 #endif
1946 #ifdef MODET
1947 	      if (BITS (4, 7) == 0x9)
1948 		{
1949 		  /* MULL */
1950 		  /* 32x32 = 64 */
1951 		  ARMul_Icycles (state,
1952 				 Multiply64 (state, instr, LUNSIGNED,
1953 					     LDEFAULT), 0L);
1954 		  break;
1955 		}
1956 #endif
1957 	      rhs = DPRegRHS;
1958 	      dest = LHS + rhs;
1959 	      WRITEDEST (dest);
1960 	      break;
1961 
1962 	    case 0x09:		/* ADDS reg */
1963 #ifdef MODET
1964 	      if ((BITS (4, 11) & 0xF9) == 0x9)
1965 		/* LDR register offset, no write-back, up, post indexed.  */
1966 		LHPOSTUP ();
1967 	      /* Fall through to remaining instruction decoding.  */
1968 #endif
1969 #ifdef MODET
1970 	      if (BITS (4, 7) == 0x9)
1971 		{
1972 		  /* MULL */
1973 		  /* 32x32=64 */
1974 		  ARMul_Icycles (state,
1975 				 Multiply64 (state, instr, LUNSIGNED, LSCC),
1976 				 0L);
1977 		  break;
1978 		}
1979 #endif
1980 	      lhs = LHS;
1981 	      rhs = DPRegRHS;
1982 	      dest = lhs + rhs;
1983 	      ASSIGNZ (dest == 0);
1984 	      if ((lhs | rhs) >> 30)
1985 		{
1986 		  /* Possible C,V,N to set.  */
1987 		  ASSIGNN (NEG (dest));
1988 		  ARMul_AddCarry (state, lhs, rhs, dest);
1989 		  ARMul_AddOverflow (state, lhs, rhs, dest);
1990 		}
1991 	      else
1992 		{
1993 		  CLEARN;
1994 		  CLEARC;
1995 		  CLEARV;
1996 		}
1997 	      WRITESDEST (dest);
1998 	      break;
1999 
2000 	    case 0x0a:		/* ADC reg */
2001 #ifdef MODET
2002 	      if (BITS (4, 11) == 0xB)
2003 		{
2004 		  /* STRH register offset, write-back, up, post-indexed.  */
2005 		  SHUPWB ();
2006 		  break;
2007 		}
2008 	      if (BITS (4, 7) == 0x9)
2009 		{
2010 		  /* MULL */
2011 		  /* 32x32=64 */
2012 		  ARMul_Icycles (state,
2013 				 MultiplyAdd64 (state, instr, LUNSIGNED,
2014 						LDEFAULT), 0L);
2015 		  break;
2016 		}
2017 #endif
2018 	      rhs = DPRegRHS;
2019 	      dest = LHS + rhs + CFLAG;
2020 	      WRITEDEST (dest);
2021 	      break;
2022 
2023 	    case 0x0b:		/* ADCS reg */
2024 #ifdef MODET
2025 	      if ((BITS (4, 11) & 0xF9) == 0x9)
2026 		/* LDR register offset, write-back, up, post indexed.  */
2027 		LHPOSTUP ();
2028 	      /* Fall through to remaining instruction decoding.  */
2029 	      if (BITS (4, 7) == 0x9)
2030 		{
2031 		  /* MULL */
2032 		  /* 32x32=64 */
2033 		  ARMul_Icycles (state,
2034 				 MultiplyAdd64 (state, instr, LUNSIGNED,
2035 						LSCC), 0L);
2036 		  break;
2037 		}
2038 #endif
2039 	      lhs = LHS;
2040 	      rhs = DPRegRHS;
2041 	      dest = lhs + rhs + CFLAG;
2042 	      ASSIGNZ (dest == 0);
2043 	      if ((lhs | rhs) >> 30)
2044 		{
2045 		  /* Possible C,V,N to set.  */
2046 		  ASSIGNN (NEG (dest));
2047 		  ARMul_AddCarry (state, lhs, rhs, dest);
2048 		  ARMul_AddOverflow (state, lhs, rhs, dest);
2049 		}
2050 	      else
2051 		{
2052 		  CLEARN;
2053 		  CLEARC;
2054 		  CLEARV;
2055 		}
2056 	      WRITESDEST (dest);
2057 	      break;
2058 
2059 	    case 0x0c:		/* SBC reg */
2060 #ifdef MODET
2061 	      if (BITS (4, 7) == 0xB)
2062 		{
2063 		  /* STRH immediate offset, no write-back, up post indexed.  */
2064 		  SHUPWB ();
2065 		  break;
2066 		}
2067 	      if (BITS (4, 7) == 0xD)
2068 		{
2069 		  Handle_Load_Double (state, instr);
2070 		  break;
2071 		}
2072 	      if (BITS (4, 7) == 0xF)
2073 		{
2074 		  Handle_Store_Double (state, instr);
2075 		  break;
2076 		}
2077 	      if (BITS (4, 7) == 0x9)
2078 		{
2079 		  /* MULL */
2080 		  /* 32x32=64 */
2081 		  ARMul_Icycles (state,
2082 				 Multiply64 (state, instr, LSIGNED, LDEFAULT),
2083 				 0L);
2084 		  break;
2085 		}
2086 #endif
2087 	      rhs = DPRegRHS;
2088 	      dest = LHS - rhs - !CFLAG;
2089 	      WRITEDEST (dest);
2090 	      break;
2091 
2092 	    case 0x0d:		/* SBCS reg */
2093 #ifdef MODET
2094 	      if ((BITS (4, 7) & 0x9) == 0x9)
2095 		/* LDR immediate offset, no write-back, up, post indexed.  */
2096 		LHPOSTUP ();
2097 
2098 	      if (BITS (4, 7) == 0x9)
2099 		{
2100 		  /* MULL */
2101 		  /* 32x32=64 */
2102 		  ARMul_Icycles (state,
2103 				 Multiply64 (state, instr, LSIGNED, LSCC),
2104 				 0L);
2105 		  break;
2106 		}
2107 #endif
2108 	      lhs = LHS;
2109 	      rhs = DPRegRHS;
2110 	      dest = lhs - rhs - !CFLAG;
2111 	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))
2112 		{
2113 		  ARMul_SubCarry (state, lhs, rhs, dest);
2114 		  ARMul_SubOverflow (state, lhs, rhs, dest);
2115 		}
2116 	      else
2117 		{
2118 		  CLEARC;
2119 		  CLEARV;
2120 		}
2121 	      WRITESDEST (dest);
2122 	      break;
2123 
2124 	    case 0x0e:		/* RSC reg */
2125 #ifdef MODET
2126 	      if (BITS (4, 7) == 0xB)
2127 		{
2128 		  /* STRH immediate offset, write-back, up, post indexed.  */
2129 		  SHUPWB ();
2130 		  break;
2131 		}
2132 
2133 	      if (BITS (4, 7) == 0x9)
2134 		{
2135 		  /* MULL */
2136 		  /* 32x32=64 */
2137 		  ARMul_Icycles (state,
2138 				 MultiplyAdd64 (state, instr, LSIGNED,
2139 						LDEFAULT), 0L);
2140 		  break;
2141 		}
2142 #endif
2143 	      rhs = DPRegRHS;
2144 	      dest = rhs - LHS - !CFLAG;
2145 	      WRITEDEST (dest);
2146 	      break;
2147 
2148 	    case 0x0f:		/* RSCS reg */
2149 #ifdef MODET
2150 	      if ((BITS (4, 7) & 0x9) == 0x9)
2151 		/* LDR immediate offset, write-back, up, post indexed.  */
2152 		LHPOSTUP ();
2153 	      /* Fall through to remaining instruction decoding.  */
2154 
2155 	      if (BITS (4, 7) == 0x9)
2156 		{
2157 		  /* MULL */
2158 		  /* 32x32=64 */
2159 		  ARMul_Icycles (state,
2160 				 MultiplyAdd64 (state, instr, LSIGNED, LSCC),
2161 				 0L);
2162 		  break;
2163 		}
2164 #endif
2165 	      lhs = LHS;
2166 	      rhs = DPRegRHS;
2167 	      dest = rhs - lhs - !CFLAG;
2168 
2169 	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))
2170 		{
2171 		  ARMul_SubCarry (state, rhs, lhs, dest);
2172 		  ARMul_SubOverflow (state, rhs, lhs, dest);
2173 		}
2174 	      else
2175 		{
2176 		  CLEARC;
2177 		  CLEARV;
2178 		}
2179 	      WRITESDEST (dest);
2180 	      break;
2181 
2182 	    case 0x10:		/* TST reg and MRS CPSR and SWP word.  */
2183 	      if (state->is_v5e)
2184 		{
2185 		  if (BIT (4) == 0 && BIT (7) == 1)
2186 		    {
2187 		      /* ElSegundo SMLAxy insn.  */
2188 		      ARMword op1 = state->Reg[BITS (0, 3)];
2189 		      ARMword op2 = state->Reg[BITS (8, 11)];
2190 		      ARMword Rn = state->Reg[BITS (12, 15)];
2191 
2192 		      if (BIT (5))
2193 			op1 >>= 16;
2194 		      if (BIT (6))
2195 			op2 >>= 16;
2196 		      op1 &= 0xFFFF;
2197 		      op2 &= 0xFFFF;
2198 		      if (op1 & 0x8000)
2199 			op1 -= 65536;
2200 		      if (op2 & 0x8000)
2201 			op2 -= 65536;
2202 		      op1 *= op2;
2203 
2204 		      if (AddOverflow (op1, Rn, op1 + Rn))
2205 			SETS;
2206 		      state->Reg[BITS (16, 19)] = op1 + Rn;
2207 		      break;
2208 		    }
2209 
2210 		  if (BITS (4, 11) == 5)
2211 		    {
2212 		      /* ElSegundo QADD insn.  */
2213 		      ARMword op1 = state->Reg[BITS (0, 3)];
2214 		      ARMword op2 = state->Reg[BITS (16, 19)];
2215 		      ARMword result = op1 + op2;
2216 		      if (AddOverflow (op1, op2, result))
2217 			{
2218 			  result = POS (result) ? 0x80000000 : 0x7fffffff;
2219 			  SETS;
2220 			}
2221 		      state->Reg[BITS (12, 15)] = result;
2222 		      break;
2223 		    }
2224 		}
2225 #ifdef MODET
2226 	      if (BITS (4, 11) == 0xB)
2227 		{
2228 		  /* STRH register offset, no write-back, down, pre indexed.  */
2229 		  SHPREDOWN ();
2230 		  break;
2231 		}
2232 	      if (BITS (4, 7) == 0xD)
2233 		{
2234 		  Handle_Load_Double (state, instr);
2235 		  break;
2236 		}
2237 	      if (BITS (4, 7) == 0xF)
2238 		{
2239 		  Handle_Store_Double (state, instr);
2240 		  break;
2241 		}
2242 #endif
2243 	      if (BITS (4, 11) == 9)
2244 		{
2245 		  /* SWP */
2246 		  UNDEF_SWPPC;
2247 		  temp = LHS;
2248 		  BUSUSEDINCPCS;
2249 #ifndef MODE32
2250 		  if (VECTORACCESS (temp) || ADDREXCEPT (temp))
2251 		    {
2252 		      INTERNALABORT (temp);
2253 		      (void) ARMul_LoadWordN (state, temp);
2254 		      (void) ARMul_LoadWordN (state, temp);
2255 		    }
2256 		  else
2257 #endif
2258 		    dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]);
2259 		  if (temp & 3)
2260 		    DEST = ARMul_Align (state, temp, dest);
2261 		  else
2262 		    DEST = dest;
2263 		  if (state->abortSig || state->Aborted)
2264 		    TAKEABORT;
2265 		}
2266 	      else if ((BITS (0, 11) == 0) && (LHSReg == 15))
2267 		{		/* MRS CPSR */
2268 		  UNDEF_MRSPC;
2269 		  DEST = ECC | EINT | EMODE;
2270 		}
2271 	      else
2272 		{
2273 #ifdef MODE32
2274 		  if (state->is_v6
2275 		      && handle_v6_insn (state, instr))
2276 		    break;
2277 #endif
2278 		  UNDEF_Test;
2279 		}
2280 	      break;
2281 
2282 	    case 0x11:		/* TSTP reg */
2283 #ifdef MODET
2284 	      if ((BITS (4, 11) & 0xF9) == 0x9)
2285 		/* LDR register offset, no write-back, down, pre indexed.  */
2286 		LHPREDOWN ();
2287 	      /* Continue with remaining instruction decode.  */
2288 #endif
2289 	      if (DESTReg == 15)
2290 		{
2291 		  /* TSTP reg */
2292 #ifdef MODE32
2293 		  state->Cpsr = GETSPSR (state->Bank);
2294 		  ARMul_CPSRAltered (state);
2295 #else
2296 		  rhs = DPRegRHS;
2297 		  temp = LHS & rhs;
2298 		  SETR15PSR (temp);
2299 #endif
2300 		}
2301 	      else
2302 		{
2303 		  /* TST reg */
2304 		  rhs = DPSRegRHS;
2305 		  dest = LHS & rhs;
2306 		  ARMul_NegZero (state, dest);
2307 		}
2308 	      break;
2309 
2310 	    case 0x12:		/* TEQ reg and MSR reg to CPSR (ARM6).  */
2311 	      if (state->is_v5)
2312 		{
2313 		  if (BITS (4, 7) == 3)
2314 		    {
2315 		      /* BLX(2) */
2316 		      ARMword temp;
2317 
2318 		      if (TFLAG)
2319 			temp = (pc + 2) | 1;
2320 		      else
2321 			temp = pc + 4;
2322 
2323 		      WriteR15Branch (state, state->Reg[RHSReg]);
2324 		      state->Reg[14] = temp;
2325 		      break;
2326 		    }
2327 		}
2328 
2329 	      if (state->is_v5e)
2330 		{
2331 		  if (BIT (4) == 0 && BIT (7) == 1
2332 		      && (BIT (5) == 0 || BITS (12, 15) == 0))
2333 		    {
2334 		      /* ElSegundo SMLAWy/SMULWy insn.  */
2335 		      ARMdword op1 = state->Reg[BITS (0, 3)];
2336 		      ARMdword op2 = state->Reg[BITS (8, 11)];
2337 		      ARMdword result;
2338 
2339 		      if (BIT (6))
2340 			op2 >>= 16;
2341 		      if (op1 & 0x80000000)
2342 			op1 -= 1ULL << 32;
2343 		      op2 &= 0xFFFF;
2344 		      if (op2 & 0x8000)
2345 			op2 -= 65536;
2346 		      result = (op1 * op2) >> 16;
2347 
2348 		      if (BIT (5) == 0)
2349 			{
2350 			  ARMword Rn = state->Reg[BITS (12, 15)];
2351 
2352 			  if (AddOverflow (result, Rn, result + Rn))
2353 			    SETS;
2354 			  result += Rn;
2355 			}
2356 		      state->Reg[BITS (16, 19)] = result;
2357 		      break;
2358 		    }
2359 
2360 		  if (BITS (4, 11) == 5)
2361 		    {
2362 		      /* ElSegundo QSUB insn.  */
2363 		      ARMword op1 = state->Reg[BITS (0, 3)];
2364 		      ARMword op2 = state->Reg[BITS (16, 19)];
2365 		      ARMword result = op1 - op2;
2366 
2367 		      if (SubOverflow (op1, op2, result))
2368 			{
2369 			  result = POS (result) ? 0x80000000 : 0x7fffffff;
2370 			  SETS;
2371 			}
2372 
2373 		      state->Reg[BITS (12, 15)] = result;
2374 		      break;
2375 		    }
2376 		}
2377 #ifdef MODET
2378 	      if (BITS (4, 11) == 0xB)
2379 		{
2380 		  /* STRH register offset, write-back, down, pre indexed.  */
2381 		  SHPREDOWNWB ();
2382 		  break;
2383 		}
2384 	      if (BITS (4, 27) == 0x12FFF1)
2385 		{
2386 		  /* BX */
2387 		  WriteR15Branch (state, state->Reg[RHSReg]);
2388 		  break;
2389 		}
2390 	      if (BITS (4, 7) == 0xD)
2391 		{
2392 		  Handle_Load_Double (state, instr);
2393 		  break;
2394 		}
2395 	      if (BITS (4, 7) == 0xF)
2396 		{
2397 		  Handle_Store_Double (state, instr);
2398 		  break;
2399 		}
2400 #endif
2401 	      if (state->is_v5)
2402 		{
2403 		  if (BITS (4, 7) == 0x7)
2404 		    {
2405 		      extern int SWI_vector_installed;
2406 
2407 		      /* Hardware is allowed to optionally override this
2408 			 instruction and treat it as a breakpoint.  Since
2409 			 this is a simulator not hardware, we take the position
2410 			 that if a SWI vector was not installed, then an Abort
2411 			 vector was probably not installed either, and so
2412 			 normally this instruction would be ignored, even if an
2413 			 Abort is generated.  This is a bad thing, since GDB
2414 			 uses this instruction for its breakpoints (at least in
2415 			 Thumb mode it does).  So intercept the instruction here
2416 			 and generate a breakpoint SWI instead.  */
2417 		      if (! SWI_vector_installed)
2418 			ARMul_OSHandleSWI (state, SWI_Breakpoint);
2419 		      else
2420 			{
2421 			  /* BKPT - normally this will cause an abort, but on the
2422 			     XScale we must check the DCSR.  */
2423 			  XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
2424 	                  if (!XScale_debug_moe (state, ARMul_CP14_R10_MOE_BT))
2425 			    break;
2426 			}
2427 
2428 		      /* Force the next instruction to be refetched.  */
2429 		      state->NextInstr = RESUME;
2430 		      break;
2431 		    }
2432 		}
2433 	      if (DESTReg == 15)
2434 		{
2435 		  /* MSR reg to CPSR.  */
2436 		  UNDEF_MSRPC;
2437 		  temp = DPRegRHS;
2438 #ifdef MODET
2439 		  /* Don't allow TBIT to be set by MSR.  */
2440 		  temp &= ~ TBIT;
2441 #endif
2442 		  ARMul_FixCPSR (state, instr, temp);
2443 		}
2444 #ifdef MODE32
2445 	      else if (state->is_v6
2446 		       && handle_v6_insn (state, instr))
2447 		break;
2448 #endif
2449 	      else
2450 		UNDEF_Test;
2451 
2452 	      break;
2453 
2454 	    case 0x13:		/* TEQP reg */
2455 #ifdef MODET
2456 	      if ((BITS (4, 11) & 0xF9) == 0x9)
2457 		/* LDR register offset, write-back, down, pre indexed.  */
2458 		LHPREDOWNWB ();
2459 	      /* Continue with remaining instruction decode.  */
2460 #endif
2461 	      if (DESTReg == 15)
2462 		{
2463 		  /* TEQP reg */
2464 #ifdef MODE32
2465 		  state->Cpsr = GETSPSR (state->Bank);
2466 		  ARMul_CPSRAltered (state);
2467 #else
2468 		  rhs = DPRegRHS;
2469 		  temp = LHS ^ rhs;
2470 		  SETR15PSR (temp);
2471 #endif
2472 		}
2473 	      else
2474 		{
2475 		  /* TEQ Reg.  */
2476 		  rhs = DPSRegRHS;
2477 		  dest = LHS ^ rhs;
2478 		  ARMul_NegZero (state, dest);
2479 		}
2480 	      break;
2481 
2482 	    case 0x14:		/* CMP reg and MRS SPSR and SWP byte.  */
2483 	      if (state->is_v5e)
2484 		{
2485 		  if (BIT (4) == 0 && BIT (7) == 1)
2486 		    {
2487 		      /* ElSegundo SMLALxy insn.  */
2488 		      ARMdword op1 = state->Reg[BITS (0, 3)];
2489 		      ARMdword op2 = state->Reg[BITS (8, 11)];
2490 		      ARMdword dest;
2491 
2492 		      if (BIT (5))
2493 			op1 >>= 16;
2494 		      if (BIT (6))
2495 			op2 >>= 16;
2496 		      op1 &= 0xFFFF;
2497 		      if (op1 & 0x8000)
2498 			op1 -= 65536;
2499 		      op2 &= 0xFFFF;
2500 		      if (op2 & 0x8000)
2501 			op2 -= 65536;
2502 
2503 		      dest = (ARMdword) state->Reg[BITS (16, 19)] << 32;
2504 		      dest |= state->Reg[BITS (12, 15)];
2505 		      dest += op1 * op2;
2506 		      state->Reg[BITS (12, 15)] = dest;
2507 		      state->Reg[BITS (16, 19)] = dest >> 32;
2508 		      break;
2509 		    }
2510 
2511 		  if (BITS (4, 11) == 5)
2512 		    {
2513 		      /* ElSegundo QDADD insn.  */
2514 		      ARMword op1 = state->Reg[BITS (0, 3)];
2515 		      ARMword op2 = state->Reg[BITS (16, 19)];
2516 		      ARMword op2d = op2 + op2;
2517 		      ARMword result;
2518 
2519 		      if (AddOverflow (op2, op2, op2d))
2520 			{
2521 			  SETS;
2522 			  op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
2523 			}
2524 
2525 		      result = op1 + op2d;
2526 		      if (AddOverflow (op1, op2d, result))
2527 			{
2528 			  SETS;
2529 			  result = POS (result) ? 0x80000000 : 0x7fffffff;
2530 			}
2531 
2532 		      state->Reg[BITS (12, 15)] = result;
2533 		      break;
2534 		    }
2535 		}
2536 #ifdef MODET
2537 	      if (BITS (4, 7) == 0xB)
2538 		{
2539 		  /* STRH immediate offset, no write-back, down, pre indexed.  */
2540 		  SHPREDOWN ();
2541 		  break;
2542 		}
2543 	      if (BITS (4, 7) == 0xD)
2544 		{
2545 		  Handle_Load_Double (state, instr);
2546 		  break;
2547 		}
2548 	      if (BITS (4, 7) == 0xF)
2549 		{
2550 		  Handle_Store_Double (state, instr);
2551 		  break;
2552 		}
2553 #endif
2554 	      if (BITS (4, 11) == 9)
2555 		{
2556 		  /* SWP */
2557 		  UNDEF_SWPPC;
2558 		  temp = LHS;
2559 		  BUSUSEDINCPCS;
2560 #ifndef MODE32
2561 		  if (VECTORACCESS (temp) || ADDREXCEPT (temp))
2562 		    {
2563 		      INTERNALABORT (temp);
2564 		      (void) ARMul_LoadByte (state, temp);
2565 		      (void) ARMul_LoadByte (state, temp);
2566 		    }
2567 		  else
2568 #endif
2569 		    DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
2570 		  if (state->abortSig || state->Aborted)
2571 		    TAKEABORT;
2572 		}
2573 	      else if ((BITS (0, 11) == 0) && (LHSReg == 15))
2574 		{
2575 		  /* MRS SPSR */
2576 		  UNDEF_MRSPC;
2577 		  DEST = GETSPSR (state->Bank);
2578 		}
2579 #ifdef MODE32
2580 	      else if (state->is_v6
2581 		       && handle_v6_insn (state, instr))
2582 		break;
2583 #endif
2584 	      else
2585 		UNDEF_Test;
2586 
2587 	      break;
2588 
2589 	    case 0x15:		/* CMPP reg.  */
2590 #ifdef MODET
2591 	      if ((BITS (4, 7) & 0x9) == 0x9)
2592 		/* LDR immediate offset, no write-back, down, pre indexed.  */
2593 		LHPREDOWN ();
2594 	      /* Continue with remaining instruction decode.  */
2595 #endif
2596 	      if (DESTReg == 15)
2597 		{
2598 		  /* CMPP reg.  */
2599 #ifdef MODE32
2600 		  state->Cpsr = GETSPSR (state->Bank);
2601 		  ARMul_CPSRAltered (state);
2602 #else
2603 		  rhs = DPRegRHS;
2604 		  temp = LHS - rhs;
2605 		  SETR15PSR (temp);
2606 #endif
2607 		}
2608 	      else
2609 		{
2610 		  /* CMP reg.  */
2611 		  lhs = LHS;
2612 		  rhs = DPRegRHS;
2613 		  dest = lhs - rhs;
2614 		  ARMul_NegZero (state, dest);
2615 		  if ((lhs >= rhs) || ((rhs | lhs) >> 31))
2616 		    {
2617 		      ARMul_SubCarry (state, lhs, rhs, dest);
2618 		      ARMul_SubOverflow (state, lhs, rhs, dest);
2619 		    }
2620 		  else
2621 		    {
2622 		      CLEARC;
2623 		      CLEARV;
2624 		    }
2625 		}
2626 	      break;
2627 
2628 	    case 0x16:		/* CMN reg and MSR reg to SPSR */
2629 	      if (state->is_v5e)
2630 		{
2631 		  if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0)
2632 		    {
2633 		      /* ElSegundo SMULxy insn.  */
2634 		      ARMword op1 = state->Reg[BITS (0, 3)];
2635 		      ARMword op2 = state->Reg[BITS (8, 11)];
2636 
2637 		      if (BIT (5))
2638 			op1 >>= 16;
2639 		      if (BIT (6))
2640 			op2 >>= 16;
2641 		      op1 &= 0xFFFF;
2642 		      op2 &= 0xFFFF;
2643 		      if (op1 & 0x8000)
2644 			op1 -= 65536;
2645 		      if (op2 & 0x8000)
2646 			op2 -= 65536;
2647 
2648 		      state->Reg[BITS (16, 19)] = op1 * op2;
2649 		      break;
2650 		    }
2651 
2652 		  if (BITS (4, 11) == 5)
2653 		    {
2654 		      /* ElSegundo QDSUB insn.  */
2655 		      ARMword op1 = state->Reg[BITS (0, 3)];
2656 		      ARMword op2 = state->Reg[BITS (16, 19)];
2657 		      ARMword op2d = op2 + op2;
2658 		      ARMword result;
2659 
2660 		      if (AddOverflow (op2, op2, op2d))
2661 			{
2662 			  SETS;
2663 			  op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
2664 			}
2665 
2666 		      result = op1 - op2d;
2667 		      if (SubOverflow (op1, op2d, result))
2668 			{
2669 			  SETS;
2670 			  result = POS (result) ? 0x80000000 : 0x7fffffff;
2671 			}
2672 
2673 		      state->Reg[BITS (12, 15)] = result;
2674 		      break;
2675 		    }
2676 		}
2677 
2678 	      if (state->is_v5)
2679 		{
2680 		  if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF)
2681 		    {
2682 		      /* ARM5 CLZ insn.  */
2683 		      ARMword op1 = state->Reg[BITS (0, 3)];
2684 		      int result = 32;
2685 
2686 		      if (op1)
2687 			for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
2688 			  result++;
2689 
2690 		      state->Reg[BITS (12, 15)] = result;
2691 		      break;
2692 		    }
2693 		}
2694 #ifdef MODET
2695 	      if (BITS (4, 7) == 0xB)
2696 		{
2697 		  /* STRH immediate offset, write-back, down, pre indexed.  */
2698 		  SHPREDOWNWB ();
2699 		  break;
2700 		}
2701 	      if (BITS (4, 7) == 0xD)
2702 		{
2703 		  Handle_Load_Double (state, instr);
2704 		  break;
2705 		}
2706 	      if (BITS (4, 7) == 0xF)
2707 		{
2708 		  Handle_Store_Double (state, instr);
2709 		  break;
2710 		}
2711 #endif
2712 	      if (DESTReg == 15)
2713 		{
2714 		  /* MSR */
2715 		  UNDEF_MSRPC;
2716 		  ARMul_FixSPSR (state, instr, DPRegRHS);
2717 		}
2718 	      else
2719 		{
2720 #ifdef MODE32
2721 		  if (state->is_v6
2722 		      && handle_v6_insn (state, instr))
2723 		    break;
2724 #endif
2725 		  UNDEF_Test;
2726 		}
2727 	      break;
2728 
2729 	    case 0x17:		/* CMNP reg */
2730 #ifdef MODET
2731 	      if ((BITS (4, 7) & 0x9) == 0x9)
2732 		/* LDR immediate offset, write-back, down, pre indexed.  */
2733 		LHPREDOWNWB ();
2734 	      /* Continue with remaining instruction decoding.  */
2735 #endif
2736 	      if (DESTReg == 15)
2737 		{
2738 #ifdef MODE32
2739 		  state->Cpsr = GETSPSR (state->Bank);
2740 		  ARMul_CPSRAltered (state);
2741 #else
2742 		  rhs = DPRegRHS;
2743 		  temp = LHS + rhs;
2744 		  SETR15PSR (temp);
2745 #endif
2746 		  break;
2747 		}
2748 	      else
2749 		{
2750 		  /* CMN reg.  */
2751 		  lhs = LHS;
2752 		  rhs = DPRegRHS;
2753 		  dest = lhs + rhs;
2754 		  ASSIGNZ (dest == 0);
2755 		  if ((lhs | rhs) >> 30)
2756 		    {
2757 		      /* Possible C,V,N to set.  */
2758 		      ASSIGNN (NEG (dest));
2759 		      ARMul_AddCarry (state, lhs, rhs, dest);
2760 		      ARMul_AddOverflow (state, lhs, rhs, dest);
2761 		    }
2762 		  else
2763 		    {
2764 		      CLEARN;
2765 		      CLEARC;
2766 		      CLEARV;
2767 		    }
2768 		}
2769 	      break;
2770 
2771 	    case 0x18:		/* ORR reg */
2772 #ifdef MODET
2773 	      if (BITS (4, 11) == 0xB)
2774 		{
2775 		  /* STRH register offset, no write-back, up, pre indexed.  */
2776 		  SHPREUP ();
2777 		  break;
2778 		}
2779 	      if (BITS (4, 7) == 0xD)
2780 		{
2781 		  Handle_Load_Double (state, instr);
2782 		  break;
2783 		}
2784 	      if (BITS (4, 7) == 0xF)
2785 		{
2786 		  Handle_Store_Double (state, instr);
2787 		  break;
2788 		}
2789 #endif
2790 	      rhs = DPRegRHS;
2791 	      dest = LHS | rhs;
2792 	      WRITEDEST (dest);
2793 	      break;
2794 
2795 	    case 0x19:		/* ORRS reg */
2796 #ifdef MODET
2797 	      if ((BITS (4, 11) & 0xF9) == 0x9)
2798 		/* LDR register offset, no write-back, up, pre indexed.  */
2799 		LHPREUP ();
2800 	      /* Continue with remaining instruction decoding.  */
2801 #endif
2802 	      rhs = DPSRegRHS;
2803 	      dest = LHS | rhs;
2804 	      WRITESDEST (dest);
2805 	      break;
2806 
2807 	    case 0x1a:		/* MOV reg */
2808 #ifdef MODET
2809 	      if (BITS (4, 11) == 0xB)
2810 		{
2811 		  /* STRH register offset, write-back, up, pre indexed.  */
2812 		  SHPREUPWB ();
2813 		  break;
2814 		}
2815 	      if (BITS (4, 7) == 0xD)
2816 		{
2817 		  Handle_Load_Double (state, instr);
2818 		  break;
2819 		}
2820 	      if (BITS (4, 7) == 0xF)
2821 		{
2822 		  Handle_Store_Double (state, instr);
2823 		  break;
2824 		}
2825 #endif
2826 	      dest = DPRegRHS;
2827 	      WRITEDEST (dest);
2828 	      break;
2829 
2830 	    case 0x1b:		/* MOVS reg */
2831 #ifdef MODET
2832 	      if ((BITS (4, 11) & 0xF9) == 0x9)
2833 		/* LDR register offset, write-back, up, pre indexed.  */
2834 		LHPREUPWB ();
2835 	      /* Continue with remaining instruction decoding.  */
2836 #endif
2837 	      dest = DPSRegRHS;
2838 	      WRITESDEST (dest);
2839 	      break;
2840 
2841 	    case 0x1c:		/* BIC reg */
2842 #ifdef MODET
2843 	      if (BITS (4, 7) == 0xB)
2844 		{
2845 		  /* STRH immediate offset, no write-back, up, pre indexed.  */
2846 		  SHPREUP ();
2847 		  break;
2848 		}
2849 	      if (BITS (4, 7) == 0xD)
2850 		{
2851 		  Handle_Load_Double (state, instr);
2852 		  break;
2853 		}
2854 	      else if (BITS (4, 7) == 0xF)
2855 		{
2856 		  Handle_Store_Double (state, instr);
2857 		  break;
2858 		}
2859 #endif
2860 	      rhs = DPRegRHS;
2861 	      dest = LHS & ~rhs;
2862 	      WRITEDEST (dest);
2863 	      break;
2864 
2865 	    case 0x1d:		/* BICS reg */
2866 #ifdef MODET
2867 	      if ((BITS (4, 7) & 0x9) == 0x9)
2868 		/* LDR immediate offset, no write-back, up, pre indexed.  */
2869 		LHPREUP ();
2870 	      /* Continue with instruction decoding.  */
2871 #endif
2872 	      rhs = DPSRegRHS;
2873 	      dest = LHS & ~rhs;
2874 	      WRITESDEST (dest);
2875 	      break;
2876 
2877 	    case 0x1e:		/* MVN reg */
2878 #ifdef MODET
2879 	      if (BITS (4, 7) == 0xB)
2880 		{
2881 		  /* STRH immediate offset, write-back, up, pre indexed.  */
2882 		  SHPREUPWB ();
2883 		  break;
2884 		}
2885 	      if (BITS (4, 7) == 0xD)
2886 		{
2887 		  Handle_Load_Double (state, instr);
2888 		  break;
2889 		}
2890 	      if (BITS (4, 7) == 0xF)
2891 		{
2892 		  Handle_Store_Double (state, instr);
2893 		  break;
2894 		}
2895 #endif
2896 	      dest = ~DPRegRHS;
2897 	      WRITEDEST (dest);
2898 	      break;
2899 
2900 	    case 0x1f:		/* MVNS reg */
2901 #ifdef MODET
2902 	      if ((BITS (4, 7) & 0x9) == 0x9)
2903 		/* LDR immediate offset, write-back, up, pre indexed.  */
2904 		LHPREUPWB ();
2905 	      /* Continue instruction decoding.  */
2906 #endif
2907 	      dest = ~DPSRegRHS;
2908 	      WRITESDEST (dest);
2909 	      break;
2910 
2911 
2912 	      /* Data Processing Immediate RHS Instructions.  */
2913 
2914 	    case 0x20:		/* AND immed */
2915 	      dest = LHS & DPImmRHS;
2916 	      WRITEDEST (dest);
2917 	      break;
2918 
2919 	    case 0x21:		/* ANDS immed */
2920 	      DPSImmRHS;
2921 	      dest = LHS & rhs;
2922 	      WRITESDEST (dest);
2923 	      break;
2924 
2925 	    case 0x22:		/* EOR immed */
2926 	      dest = LHS ^ DPImmRHS;
2927 	      WRITEDEST (dest);
2928 	      break;
2929 
2930 	    case 0x23:		/* EORS immed */
2931 	      DPSImmRHS;
2932 	      dest = LHS ^ rhs;
2933 	      WRITESDEST (dest);
2934 	      break;
2935 
2936 	    case 0x24:		/* SUB immed */
2937 	      dest = LHS - DPImmRHS;
2938 	      WRITEDEST (dest);
2939 	      break;
2940 
2941 	    case 0x25:		/* SUBS immed */
2942 	      lhs = LHS;
2943 	      rhs = DPImmRHS;
2944 	      dest = lhs - rhs;
2945 
2946 	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))
2947 		{
2948 		  ARMul_SubCarry (state, lhs, rhs, dest);
2949 		  ARMul_SubOverflow (state, lhs, rhs, dest);
2950 		}
2951 	      else
2952 		{
2953 		  CLEARC;
2954 		  CLEARV;
2955 		}
2956 	      WRITESDEST (dest);
2957 	      break;
2958 
2959 	    case 0x26:		/* RSB immed */
2960 	      dest = DPImmRHS - LHS;
2961 	      WRITEDEST (dest);
2962 	      break;
2963 
2964 	    case 0x27:		/* RSBS immed */
2965 	      lhs = LHS;
2966 	      rhs = DPImmRHS;
2967 	      dest = rhs - lhs;
2968 
2969 	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))
2970 		{
2971 		  ARMul_SubCarry (state, rhs, lhs, dest);
2972 		  ARMul_SubOverflow (state, rhs, lhs, dest);
2973 		}
2974 	      else
2975 		{
2976 		  CLEARC;
2977 		  CLEARV;
2978 		}
2979 	      WRITESDEST (dest);
2980 	      break;
2981 
2982 	    case 0x28:		/* ADD immed */
2983 	      dest = LHS + DPImmRHS;
2984 	      WRITEDEST (dest);
2985 	      break;
2986 
2987 	    case 0x29:		/* ADDS immed */
2988 	      lhs = LHS;
2989 	      rhs = DPImmRHS;
2990 	      dest = lhs + rhs;
2991 	      ASSIGNZ (dest == 0);
2992 
2993 	      if ((lhs | rhs) >> 30)
2994 		{
2995 		  /* Possible C,V,N to set.  */
2996 		  ASSIGNN (NEG (dest));
2997 		  ARMul_AddCarry (state, lhs, rhs, dest);
2998 		  ARMul_AddOverflow (state, lhs, rhs, dest);
2999 		}
3000 	      else
3001 		{
3002 		  CLEARN;
3003 		  CLEARC;
3004 		  CLEARV;
3005 		}
3006 	      WRITESDEST (dest);
3007 	      break;
3008 
3009 	    case 0x2a:		/* ADC immed */
3010 	      dest = LHS + DPImmRHS + CFLAG;
3011 	      WRITEDEST (dest);
3012 	      break;
3013 
3014 	    case 0x2b:		/* ADCS immed */
3015 	      lhs = LHS;
3016 	      rhs = DPImmRHS;
3017 	      dest = lhs + rhs + CFLAG;
3018 	      ASSIGNZ (dest == 0);
3019 	      if ((lhs | rhs) >> 30)
3020 		{
3021 		  /* Possible C,V,N to set.  */
3022 		  ASSIGNN (NEG (dest));
3023 		  ARMul_AddCarry (state, lhs, rhs, dest);
3024 		  ARMul_AddOverflow (state, lhs, rhs, dest);
3025 		}
3026 	      else
3027 		{
3028 		  CLEARN;
3029 		  CLEARC;
3030 		  CLEARV;
3031 		}
3032 	      WRITESDEST (dest);
3033 	      break;
3034 
3035 	    case 0x2c:		/* SBC immed */
3036 	      dest = LHS - DPImmRHS - !CFLAG;
3037 	      WRITEDEST (dest);
3038 	      break;
3039 
3040 	    case 0x2d:		/* SBCS immed */
3041 	      lhs = LHS;
3042 	      rhs = DPImmRHS;
3043 	      dest = lhs - rhs - !CFLAG;
3044 	      if ((lhs >= rhs) || ((rhs | lhs) >> 31))
3045 		{
3046 		  ARMul_SubCarry (state, lhs, rhs, dest);
3047 		  ARMul_SubOverflow (state, lhs, rhs, dest);
3048 		}
3049 	      else
3050 		{
3051 		  CLEARC;
3052 		  CLEARV;
3053 		}
3054 	      WRITESDEST (dest);
3055 	      break;
3056 
3057 	    case 0x2e:		/* RSC immed */
3058 	      dest = DPImmRHS - LHS - !CFLAG;
3059 	      WRITEDEST (dest);
3060 	      break;
3061 
3062 	    case 0x2f:		/* RSCS immed */
3063 	      lhs = LHS;
3064 	      rhs = DPImmRHS;
3065 	      dest = rhs - lhs - !CFLAG;
3066 	      if ((rhs >= lhs) || ((rhs | lhs) >> 31))
3067 		{
3068 		  ARMul_SubCarry (state, rhs, lhs, dest);
3069 		  ARMul_SubOverflow (state, rhs, lhs, dest);
3070 		}
3071 	      else
3072 		{
3073 		  CLEARC;
3074 		  CLEARV;
3075 		}
3076 	      WRITESDEST (dest);
3077 	      break;
3078 
3079 	    case 0x30:		/* MOVW immed */
3080 #ifdef MODE32
3081 	      if (state->is_v6
3082 		  && handle_v6_insn (state, instr))
3083 		break;
3084 #endif
3085 	      dest = BITS (0, 11);
3086 	      dest |= (BITS (16, 19) << 12);
3087 	      WRITEDEST (dest);
3088 	      break;
3089 
3090 	    case 0x31:		/* TSTP immed */
3091 	      if (DESTReg == 15)
3092 		{
3093 		  /* TSTP immed.  */
3094 #ifdef MODE32
3095 		  state->Cpsr = GETSPSR (state->Bank);
3096 		  ARMul_CPSRAltered (state);
3097 #else
3098 		  temp = LHS & DPImmRHS;
3099 		  SETR15PSR (temp);
3100 #endif
3101 		}
3102 	      else
3103 		{
3104 		  /* TST immed.  */
3105 		  DPSImmRHS;
3106 		  dest = LHS & rhs;
3107 		  ARMul_NegZero (state, dest);
3108 		}
3109 	      break;
3110 
3111 	    case 0x32:		/* TEQ immed and MSR immed to CPSR */
3112 	      if (DESTReg == 15)
3113 		/* MSR immed to CPSR.  */
3114 		ARMul_FixCPSR (state, instr, DPImmRHS);
3115 #ifdef MODE32
3116 	      else if (state->is_v6
3117 		       && handle_v6_insn (state, instr))
3118 		break;
3119 #endif
3120 	      else
3121 		UNDEF_Test;
3122 	      break;
3123 
3124 	    case 0x33:		/* TEQP immed */
3125 	      if (DESTReg == 15)
3126 		{
3127 		  /* TEQP immed.  */
3128 #ifdef MODE32
3129 		  state->Cpsr = GETSPSR (state->Bank);
3130 		  ARMul_CPSRAltered (state);
3131 #else
3132 		  temp = LHS ^ DPImmRHS;
3133 		  SETR15PSR (temp);
3134 #endif
3135 		}
3136 	      else
3137 		{
3138 		  DPSImmRHS;	/* TEQ immed */
3139 		  dest = LHS ^ rhs;
3140 		  ARMul_NegZero (state, dest);
3141 		}
3142 	      break;
3143 
3144 	    case 0x34:		/* MOVT immed */
3145 #ifdef MODE32
3146 	      if (state->is_v6
3147 		  && handle_v6_insn (state, instr))
3148 		break;
3149 #endif
3150 	      DEST &= 0xFFFF;
3151 	      dest  = BITS (0, 11);
3152 	      dest |= (BITS (16, 19) << 12);
3153 	      DEST |= (dest << 16);
3154 	      break;
3155 
3156 	    case 0x35:		/* CMPP immed */
3157 	      if (DESTReg == 15)
3158 		{
3159 		  /* CMPP immed.  */
3160 #ifdef MODE32
3161 		  state->Cpsr = GETSPSR (state->Bank);
3162 		  ARMul_CPSRAltered (state);
3163 #else
3164 		  temp = LHS - DPImmRHS;
3165 		  SETR15PSR (temp);
3166 #endif
3167 		  break;
3168 		}
3169 	      else
3170 		{
3171 		  /* CMP immed.  */
3172 		  lhs = LHS;
3173 		  rhs = DPImmRHS;
3174 		  dest = lhs - rhs;
3175 		  ARMul_NegZero (state, dest);
3176 
3177 		  if ((lhs >= rhs) || ((rhs | lhs) >> 31))
3178 		    {
3179 		      ARMul_SubCarry (state, lhs, rhs, dest);
3180 		      ARMul_SubOverflow (state, lhs, rhs, dest);
3181 		    }
3182 		  else
3183 		    {
3184 		      CLEARC;
3185 		      CLEARV;
3186 		    }
3187 		}
3188 	      break;
3189 
3190 	    case 0x36:		/* CMN immed and MSR immed to SPSR */
3191 	      if (DESTReg == 15)
3192 		ARMul_FixSPSR (state, instr, DPImmRHS);
3193 #ifdef MODE32
3194 	      else if (state->is_v6
3195 		       && handle_v6_insn (state, instr))
3196 		break;
3197 #endif
3198 	      else
3199 		UNDEF_Test;
3200 	      break;
3201 
3202 	    case 0x37:		/* CMNP immed.  */
3203 	      if (DESTReg == 15)
3204 		{
3205 		  /* CMNP immed.  */
3206 #ifdef MODE32
3207 		  state->Cpsr = GETSPSR (state->Bank);
3208 		  ARMul_CPSRAltered (state);
3209 #else
3210 		  temp = LHS + DPImmRHS;
3211 		  SETR15PSR (temp);
3212 #endif
3213 		  break;
3214 		}
3215 	      else
3216 		{
3217 		  /* CMN immed.  */
3218 		  lhs = LHS;
3219 		  rhs = DPImmRHS;
3220 		  dest = lhs + rhs;
3221 		  ASSIGNZ (dest == 0);
3222 		  if ((lhs | rhs) >> 30)
3223 		    {
3224 		      /* Possible C,V,N to set.  */
3225 		      ASSIGNN (NEG (dest));
3226 		      ARMul_AddCarry (state, lhs, rhs, dest);
3227 		      ARMul_AddOverflow (state, lhs, rhs, dest);
3228 		    }
3229 		  else
3230 		    {
3231 		      CLEARN;
3232 		      CLEARC;
3233 		      CLEARV;
3234 		    }
3235 		}
3236 	      break;
3237 
3238 	    case 0x38:		/* ORR immed.  */
3239 	      dest = LHS | DPImmRHS;
3240 	      WRITEDEST (dest);
3241 	      break;
3242 
3243 	    case 0x39:		/* ORRS immed.  */
3244 	      DPSImmRHS;
3245 	      dest = LHS | rhs;
3246 	      WRITESDEST (dest);
3247 	      break;
3248 
3249 	    case 0x3a:		/* MOV immed.  */
3250 	      dest = DPImmRHS;
3251 	      WRITEDEST (dest);
3252 	      break;
3253 
3254 	    case 0x3b:		/* MOVS immed.  */
3255 	      DPSImmRHS;
3256 	      WRITESDEST (rhs);
3257 	      break;
3258 
3259 	    case 0x3c:		/* BIC immed.  */
3260 	      dest = LHS & ~DPImmRHS;
3261 	      WRITEDEST (dest);
3262 	      break;
3263 
3264 	    case 0x3d:		/* BICS immed.  */
3265 	      DPSImmRHS;
3266 	      dest = LHS & ~rhs;
3267 	      WRITESDEST (dest);
3268 	      break;
3269 
3270 	    case 0x3e:		/* MVN immed.  */
3271 	      dest = ~DPImmRHS;
3272 	      WRITEDEST (dest);
3273 	      break;
3274 
3275 	    case 0x3f:		/* MVNS immed.  */
3276 	      DPSImmRHS;
3277 	      WRITESDEST (~rhs);
3278 	      break;
3279 
3280 
3281 	      /* Single Data Transfer Immediate RHS Instructions.  */
3282 
3283 	    case 0x40:		/* Store Word, No WriteBack, Post Dec, Immed.  */
3284 	      lhs = LHS;
3285 	      if (StoreWord (state, instr, lhs))
3286 		LSBase = lhs - LSImmRHS;
3287 	      break;
3288 
3289 	    case 0x41:		/* Load Word, No WriteBack, Post Dec, Immed.  */
3290 	      lhs = LHS;
3291 	      if (LoadWord (state, instr, lhs))
3292 		LSBase = lhs - LSImmRHS;
3293 	      break;
3294 
3295 	    case 0x42:		/* Store Word, WriteBack, Post Dec, Immed.  */
3296 	      UNDEF_LSRBaseEQDestWb;
3297 	      UNDEF_LSRPCBaseWb;
3298 	      lhs = LHS;
3299 	      temp = lhs - LSImmRHS;
3300 	      state->NtransSig = LOW;
3301 	      if (StoreWord (state, instr, lhs))
3302 		LSBase = temp;
3303 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3304 	      break;
3305 
3306 	    case 0x43:		/* Load Word, WriteBack, Post Dec, Immed.  */
3307 	      UNDEF_LSRBaseEQDestWb;
3308 	      UNDEF_LSRPCBaseWb;
3309 	      lhs = LHS;
3310 	      state->NtransSig = LOW;
3311 	      if (LoadWord (state, instr, lhs))
3312 		LSBase = lhs - LSImmRHS;
3313 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3314 	      break;
3315 
3316 	    case 0x44:		/* Store Byte, No WriteBack, Post Dec, Immed.  */
3317 	      lhs = LHS;
3318 	      if (StoreByte (state, instr, lhs))
3319 		LSBase = lhs - LSImmRHS;
3320 	      break;
3321 
3322 	    case 0x45:		/* Load Byte, No WriteBack, Post Dec, Immed.  */
3323 	      lhs = LHS;
3324 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
3325 		LSBase = lhs - LSImmRHS;
3326 	      break;
3327 
3328 	    case 0x46:		/* Store Byte, WriteBack, Post Dec, Immed.  */
3329 	      UNDEF_LSRBaseEQDestWb;
3330 	      UNDEF_LSRPCBaseWb;
3331 	      lhs = LHS;
3332 	      state->NtransSig = LOW;
3333 	      if (StoreByte (state, instr, lhs))
3334 		LSBase = lhs - LSImmRHS;
3335 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3336 	      break;
3337 
3338 	    case 0x47:		/* Load Byte, WriteBack, Post Dec, Immed.  */
3339 	      UNDEF_LSRBaseEQDestWb;
3340 	      UNDEF_LSRPCBaseWb;
3341 	      lhs = LHS;
3342 	      state->NtransSig = LOW;
3343 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
3344 		LSBase = lhs - LSImmRHS;
3345 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3346 	      break;
3347 
3348 	    case 0x48:		/* Store Word, No WriteBack, Post Inc, Immed.  */
3349 	      lhs = LHS;
3350 	      if (StoreWord (state, instr, lhs))
3351 		LSBase = lhs + LSImmRHS;
3352 	      break;
3353 
3354 	    case 0x49:		/* Load Word, No WriteBack, Post Inc, Immed.  */
3355 	      lhs = LHS;
3356 	      if (LoadWord (state, instr, lhs))
3357 		LSBase = lhs + LSImmRHS;
3358 	      break;
3359 
3360 	    case 0x4a:		/* Store Word, WriteBack, Post Inc, Immed.  */
3361 	      UNDEF_LSRBaseEQDestWb;
3362 	      UNDEF_LSRPCBaseWb;
3363 	      lhs = LHS;
3364 	      state->NtransSig = LOW;
3365 	      if (StoreWord (state, instr, lhs))
3366 		LSBase = lhs + LSImmRHS;
3367 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3368 	      break;
3369 
3370 	    case 0x4b:		/* Load Word, WriteBack, Post Inc, Immed.  */
3371 	      UNDEF_LSRBaseEQDestWb;
3372 	      UNDEF_LSRPCBaseWb;
3373 	      lhs = LHS;
3374 	      state->NtransSig = LOW;
3375 	      if (LoadWord (state, instr, lhs))
3376 		LSBase = lhs + LSImmRHS;
3377 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3378 	      break;
3379 
3380 	    case 0x4c:		/* Store Byte, No WriteBack, Post Inc, Immed.  */
3381 	      lhs = LHS;
3382 	      if (StoreByte (state, instr, lhs))
3383 		LSBase = lhs + LSImmRHS;
3384 	      break;
3385 
3386 	    case 0x4d:		/* Load Byte, No WriteBack, Post Inc, Immed.  */
3387 	      lhs = LHS;
3388 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
3389 		LSBase = lhs + LSImmRHS;
3390 	      break;
3391 
3392 	    case 0x4e:		/* Store Byte, WriteBack, Post Inc, Immed.  */
3393 	      UNDEF_LSRBaseEQDestWb;
3394 	      UNDEF_LSRPCBaseWb;
3395 	      lhs = LHS;
3396 	      state->NtransSig = LOW;
3397 	      if (StoreByte (state, instr, lhs))
3398 		LSBase = lhs + LSImmRHS;
3399 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3400 	      break;
3401 
3402 	    case 0x4f:		/* Load Byte, WriteBack, Post Inc, Immed.  */
3403 	      UNDEF_LSRBaseEQDestWb;
3404 	      UNDEF_LSRPCBaseWb;
3405 	      lhs = LHS;
3406 	      state->NtransSig = LOW;
3407 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
3408 		LSBase = lhs + LSImmRHS;
3409 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3410 	      break;
3411 
3412 
3413 	    case 0x50:		/* Store Word, No WriteBack, Pre Dec, Immed.  */
3414 	      (void) StoreWord (state, instr, LHS - LSImmRHS);
3415 	      break;
3416 
3417 	    case 0x51:		/* Load Word, No WriteBack, Pre Dec, Immed.  */
3418 	      (void) LoadWord (state, instr, LHS - LSImmRHS);
3419 	      break;
3420 
3421 	    case 0x52:		/* Store Word, WriteBack, Pre Dec, Immed.  */
3422 	      UNDEF_LSRBaseEQDestWb;
3423 	      UNDEF_LSRPCBaseWb;
3424 	      temp = LHS - LSImmRHS;
3425 	      if (StoreWord (state, instr, temp))
3426 		LSBase = temp;
3427 	      break;
3428 
3429 	    case 0x53:		/* Load Word, WriteBack, Pre Dec, Immed.  */
3430 	      UNDEF_LSRBaseEQDestWb;
3431 	      UNDEF_LSRPCBaseWb;
3432 	      temp = LHS - LSImmRHS;
3433 	      if (LoadWord (state, instr, temp))
3434 		LSBase = temp;
3435 	      break;
3436 
3437 	    case 0x54:		/* Store Byte, No WriteBack, Pre Dec, Immed.  */
3438 	      (void) StoreByte (state, instr, LHS - LSImmRHS);
3439 	      break;
3440 
3441 	    case 0x55:		/* Load Byte, No WriteBack, Pre Dec, Immed.  */
3442 	      (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED);
3443 	      break;
3444 
3445 	    case 0x56:		/* Store Byte, WriteBack, Pre Dec, Immed.  */
3446 	      UNDEF_LSRBaseEQDestWb;
3447 	      UNDEF_LSRPCBaseWb;
3448 	      temp = LHS - LSImmRHS;
3449 	      if (StoreByte (state, instr, temp))
3450 		LSBase = temp;
3451 	      break;
3452 
3453 	    case 0x57:		/* Load Byte, WriteBack, Pre Dec, Immed.  */
3454 	      UNDEF_LSRBaseEQDestWb;
3455 	      UNDEF_LSRPCBaseWb;
3456 	      temp = LHS - LSImmRHS;
3457 	      if (LoadByte (state, instr, temp, LUNSIGNED))
3458 		LSBase = temp;
3459 	      break;
3460 
3461 	    case 0x58:		/* Store Word, No WriteBack, Pre Inc, Immed.  */
3462 	      (void) StoreWord (state, instr, LHS + LSImmRHS);
3463 	      break;
3464 
3465 	    case 0x59:		/* Load Word, No WriteBack, Pre Inc, Immed.  */
3466 	      (void) LoadWord (state, instr, LHS + LSImmRHS);
3467 	      break;
3468 
3469 	    case 0x5a:		/* Store Word, WriteBack, Pre Inc, Immed.  */
3470 	      UNDEF_LSRBaseEQDestWb;
3471 	      UNDEF_LSRPCBaseWb;
3472 	      temp = LHS + LSImmRHS;
3473 	      if (StoreWord (state, instr, temp))
3474 		LSBase = temp;
3475 	      break;
3476 
3477 	    case 0x5b:		/* Load Word, WriteBack, Pre Inc, Immed.  */
3478 	      UNDEF_LSRBaseEQDestWb;
3479 	      UNDEF_LSRPCBaseWb;
3480 	      temp = LHS + LSImmRHS;
3481 	      if (LoadWord (state, instr, temp))
3482 		LSBase = temp;
3483 	      break;
3484 
3485 	    case 0x5c:		/* Store Byte, No WriteBack, Pre Inc, Immed.  */
3486 	      (void) StoreByte (state, instr, LHS + LSImmRHS);
3487 	      break;
3488 
3489 	    case 0x5d:		/* Load Byte, No WriteBack, Pre Inc, Immed.  */
3490 	      (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED);
3491 	      break;
3492 
3493 	    case 0x5e:		/* Store Byte, WriteBack, Pre Inc, Immed.  */
3494 	      UNDEF_LSRBaseEQDestWb;
3495 	      UNDEF_LSRPCBaseWb;
3496 	      temp = LHS + LSImmRHS;
3497 	      if (StoreByte (state, instr, temp))
3498 		LSBase = temp;
3499 	      break;
3500 
3501 	    case 0x5f:		/* Load Byte, WriteBack, Pre Inc, Immed.  */
3502 	      UNDEF_LSRBaseEQDestWb;
3503 	      UNDEF_LSRPCBaseWb;
3504 	      temp = LHS + LSImmRHS;
3505 	      if (LoadByte (state, instr, temp, LUNSIGNED))
3506 		LSBase = temp;
3507 	      break;
3508 
3509 
3510 	      /* Single Data Transfer Register RHS Instructions.  */
3511 
3512 	    case 0x60:		/* Store Word, No WriteBack, Post Dec, Reg.  */
3513 	      if (BIT (4))
3514 		{
3515 #ifdef MODE32
3516 		  if (state->is_v6
3517 		      && handle_v6_insn (state, instr))
3518 		    break;
3519 #endif
3520 		  ARMul_UndefInstr (state, instr);
3521 		  break;
3522 		}
3523 	      UNDEF_LSRBaseEQOffWb;
3524 	      UNDEF_LSRBaseEQDestWb;
3525 	      UNDEF_LSRPCBaseWb;
3526 	      UNDEF_LSRPCOffWb;
3527 	      lhs = LHS;
3528 	      if (StoreWord (state, instr, lhs))
3529 		LSBase = lhs - LSRegRHS;
3530 	      break;
3531 
3532 	    case 0x61:		/* Load Word, No WriteBack, Post Dec, Reg.  */
3533 	      if (BIT (4))
3534 		{
3535 #ifdef MODE32
3536 		  if (state->is_v6
3537 		      && handle_v6_insn (state, instr))
3538 		    break;
3539 #endif
3540 		  ARMul_UndefInstr (state, instr);
3541 		  break;
3542 		}
3543 	      UNDEF_LSRBaseEQOffWb;
3544 	      UNDEF_LSRBaseEQDestWb;
3545 	      UNDEF_LSRPCBaseWb;
3546 	      UNDEF_LSRPCOffWb;
3547 	      lhs = LHS;
3548 	      temp = lhs - LSRegRHS;
3549 	      if (LoadWord (state, instr, lhs))
3550 		LSBase = temp;
3551 	      break;
3552 
3553 	    case 0x62:		/* Store Word, WriteBack, Post Dec, Reg.  */
3554 	      if (BIT (4))
3555 		{
3556 #ifdef MODE32
3557 		  if (state->is_v6
3558 		      && handle_v6_insn (state, instr))
3559 		    break;
3560 #endif
3561 		  ARMul_UndefInstr (state, instr);
3562 		  break;
3563 		}
3564 	      UNDEF_LSRBaseEQOffWb;
3565 	      UNDEF_LSRBaseEQDestWb;
3566 	      UNDEF_LSRPCBaseWb;
3567 	      UNDEF_LSRPCOffWb;
3568 	      lhs = LHS;
3569 	      state->NtransSig = LOW;
3570 	      if (StoreWord (state, instr, lhs))
3571 		LSBase = lhs - LSRegRHS;
3572 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3573 	      break;
3574 
3575 	    case 0x63:		/* Load Word, WriteBack, Post Dec, Reg.  */
3576 	      if (BIT (4))
3577 		{
3578 #ifdef MODE32
3579 		  if (state->is_v6
3580 		      && handle_v6_insn (state, instr))
3581 		    break;
3582 #endif
3583 		  ARMul_UndefInstr (state, instr);
3584 		  break;
3585 		}
3586 	      UNDEF_LSRBaseEQOffWb;
3587 	      UNDEF_LSRBaseEQDestWb;
3588 	      UNDEF_LSRPCBaseWb;
3589 	      UNDEF_LSRPCOffWb;
3590 	      lhs = LHS;
3591 	      temp = lhs - LSRegRHS;
3592 	      state->NtransSig = LOW;
3593 	      if (LoadWord (state, instr, lhs))
3594 		LSBase = temp;
3595 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3596 	      break;
3597 
3598 	    case 0x64:		/* Store Byte, No WriteBack, Post Dec, Reg.  */
3599 	      if (BIT (4))
3600 		{
3601 #ifdef MODE32
3602 		  if (state->is_v6
3603 		      && handle_v6_insn (state, instr))
3604 		    break;
3605 #endif
3606 		  ARMul_UndefInstr (state, instr);
3607 		  break;
3608 		}
3609 	      UNDEF_LSRBaseEQOffWb;
3610 	      UNDEF_LSRBaseEQDestWb;
3611 	      UNDEF_LSRPCBaseWb;
3612 	      UNDEF_LSRPCOffWb;
3613 	      lhs = LHS;
3614 	      if (StoreByte (state, instr, lhs))
3615 		LSBase = lhs - LSRegRHS;
3616 	      break;
3617 
3618 	    case 0x65:		/* Load Byte, No WriteBack, Post Dec, Reg.  */
3619 	      if (BIT (4))
3620 		{
3621 #ifdef MODE32
3622 		  if (state->is_v6
3623 		      && handle_v6_insn (state, instr))
3624 		    break;
3625 #endif
3626 		  ARMul_UndefInstr (state, instr);
3627 		  break;
3628 		}
3629 	      UNDEF_LSRBaseEQOffWb;
3630 	      UNDEF_LSRBaseEQDestWb;
3631 	      UNDEF_LSRPCBaseWb;
3632 	      UNDEF_LSRPCOffWb;
3633 	      lhs = LHS;
3634 	      temp = lhs - LSRegRHS;
3635 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
3636 		LSBase = temp;
3637 	      break;
3638 
3639 	    case 0x66:		/* Store Byte, WriteBack, Post Dec, Reg.  */
3640 	      if (BIT (4))
3641 		{
3642 #ifdef MODE32
3643 		  if (state->is_v6
3644 		      && handle_v6_insn (state, instr))
3645 		    break;
3646 #endif
3647 		  ARMul_UndefInstr (state, instr);
3648 		  break;
3649 		}
3650 	      UNDEF_LSRBaseEQOffWb;
3651 	      UNDEF_LSRBaseEQDestWb;
3652 	      UNDEF_LSRPCBaseWb;
3653 	      UNDEF_LSRPCOffWb;
3654 	      lhs = LHS;
3655 	      state->NtransSig = LOW;
3656 	      if (StoreByte (state, instr, lhs))
3657 		LSBase = lhs - LSRegRHS;
3658 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3659 	      break;
3660 
3661 	    case 0x67:		/* Load Byte, WriteBack, Post Dec, Reg.  */
3662 	      if (BIT (4))
3663 		{
3664 #ifdef MODE32
3665 		  if (state->is_v6
3666 		      && handle_v6_insn (state, instr))
3667 		    break;
3668 #endif
3669 		  ARMul_UndefInstr (state, instr);
3670 		  break;
3671 		}
3672 	      UNDEF_LSRBaseEQOffWb;
3673 	      UNDEF_LSRBaseEQDestWb;
3674 	      UNDEF_LSRPCBaseWb;
3675 	      UNDEF_LSRPCOffWb;
3676 	      lhs = LHS;
3677 	      temp = lhs - LSRegRHS;
3678 	      state->NtransSig = LOW;
3679 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
3680 		LSBase = temp;
3681 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3682 	      break;
3683 
3684 	    case 0x68:		/* Store Word, No WriteBack, Post Inc, Reg.  */
3685 	      if (BIT (4))
3686 		{
3687 #ifdef MODE32
3688 		  if (state->is_v6
3689 		      && handle_v6_insn (state, instr))
3690 		    break;
3691 #endif
3692 		  ARMul_UndefInstr (state, instr);
3693 		  break;
3694 		}
3695 	      UNDEF_LSRBaseEQOffWb;
3696 	      UNDEF_LSRBaseEQDestWb;
3697 	      UNDEF_LSRPCBaseWb;
3698 	      UNDEF_LSRPCOffWb;
3699 	      lhs = LHS;
3700 	      if (StoreWord (state, instr, lhs))
3701 		LSBase = lhs + LSRegRHS;
3702 	      break;
3703 
3704 	    case 0x69:		/* Load Word, No WriteBack, Post Inc, Reg.  */
3705 	      if (BIT (4))
3706 		{
3707 #ifdef MODE32
3708 		  if (state->is_v6
3709 		      && handle_v6_insn (state, instr))
3710 		    break;
3711 #endif
3712 		  ARMul_UndefInstr (state, instr);
3713 		  break;
3714 		}
3715 	      UNDEF_LSRBaseEQOffWb;
3716 	      UNDEF_LSRBaseEQDestWb;
3717 	      UNDEF_LSRPCBaseWb;
3718 	      UNDEF_LSRPCOffWb;
3719 	      lhs = LHS;
3720 	      temp = lhs + LSRegRHS;
3721 	      if (LoadWord (state, instr, lhs))
3722 		LSBase = temp;
3723 	      break;
3724 
3725 	    case 0x6a:		/* Store Word, WriteBack, Post Inc, Reg.  */
3726 	      if (BIT (4))
3727 		{
3728 #ifdef MODE32
3729 		  if (state->is_v6
3730 		      && handle_v6_insn (state, instr))
3731 		    break;
3732 #endif
3733 		  ARMul_UndefInstr (state, instr);
3734 		  break;
3735 		}
3736 	      UNDEF_LSRBaseEQOffWb;
3737 	      UNDEF_LSRBaseEQDestWb;
3738 	      UNDEF_LSRPCBaseWb;
3739 	      UNDEF_LSRPCOffWb;
3740 	      lhs = LHS;
3741 	      state->NtransSig = LOW;
3742 	      if (StoreWord (state, instr, lhs))
3743 		LSBase = lhs + LSRegRHS;
3744 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3745 	      break;
3746 
3747 	    case 0x6b:		/* Load Word, WriteBack, Post Inc, Reg.  */
3748 	      if (BIT (4))
3749 		{
3750 #ifdef MODE32
3751 		  if (state->is_v6
3752 		      && handle_v6_insn (state, instr))
3753 		    break;
3754 #endif
3755 		  ARMul_UndefInstr (state, instr);
3756 		  break;
3757 		}
3758 	      UNDEF_LSRBaseEQOffWb;
3759 	      UNDEF_LSRBaseEQDestWb;
3760 	      UNDEF_LSRPCBaseWb;
3761 	      UNDEF_LSRPCOffWb;
3762 	      lhs = LHS;
3763 	      temp = lhs + LSRegRHS;
3764 	      state->NtransSig = LOW;
3765 	      if (LoadWord (state, instr, lhs))
3766 		LSBase = temp;
3767 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3768 	      break;
3769 
3770 	    case 0x6c:		/* Store Byte, No WriteBack, Post Inc, Reg.  */
3771 	      if (BIT (4))
3772 		{
3773 #ifdef MODE32
3774 		  if (state->is_v6
3775 		      && handle_v6_insn (state, instr))
3776 		    break;
3777 #endif
3778 		  ARMul_UndefInstr (state, instr);
3779 		  break;
3780 		}
3781 	      UNDEF_LSRBaseEQOffWb;
3782 	      UNDEF_LSRBaseEQDestWb;
3783 	      UNDEF_LSRPCBaseWb;
3784 	      UNDEF_LSRPCOffWb;
3785 	      lhs = LHS;
3786 	      if (StoreByte (state, instr, lhs))
3787 		LSBase = lhs + LSRegRHS;
3788 	      break;
3789 
3790 	    case 0x6d:		/* Load Byte, No WriteBack, Post Inc, Reg.  */
3791 	      if (BIT (4))
3792 		{
3793 #ifdef MODE32
3794 		  if (state->is_v6
3795 		      && handle_v6_insn (state, instr))
3796 		    break;
3797 #endif
3798 		  ARMul_UndefInstr (state, instr);
3799 		  break;
3800 		}
3801 	      UNDEF_LSRBaseEQOffWb;
3802 	      UNDEF_LSRBaseEQDestWb;
3803 	      UNDEF_LSRPCBaseWb;
3804 	      UNDEF_LSRPCOffWb;
3805 	      lhs = LHS;
3806 	      temp = lhs + LSRegRHS;
3807 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
3808 		LSBase = temp;
3809 	      break;
3810 
3811 	    case 0x6e:		/* Store Byte, WriteBack, Post Inc, Reg.  */
3812 	      if (BIT (4))
3813 		{
3814 #ifdef MODE32
3815 		  if (state->is_v6
3816 		      && handle_v6_insn (state, instr))
3817 		    break;
3818 #endif
3819 		  ARMul_UndefInstr (state, instr);
3820 		  break;
3821 		}
3822 	      UNDEF_LSRBaseEQOffWb;
3823 	      UNDEF_LSRBaseEQDestWb;
3824 	      UNDEF_LSRPCBaseWb;
3825 	      UNDEF_LSRPCOffWb;
3826 	      lhs = LHS;
3827 	      state->NtransSig = LOW;
3828 	      if (StoreByte (state, instr, lhs))
3829 		LSBase = lhs + LSRegRHS;
3830 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3831 	      break;
3832 
3833 	    case 0x6f:		/* Load Byte, WriteBack, Post Inc, Reg.  */
3834 	      if (BIT (4))
3835 		{
3836 #ifdef MODE32
3837 		  if (state->is_v6
3838 		      && handle_v6_insn (state, instr))
3839 		    break;
3840 #endif
3841 		  ARMul_UndefInstr (state, instr);
3842 		  break;
3843 		}
3844 	      UNDEF_LSRBaseEQOffWb;
3845 	      UNDEF_LSRBaseEQDestWb;
3846 	      UNDEF_LSRPCBaseWb;
3847 	      UNDEF_LSRPCOffWb;
3848 	      lhs = LHS;
3849 	      temp = lhs + LSRegRHS;
3850 	      state->NtransSig = LOW;
3851 	      if (LoadByte (state, instr, lhs, LUNSIGNED))
3852 		LSBase = temp;
3853 	      state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3854 	      break;
3855 
3856 
3857 	    case 0x70:		/* Store Word, No WriteBack, Pre Dec, Reg.  */
3858 	      if (BIT (4))
3859 		{
3860 #ifdef MODE32
3861 		  if (state->is_v6
3862 		      && handle_v6_insn (state, instr))
3863 		    break;
3864 #endif
3865 		  ARMul_UndefInstr (state, instr);
3866 		  break;
3867 		}
3868 	      (void) StoreWord (state, instr, LHS - LSRegRHS);
3869 	      break;
3870 
3871 	    case 0x71:		/* Load Word, No WriteBack, Pre Dec, Reg.  */
3872 	      if (BIT (4))
3873 		{
3874 #ifdef MODE32
3875 		  if (state->is_v6
3876 		      && handle_v6_insn (state, instr))
3877 		    break;
3878 #endif
3879 		  ARMul_UndefInstr (state, instr);
3880 		  break;
3881 		}
3882 	      (void) LoadWord (state, instr, LHS - LSRegRHS);
3883 	      break;
3884 
3885 	    case 0x72:		/* Store Word, WriteBack, Pre Dec, Reg.  */
3886 	      if (BIT (4))
3887 		{
3888 #ifdef MODE32
3889 		  if (state->is_v6
3890 		      && handle_v6_insn (state, instr))
3891 		    break;
3892 #endif
3893 		  ARMul_UndefInstr (state, instr);
3894 		  break;
3895 		}
3896 	      UNDEF_LSRBaseEQOffWb;
3897 	      UNDEF_LSRBaseEQDestWb;
3898 	      UNDEF_LSRPCBaseWb;
3899 	      UNDEF_LSRPCOffWb;
3900 	      temp = LHS - LSRegRHS;
3901 	      if (StoreWord (state, instr, temp))
3902 		LSBase = temp;
3903 	      break;
3904 
3905 	    case 0x73:		/* Load Word, WriteBack, Pre Dec, Reg.  */
3906 	      if (BIT (4))
3907 		{
3908 #ifdef MODE32
3909 		  if (state->is_v6
3910 		      && handle_v6_insn (state, instr))
3911 		    break;
3912 #endif
3913 		  ARMul_UndefInstr (state, instr);
3914 		  break;
3915 		}
3916 	      UNDEF_LSRBaseEQOffWb;
3917 	      UNDEF_LSRBaseEQDestWb;
3918 	      UNDEF_LSRPCBaseWb;
3919 	      UNDEF_LSRPCOffWb;
3920 	      temp = LHS - LSRegRHS;
3921 	      if (LoadWord (state, instr, temp))
3922 		LSBase = temp;
3923 	      break;
3924 
3925 	    case 0x74:		/* Store Byte, No WriteBack, Pre Dec, Reg.  */
3926 	      if (BIT (4))
3927 		{
3928 #ifdef MODE32
3929 		  if (state->is_v6
3930 		      && handle_v6_insn (state, instr))
3931 		    break;
3932 #endif
3933 		  ARMul_UndefInstr (state, instr);
3934 		  break;
3935 		}
3936 	      (void) StoreByte (state, instr, LHS - LSRegRHS);
3937 	      break;
3938 
3939 	    case 0x75:		/* Load Byte, No WriteBack, Pre Dec, Reg.  */
3940 	      if (BIT (4))
3941 		{
3942 #ifdef MODE32
3943 		  if (state->is_v6
3944 		      && handle_v6_insn (state, instr))
3945 		    break;
3946 #endif
3947 		  ARMul_UndefInstr (state, instr);
3948 		  break;
3949 		}
3950 	      (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED);
3951 	      break;
3952 
3953 	    case 0x76:		/* Store Byte, WriteBack, Pre Dec, Reg.  */
3954 	      if (BIT (4))
3955 		{
3956 #ifdef MODE32
3957 		  if (state->is_v6
3958 		      && handle_v6_insn (state, instr))
3959 		    break;
3960 #endif
3961 		  ARMul_UndefInstr (state, instr);
3962 		  break;
3963 		}
3964 	      UNDEF_LSRBaseEQOffWb;
3965 	      UNDEF_LSRBaseEQDestWb;
3966 	      UNDEF_LSRPCBaseWb;
3967 	      UNDEF_LSRPCOffWb;
3968 	      temp = LHS - LSRegRHS;
3969 	      if (StoreByte (state, instr, temp))
3970 		LSBase = temp;
3971 	      break;
3972 
3973 	    case 0x77:		/* Load Byte, WriteBack, Pre Dec, Reg.  */
3974 	      if (BIT (4))
3975 		{
3976 #ifdef MODE32
3977 		  if (state->is_v6
3978 		      && handle_v6_insn (state, instr))
3979 		    break;
3980 #endif
3981 		  ARMul_UndefInstr (state, instr);
3982 		  break;
3983 		}
3984 	      UNDEF_LSRBaseEQOffWb;
3985 	      UNDEF_LSRBaseEQDestWb;
3986 	      UNDEF_LSRPCBaseWb;
3987 	      UNDEF_LSRPCOffWb;
3988 	      temp = LHS - LSRegRHS;
3989 	      if (LoadByte (state, instr, temp, LUNSIGNED))
3990 		LSBase = temp;
3991 	      break;
3992 
3993 	    case 0x78:		/* Store Word, No WriteBack, Pre Inc, Reg.  */
3994 	      if (BIT (4))
3995 		{
3996 #ifdef MODE32
3997 		  if (state->is_v6
3998 		      && handle_v6_insn (state, instr))
3999 		    break;
4000 #endif
4001 		  ARMul_UndefInstr (state, instr);
4002 		  break;
4003 		}
4004 	      (void) StoreWord (state, instr, LHS + LSRegRHS);
4005 	      break;
4006 
4007 	    case 0x79:		/* Load Word, No WriteBack, Pre Inc, Reg.  */
4008 	      if (BIT (4))
4009 		{
4010 #ifdef MODE32
4011 		  if (state->is_v6
4012 		      && handle_v6_insn (state, instr))
4013 		    break;
4014 #endif
4015 		  ARMul_UndefInstr (state, instr);
4016 		  break;
4017 		}
4018 	      (void) LoadWord (state, instr, LHS + LSRegRHS);
4019 	      break;
4020 
4021 	    case 0x7a:		/* Store Word, WriteBack, Pre Inc, Reg.  */
4022 	      if (BIT (4))
4023 		{
4024 #ifdef MODE32
4025 		  if (state->is_v6
4026 		      && handle_v6_insn (state, instr))
4027 		    break;
4028 #endif
4029 		  ARMul_UndefInstr (state, instr);
4030 		  break;
4031 		}
4032 	      UNDEF_LSRBaseEQOffWb;
4033 	      UNDEF_LSRBaseEQDestWb;
4034 	      UNDEF_LSRPCBaseWb;
4035 	      UNDEF_LSRPCOffWb;
4036 	      temp = LHS + LSRegRHS;
4037 	      if (StoreWord (state, instr, temp))
4038 		LSBase = temp;
4039 	      break;
4040 
4041 	    case 0x7b:		/* Load Word, WriteBack, Pre Inc, Reg.  */
4042 	      if (BIT (4))
4043 		{
4044 #ifdef MODE32
4045 		  if (state->is_v6
4046 		      && handle_v6_insn (state, instr))
4047 		    break;
4048 #endif
4049 		  ARMul_UndefInstr (state, instr);
4050 		  break;
4051 		}
4052 	      UNDEF_LSRBaseEQOffWb;
4053 	      UNDEF_LSRBaseEQDestWb;
4054 	      UNDEF_LSRPCBaseWb;
4055 	      UNDEF_LSRPCOffWb;
4056 	      temp = LHS + LSRegRHS;
4057 	      if (LoadWord (state, instr, temp))
4058 		LSBase = temp;
4059 	      break;
4060 
4061 	    case 0x7c:		/* Store Byte, No WriteBack, Pre Inc, Reg.  */
4062 	      if (BIT (4))
4063 		{
4064 #ifdef MODE32
4065 		  if (state->is_v6
4066 		      && handle_v6_insn (state, instr))
4067 		    break;
4068 #endif
4069 		  ARMul_UndefInstr (state, instr);
4070 		  break;
4071 		}
4072 	      (void) StoreByte (state, instr, LHS + LSRegRHS);
4073 	      break;
4074 
4075 	    case 0x7d:		/* Load Byte, No WriteBack, Pre Inc, Reg.  */
4076 	      if (BIT (4))
4077 		{
4078 #ifdef MODE32
4079 		  if (state->is_v6
4080 		      && handle_v6_insn (state, instr))
4081 		    break;
4082 #endif
4083 		  ARMul_UndefInstr (state, instr);
4084 		  break;
4085 		}
4086 	      (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED);
4087 	      break;
4088 
4089 	    case 0x7e:		/* Store Byte, WriteBack, Pre Inc, Reg.  */
4090 	      if (BIT (4))
4091 		{
4092 #ifdef MODE32
4093 		  if (state->is_v6
4094 		      && handle_v6_insn (state, instr))
4095 		    break;
4096 #endif
4097 		  ARMul_UndefInstr (state, instr);
4098 		  break;
4099 		}
4100 	      UNDEF_LSRBaseEQOffWb;
4101 	      UNDEF_LSRBaseEQDestWb;
4102 	      UNDEF_LSRPCBaseWb;
4103 	      UNDEF_LSRPCOffWb;
4104 	      temp = LHS + LSRegRHS;
4105 	      if (StoreByte (state, instr, temp))
4106 		LSBase = temp;
4107 	      break;
4108 
4109 	    case 0x7f:		/* Load Byte, WriteBack, Pre Inc, Reg.  */
4110 	      if (BIT (4))
4111 		{
4112 		  /* Check for the special breakpoint opcode.
4113 		     This value should correspond to the value defined
4114 		     as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h.  */
4115 		  if (BITS (0, 19) == 0xfdefe)
4116 		    {
4117 		      if (!ARMul_OSHandleSWI (state, SWI_Breakpoint))
4118 			ARMul_Abort (state, ARMul_SWIV);
4119 		    }
4120 #ifdef MODE32
4121 		  else if (state->is_v6
4122 			   && handle_v6_insn (state, instr))
4123 		    break;
4124 #endif
4125 		  else
4126 		    ARMul_UndefInstr (state, instr);
4127 		  break;
4128 		}
4129 	      UNDEF_LSRBaseEQOffWb;
4130 	      UNDEF_LSRBaseEQDestWb;
4131 	      UNDEF_LSRPCBaseWb;
4132 	      UNDEF_LSRPCOffWb;
4133 	      temp = LHS + LSRegRHS;
4134 	      if (LoadByte (state, instr, temp, LUNSIGNED))
4135 		LSBase = temp;
4136 	      break;
4137 
4138 
4139 	      /* Multiple Data Transfer Instructions.  */
4140 
4141 	    case 0x80:		/* Store, No WriteBack, Post Dec.  */
4142 	      STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
4143 	      break;
4144 
4145 	    case 0x81:		/* Load, No WriteBack, Post Dec.  */
4146 	      LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
4147 	      break;
4148 
4149 	    case 0x82:		/* Store, WriteBack, Post Dec.  */
4150 	      temp = LSBase - LSMNumRegs;
4151 	      STOREMULT (instr, temp + 4L, temp);
4152 	      break;
4153 
4154 	    case 0x83:		/* Load, WriteBack, Post Dec.  */
4155 	      temp = LSBase - LSMNumRegs;
4156 	      LOADMULT (instr, temp + 4L, temp);
4157 	      break;
4158 
4159 	    case 0x84:		/* Store, Flags, No WriteBack, Post Dec.  */
4160 	      STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
4161 	      break;
4162 
4163 	    case 0x85:		/* Load, Flags, No WriteBack, Post Dec.  */
4164 	      LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
4165 	      break;
4166 
4167 	    case 0x86:		/* Store, Flags, WriteBack, Post Dec.  */
4168 	      temp = LSBase - LSMNumRegs;
4169 	      STORESMULT (instr, temp + 4L, temp);
4170 	      break;
4171 
4172 	    case 0x87:		/* Load, Flags, WriteBack, Post Dec.  */
4173 	      temp = LSBase - LSMNumRegs;
4174 	      LOADSMULT (instr, temp + 4L, temp);
4175 	      break;
4176 
4177 	    case 0x88:		/* Store, No WriteBack, Post Inc.  */
4178 	      STOREMULT (instr, LSBase, 0L);
4179 	      break;
4180 
4181 	    case 0x89:		/* Load, No WriteBack, Post Inc.  */
4182 	      LOADMULT (instr, LSBase, 0L);
4183 	      break;
4184 
4185 	    case 0x8a:		/* Store, WriteBack, Post Inc.  */
4186 	      temp = LSBase;
4187 	      STOREMULT (instr, temp, temp + LSMNumRegs);
4188 	      break;
4189 
4190 	    case 0x8b:		/* Load, WriteBack, Post Inc.  */
4191 	      temp = LSBase;
4192 	      LOADMULT (instr, temp, temp + LSMNumRegs);
4193 	      break;
4194 
4195 	    case 0x8c:		/* Store, Flags, No WriteBack, Post Inc.  */
4196 	      STORESMULT (instr, LSBase, 0L);
4197 	      break;
4198 
4199 	    case 0x8d:		/* Load, Flags, No WriteBack, Post Inc.  */
4200 	      LOADSMULT (instr, LSBase, 0L);
4201 	      break;
4202 
4203 	    case 0x8e:		/* Store, Flags, WriteBack, Post Inc.  */
4204 	      temp = LSBase;
4205 	      STORESMULT (instr, temp, temp + LSMNumRegs);
4206 	      break;
4207 
4208 	    case 0x8f:		/* Load, Flags, WriteBack, Post Inc.  */
4209 	      temp = LSBase;
4210 	      LOADSMULT (instr, temp, temp + LSMNumRegs);
4211 	      break;
4212 
4213 	    case 0x90:		/* Store, No WriteBack, Pre Dec.  */
4214 	      STOREMULT (instr, LSBase - LSMNumRegs, 0L);
4215 	      break;
4216 
4217 	    case 0x91:		/* Load, No WriteBack, Pre Dec.  */
4218 	      LOADMULT (instr, LSBase - LSMNumRegs, 0L);
4219 	      break;
4220 
4221 	    case 0x92:		/* Store, WriteBack, Pre Dec.  */
4222 	      temp = LSBase - LSMNumRegs;
4223 	      STOREMULT (instr, temp, temp);
4224 	      break;
4225 
4226 	    case 0x93:		/* Load, WriteBack, Pre Dec.  */
4227 	      temp = LSBase - LSMNumRegs;
4228 	      LOADMULT (instr, temp, temp);
4229 	      break;
4230 
4231 	    case 0x94:		/* Store, Flags, No WriteBack, Pre Dec.  */
4232 	      STORESMULT (instr, LSBase - LSMNumRegs, 0L);
4233 	      break;
4234 
4235 	    case 0x95:		/* Load, Flags, No WriteBack, Pre Dec.  */
4236 	      LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
4237 	      break;
4238 
4239 	    case 0x96:		/* Store, Flags, WriteBack, Pre Dec.  */
4240 	      temp = LSBase - LSMNumRegs;
4241 	      STORESMULT (instr, temp, temp);
4242 	      break;
4243 
4244 	    case 0x97:		/* Load, Flags, WriteBack, Pre Dec.  */
4245 	      temp = LSBase - LSMNumRegs;
4246 	      LOADSMULT (instr, temp, temp);
4247 	      break;
4248 
4249 	    case 0x98:		/* Store, No WriteBack, Pre Inc.  */
4250 	      STOREMULT (instr, LSBase + 4L, 0L);
4251 	      break;
4252 
4253 	    case 0x99:		/* Load, No WriteBack, Pre Inc.  */
4254 	      LOADMULT (instr, LSBase + 4L, 0L);
4255 	      break;
4256 
4257 	    case 0x9a:		/* Store, WriteBack, Pre Inc.  */
4258 	      temp = LSBase;
4259 	      STOREMULT (instr, temp + 4L, temp + LSMNumRegs);
4260 	      break;
4261 
4262 	    case 0x9b:		/* Load, WriteBack, Pre Inc.  */
4263 	      temp = LSBase;
4264 	      LOADMULT (instr, temp + 4L, temp + LSMNumRegs);
4265 	      break;
4266 
4267 	    case 0x9c:		/* Store, Flags, No WriteBack, Pre Inc.  */
4268 	      STORESMULT (instr, LSBase + 4L, 0L);
4269 	      break;
4270 
4271 	    case 0x9d:		/* Load, Flags, No WriteBack, Pre Inc.  */
4272 	      LOADSMULT (instr, LSBase + 4L, 0L);
4273 	      break;
4274 
4275 	    case 0x9e:		/* Store, Flags, WriteBack, Pre Inc.  */
4276 	      temp = LSBase;
4277 	      STORESMULT (instr, temp + 4L, temp + LSMNumRegs);
4278 	      break;
4279 
4280 	    case 0x9f:		/* Load, Flags, WriteBack, Pre Inc.  */
4281 	      temp = LSBase;
4282 	      LOADSMULT (instr, temp + 4L, temp + LSMNumRegs);
4283 	      break;
4284 
4285 
4286 	      /* Branch forward.  */
4287 	    case 0xa0:
4288 	    case 0xa1:
4289 	    case 0xa2:
4290 	    case 0xa3:
4291 	    case 0xa4:
4292 	    case 0xa5:
4293 	    case 0xa6:
4294 	    case 0xa7:
4295 	      state->Reg[15] = pc + 8 + POSBRANCH;
4296 	      FLUSHPIPE;
4297 	      break;
4298 
4299 
4300 	      /* Branch backward.  */
4301 	    case 0xa8:
4302 	    case 0xa9:
4303 	    case 0xaa:
4304 	    case 0xab:
4305 	    case 0xac:
4306 	    case 0xad:
4307 	    case 0xae:
4308 	    case 0xaf:
4309 	      state->Reg[15] = pc + 8 + NEGBRANCH;
4310 	      FLUSHPIPE;
4311 	      break;
4312 
4313 	      /* Branch and Link forward.  */
4314 	    case 0xb0:
4315 	    case 0xb1:
4316 	    case 0xb2:
4317 	    case 0xb3:
4318 	    case 0xb4:
4319 	    case 0xb5:
4320 	    case 0xb6:
4321 	    case 0xb7:
4322 	      /* Put PC into Link.  */
4323 #ifdef MODE32
4324 	      state->Reg[14] = pc + 4;
4325 #else
4326 	      state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
4327 #endif
4328 	      state->Reg[15] = pc + 8 + POSBRANCH;
4329 	      FLUSHPIPE;
4330 	      if (trace_funcs)
4331 		fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
4332 	      break;
4333 
4334 	      /* Branch and Link backward.  */
4335 	    case 0xb8:
4336 	    case 0xb9:
4337 	    case 0xba:
4338 	    case 0xbb:
4339 	    case 0xbc:
4340 	    case 0xbd:
4341 	    case 0xbe:
4342 	    case 0xbf:
4343 	      /* Put PC into Link.  */
4344 #ifdef MODE32
4345 	      state->Reg[14] = pc + 4;
4346 #else
4347 	      state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
4348 #endif
4349 	      state->Reg[15] = pc + 8 + NEGBRANCH;
4350 	      FLUSHPIPE;
4351 	      if (trace_funcs)
4352 		fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
4353 	      break;
4354 
4355 	      /* Co-Processor Data Transfers.  */
4356 	    case 0xc4:
4357 	      if (state->is_v5)
4358 		{
4359 		  if (CPNum == 10 || CPNum == 11)
4360 		    handle_VFP_move (state, instr);
4361 		  /* Reading from R15 is UNPREDICTABLE.  */
4362 		  else if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
4363 		    ARMul_UndefInstr (state, instr);
4364 		  /* Is access to coprocessor 0 allowed ?  */
4365 		  else if (! CP_ACCESS_ALLOWED (state, CPNum))
4366 		    ARMul_UndefInstr (state, instr);
4367 		  /* Special treatment for XScale coprocessors.  */
4368 		  else if (state->is_XScale)
4369 		    {
4370 		      /* Only opcode 0 is supported.  */
4371 		      if (BITS (4, 7) != 0x00)
4372 			ARMul_UndefInstr (state, instr);
4373 		      /* Only coporcessor 0 is supported.  */
4374 		      else if (CPNum != 0x00)
4375 			ARMul_UndefInstr (state, instr);
4376 		      /* Only accumulator 0 is supported.  */
4377 		      else if (BITS (0, 3) != 0x00)
4378 			ARMul_UndefInstr (state, instr);
4379 		      else
4380 			{
4381 			  /* XScale MAR insn.  Move two registers into accumulator.  */
4382 			  state->Accumulator = state->Reg[BITS (12, 15)];
4383 			  state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32;
4384 			}
4385 		    }
4386 		  else
4387 		    /* FIXME: Not sure what to do for other v5 processors.  */
4388 		    ARMul_UndefInstr (state, instr);
4389 		  break;
4390 		}
4391 	      /* Drop through.  */
4392 
4393 	    case 0xc0:		/* Store , No WriteBack , Post Dec.  */
4394 	      ARMul_STC (state, instr, LHS);
4395 	      break;
4396 
4397 	    case 0xc5:
4398 	      if (state->is_v5)
4399 		{
4400 		  if (CPNum == 10 || CPNum == 11)
4401 		    handle_VFP_move (state, instr);
4402 		  /* Writes to R15 are UNPREDICATABLE.  */
4403 		  else if (DESTReg == 15 || LHSReg == 15)
4404 		    ARMul_UndefInstr (state, instr);
4405 		  /* Is access to the coprocessor allowed ?  */
4406 		  else if (! CP_ACCESS_ALLOWED (state, CPNum))
4407 		    ARMul_UndefInstr (state, instr);
4408 		  /* Special handling for XScale coprcoessors.  */
4409 		  else if (state->is_XScale)
4410 		    {
4411 		      /* Only opcode 0 is supported.  */
4412 		      if (BITS (4, 7) != 0x00)
4413 			ARMul_UndefInstr (state, instr);
4414 		      /* Only coprocessor 0 is supported.  */
4415 		      else if (CPNum != 0x00)
4416 			ARMul_UndefInstr (state, instr);
4417 		      /* Only accumulator 0 is supported.  */
4418 		      else if (BITS (0, 3) != 0x00)
4419 			ARMul_UndefInstr (state, instr);
4420 		      else
4421 			{
4422 			  /* XScale MRA insn.  Move accumulator into two registers.  */
4423 			  ARMword t1 = (state->Accumulator >> 32) & 255;
4424 
4425 			  if (t1 & 128)
4426 			    t1 -= 256;
4427 
4428 			  state->Reg[BITS (12, 15)] = state->Accumulator;
4429 			  state->Reg[BITS (16, 19)] = t1;
4430 			  break;
4431 			}
4432 		    }
4433 		  else
4434 		    /* FIXME: Not sure what to do for other v5 processors.  */
4435 		    ARMul_UndefInstr (state, instr);
4436 		  break;
4437 		}
4438 	      /* Drop through.  */
4439 
4440 	    case 0xc1:		/* Load , No WriteBack , Post Dec.  */
4441 	      ARMul_LDC (state, instr, LHS);
4442 	      break;
4443 
4444 	    case 0xc2:
4445 	    case 0xc6:		/* Store , WriteBack , Post Dec.  */
4446 	      lhs = LHS;
4447 	      state->Base = lhs - LSCOff;
4448 	      ARMul_STC (state, instr, lhs);
4449 	      break;
4450 
4451 	    case 0xc3:
4452 	    case 0xc7:		/* Load , WriteBack , Post Dec.  */
4453 	      lhs = LHS;
4454 	      state->Base = lhs - LSCOff;
4455 	      ARMul_LDC (state, instr, lhs);
4456 	      break;
4457 
4458 	    case 0xc8:
4459 	    case 0xcc:		/* Store , No WriteBack , Post Inc.  */
4460 	      ARMul_STC (state, instr, LHS);
4461 	      break;
4462 
4463 	    case 0xc9:
4464 	    case 0xcd:		/* Load , No WriteBack , Post Inc.  */
4465 	      ARMul_LDC (state, instr, LHS);
4466 	      break;
4467 
4468 	    case 0xca:
4469 	    case 0xce:		/* Store , WriteBack , Post Inc.  */
4470 	      lhs = LHS;
4471 	      state->Base = lhs + LSCOff;
4472 	      ARMul_STC (state, instr, LHS);
4473 	      break;
4474 
4475 	    case 0xcb:
4476 	    case 0xcf:		/* Load , WriteBack , Post Inc.  */
4477 	      lhs = LHS;
4478 	      state->Base = lhs + LSCOff;
4479 	      ARMul_LDC (state, instr, LHS);
4480 	      break;
4481 
4482 	    case 0xd0:
4483 	    case 0xd4:		/* Store , No WriteBack , Pre Dec.  */
4484 	      ARMul_STC (state, instr, LHS - LSCOff);
4485 	      break;
4486 
4487 	    case 0xd1:
4488 	    case 0xd5:		/* Load , No WriteBack , Pre Dec.  */
4489 	      ARMul_LDC (state, instr, LHS - LSCOff);
4490 	      break;
4491 
4492 	    case 0xd2:
4493 	    case 0xd6:		/* Store , WriteBack , Pre Dec.  */
4494 	      lhs = LHS - LSCOff;
4495 	      state->Base = lhs;
4496 	      ARMul_STC (state, instr, lhs);
4497 	      break;
4498 
4499 	    case 0xd3:
4500 	    case 0xd7:		/* Load , WriteBack , Pre Dec.  */
4501 	      lhs = LHS - LSCOff;
4502 	      state->Base = lhs;
4503 	      ARMul_LDC (state, instr, lhs);
4504 	      break;
4505 
4506 	    case 0xd8:
4507 	    case 0xdc:		/* Store , No WriteBack , Pre Inc.  */
4508 	      ARMul_STC (state, instr, LHS + LSCOff);
4509 	      break;
4510 
4511 	    case 0xd9:
4512 	    case 0xdd:		/* Load , No WriteBack , Pre Inc.  */
4513 	      ARMul_LDC (state, instr, LHS + LSCOff);
4514 	      break;
4515 
4516 	    case 0xda:
4517 	    case 0xde:		/* Store , WriteBack , Pre Inc.  */
4518 	      lhs = LHS + LSCOff;
4519 	      state->Base = lhs;
4520 	      ARMul_STC (state, instr, lhs);
4521 	      break;
4522 
4523 	    case 0xdb:
4524 	    case 0xdf:		/* Load , WriteBack , Pre Inc.  */
4525 	      lhs = LHS + LSCOff;
4526 	      state->Base = lhs;
4527 	      ARMul_LDC (state, instr, lhs);
4528 	      break;
4529 
4530 
4531 	      /* Co-Processor Register Transfers (MCR) and Data Ops.  */
4532 
4533 	    case 0xe2:
4534 	      if (! CP_ACCESS_ALLOWED (state, CPNum))
4535 		{
4536 		  ARMul_UndefInstr (state, instr);
4537 		  break;
4538 		}
4539 	      if (state->is_XScale)
4540 		switch (BITS (18, 19))
4541 		  {
4542 		  case 0x0:
4543 		    if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
4544 		      {
4545 			/* XScale MIA instruction.  Signed multiplication of
4546 			   two 32 bit values and addition to 40 bit accumulator.  */
4547 			ARMsdword Rm = state->Reg[MULLHSReg];
4548 			ARMsdword Rs = state->Reg[MULACCReg];
4549 
4550 			if (Rm & (1 << 31))
4551 			  Rm -= 1ULL << 32;
4552 			if (Rs & (1 << 31))
4553 			  Rs -= 1ULL << 32;
4554 			state->Accumulator += Rm * Rs;
4555 			goto donext;
4556 		      }
4557 		    break;
4558 
4559 		  case 0x2:
4560 		    if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
4561 		      {
4562 			/* XScale MIAPH instruction.  */
4563 			ARMword t1 = state->Reg[MULLHSReg] >> 16;
4564 			ARMword t2 = state->Reg[MULACCReg] >> 16;
4565 			ARMword t3 = state->Reg[MULLHSReg] & 0xffff;
4566 			ARMword t4 = state->Reg[MULACCReg] & 0xffff;
4567 			ARMsdword t5;
4568 
4569 			if (t1 & (1 << 15))
4570 			  t1 -= 1 << 16;
4571 			if (t2 & (1 << 15))
4572 			  t2 -= 1 << 16;
4573 			if (t3 & (1 << 15))
4574 			  t3 -= 1 << 16;
4575 			if (t4 & (1 << 15))
4576 			  t4 -= 1 << 16;
4577 			t1 *= t2;
4578 			t5 = t1;
4579 			if (t5 & (1 << 31))
4580 			  t5 -= 1ULL << 32;
4581 			state->Accumulator += t5;
4582 			t3 *= t4;
4583 			t5 = t3;
4584 			if (t5 & (1 << 31))
4585 			  t5 -= 1ULL << 32;
4586 			state->Accumulator += t5;
4587 			goto donext;
4588 		      }
4589 		    break;
4590 
4591 		  case 0x3:
4592 		    if (BITS (4, 11) == 1)
4593 		      {
4594 			/* XScale MIAxy instruction.  */
4595 			ARMword t1;
4596 			ARMword t2;
4597 			ARMsdword t5;
4598 
4599 			if (BIT (17))
4600 			  t1 = state->Reg[MULLHSReg] >> 16;
4601 			else
4602 			  t1 = state->Reg[MULLHSReg] & 0xffff;
4603 
4604 			if (BIT (16))
4605 			  t2 = state->Reg[MULACCReg] >> 16;
4606 			else
4607 			  t2 = state->Reg[MULACCReg] & 0xffff;
4608 
4609 			if (t1 & (1 << 15))
4610 			  t1 -= 1 << 16;
4611 			if (t2 & (1 << 15))
4612 			  t2 -= 1 << 16;
4613 			t1 *= t2;
4614 			t5 = t1;
4615 			if (t5 & (1 << 31))
4616 			  t5 -= 1ULL << 32;
4617 			state->Accumulator += t5;
4618 			goto donext;
4619 		      }
4620 		    break;
4621 
4622 		  default:
4623 		    break;
4624 		  }
4625 	      /* Drop through.  */
4626 
4627 	    case 0xe0:
4628 	    case 0xe4:
4629 	    case 0xe6:
4630 	    case 0xe8:
4631 	    case 0xea:
4632 	    case 0xec:
4633 	    case 0xee:
4634 	      if (BIT (4))
4635 		{
4636 		  if (CPNum == 10 || CPNum == 11)
4637 		    handle_VFP_move (state, instr);
4638 		  /* MCR.  */
4639 		  else if (DESTReg == 15)
4640 		    {
4641 		      UNDEF_MCRPC;
4642 #ifdef MODE32
4643 		      ARMul_MCR (state, instr, state->Reg[15] + isize);
4644 #else
4645 		      ARMul_MCR (state, instr, ECC | ER15INT | EMODE |
4646 				 ((state->Reg[15] + isize) & R15PCBITS));
4647 #endif
4648 		    }
4649 		  else
4650 		    ARMul_MCR (state, instr, DEST);
4651 		}
4652 	      else
4653 		/* CDP Part 1.  */
4654 		ARMul_CDP (state, instr);
4655 	      break;
4656 
4657 
4658 	      /* Co-Processor Register Transfers (MRC) and Data Ops.  */
4659 	    case 0xe1:
4660 	    case 0xe3:
4661 	    case 0xe5:
4662 	    case 0xe7:
4663 	    case 0xe9:
4664 	    case 0xeb:
4665 	    case 0xed:
4666 	    case 0xef:
4667 	      if (BIT (4))
4668 		{
4669 		  if (CPNum == 10 || CPNum == 11)
4670 		    {
4671 		      switch (BITS (20, 27))
4672 			{
4673 			case 0xEF:
4674 			  if (BITS (16, 19) == 0x1
4675 			      && BITS (0, 11) == 0xA10)
4676 			    {
4677 			      /* VMRS  */
4678 			      if (DESTReg == 15)
4679 				{
4680 				  ARMul_SetCPSR (state, (state->FPSCR & 0xF0000000)
4681 						 | (ARMul_GetCPSR (state) & 0x0FFFFFFF));
4682 
4683 				  if (trace)
4684 				    fprintf (stderr, " VFP: VMRS: set flags to %c%c%c%c\n",
4685 					     ARMul_GetCPSR (state) & NBIT ? 'N' : '-',
4686 					     ARMul_GetCPSR (state) & ZBIT ? 'Z' : '-',
4687 					     ARMul_GetCPSR (state) & CBIT ? 'C' : '-',
4688 					     ARMul_GetCPSR (state) & VBIT ? 'V' : '-');
4689 				}
4690 			      else
4691 				{
4692 				  state->Reg[DESTReg] = state->FPSCR;
4693 
4694 				  if (trace)
4695 				    fprintf (stderr, " VFP: VMRS: r%d = %x\n", DESTReg, state->Reg[DESTReg]);
4696 				}
4697 			    }
4698 			  else
4699 			    fprintf (stderr, "SIM: VFP: Unimplemented: Compare op\n");
4700 			  break;
4701 
4702 			case 0xE0:
4703 			case 0xE1:
4704 			  /* VMOV reg <-> single precision.  */
4705 			  if (BITS (0,6) != 0x10 || BITS (8,11) != 0xA)
4706 			    fprintf (stderr, "SIM: VFP: Unimplemented: move op\n");
4707 			  else if (BIT (20))
4708 			    state->Reg[BITS (12, 15)] = VFP_uword (BITS (16, 19) << 1 | BIT (7));
4709 			  else
4710 			    VFP_uword (BITS (16, 19) << 1 | BIT (7)) = state->Reg[BITS (12, 15)];
4711 			  break;
4712 
4713 			default:
4714 			  fprintf (stderr, "SIM: VFP: Unimplemented: CDP op\n");
4715 			  break;
4716 			}
4717 		    }
4718 		  else
4719 		    {
4720 		      /* MRC */
4721 		      temp = ARMul_MRC (state, instr);
4722 		      if (DESTReg == 15)
4723 			{
4724 			  ASSIGNN ((temp & NBIT) != 0);
4725 			  ASSIGNZ ((temp & ZBIT) != 0);
4726 			  ASSIGNC ((temp & CBIT) != 0);
4727 			  ASSIGNV ((temp & VBIT) != 0);
4728 			}
4729 		      else
4730 			DEST = temp;
4731 		    }
4732 		}
4733 	      else
4734 		/* CDP Part 2.  */
4735 		ARMul_CDP (state, instr);
4736 	      break;
4737 
4738 
4739 	      /* SWI instruction.  */
4740 	    case 0xf0:
4741 	    case 0xf1:
4742 	    case 0xf2:
4743 	    case 0xf3:
4744 	    case 0xf4:
4745 	    case 0xf5:
4746 	    case 0xf6:
4747 	    case 0xf7:
4748 	    case 0xf8:
4749 	    case 0xf9:
4750 	    case 0xfa:
4751 	    case 0xfb:
4752 	    case 0xfc:
4753 	    case 0xfd:
4754 	    case 0xfe:
4755 	    case 0xff:
4756 	      if (instr == ARMul_ABORTWORD && state->AbortAddr == pc)
4757 		{
4758 		  /* A prefetch abort.  */
4759 		  XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
4760 		  ARMul_Abort (state, ARMul_PrefetchAbortV);
4761 		  break;
4762 		}
4763 
4764 	      if (!ARMul_OSHandleSWI (state, BITS (0, 23)))
4765 		ARMul_Abort (state, ARMul_SWIV);
4766 
4767 	      break;
4768 	    }
4769 	}
4770 
4771 #ifdef MODET
4772     donext:
4773 #endif
4774 
4775       if (state->Emulate == ONCE)
4776 	state->Emulate = STOP;
4777       /* If we have changed mode, allow the PC to advance before stopping.  */
4778       else if (state->Emulate == CHANGEMODE)
4779 	continue;
4780       else if (state->Emulate != RUN)
4781 	break;
4782     }
4783   while (!stop_simulator);
4784 
4785   state->decoded = decoded;
4786   state->loaded = loaded;
4787   state->pc = pc;
4788 
4789   return pc;
4790 }
4791 
4792 /* This routine evaluates most Data Processing register RHS's with the S
4793    bit clear.  It is intended to be called from the macro DPRegRHS, which
4794    filters the common case of an unshifted register with in line code.  */
4795 
4796 static ARMword
4797 GetDPRegRHS (ARMul_State * state, ARMword instr)
4798 {
4799   ARMword shamt, base;
4800 
4801   base = RHSReg;
4802   if (BIT (4))
4803     {
4804       /* Shift amount in a register.  */
4805       UNDEF_Shift;
4806       INCPC;
4807 #ifndef MODE32
4808       if (base == 15)
4809 	base = ECC | ER15INT | R15PC | EMODE;
4810       else
4811 #endif
4812 	base = state->Reg[base];
4813       ARMul_Icycles (state, 1, 0L);
4814       shamt = state->Reg[BITS (8, 11)] & 0xff;
4815       switch ((int) BITS (5, 6))
4816 	{
4817 	case LSL:
4818 	  if (shamt == 0)
4819 	    return (base);
4820 	  else if (shamt >= 32)
4821 	    return (0);
4822 	  else
4823 	    return (base << shamt);
4824 	case LSR:
4825 	  if (shamt == 0)
4826 	    return (base);
4827 	  else if (shamt >= 32)
4828 	    return (0);
4829 	  else
4830 	    return (base >> shamt);
4831 	case ASR:
4832 	  if (shamt == 0)
4833 	    return (base);
4834 	  else if (shamt >= 32)
4835 	    return ((ARMword) ((ARMsword) base >> 31L));
4836 	  else
4837 	    return ((ARMword) ((ARMsword) base >> (int) shamt));
4838 	case ROR:
4839 	  shamt &= 0x1f;
4840 	  if (shamt == 0)
4841 	    return (base);
4842 	  else
4843 	    return ((base << (32 - shamt)) | (base >> shamt));
4844 	}
4845     }
4846   else
4847     {
4848       /* Shift amount is a constant.  */
4849 #ifndef MODE32
4850       if (base == 15)
4851 	base = ECC | ER15INT | R15PC | EMODE;
4852       else
4853 #endif
4854 	base = state->Reg[base];
4855       shamt = BITS (7, 11);
4856       switch ((int) BITS (5, 6))
4857 	{
4858 	case LSL:
4859 	  return (base << shamt);
4860 	case LSR:
4861 	  if (shamt == 0)
4862 	    return (0);
4863 	  else
4864 	    return (base >> shamt);
4865 	case ASR:
4866 	  if (shamt == 0)
4867 	    return ((ARMword) ((ARMsword) base >> 31L));
4868 	  else
4869 	    return ((ARMword) ((ARMsword) base >> (int) shamt));
4870 	case ROR:
4871 	  if (shamt == 0)
4872 	    /* It's an RRX.  */
4873 	    return ((base >> 1) | (CFLAG << 31));
4874 	  else
4875 	    return ((base << (32 - shamt)) | (base >> shamt));
4876 	}
4877     }
4878 
4879   return 0;
4880 }
4881 
4882 /* This routine evaluates most Logical Data Processing register RHS's
4883    with the S bit set.  It is intended to be called from the macro
4884    DPSRegRHS, which filters the common case of an unshifted register
4885    with in line code.  */
4886 
4887 static ARMword
4888 GetDPSRegRHS (ARMul_State * state, ARMword instr)
4889 {
4890   ARMword shamt, base;
4891 
4892   base = RHSReg;
4893   if (BIT (4))
4894     {
4895       /* Shift amount in a register.  */
4896       UNDEF_Shift;
4897       INCPC;
4898 #ifndef MODE32
4899       if (base == 15)
4900 	base = ECC | ER15INT | R15PC | EMODE;
4901       else
4902 #endif
4903 	base = state->Reg[base];
4904       ARMul_Icycles (state, 1, 0L);
4905       shamt = state->Reg[BITS (8, 11)] & 0xff;
4906       switch ((int) BITS (5, 6))
4907 	{
4908 	case LSL:
4909 	  if (shamt == 0)
4910 	    return (base);
4911 	  else if (shamt == 32)
4912 	    {
4913 	      ASSIGNC (base & 1);
4914 	      return (0);
4915 	    }
4916 	  else if (shamt > 32)
4917 	    {
4918 	      CLEARC;
4919 	      return (0);
4920 	    }
4921 	  else
4922 	    {
4923 	      ASSIGNC ((base >> (32 - shamt)) & 1);
4924 	      return (base << shamt);
4925 	    }
4926 	case LSR:
4927 	  if (shamt == 0)
4928 	    return (base);
4929 	  else if (shamt == 32)
4930 	    {
4931 	      ASSIGNC (base >> 31);
4932 	      return (0);
4933 	    }
4934 	  else if (shamt > 32)
4935 	    {
4936 	      CLEARC;
4937 	      return (0);
4938 	    }
4939 	  else
4940 	    {
4941 	      ASSIGNC ((base >> (shamt - 1)) & 1);
4942 	      return (base >> shamt);
4943 	    }
4944 	case ASR:
4945 	  if (shamt == 0)
4946 	    return (base);
4947 	  else if (shamt >= 32)
4948 	    {
4949 	      ASSIGNC (base >> 31L);
4950 	      return ((ARMword) ((ARMsword) base >> 31L));
4951 	    }
4952 	  else
4953 	    {
4954 	      ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1);
4955 	      return ((ARMword) ((ARMsword) base >> (int) shamt));
4956 	    }
4957 	case ROR:
4958 	  if (shamt == 0)
4959 	    return (base);
4960 	  shamt &= 0x1f;
4961 	  if (shamt == 0)
4962 	    {
4963 	      ASSIGNC (base >> 31);
4964 	      return (base);
4965 	    }
4966 	  else
4967 	    {
4968 	      ASSIGNC ((base >> (shamt - 1)) & 1);
4969 	      return ((base << (32 - shamt)) | (base >> shamt));
4970 	    }
4971 	}
4972     }
4973   else
4974     {
4975       /* Shift amount is a constant.  */
4976 #ifndef MODE32
4977       if (base == 15)
4978 	base = ECC | ER15INT | R15PC | EMODE;
4979       else
4980 #endif
4981 	base = state->Reg[base];
4982       shamt = BITS (7, 11);
4983 
4984       switch ((int) BITS (5, 6))
4985 	{
4986 	case LSL:
4987 	  ASSIGNC ((base >> (32 - shamt)) & 1);
4988 	  return (base << shamt);
4989 	case LSR:
4990 	  if (shamt == 0)
4991 	    {
4992 	      ASSIGNC (base >> 31);
4993 	      return (0);
4994 	    }
4995 	  else
4996 	    {
4997 	      ASSIGNC ((base >> (shamt - 1)) & 1);
4998 	      return (base >> shamt);
4999 	    }
5000 	case ASR:
5001 	  if (shamt == 0)
5002 	    {
5003 	      ASSIGNC (base >> 31L);
5004 	      return ((ARMword) ((ARMsword) base >> 31L));
5005 	    }
5006 	  else
5007 	    {
5008 	      ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1);
5009 	      return ((ARMword) ((ARMsword) base >> (int) shamt));
5010 	    }
5011 	case ROR:
5012 	  if (shamt == 0)
5013 	    {
5014 	      /* It's an RRX.  */
5015 	      shamt = CFLAG;
5016 	      ASSIGNC (base & 1);
5017 	      return ((base >> 1) | (shamt << 31));
5018 	    }
5019 	  else
5020 	    {
5021 	      ASSIGNC ((base >> (shamt - 1)) & 1);
5022 	      return ((base << (32 - shamt)) | (base >> shamt));
5023 	    }
5024 	}
5025     }
5026 
5027   return 0;
5028 }
5029 
5030 /* This routine handles writes to register 15 when the S bit is not set.  */
5031 
5032 static void
5033 WriteR15 (ARMul_State * state, ARMword src)
5034 {
5035   /* The ARM documentation states that the two least significant bits
5036      are discarded when setting PC, except in the cases handled by
5037      WriteR15Branch() below.  It's probably an oversight: in THUMB
5038      mode, the second least significant bit should probably not be
5039      discarded.  */
5040 #ifdef MODET
5041   if (TFLAG)
5042     src &= 0xfffffffe;
5043   else
5044 #endif
5045     src &= 0xfffffffc;
5046 
5047 #ifdef MODE32
5048   state->Reg[15] = src & PCBITS;
5049 #else
5050   state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
5051   ARMul_R15Altered (state);
5052 #endif
5053 
5054   FLUSHPIPE;
5055   if (trace_funcs)
5056     fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
5057 }
5058 
5059 /* This routine handles writes to register 15 when the S bit is set.  */
5060 
5061 static void
5062 WriteSR15 (ARMul_State * state, ARMword src)
5063 {
5064 #ifdef MODE32
5065   if (state->Bank > 0)
5066     {
5067       state->Cpsr = state->Spsr[state->Bank];
5068       ARMul_CPSRAltered (state);
5069     }
5070 #ifdef MODET
5071   if (TFLAG)
5072     src &= 0xfffffffe;
5073   else
5074 #endif
5075     src &= 0xfffffffc;
5076   state->Reg[15] = src & PCBITS;
5077 #else
5078 #ifdef MODET
5079   if (TFLAG)
5080     /* ARMul_R15Altered would have to support it.  */
5081     abort ();
5082   else
5083 #endif
5084     src &= 0xfffffffc;
5085 
5086   if (state->Bank == USERBANK)
5087     state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
5088   else
5089     state->Reg[15] = src;
5090 
5091   ARMul_R15Altered (state);
5092 #endif
5093   FLUSHPIPE;
5094   if (trace_funcs)
5095     fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
5096 }
5097 
5098 /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
5099    will switch to Thumb mode if the least significant bit is set.  */
5100 
5101 static void
5102 WriteR15Branch (ARMul_State * state, ARMword src)
5103 {
5104 #ifdef MODET
5105   if (src & 1)
5106     {
5107       /* Thumb bit.  */
5108       SETT;
5109       state->Reg[15] = src & 0xfffffffe;
5110     }
5111   else
5112     {
5113       CLEART;
5114       state->Reg[15] = src & 0xfffffffc;
5115     }
5116   FLUSHPIPE;
5117   if (trace_funcs)
5118     fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
5119 #else
5120   WriteR15 (state, src);
5121 #endif
5122 }
5123 
5124 /* Before ARM_v5 LDR and LDM of pc did not change mode.  */
5125 
5126 static void
5127 WriteR15Load (ARMul_State * state, ARMword src)
5128 {
5129   if (state->is_v5)
5130     WriteR15Branch (state, src);
5131   else
5132     WriteR15 (state, src);
5133 }
5134 
5135 /* This routine evaluates most Load and Store register RHS's.  It is
5136    intended to be called from the macro LSRegRHS, which filters the
5137    common case of an unshifted register with in line code.  */
5138 
5139 static ARMword
5140 GetLSRegRHS (ARMul_State * state, ARMword instr)
5141 {
5142   ARMword shamt, base;
5143 
5144   base = RHSReg;
5145 #ifndef MODE32
5146   if (base == 15)
5147     /* Now forbidden, but ...  */
5148     base = ECC | ER15INT | R15PC | EMODE;
5149   else
5150 #endif
5151     base = state->Reg[base];
5152 
5153   shamt = BITS (7, 11);
5154   switch ((int) BITS (5, 6))
5155     {
5156     case LSL:
5157       return (base << shamt);
5158     case LSR:
5159       if (shamt == 0)
5160 	return (0);
5161       else
5162 	return (base >> shamt);
5163     case ASR:
5164       if (shamt == 0)
5165 	return ((ARMword) ((ARMsword) base >> 31L));
5166       else
5167 	return ((ARMword) ((ARMsword) base >> (int) shamt));
5168     case ROR:
5169       if (shamt == 0)
5170 	/* It's an RRX.  */
5171 	return ((base >> 1) | (CFLAG << 31));
5172       else
5173 	return ((base << (32 - shamt)) | (base >> shamt));
5174     default:
5175       break;
5176     }
5177   return 0;
5178 }
5179 
5180 /* This routine evaluates the ARM7T halfword and signed transfer RHS's.  */
5181 
5182 static ARMword
5183 GetLS7RHS (ARMul_State * state, ARMword instr)
5184 {
5185   if (BIT (22) == 0)
5186     {
5187       /* Register.  */
5188 #ifndef MODE32
5189       if (RHSReg == 15)
5190 	/* Now forbidden, but ...  */
5191 	return ECC | ER15INT | R15PC | EMODE;
5192 #endif
5193       return state->Reg[RHSReg];
5194     }
5195 
5196   /* Immediate.  */
5197   return BITS (0, 3) | (BITS (8, 11) << 4);
5198 }
5199 
5200 /* This function does the work of loading a word for a LDR instruction.  */
5201 
5202 static unsigned
5203 LoadWord (ARMul_State * state, ARMword instr, ARMword address)
5204 {
5205   ARMword dest;
5206 
5207   BUSUSEDINCPCS;
5208 #ifndef MODE32
5209   if (ADDREXCEPT (address))
5210     INTERNALABORT (address);
5211 #endif
5212 
5213   dest = ARMul_LoadWordN (state, address);
5214 
5215   if (state->Aborted)
5216     {
5217       TAKEABORT;
5218       return state->lateabtSig;
5219     }
5220   if (address & 3)
5221     dest = ARMul_Align (state, address, dest);
5222   WRITEDESTB (dest);
5223   ARMul_Icycles (state, 1, 0L);
5224 
5225   return (DESTReg != LHSReg);
5226 }
5227 
5228 #ifdef MODET
5229 /* This function does the work of loading a halfword.  */
5230 
5231 static unsigned
5232 LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
5233 	      int signextend)
5234 {
5235   ARMword dest;
5236 
5237   BUSUSEDINCPCS;
5238 #ifndef MODE32
5239   if (ADDREXCEPT (address))
5240     INTERNALABORT (address);
5241 #endif
5242   dest = ARMul_LoadHalfWord (state, address);
5243   if (state->Aborted)
5244     {
5245       TAKEABORT;
5246       return state->lateabtSig;
5247     }
5248   UNDEF_LSRBPC;
5249   if (signextend)
5250     if (dest & 1 << (16 - 1))
5251       dest = (dest & ((1 << 16) - 1)) - (1 << 16);
5252 
5253   WRITEDEST (dest);
5254   ARMul_Icycles (state, 1, 0L);
5255   return (DESTReg != LHSReg);
5256 }
5257 
5258 #endif /* MODET */
5259 
5260 /* This function does the work of loading a byte for a LDRB instruction.  */
5261 
5262 static unsigned
5263 LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend)
5264 {
5265   ARMword dest;
5266 
5267   BUSUSEDINCPCS;
5268 #ifndef MODE32
5269   if (ADDREXCEPT (address))
5270     INTERNALABORT (address);
5271 #endif
5272   dest = ARMul_LoadByte (state, address);
5273   if (state->Aborted)
5274     {
5275       TAKEABORT;
5276       return state->lateabtSig;
5277     }
5278   UNDEF_LSRBPC;
5279   if (signextend)
5280     if (dest & 1 << (8 - 1))
5281       dest = (dest & ((1 << 8) - 1)) - (1 << 8);
5282 
5283   WRITEDEST (dest);
5284   ARMul_Icycles (state, 1, 0L);
5285 
5286   return (DESTReg != LHSReg);
5287 }
5288 
5289 /* This function does the work of loading two words for a LDRD instruction.  */
5290 
5291 static void
5292 Handle_Load_Double (ARMul_State * state, ARMword instr)
5293 {
5294   ARMword dest_reg;
5295   ARMword addr_reg;
5296   ARMword write_back  = BIT (21);
5297   ARMword immediate   = BIT (22);
5298   ARMword add_to_base = BIT (23);
5299   ARMword pre_indexed = BIT (24);
5300   ARMword offset;
5301   ARMword addr;
5302   ARMword sum;
5303   ARMword base;
5304   ARMword value1;
5305   ARMword value2;
5306 
5307   BUSUSEDINCPCS;
5308 
5309   /* If the writeback bit is set, the pre-index bit must be clear.  */
5310   if (write_back && ! pre_indexed)
5311     {
5312       ARMul_UndefInstr (state, instr);
5313       return;
5314     }
5315 
5316   /* Extract the base address register.  */
5317   addr_reg = LHSReg;
5318 
5319   /* Extract the destination register and check it.  */
5320   dest_reg = DESTReg;
5321 
5322   /* Destination register must be even.  */
5323   if ((dest_reg & 1)
5324     /* Destination register cannot be LR.  */
5325       || (dest_reg == 14))
5326     {
5327       ARMul_UndefInstr (state, instr);
5328       return;
5329     }
5330 
5331   /* Compute the base address.  */
5332   base = state->Reg[addr_reg];
5333 
5334   /* Compute the offset.  */
5335   offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
5336 
5337   /* Compute the sum of the two.  */
5338   if (add_to_base)
5339     sum = base + offset;
5340   else
5341     sum = base - offset;
5342 
5343   /* If this is a pre-indexed mode use the sum.  */
5344   if (pre_indexed)
5345     addr = sum;
5346   else
5347     addr = base;
5348 
5349   if (state->is_v6 && (addr & 0x3) == 0)
5350     /* Word alignment is enough for v6.  */
5351     ;
5352   /* The address must be aligned on a 8 byte boundary.  */
5353   else if (addr & 0x7)
5354     {
5355 #ifdef ABORTS
5356       ARMul_DATAABORT (addr);
5357 #else
5358       ARMul_UndefInstr (state, instr);
5359 #endif
5360       return;
5361     }
5362 
5363   /* For pre indexed or post indexed addressing modes,
5364      check that the destination registers do not overlap
5365      the address registers.  */
5366   if ((! pre_indexed || write_back)
5367       && (   addr_reg == dest_reg
5368 	  || addr_reg == dest_reg + 1))
5369     {
5370       ARMul_UndefInstr (state, instr);
5371       return;
5372     }
5373 
5374   /* Load the words.  */
5375   value1 = ARMul_LoadWordN (state, addr);
5376   value2 = ARMul_LoadWordN (state, addr + 4);
5377 
5378   /* Check for data aborts.  */
5379   if (state->Aborted)
5380     {
5381       TAKEABORT;
5382       return;
5383     }
5384 
5385   ARMul_Icycles (state, 2, 0L);
5386 
5387   /* Store the values.  */
5388   state->Reg[dest_reg] = value1;
5389   state->Reg[dest_reg + 1] = value2;
5390 
5391   /* Do the post addressing and writeback.  */
5392   if (! pre_indexed)
5393     addr = sum;
5394 
5395   if (! pre_indexed || write_back)
5396     state->Reg[addr_reg] = addr;
5397 }
5398 
5399 /* This function does the work of storing two words for a STRD instruction.  */
5400 
5401 static void
5402 Handle_Store_Double (ARMul_State * state, ARMword instr)
5403 {
5404   ARMword src_reg;
5405   ARMword addr_reg;
5406   ARMword write_back  = BIT (21);
5407   ARMword immediate   = BIT (22);
5408   ARMword add_to_base = BIT (23);
5409   ARMword pre_indexed = BIT (24);
5410   ARMword offset;
5411   ARMword addr;
5412   ARMword sum;
5413   ARMword base;
5414 
5415   BUSUSEDINCPCS;
5416 
5417   /* If the writeback bit is set, the pre-index bit must be clear.  */
5418   if (write_back && ! pre_indexed)
5419     {
5420       ARMul_UndefInstr (state, instr);
5421       return;
5422     }
5423 
5424   /* Extract the base address register.  */
5425   addr_reg = LHSReg;
5426 
5427   /* Base register cannot be PC.  */
5428   if (addr_reg == 15)
5429     {
5430       ARMul_UndefInstr (state, instr);
5431       return;
5432     }
5433 
5434   /* Extract the source register.  */
5435   src_reg = DESTReg;
5436 
5437   /* Source register must be even.  */
5438   if (src_reg & 1)
5439     {
5440       ARMul_UndefInstr (state, instr);
5441       return;
5442     }
5443 
5444   /* Compute the base address.  */
5445   base = state->Reg[addr_reg];
5446 
5447   /* Compute the offset.  */
5448   offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
5449 
5450   /* Compute the sum of the two.  */
5451   if (add_to_base)
5452     sum = base + offset;
5453   else
5454     sum = base - offset;
5455 
5456   /* If this is a pre-indexed mode use the sum.  */
5457   if (pre_indexed)
5458     addr = sum;
5459   else
5460     addr = base;
5461 
5462   /* The address must be aligned on a 8 byte boundary.  */
5463   if (state->is_v6 && (addr & 0x3) == 0)
5464     /* Word alignment is enough for v6.  */
5465     ;
5466   else if (addr & 0x7)
5467     {
5468 #ifdef ABORTS
5469       ARMul_DATAABORT (addr);
5470 #else
5471       ARMul_UndefInstr (state, instr);
5472 #endif
5473       return;
5474     }
5475 
5476   /* For pre indexed or post indexed addressing modes,
5477      check that the destination registers do not overlap
5478      the address registers.  */
5479   if ((! pre_indexed || write_back)
5480       && (   addr_reg == src_reg
5481 	  || addr_reg == src_reg + 1))
5482     {
5483       ARMul_UndefInstr (state, instr);
5484       return;
5485     }
5486 
5487   /* Load the words.  */
5488   ARMul_StoreWordN (state, addr, state->Reg[src_reg]);
5489   ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]);
5490 
5491   if (state->Aborted)
5492     {
5493       TAKEABORT;
5494       return;
5495     }
5496 
5497   /* Do the post addressing and writeback.  */
5498   if (! pre_indexed)
5499     addr = sum;
5500 
5501   if (! pre_indexed || write_back)
5502     state->Reg[addr_reg] = addr;
5503 }
5504 
5505 /* This function does the work of storing a word from a STR instruction.  */
5506 
5507 static unsigned
5508 StoreWord (ARMul_State * state, ARMword instr, ARMword address)
5509 {
5510   BUSUSEDINCPCN;
5511 #ifndef MODE32
5512   if (DESTReg == 15)
5513     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
5514 #endif
5515 #ifdef MODE32
5516   ARMul_StoreWordN (state, address, DEST);
5517 #else
5518   if (VECTORACCESS (address) || ADDREXCEPT (address))
5519     {
5520       INTERNALABORT (address);
5521       (void) ARMul_LoadWordN (state, address);
5522     }
5523   else
5524     ARMul_StoreWordN (state, address, DEST);
5525 #endif
5526   if (state->Aborted)
5527     {
5528       TAKEABORT;
5529       return state->lateabtSig;
5530     }
5531   return TRUE;
5532 }
5533 
5534 #ifdef MODET
5535 /* This function does the work of storing a byte for a STRH instruction.  */
5536 
5537 static unsigned
5538 StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
5539 {
5540   BUSUSEDINCPCN;
5541 
5542 #ifndef MODE32
5543   if (DESTReg == 15)
5544     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
5545 #endif
5546 
5547 #ifdef MODE32
5548   ARMul_StoreHalfWord (state, address, DEST);
5549 #else
5550   if (VECTORACCESS (address) || ADDREXCEPT (address))
5551     {
5552       INTERNALABORT (address);
5553       (void) ARMul_LoadHalfWord (state, address);
5554     }
5555   else
5556     ARMul_StoreHalfWord (state, address, DEST);
5557 #endif
5558 
5559   if (state->Aborted)
5560     {
5561       TAKEABORT;
5562       return state->lateabtSig;
5563     }
5564   return TRUE;
5565 }
5566 
5567 #endif /* MODET */
5568 
5569 /* This function does the work of storing a byte for a STRB instruction.  */
5570 
5571 static unsigned
5572 StoreByte (ARMul_State * state, ARMword instr, ARMword address)
5573 {
5574   BUSUSEDINCPCN;
5575 #ifndef MODE32
5576   if (DESTReg == 15)
5577     state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
5578 #endif
5579 #ifdef MODE32
5580   ARMul_StoreByte (state, address, DEST);
5581 #else
5582   if (VECTORACCESS (address) || ADDREXCEPT (address))
5583     {
5584       INTERNALABORT (address);
5585       (void) ARMul_LoadByte (state, address);
5586     }
5587   else
5588     ARMul_StoreByte (state, address, DEST);
5589 #endif
5590   if (state->Aborted)
5591     {
5592       TAKEABORT;
5593       return state->lateabtSig;
5594     }
5595   UNDEF_LSRBPC;
5596   return TRUE;
5597 }
5598 
5599 /* This function does the work of loading the registers listed in an LDM
5600    instruction, when the S bit is clear.  The code here is always increment
5601    after, it's up to the caller to get the input address correct and to
5602    handle base register modification.  */
5603 
5604 static void
5605 LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
5606 {
5607   ARMword dest, temp;
5608 
5609   UNDEF_LSMNoRegs;
5610   UNDEF_LSMPCBase;
5611   UNDEF_LSMBaseInListWb;
5612   BUSUSEDINCPCS;
5613 #ifndef MODE32
5614   if (ADDREXCEPT (address))
5615     INTERNALABORT (address);
5616 #endif
5617   if (BIT (21) && LHSReg != 15)
5618     LSBase = WBBase;
5619 
5620   /* N cycle first.  */
5621   for (temp = 0; !BIT (temp); temp++)
5622     ;
5623 
5624   dest = ARMul_LoadWordN (state, address);
5625 
5626   if (!state->abortSig && !state->Aborted)
5627     state->Reg[temp++] = dest;
5628   else if (!state->Aborted)
5629     {
5630       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5631       state->Aborted = ARMul_DataAbortV;
5632     }
5633 
5634   /* S cycles from here on.  */
5635   for (; temp < 16; temp ++)
5636     if (BIT (temp))
5637       {
5638 	/* Load this register.  */
5639 	address += 4;
5640 	dest = ARMul_LoadWordS (state, address);
5641 
5642 	if (!state->abortSig && !state->Aborted)
5643 	  state->Reg[temp] = dest;
5644 	else if (!state->Aborted)
5645 	  {
5646             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5647 	    state->Aborted = ARMul_DataAbortV;
5648 	  }
5649       }
5650 
5651   if (BIT (15) && !state->Aborted)
5652     /* PC is in the reg list.  */
5653     WriteR15Load (state, PC);
5654 
5655   /* To write back the final register.  */
5656   ARMul_Icycles (state, 1, 0L);
5657 
5658   if (state->Aborted)
5659     {
5660       if (BIT (21) && LHSReg != 15)
5661 	LSBase = WBBase;
5662       TAKEABORT;
5663     }
5664 }
5665 
5666 /* This function does the work of loading the registers listed in an LDM
5667    instruction, when the S bit is set. The code here is always increment
5668    after, it's up to the caller to get the input address correct and to
5669    handle base register modification.  */
5670 
5671 static void
5672 LoadSMult (ARMul_State * state,
5673 	   ARMword       instr,
5674 	   ARMword       address,
5675 	   ARMword       WBBase)
5676 {
5677   ARMword dest, temp;
5678 
5679   UNDEF_LSMNoRegs;
5680   UNDEF_LSMPCBase;
5681   UNDEF_LSMBaseInListWb;
5682 
5683   BUSUSEDINCPCS;
5684 
5685 #ifndef MODE32
5686   if (ADDREXCEPT (address))
5687     INTERNALABORT (address);
5688 #endif
5689 
5690   if (BIT (21) && LHSReg != 15)
5691     LSBase = WBBase;
5692 
5693   if (!BIT (15) && state->Bank != USERBANK)
5694     {
5695       /* Temporary reg bank switch.  */
5696       (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
5697       UNDEF_LSMUserBankWb;
5698     }
5699 
5700   /* N cycle first.  */
5701   for (temp = 0; !BIT (temp); temp ++)
5702     ;
5703 
5704   dest = ARMul_LoadWordN (state, address);
5705 
5706   if (!state->abortSig)
5707     state->Reg[temp++] = dest;
5708   else if (!state->Aborted)
5709     {
5710       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5711       state->Aborted = ARMul_DataAbortV;
5712     }
5713 
5714   /* S cycles from here on.  */
5715   for (; temp < 16; temp++)
5716     if (BIT (temp))
5717       {
5718 	/* Load this register.  */
5719 	address += 4;
5720 	dest = ARMul_LoadWordS (state, address);
5721 
5722 	if (!state->abortSig && !state->Aborted)
5723 	  state->Reg[temp] = dest;
5724 	else if (!state->Aborted)
5725 	  {
5726             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5727 	    state->Aborted = ARMul_DataAbortV;
5728 	  }
5729       }
5730 
5731   if (BIT (15) && !state->Aborted)
5732     {
5733       /* PC is in the reg list.  */
5734 #ifdef MODE32
5735       if (state->Mode != USER26MODE && state->Mode != USER32MODE)
5736 	{
5737 	  state->Cpsr = GETSPSR (state->Bank);
5738 	  ARMul_CPSRAltered (state);
5739 	}
5740 
5741       WriteR15 (state, PC);
5742 #else
5743       if (state->Mode == USER26MODE || state->Mode == USER32MODE)
5744 	{
5745 	  /* Protect bits in user mode.  */
5746 	  ASSIGNN ((state->Reg[15] & NBIT) != 0);
5747 	  ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
5748 	  ASSIGNC ((state->Reg[15] & CBIT) != 0);
5749 	  ASSIGNV ((state->Reg[15] & VBIT) != 0);
5750 	}
5751       else
5752 	ARMul_R15Altered (state);
5753 
5754       FLUSHPIPE;
5755 #endif
5756     }
5757 
5758   if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE)
5759     /* Restore the correct bank.  */
5760     (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
5761 
5762   /* To write back the final register.  */
5763   ARMul_Icycles (state, 1, 0L);
5764 
5765   if (state->Aborted)
5766     {
5767       if (BIT (21) && LHSReg != 15)
5768 	LSBase = WBBase;
5769 
5770       TAKEABORT;
5771     }
5772 }
5773 
5774 /* This function does the work of storing the registers listed in an STM
5775    instruction, when the S bit is clear.  The code here is always increment
5776    after, it's up to the caller to get the input address correct and to
5777    handle base register modification.  */
5778 
5779 static void
5780 StoreMult (ARMul_State * state,
5781 	   ARMword instr,
5782 	   ARMword address,
5783 	   ARMword WBBase)
5784 {
5785   ARMword temp;
5786 
5787   UNDEF_LSMNoRegs;
5788   UNDEF_LSMPCBase;
5789   UNDEF_LSMBaseInListWb;
5790 
5791   if (!TFLAG)
5792     /* N-cycle, increment the PC and update the NextInstr state.  */
5793     BUSUSEDINCPCN;
5794 
5795 #ifndef MODE32
5796   if (VECTORACCESS (address) || ADDREXCEPT (address))
5797     INTERNALABORT (address);
5798 
5799   if (BIT (15))
5800     PATCHR15;
5801 #endif
5802 
5803   /* N cycle first.  */
5804   for (temp = 0; !BIT (temp); temp ++)
5805     ;
5806 
5807 #ifdef MODE32
5808   ARMul_StoreWordN (state, address, state->Reg[temp++]);
5809 #else
5810   if (state->Aborted)
5811     {
5812       (void) ARMul_LoadWordN (state, address);
5813 
5814       /* Fake the Stores as Loads.  */
5815       for (; temp < 16; temp++)
5816 	if (BIT (temp))
5817 	  {
5818 	    /* Save this register.  */
5819 	    address += 4;
5820 	    (void) ARMul_LoadWordS (state, address);
5821 	  }
5822 
5823       if (BIT (21) && LHSReg != 15)
5824 	LSBase = WBBase;
5825       TAKEABORT;
5826       return;
5827     }
5828   else
5829     ARMul_StoreWordN (state, address, state->Reg[temp++]);
5830 #endif
5831 
5832   if (state->abortSig && !state->Aborted)
5833     {
5834       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5835       state->Aborted = ARMul_DataAbortV;
5836     }
5837 
5838   if (BIT (21) && LHSReg != 15)
5839     LSBase = WBBase;
5840 
5841   /* S cycles from here on.  */
5842   for (; temp < 16; temp ++)
5843     if (BIT (temp))
5844       {
5845 	/* Save this register.  */
5846 	address += 4;
5847 
5848 	ARMul_StoreWordS (state, address, state->Reg[temp]);
5849 
5850 	if (state->abortSig && !state->Aborted)
5851 	  {
5852             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5853 	    state->Aborted = ARMul_DataAbortV;
5854 	  }
5855       }
5856 
5857   if (state->Aborted)
5858     TAKEABORT;
5859 }
5860 
5861 /* This function does the work of storing the registers listed in an STM
5862    instruction when the S bit is set.  The code here is always increment
5863    after, it's up to the caller to get the input address correct and to
5864    handle base register modification.  */
5865 
5866 static void
5867 StoreSMult (ARMul_State * state,
5868 	    ARMword       instr,
5869 	    ARMword       address,
5870 	    ARMword       WBBase)
5871 {
5872   ARMword temp;
5873 
5874   UNDEF_LSMNoRegs;
5875   UNDEF_LSMPCBase;
5876   UNDEF_LSMBaseInListWb;
5877 
5878   BUSUSEDINCPCN;
5879 
5880 #ifndef MODE32
5881   if (VECTORACCESS (address) || ADDREXCEPT (address))
5882     INTERNALABORT (address);
5883 
5884   if (BIT (15))
5885     PATCHR15;
5886 #endif
5887 
5888   if (state->Bank != USERBANK)
5889     {
5890       /* Force User Bank.  */
5891       (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
5892       UNDEF_LSMUserBankWb;
5893     }
5894 
5895   for (temp = 0; !BIT (temp); temp++)
5896     ;	/* N cycle first.  */
5897 
5898 #ifdef MODE32
5899   ARMul_StoreWordN (state, address, state->Reg[temp++]);
5900 #else
5901   if (state->Aborted)
5902     {
5903       (void) ARMul_LoadWordN (state, address);
5904 
5905       for (; temp < 16; temp++)
5906 	/* Fake the Stores as Loads.  */
5907 	if (BIT (temp))
5908 	  {
5909 	    /* Save this register.  */
5910 	    address += 4;
5911 
5912 	    (void) ARMul_LoadWordS (state, address);
5913 	  }
5914 
5915       if (BIT (21) && LHSReg != 15)
5916 	LSBase = WBBase;
5917 
5918       TAKEABORT;
5919       return;
5920     }
5921   else
5922     ARMul_StoreWordN (state, address, state->Reg[temp++]);
5923 #endif
5924 
5925   if (state->abortSig && !state->Aborted)
5926     {
5927       XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5928       state->Aborted = ARMul_DataAbortV;
5929     }
5930 
5931   /* S cycles from here on.  */
5932   for (; temp < 16; temp++)
5933     if (BIT (temp))
5934       {
5935 	/* Save this register.  */
5936 	address += 4;
5937 
5938 	ARMul_StoreWordS (state, address, state->Reg[temp]);
5939 
5940 	if (state->abortSig && !state->Aborted)
5941 	  {
5942             XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5943 	    state->Aborted = ARMul_DataAbortV;
5944 	  }
5945       }
5946 
5947   if (state->Mode != USER26MODE && state->Mode != USER32MODE)
5948     /* Restore the correct bank.  */
5949     (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
5950 
5951   if (BIT (21) && LHSReg != 15)
5952     LSBase = WBBase;
5953 
5954   if (state->Aborted)
5955     TAKEABORT;
5956 }
5957 
5958 /* This function does the work of adding two 32bit values
5959    together, and calculating if a carry has occurred.  */
5960 
5961 static ARMword
5962 Add32 (ARMword a1, ARMword a2, int *carry)
5963 {
5964   ARMword result = (a1 + a2);
5965   unsigned int uresult = (unsigned int) result;
5966   unsigned int ua1 = (unsigned int) a1;
5967 
5968   /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
5969      or (result > RdLo) then we have no carry.  */
5970   if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
5971     *carry = 1;
5972   else
5973     *carry = 0;
5974 
5975   return result;
5976 }
5977 
5978 /* This function does the work of multiplying
5979    two 32bit values to give a 64bit result.  */
5980 
5981 static unsigned
5982 Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
5983 {
5984   /* Operand register numbers.  */
5985   int nRdHi, nRdLo, nRs, nRm;
5986   ARMword RdHi = 0, RdLo = 0, Rm;
5987   /* Cycle count.  */
5988   int scount;
5989 
5990   nRdHi = BITS (16, 19);
5991   nRdLo = BITS (12, 15);
5992   nRs = BITS (8, 11);
5993   nRm = BITS (0, 3);
5994 
5995   /* Needed to calculate the cycle count.  */
5996   Rm = state->Reg[nRm];
5997 
5998   /* Check for illegal operand combinations first.  */
5999   if (   nRdHi != 15
6000       && nRdLo != 15
6001       && nRs   != 15
6002       && nRm   != 15
6003       && nRdHi != nRdLo)
6004     {
6005       /* Intermediate results.  */
6006       ARMword lo, mid1, mid2, hi;
6007       int carry;
6008       ARMword Rs = state->Reg[nRs];
6009       int sign = 0;
6010 
6011 #ifdef MODE32
6012       if (state->is_v6)
6013 	;
6014       else
6015 #endif
6016 	/* BAD code can trigger this result.  So only complain if debugging.  */
6017 	if (state->Debug && (nRdHi == nRm || nRdLo == nRm))
6018 	  fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS: %d %d %d\n",
6019 		   nRdHi, nRdLo, nRm);
6020       if (msigned)
6021 	{
6022 	  /* Compute sign of result and adjust operands if necessary.  */
6023 	  sign = (Rm ^ Rs) & 0x80000000;
6024 
6025 	  if (((ARMsword) Rm) < 0)
6026 	    Rm = -Rm;
6027 
6028 	  if (((ARMsword) Rs) < 0)
6029 	    Rs = -Rs;
6030 	}
6031 
6032       /* We can split the 32x32 into four 16x16 operations. This
6033 	 ensures that we do not lose precision on 32bit only hosts.  */
6034       lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
6035       mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
6036       mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
6037       hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
6038 
6039       /* We now need to add all of these results together, taking
6040 	 care to propogate the carries from the additions.  */
6041       RdLo = Add32 (lo, (mid1 << 16), &carry);
6042       RdHi = carry;
6043       RdLo = Add32 (RdLo, (mid2 << 16), &carry);
6044       RdHi +=
6045 	(carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
6046 
6047       if (sign)
6048 	{
6049 	  /* Negate result if necessary.  */
6050 	  RdLo = ~RdLo;
6051 	  RdHi = ~RdHi;
6052 	  if (RdLo == 0xFFFFFFFF)
6053 	    {
6054 	      RdLo = 0;
6055 	      RdHi += 1;
6056 	    }
6057 	  else
6058 	    RdLo += 1;
6059 	}
6060 
6061       state->Reg[nRdLo] = RdLo;
6062       state->Reg[nRdHi] = RdHi;
6063     }
6064   else if (state->Debug)
6065     fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS\n");
6066 
6067   if (scc)
6068     /* Ensure that both RdHi and RdLo are used to compute Z,
6069        but don't let RdLo's sign bit make it to N.  */
6070     ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
6071 
6072   /* The cycle count depends on whether the instruction is a signed or
6073      unsigned multiply, and what bits are clear in the multiplier.  */
6074   if (msigned && (Rm & ((unsigned) 1 << 31)))
6075     /* Invert the bits to make the check against zero.  */
6076     Rm = ~Rm;
6077 
6078   if ((Rm & 0xFFFFFF00) == 0)
6079     scount = 1;
6080   else if ((Rm & 0xFFFF0000) == 0)
6081     scount = 2;
6082   else if ((Rm & 0xFF000000) == 0)
6083     scount = 3;
6084   else
6085     scount = 4;
6086 
6087   return 2 + scount;
6088 }
6089 
6090 /* This function does the work of multiplying two 32bit
6091    values and adding a 64bit value to give a 64bit result.  */
6092 
6093 static unsigned
6094 MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc)
6095 {
6096   unsigned scount;
6097   ARMword RdLo, RdHi;
6098   int nRdHi, nRdLo;
6099   int carry = 0;
6100 
6101   nRdHi = BITS (16, 19);
6102   nRdLo = BITS (12, 15);
6103 
6104   RdHi = state->Reg[nRdHi];
6105   RdLo = state->Reg[nRdLo];
6106 
6107   scount = Multiply64 (state, instr, msigned, LDEFAULT);
6108 
6109   RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry);
6110   RdHi = (RdHi + state->Reg[nRdHi]) + carry;
6111 
6112   state->Reg[nRdLo] = RdLo;
6113   state->Reg[nRdHi] = RdHi;
6114 
6115   if (scc)
6116     /* Ensure that both RdHi and RdLo are used to compute Z,
6117        but don't let RdLo's sign bit make it to N.  */
6118     ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
6119 
6120   /* Extra cycle for addition.  */
6121   return scount + 1;
6122 }
6123