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