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