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