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