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>.
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.
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.
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/>. */
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);
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 */
51 #ifdef NEED_UI_LOOP_HOOK
52 /* How often to run the ui_loop update, when in use. */
53 #define UI_LOOP_POLL_INTERVAL 0x32000
55 /* Counter for the ui_loop_hook update. */
56 static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
58 /* Actual hook to call to run through gdb's gui event loop. */
59 extern int (*deprecated_ui_loop_hook) (int);
60 #endif /* NEED_UI_LOOP_HOOK */
62 extern int stop_simulator;
64 /* Short-hand macros for LDR/STR. */
66 /* Store post decrement writeback. */
69 if (StoreHalfWord (state, instr, lhs)) \
70 LSBase = lhs - GetLS7RHS (state, instr);
72 /* Store post increment writeback. */
75 if (StoreHalfWord (state, instr, lhs)) \
76 LSBase = lhs + GetLS7RHS (state, instr);
78 /* Store pre decrement. */
80 (void)StoreHalfWord (state, instr, LHS - GetLS7RHS (state, instr));
82 /* Store pre decrement writeback. */
83 #define SHPREDOWNWB() \
84 temp = LHS - GetLS7RHS (state, instr); \
85 if (StoreHalfWord (state, instr, temp)) \
88 /* Store pre increment. */
90 (void)StoreHalfWord (state, instr, LHS + GetLS7RHS (state, instr));
92 /* Store pre increment writeback. */
94 temp = LHS + GetLS7RHS (state, instr); \
95 if (StoreHalfWord (state, instr, temp)) \
98 /* Load post decrement writeback. */
99 #define LHPOSTDOWN() \
103 temp = lhs - GetLS7RHS (state, instr); \
105 switch (BITS (5, 6)) \
108 if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \
112 if (LoadByte (state, instr, lhs, LSIGNED)) \
116 if (LoadHalfWord (state, instr, lhs, LSIGNED)) \
119 case 0: /* SWP handled elsewhere. */ \
128 /* Load post increment writeback. */
133 temp = lhs + GetLS7RHS (state, instr); \
135 switch (BITS (5, 6)) \
138 if (LoadHalfWord (state, instr, lhs, LUNSIGNED)) \
142 if (LoadByte (state, instr, lhs, LSIGNED)) \
146 if (LoadHalfWord (state, instr, lhs, LSIGNED)) \
149 case 0: /* SWP handled elsewhere. */ \
158 /* Load pre decrement. */
159 #define LHPREDOWN() \
163 temp = LHS - GetLS7RHS (state, instr); \
164 switch (BITS (5, 6)) \
167 (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \
170 (void) LoadByte (state, instr, temp, LSIGNED); \
173 (void) LoadHalfWord (state, instr, temp, LSIGNED); \
176 /* SWP handled elsewhere. */ \
185 /* Load pre decrement writeback. */
186 #define LHPREDOWNWB() \
190 temp = LHS - GetLS7RHS (state, instr); \
191 switch (BITS (5, 6)) \
194 if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \
198 if (LoadByte (state, instr, temp, LSIGNED)) \
202 if (LoadHalfWord (state, instr, temp, LSIGNED)) \
206 /* SWP handled elsewhere. */ \
215 /* Load pre increment. */
220 temp = LHS + GetLS7RHS (state, instr); \
221 switch (BITS (5, 6)) \
224 (void) LoadHalfWord (state, instr, temp, LUNSIGNED); \
227 (void) LoadByte (state, instr, temp, LSIGNED); \
230 (void) LoadHalfWord (state, instr, temp, LSIGNED); \
233 /* SWP handled elsewhere. */ \
242 /* Load pre increment writeback. */
243 #define LHPREUPWB() \
247 temp = LHS + GetLS7RHS (state, instr); \
248 switch (BITS (5, 6)) \
251 if (LoadHalfWord (state, instr, temp, LUNSIGNED)) \
255 if (LoadByte (state, instr, temp, LSIGNED)) \
259 if (LoadHalfWord (state, instr, temp, LSIGNED)) \
263 /* SWP handled elsewhere. */ \
272 /* Attempt to emulate an ARMv6 instruction.
273 Returns non-zero upon success. */
276 handle_v6_insn (ARMul_State * state, ARMword instr)
278 switch (BITS (20, 27))
281 case 0x03: printf ("Unhandled v6 insn: ldr\n"); break;
282 case 0x04: printf ("Unhandled v6 insn: umaal\n"); break;
283 case 0x06: printf ("Unhandled v6 insn: mls/str\n"); break;
284 case 0x16: printf ("Unhandled v6 insn: smi\n"); break;
285 case 0x18: printf ("Unhandled v6 insn: strex\n"); break;
286 case 0x19: printf ("Unhandled v6 insn: ldrex\n"); break;
287 case 0x1a: printf ("Unhandled v6 insn: strexd\n"); break;
288 case 0x1b: printf ("Unhandled v6 insn: ldrexd\n"); break;
289 case 0x1c: printf ("Unhandled v6 insn: strexb\n"); break;
290 case 0x1d: printf ("Unhandled v6 insn: ldrexb\n"); break;
291 case 0x1e: printf ("Unhandled v6 insn: strexh\n"); break;
292 case 0x1f: printf ("Unhandled v6 insn: ldrexh\n"); break;
293 case 0x30: printf ("Unhandled v6 insn: movw\n"); break;
294 case 0x32: printf ("Unhandled v6 insn: nop/sev/wfe/wfi/yield\n"); break;
295 case 0x34: printf ("Unhandled v6 insn: movt\n"); break;
296 case 0x3f: printf ("Unhandled v6 insn: rbit\n"); break;
298 case 0x61: printf ("Unhandled v6 insn: sadd/ssub\n"); break;
299 case 0x62: printf ("Unhandled v6 insn: qadd/qsub\n"); break;
300 case 0x63: printf ("Unhandled v6 insn: shadd/shsub\n"); break;
301 case 0x65: printf ("Unhandled v6 insn: uadd/usub\n"); break;
302 case 0x66: printf ("Unhandled v6 insn: uqadd/uqsub\n"); break;
303 case 0x67: printf ("Unhandled v6 insn: uhadd/uhsub\n"); break;
304 case 0x68: printf ("Unhandled v6 insn: pkh/sxtab/selsxtb\n"); break;
305 case 0x6c: printf ("Unhandled v6 insn: uxtb16/uxtab16\n"); break;
306 case 0x70: printf ("Unhandled v6 insn: smuad/smusd/smlad/smlsd\n"); break;
307 case 0x74: printf ("Unhandled v6 insn: smlald/smlsld\n"); break;
308 case 0x75: printf ("Unhandled v6 insn: smmla/smmls/smmul\n"); break;
309 case 0x78: printf ("Unhandled v6 insn: usad/usada8\n"); break;
310 case 0x7a: printf ("Unhandled v6 insn: usbfx\n"); break;
311 case 0x7c: printf ("Unhandled v6 insn: bfc/bfi\n"); break;
318 switch (BITS (4, 11))
320 case 0x07: ror = 0; break;
321 case 0x47: ror = 8; break;
322 case 0x87: ror = 16; break;
323 case 0xc7: ror = 24; break;
327 printf ("Unhandled v6 insn: ssat\n");
335 if (BITS (4, 6) == 0x7)
337 printf ("Unhandled v6 insn: ssat\n");
343 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
347 if (BITS (16, 19) == 0xf)
349 state->Reg[BITS (12, 15)] = Rm;
352 state->Reg[BITS (12, 15)] += Rm;
361 switch (BITS (4, 11))
363 case 0x07: ror = 0; break;
364 case 0x47: ror = 8; break;
365 case 0x87: ror = 16; break;
366 case 0xc7: ror = 24; break;
369 printf ("Unhandled v6 insn: rev\n");
378 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
382 if (BITS (16, 19) == 0xf)
384 state->Reg[BITS (12, 15)] = Rm;
387 state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
396 switch (BITS (4, 11))
398 case 0x07: ror = 0; break;
399 case 0x47: ror = 8; break;
400 case 0x87: ror = 16; break;
401 case 0xc7: ror = 24; break;
405 printf ("Unhandled v6 insn: usat\n");
413 if (BITS (4, 6) == 0x7)
415 printf ("Unhandled v6 insn: usat\n");
421 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFF);
423 if (BITS (16, 19) == 0xf)
425 state->Reg[BITS (12, 15)] = Rm;
428 state->Reg[BITS (12, 15)] = state->Reg[BITS (16, 19)] + Rm;
437 switch (BITS (4, 11))
439 case 0x07: ror = 0; break;
440 case 0x47: ror = 8; break;
441 case 0x87: ror = 16; break;
442 case 0xc7: ror = 24; break;
445 printf ("Unhandled v6 insn: revsh\n");
454 Rm = ((state->Reg[BITS (0, 3)] >> ror) & 0xFFFF);
456 if (BITS (16, 19) == 0xf)
458 state->Reg[BITS (12, 15)] = Rm;
462 state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm;
468 case 0x84: printf ("Unhandled v6 insn: srs\n"); break;
473 printf ("Unhandled v6 insn: UNKNOWN: %08x\n", instr);
477 /* EMULATION of ARM6. */
479 /* The PC pipeline value depends on whether ARM
480 or Thumb instructions are being executed. */
485 ARMul_Emulate32 (ARMul_State * state)
487 ARMul_Emulate26 (ARMul_State * state)
490 ARMword instr; /* The current instruction. */
491 ARMword dest = 0; /* Almost the DestBus. */
492 ARMword temp; /* Ubiquitous third hand. */
493 ARMword pc = 0; /* The address of the current instruction. */
494 ARMword lhs; /* Almost the ABus and BBus. */
496 ARMword decoded = 0; /* Instruction pipeline. */
499 /* Execute the next instruction. */
501 if (state->NextInstr < PRIMEPIPE)
503 decoded = state->decoded;
504 loaded = state->loaded;
510 /* Just keep going. */
513 switch (state->NextInstr)
516 /* Advance the pipeline, and an S cycle. */
517 state->Reg[15] += isize;
521 loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
525 /* Advance the pipeline, and an N cycle. */
526 state->Reg[15] += isize;
530 loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
535 /* Program counter advanced, and an S cycle. */
539 loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
544 /* Program counter advanced, and an N cycle. */
548 loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
553 /* The program counter has been changed. */
558 state->Reg[15] = pc + (isize * 2);
560 instr = ARMul_ReLoadInstr (state, pc, isize);
561 decoded = ARMul_ReLoadInstr (state, pc + isize, isize);
562 loaded = ARMul_ReLoadInstr (state, pc + isize * 2, isize);
567 /* The program counter has been changed. */
572 state->Reg[15] = pc + (isize * 2);
574 instr = ARMul_LoadInstrN (state, pc, isize);
575 decoded = ARMul_LoadInstrS (state, pc + (isize), isize);
576 loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
582 ARMul_EnvokeEvent (state);
584 if (! TFLAG && trace)
586 fprintf (stderr, "pc: %x, ", pc & ~1);
588 fprintf (stderr, "instr: %x\n", instr);
591 if (instr == 0 || pc < 0x10)
593 ARMul_Abort (state, ARMUndefinedInstrV);
594 state->Emulate = FALSE;
597 #if 0 /* Enable this code to help track down stack alignment bugs. */
599 static ARMword old_sp = -1;
601 if (old_sp != state->Reg[13])
603 old_sp = state->Reg[13];
604 fprintf (stderr, "pc: %08x: SP set to %08x%s\n",
605 pc & ~1, old_sp, (old_sp % 8) ? " [UNALIGNED!]" : "");
610 if (state->Exception)
612 /* Any exceptions ? */
613 if (state->NresetSig == LOW)
615 ARMul_Abort (state, ARMul_ResetV);
618 else if (!state->NfiqSig && !FFLAG)
620 ARMul_Abort (state, ARMul_FIQV);
623 else if (!state->NirqSig && !IFLAG)
625 ARMul_Abort (state, ARMul_IRQV);
630 if (state->CallDebug > 0)
632 instr = ARMul_Debug (state, pc, instr);
633 if (state->Emulate < ONCE)
635 state->NextInstr = RESUME;
640 fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n",
641 (long) pc, (long) instr, (long) state->Mode);
642 (void) fgetc (stdin);
645 else if (state->Emulate < ONCE)
647 state->NextInstr = RESUME;
654 /* Provide Thumb instruction decoding. If the processor is in Thumb
655 mode, then we can simply decode the Thumb instruction, and map it
656 to the corresponding ARM instruction (by directly loading the
657 instr variable, and letting the normal ARM simulator
658 execute). There are some caveats to ensure that the correct
659 pipelined PC value is used when executing Thumb code, and also for
660 dealing with the BL instruction. */
665 /* Check if in Thumb mode. */
666 switch (ARMul_ThumbDecode (state, pc, instr, &new))
669 /* This is a Thumb instruction. */
670 ARMul_UndefInstr (state, instr);
674 /* Already processed. */
678 /* ARM instruction available. */
681 fprintf (stderr, " emulate as: ");
683 fprintf (stderr, "%08x ", new);
685 fprintf (stderr, "\n");
688 /* So continue instruction decoding. */
698 /* Check the condition codes. */
699 if ((temp = TOPBITS (28)) == AL)
700 /* Vile deed in the need for speed. */
703 /* Check the condition code. */
704 switch ((int) TOPBITS (28))
712 if (BITS (25, 27) == 5) /* BLX(1) */
716 state->Reg[14] = pc + 4;
718 /* Force entry into Thumb mode. */
721 dest += (NEGBRANCH + (BIT (24) << 1));
723 dest += POSBRANCH + (BIT (24) << 1);
725 WriteR15Branch (state, dest);
728 else if ((instr & 0xFC70F000) == 0xF450F000)
729 /* The PLD instruction. Ignored. */
731 else if ( ((instr & 0xfe500f00) == 0xfc100100)
732 || ((instr & 0xfe500f00) == 0xfc000100))
733 /* wldrw and wstrw are unconditional. */
736 /* UNDEFINED in v5, UNPREDICTABLE in v3, v4, non executed in v1, v2. */
737 ARMul_UndefInstr (state, instr);
766 temp = (CFLAG && !ZFLAG);
769 temp = (!CFLAG || ZFLAG);
772 temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
775 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
778 temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
781 temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
785 /* Handle the Clock counter here. */
786 if (state->is_XScale)
791 ok = state->CPRead[14] (state, 0, & cp14r0);
793 if (ok && (cp14r0 & ARMul_CP14_R0_ENABLE))
795 unsigned long newcycles, nowtime = ARMul_Time (state);
797 newcycles = nowtime - state->LastTime;
798 state->LastTime = nowtime;
800 if (cp14r0 & ARMul_CP14_R0_CCD)
802 if (state->CP14R0_CCD == -1)
803 state->CP14R0_CCD = newcycles;
805 state->CP14R0_CCD += newcycles;
807 if (state->CP14R0_CCD >= 64)
811 while (state->CP14R0_CCD >= 64)
812 state->CP14R0_CCD -= 64, newcycles++;
822 state->CP14R0_CCD = -1;
824 cp14r0 |= ARMul_CP14_R0_FLAG2;
825 (void) state->CPWrite[14] (state, 0, cp14r0);
827 ok = state->CPRead[14] (state, 1, & cp14r1);
829 /* Coded like this for portability. */
830 while (ok && newcycles)
832 if (cp14r1 == 0xffffffff)
843 (void) state->CPWrite[14] (state, 1, cp14r1);
845 if (do_int && (cp14r0 & ARMul_CP14_R0_INTEN2))
849 if (state->CPRead[13] (state, 8, & temp)
850 && (temp & ARMul_CP13_R8_PMUS))
851 ARMul_Abort (state, ARMul_FIQV);
853 ARMul_Abort (state, ARMul_IRQV);
859 /* Handle hardware instructions breakpoints here. */
860 if (state->is_XScale)
862 if ( (pc | 3) == (read_cp15_reg (14, 0, 8) | 2)
863 || (pc | 3) == (read_cp15_reg (14, 0, 9) | 2))
865 if (XScale_debug_moe (state, ARMul_CP14_R10_MOE_IB))
866 ARMul_OSHandleSWI (state, SWI_Breakpoint);
870 /* Actual execution of instructions begins here. */
871 /* If the condition codes don't match, stop here. */
876 if (state->is_XScale)
878 if (BIT (20) == 0 && BITS (25, 27) == 0)
880 if (BITS (4, 7) == 0xD)
882 /* XScale Load Consecutive insn. */
883 ARMword temp = GetLS7RHS (state, instr);
884 ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
885 ARMword addr = BIT (24) ? temp2 : LHS;
888 ARMul_UndefInstr (state, instr);
890 /* Alignment violation. */
891 ARMul_Abort (state, ARMul_DataAbortV);
894 int wb = BIT (21) || (! BIT (24));
896 state->Reg[BITS (12, 15)] =
897 ARMul_LoadWordN (state, addr);
898 state->Reg[BITS (12, 15) + 1] =
899 ARMul_LoadWordN (state, addr + 4);
906 else if (BITS (4, 7) == 0xF)
908 /* XScale Store Consecutive insn. */
909 ARMword temp = GetLS7RHS (state, instr);
910 ARMword temp2 = BIT (23) ? LHS + temp : LHS - temp;
911 ARMword addr = BIT (24) ? temp2 : LHS;
914 ARMul_UndefInstr (state, instr);
916 /* Alignment violation. */
917 ARMul_Abort (state, ARMul_DataAbortV);
920 ARMul_StoreWordN (state, addr,
921 state->Reg[BITS (12, 15)]);
922 ARMul_StoreWordN (state, addr + 4,
923 state->Reg[BITS (12, 15) + 1]);
925 if (BIT (21)|| ! BIT (24))
933 if (ARMul_HandleIwmmxt (state, instr))
937 switch ((int) BITS (20, 27))
939 /* Data Processing Register RHS Instructions. */
941 case 0x00: /* AND reg and MUL */
943 if (BITS (4, 11) == 0xB)
945 /* STRH register offset, no write-back, down, post indexed. */
949 if (BITS (4, 7) == 0xD)
951 Handle_Load_Double (state, instr);
954 if (BITS (4, 7) == 0xF)
956 Handle_Store_Double (state, instr);
960 if (BITS (4, 7) == 9)
963 rhs = state->Reg[MULRHSReg];
964 if (MULLHSReg == MULDESTReg)
967 state->Reg[MULDESTReg] = 0;
969 else if (MULDESTReg != 15)
970 state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
974 for (dest = 0, temp = 0; dest < 32; dest ++)
975 if (rhs & (1L << dest))
978 /* Mult takes this many/2 I cycles. */
979 ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
990 case 0x01: /* ANDS reg and MULS */
992 if ((BITS (4, 11) & 0xF9) == 0x9)
993 /* LDR register offset, no write-back, down, post indexed. */
995 /* Fall through to rest of decoding. */
997 if (BITS (4, 7) == 9)
1000 rhs = state->Reg[MULRHSReg];
1002 if (MULLHSReg == MULDESTReg)
1005 state->Reg[MULDESTReg] = 0;
1009 else if (MULDESTReg != 15)
1011 dest = state->Reg[MULLHSReg] * rhs;
1012 ARMul_NegZero (state, dest);
1013 state->Reg[MULDESTReg] = dest;
1018 for (dest = 0, temp = 0; dest < 32; dest ++)
1019 if (rhs & (1L << dest))
1022 /* Mult takes this many/2 I cycles. */
1023 ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
1034 case 0x02: /* EOR reg and MLA */
1036 if (BITS (4, 11) == 0xB)
1038 /* STRH register offset, write-back, down, post indexed. */
1043 if (BITS (4, 7) == 9)
1045 rhs = state->Reg[MULRHSReg];
1046 if (MULLHSReg == MULDESTReg)
1049 state->Reg[MULDESTReg] = state->Reg[MULACCReg];
1051 else if (MULDESTReg != 15)
1052 state->Reg[MULDESTReg] =
1053 state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
1057 for (dest = 0, temp = 0; dest < 32; dest ++)
1058 if (rhs & (1L << dest))
1061 /* Mult takes this many/2 I cycles. */
1062 ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
1072 case 0x03: /* EORS reg and MLAS */
1074 if ((BITS (4, 11) & 0xF9) == 0x9)
1075 /* LDR register offset, write-back, down, post-indexed. */
1077 /* Fall through to rest of the decoding. */
1079 if (BITS (4, 7) == 9)
1082 rhs = state->Reg[MULRHSReg];
1084 if (MULLHSReg == MULDESTReg)
1087 dest = state->Reg[MULACCReg];
1088 ARMul_NegZero (state, dest);
1089 state->Reg[MULDESTReg] = dest;
1091 else if (MULDESTReg != 15)
1094 state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
1095 ARMul_NegZero (state, dest);
1096 state->Reg[MULDESTReg] = dest;
1101 for (dest = 0, temp = 0; dest < 32; dest ++)
1102 if (rhs & (1L << dest))
1105 /* Mult takes this many/2 I cycles. */
1106 ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
1117 case 0x04: /* SUB reg */
1119 if (BITS (4, 7) == 0xB)
1121 /* STRH immediate offset, no write-back, down, post indexed. */
1125 if (BITS (4, 7) == 0xD)
1127 Handle_Load_Double (state, instr);
1130 if (BITS (4, 7) == 0xF)
1132 Handle_Store_Double (state, instr);
1141 case 0x05: /* SUBS reg */
1143 if ((BITS (4, 7) & 0x9) == 0x9)
1144 /* LDR immediate offset, no write-back, down, post indexed. */
1146 /* Fall through to the rest of the instruction decoding. */
1152 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
1154 ARMul_SubCarry (state, lhs, rhs, dest);
1155 ARMul_SubOverflow (state, lhs, rhs, dest);
1165 case 0x06: /* RSB reg */
1167 if (BITS (4, 7) == 0xB)
1169 /* STRH immediate offset, write-back, down, post indexed. */
1179 case 0x07: /* RSBS reg */
1181 if ((BITS (4, 7) & 0x9) == 0x9)
1182 /* LDR immediate offset, write-back, down, post indexed. */
1184 /* Fall through to remainder of instruction decoding. */
1190 if ((rhs >= lhs) || ((rhs | lhs) >> 31))
1192 ARMul_SubCarry (state, rhs, lhs, dest);
1193 ARMul_SubOverflow (state, rhs, lhs, dest);
1203 case 0x08: /* ADD reg */
1205 if (BITS (4, 11) == 0xB)
1207 /* STRH register offset, no write-back, up, post indexed. */
1211 if (BITS (4, 7) == 0xD)
1213 Handle_Load_Double (state, instr);
1216 if (BITS (4, 7) == 0xF)
1218 Handle_Store_Double (state, instr);
1223 if (BITS (4, 7) == 0x9)
1227 ARMul_Icycles (state,
1228 Multiply64 (state, instr, LUNSIGNED,
1238 case 0x09: /* ADDS reg */
1240 if ((BITS (4, 11) & 0xF9) == 0x9)
1241 /* LDR register offset, no write-back, up, post indexed. */
1243 /* Fall through to remaining instruction decoding. */
1246 if (BITS (4, 7) == 0x9)
1250 ARMul_Icycles (state,
1251 Multiply64 (state, instr, LUNSIGNED, LSCC),
1259 ASSIGNZ (dest == 0);
1260 if ((lhs | rhs) >> 30)
1262 /* Possible C,V,N to set. */
1263 ASSIGNN (NEG (dest));
1264 ARMul_AddCarry (state, lhs, rhs, dest);
1265 ARMul_AddOverflow (state, lhs, rhs, dest);
1276 case 0x0a: /* ADC reg */
1278 if (BITS (4, 11) == 0xB)
1280 /* STRH register offset, write-back, up, post-indexed. */
1284 if (BITS (4, 7) == 0x9)
1288 ARMul_Icycles (state,
1289 MultiplyAdd64 (state, instr, LUNSIGNED,
1295 dest = LHS + rhs + CFLAG;
1299 case 0x0b: /* ADCS reg */
1301 if ((BITS (4, 11) & 0xF9) == 0x9)
1302 /* LDR register offset, write-back, up, post indexed. */
1304 /* Fall through to remaining instruction decoding. */
1305 if (BITS (4, 7) == 0x9)
1309 ARMul_Icycles (state,
1310 MultiplyAdd64 (state, instr, LUNSIGNED,
1317 dest = lhs + rhs + CFLAG;
1318 ASSIGNZ (dest == 0);
1319 if ((lhs | rhs) >> 30)
1321 /* Possible C,V,N to set. */
1322 ASSIGNN (NEG (dest));
1323 ARMul_AddCarry (state, lhs, rhs, dest);
1324 ARMul_AddOverflow (state, lhs, rhs, dest);
1335 case 0x0c: /* SBC reg */
1337 if (BITS (4, 7) == 0xB)
1339 /* STRH immediate offset, no write-back, up post indexed. */
1343 if (BITS (4, 7) == 0xD)
1345 Handle_Load_Double (state, instr);
1348 if (BITS (4, 7) == 0xF)
1350 Handle_Store_Double (state, instr);
1353 if (BITS (4, 7) == 0x9)
1357 ARMul_Icycles (state,
1358 Multiply64 (state, instr, LSIGNED, LDEFAULT),
1364 dest = LHS - rhs - !CFLAG;
1368 case 0x0d: /* SBCS reg */
1370 if ((BITS (4, 7) & 0x9) == 0x9)
1371 /* LDR immediate offset, no write-back, up, post indexed. */
1374 if (BITS (4, 7) == 0x9)
1378 ARMul_Icycles (state,
1379 Multiply64 (state, instr, LSIGNED, LSCC),
1386 dest = lhs - rhs - !CFLAG;
1387 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
1389 ARMul_SubCarry (state, lhs, rhs, dest);
1390 ARMul_SubOverflow (state, lhs, rhs, dest);
1400 case 0x0e: /* RSC reg */
1402 if (BITS (4, 7) == 0xB)
1404 /* STRH immediate offset, write-back, up, post indexed. */
1409 if (BITS (4, 7) == 0x9)
1413 ARMul_Icycles (state,
1414 MultiplyAdd64 (state, instr, LSIGNED,
1420 dest = rhs - LHS - !CFLAG;
1424 case 0x0f: /* RSCS reg */
1426 if ((BITS (4, 7) & 0x9) == 0x9)
1427 /* LDR immediate offset, write-back, up, post indexed. */
1429 /* Fall through to remaining instruction decoding. */
1431 if (BITS (4, 7) == 0x9)
1435 ARMul_Icycles (state,
1436 MultiplyAdd64 (state, instr, LSIGNED, LSCC),
1443 dest = rhs - lhs - !CFLAG;
1445 if ((rhs >= lhs) || ((rhs | lhs) >> 31))
1447 ARMul_SubCarry (state, rhs, lhs, dest);
1448 ARMul_SubOverflow (state, rhs, lhs, dest);
1458 case 0x10: /* TST reg and MRS CPSR and SWP word. */
1461 if (BIT (4) == 0 && BIT (7) == 1)
1463 /* ElSegundo SMLAxy insn. */
1464 ARMword op1 = state->Reg[BITS (0, 3)];
1465 ARMword op2 = state->Reg[BITS (8, 11)];
1466 ARMword Rn = state->Reg[BITS (12, 15)];
1480 if (AddOverflow (op1, Rn, op1 + Rn))
1482 state->Reg[BITS (16, 19)] = op1 + Rn;
1486 if (BITS (4, 11) == 5)
1488 /* ElSegundo QADD insn. */
1489 ARMword op1 = state->Reg[BITS (0, 3)];
1490 ARMword op2 = state->Reg[BITS (16, 19)];
1491 ARMword result = op1 + op2;
1492 if (AddOverflow (op1, op2, result))
1494 result = POS (result) ? 0x80000000 : 0x7fffffff;
1497 state->Reg[BITS (12, 15)] = result;
1502 if (BITS (4, 11) == 0xB)
1504 /* STRH register offset, no write-back, down, pre indexed. */
1508 if (BITS (4, 7) == 0xD)
1510 Handle_Load_Double (state, instr);
1513 if (BITS (4, 7) == 0xF)
1515 Handle_Store_Double (state, instr);
1519 if (BITS (4, 11) == 9)
1526 if (VECTORACCESS (temp) || ADDREXCEPT (temp))
1528 INTERNALABORT (temp);
1529 (void) ARMul_LoadWordN (state, temp);
1530 (void) ARMul_LoadWordN (state, temp);
1534 dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]);
1536 DEST = ARMul_Align (state, temp, dest);
1539 if (state->abortSig || state->Aborted)
1542 else if ((BITS (0, 11) == 0) && (LHSReg == 15))
1545 DEST = ECC | EINT | EMODE;
1553 case 0x11: /* TSTP reg */
1555 if ((BITS (4, 11) & 0xF9) == 0x9)
1556 /* LDR register offset, no write-back, down, pre indexed. */
1558 /* Continue with remaining instruction decode. */
1564 state->Cpsr = GETSPSR (state->Bank);
1565 ARMul_CPSRAltered (state);
1577 ARMul_NegZero (state, dest);
1581 case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6). */
1584 if (BITS (4, 7) == 3)
1590 temp = (pc + 2) | 1;
1594 WriteR15Branch (state, state->Reg[RHSReg]);
1595 state->Reg[14] = temp;
1602 if (BIT (4) == 0 && BIT (7) == 1
1603 && (BIT (5) == 0 || BITS (12, 15) == 0))
1605 /* ElSegundo SMLAWy/SMULWy insn. */
1606 ARMdword op1 = state->Reg[BITS (0, 3)];
1607 ARMdword op2 = state->Reg[BITS (8, 11)];
1612 if (op1 & 0x80000000)
1617 result = (op1 * op2) >> 16;
1621 ARMword Rn = state->Reg[BITS (12, 15)];
1623 if (AddOverflow (result, Rn, result + Rn))
1627 state->Reg[BITS (16, 19)] = result;
1631 if (BITS (4, 11) == 5)
1633 /* ElSegundo QSUB insn. */
1634 ARMword op1 = state->Reg[BITS (0, 3)];
1635 ARMword op2 = state->Reg[BITS (16, 19)];
1636 ARMword result = op1 - op2;
1638 if (SubOverflow (op1, op2, result))
1640 result = POS (result) ? 0x80000000 : 0x7fffffff;
1644 state->Reg[BITS (12, 15)] = result;
1649 if (BITS (4, 11) == 0xB)
1651 /* STRH register offset, write-back, down, pre indexed. */
1655 if (BITS (4, 27) == 0x12FFF1)
1658 WriteR15Branch (state, state->Reg[RHSReg]);
1661 if (BITS (4, 7) == 0xD)
1663 Handle_Load_Double (state, instr);
1666 if (BITS (4, 7) == 0xF)
1668 Handle_Store_Double (state, instr);
1674 if (BITS (4, 7) == 0x7)
1676 extern int SWI_vector_installed;
1678 /* Hardware is allowed to optionally override this
1679 instruction and treat it as a breakpoint. Since
1680 this is a simulator not hardware, we take the position
1681 that if a SWI vector was not installed, then an Abort
1682 vector was probably not installed either, and so
1683 normally this instruction would be ignored, even if an
1684 Abort is generated. This is a bad thing, since GDB
1685 uses this instruction for its breakpoints (at least in
1686 Thumb mode it does). So intercept the instruction here
1687 and generate a breakpoint SWI instead. */
1688 if (! SWI_vector_installed)
1689 ARMul_OSHandleSWI (state, SWI_Breakpoint);
1692 /* BKPT - normally this will cause an abort, but on the
1693 XScale we must check the DCSR. */
1694 XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
1695 if (!XScale_debug_moe (state, ARMul_CP14_R10_MOE_BT))
1699 /* Force the next instruction to be refetched. */
1700 state->NextInstr = RESUME;
1706 /* MSR reg to CPSR. */
1710 /* Don't allow TBIT to be set by MSR. */
1713 ARMul_FixCPSR (state, instr, temp);
1720 case 0x13: /* TEQP reg */
1722 if ((BITS (4, 11) & 0xF9) == 0x9)
1723 /* LDR register offset, write-back, down, pre indexed. */
1725 /* Continue with remaining instruction decode. */
1731 state->Cpsr = GETSPSR (state->Bank);
1732 ARMul_CPSRAltered (state);
1744 ARMul_NegZero (state, dest);
1748 case 0x14: /* CMP reg and MRS SPSR and SWP byte. */
1751 if (BIT (4) == 0 && BIT (7) == 1)
1753 /* ElSegundo SMLALxy insn. */
1754 ARMdword op1 = state->Reg[BITS (0, 3)];
1755 ARMdword op2 = state->Reg[BITS (8, 11)];
1769 dest = (ARMdword) state->Reg[BITS (16, 19)] << 32;
1770 dest |= state->Reg[BITS (12, 15)];
1772 state->Reg[BITS (12, 15)] = dest;
1773 state->Reg[BITS (16, 19)] = dest >> 32;
1777 if (BITS (4, 11) == 5)
1779 /* ElSegundo QDADD insn. */
1780 ARMword op1 = state->Reg[BITS (0, 3)];
1781 ARMword op2 = state->Reg[BITS (16, 19)];
1782 ARMword op2d = op2 + op2;
1785 if (AddOverflow (op2, op2, op2d))
1788 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
1791 result = op1 + op2d;
1792 if (AddOverflow (op1, op2d, result))
1795 result = POS (result) ? 0x80000000 : 0x7fffffff;
1798 state->Reg[BITS (12, 15)] = result;
1803 if (BITS (4, 7) == 0xB)
1805 /* STRH immediate offset, no write-back, down, pre indexed. */
1809 if (BITS (4, 7) == 0xD)
1811 Handle_Load_Double (state, instr);
1814 if (BITS (4, 7) == 0xF)
1816 Handle_Store_Double (state, instr);
1820 if (BITS (4, 11) == 9)
1827 if (VECTORACCESS (temp) || ADDREXCEPT (temp))
1829 INTERNALABORT (temp);
1830 (void) ARMul_LoadByte (state, temp);
1831 (void) ARMul_LoadByte (state, temp);
1835 DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
1836 if (state->abortSig || state->Aborted)
1839 else if ((BITS (0, 11) == 0) && (LHSReg == 15))
1843 DEST = GETSPSR (state->Bank);
1850 case 0x15: /* CMPP reg. */
1852 if ((BITS (4, 7) & 0x9) == 0x9)
1853 /* LDR immediate offset, no write-back, down, pre indexed. */
1855 /* Continue with remaining instruction decode. */
1861 state->Cpsr = GETSPSR (state->Bank);
1862 ARMul_CPSRAltered (state);
1875 ARMul_NegZero (state, dest);
1876 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
1878 ARMul_SubCarry (state, lhs, rhs, dest);
1879 ARMul_SubOverflow (state, lhs, rhs, dest);
1889 case 0x16: /* CMN reg and MSR reg to SPSR */
1892 if (BIT (4) == 0 && BIT (7) == 1 && BITS (12, 15) == 0)
1894 /* ElSegundo SMULxy insn. */
1895 ARMword op1 = state->Reg[BITS (0, 3)];
1896 ARMword op2 = state->Reg[BITS (8, 11)];
1909 state->Reg[BITS (16, 19)] = op1 * op2;
1913 if (BITS (4, 11) == 5)
1915 /* ElSegundo QDSUB insn. */
1916 ARMword op1 = state->Reg[BITS (0, 3)];
1917 ARMword op2 = state->Reg[BITS (16, 19)];
1918 ARMword op2d = op2 + op2;
1921 if (AddOverflow (op2, op2, op2d))
1924 op2d = POS (op2d) ? 0x80000000 : 0x7fffffff;
1927 result = op1 - op2d;
1928 if (SubOverflow (op1, op2d, result))
1931 result = POS (result) ? 0x80000000 : 0x7fffffff;
1934 state->Reg[BITS (12, 15)] = result;
1941 if (BITS (4, 11) == 0xF1 && BITS (16, 19) == 0xF)
1943 /* ARM5 CLZ insn. */
1944 ARMword op1 = state->Reg[BITS (0, 3)];
1948 for (result = 0; (op1 & 0x80000000) == 0; op1 <<= 1)
1951 state->Reg[BITS (12, 15)] = result;
1956 if (BITS (4, 7) == 0xB)
1958 /* STRH immediate offset, write-back, down, pre indexed. */
1962 if (BITS (4, 7) == 0xD)
1964 Handle_Load_Double (state, instr);
1967 if (BITS (4, 7) == 0xF)
1969 Handle_Store_Double (state, instr);
1977 ARMul_FixSPSR (state, instr, DPRegRHS);
1985 case 0x17: /* CMNP reg */
1987 if ((BITS (4, 7) & 0x9) == 0x9)
1988 /* LDR immediate offset, write-back, down, pre indexed. */
1990 /* Continue with remaining instruction decoding. */
1995 state->Cpsr = GETSPSR (state->Bank);
1996 ARMul_CPSRAltered (state);
2010 ASSIGNZ (dest == 0);
2011 if ((lhs | rhs) >> 30)
2013 /* Possible C,V,N to set. */
2014 ASSIGNN (NEG (dest));
2015 ARMul_AddCarry (state, lhs, rhs, dest);
2016 ARMul_AddOverflow (state, lhs, rhs, dest);
2027 case 0x18: /* ORR reg */
2029 if (BITS (4, 11) == 0xB)
2031 /* STRH register offset, no write-back, up, pre indexed. */
2035 if (BITS (4, 7) == 0xD)
2037 Handle_Load_Double (state, instr);
2040 if (BITS (4, 7) == 0xF)
2042 Handle_Store_Double (state, instr);
2051 case 0x19: /* ORRS reg */
2053 if ((BITS (4, 11) & 0xF9) == 0x9)
2054 /* LDR register offset, no write-back, up, pre indexed. */
2056 /* Continue with remaining instruction decoding. */
2063 case 0x1a: /* MOV reg */
2065 if (BITS (4, 11) == 0xB)
2067 /* STRH register offset, write-back, up, pre indexed. */
2071 if (BITS (4, 7) == 0xD)
2073 Handle_Load_Double (state, instr);
2076 if (BITS (4, 7) == 0xF)
2078 Handle_Store_Double (state, instr);
2086 case 0x1b: /* MOVS reg */
2088 if ((BITS (4, 11) & 0xF9) == 0x9)
2089 /* LDR register offset, write-back, up, pre indexed. */
2091 /* Continue with remaining instruction decoding. */
2097 case 0x1c: /* BIC reg */
2099 if (BITS (4, 7) == 0xB)
2101 /* STRH immediate offset, no write-back, up, pre indexed. */
2105 if (BITS (4, 7) == 0xD)
2107 Handle_Load_Double (state, instr);
2110 else if (BITS (4, 7) == 0xF)
2112 Handle_Store_Double (state, instr);
2121 case 0x1d: /* BICS reg */
2123 if ((BITS (4, 7) & 0x9) == 0x9)
2124 /* LDR immediate offset, no write-back, up, pre indexed. */
2126 /* Continue with instruction decoding. */
2133 case 0x1e: /* MVN reg */
2135 if (BITS (4, 7) == 0xB)
2137 /* STRH immediate offset, write-back, up, pre indexed. */
2141 if (BITS (4, 7) == 0xD)
2143 Handle_Load_Double (state, instr);
2146 if (BITS (4, 7) == 0xF)
2148 Handle_Store_Double (state, instr);
2156 case 0x1f: /* MVNS reg */
2158 if ((BITS (4, 7) & 0x9) == 0x9)
2159 /* LDR immediate offset, write-back, up, pre indexed. */
2161 /* Continue instruction decoding. */
2168 /* Data Processing Immediate RHS Instructions. */
2170 case 0x20: /* AND immed */
2171 dest = LHS & DPImmRHS;
2175 case 0x21: /* ANDS immed */
2181 case 0x22: /* EOR immed */
2182 dest = LHS ^ DPImmRHS;
2186 case 0x23: /* EORS immed */
2192 case 0x24: /* SUB immed */
2193 dest = LHS - DPImmRHS;
2197 case 0x25: /* SUBS immed */
2202 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
2204 ARMul_SubCarry (state, lhs, rhs, dest);
2205 ARMul_SubOverflow (state, lhs, rhs, dest);
2215 case 0x26: /* RSB immed */
2216 dest = DPImmRHS - LHS;
2220 case 0x27: /* RSBS immed */
2225 if ((rhs >= lhs) || ((rhs | lhs) >> 31))
2227 ARMul_SubCarry (state, rhs, lhs, dest);
2228 ARMul_SubOverflow (state, rhs, lhs, dest);
2238 case 0x28: /* ADD immed */
2239 dest = LHS + DPImmRHS;
2243 case 0x29: /* ADDS immed */
2247 ASSIGNZ (dest == 0);
2249 if ((lhs | rhs) >> 30)
2251 /* Possible C,V,N to set. */
2252 ASSIGNN (NEG (dest));
2253 ARMul_AddCarry (state, lhs, rhs, dest);
2254 ARMul_AddOverflow (state, lhs, rhs, dest);
2265 case 0x2a: /* ADC immed */
2266 dest = LHS + DPImmRHS + CFLAG;
2270 case 0x2b: /* ADCS immed */
2273 dest = lhs + rhs + CFLAG;
2274 ASSIGNZ (dest == 0);
2275 if ((lhs | rhs) >> 30)
2277 /* Possible C,V,N to set. */
2278 ASSIGNN (NEG (dest));
2279 ARMul_AddCarry (state, lhs, rhs, dest);
2280 ARMul_AddOverflow (state, lhs, rhs, dest);
2291 case 0x2c: /* SBC immed */
2292 dest = LHS - DPImmRHS - !CFLAG;
2296 case 0x2d: /* SBCS immed */
2299 dest = lhs - rhs - !CFLAG;
2300 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
2302 ARMul_SubCarry (state, lhs, rhs, dest);
2303 ARMul_SubOverflow (state, lhs, rhs, dest);
2313 case 0x2e: /* RSC immed */
2314 dest = DPImmRHS - LHS - !CFLAG;
2318 case 0x2f: /* RSCS immed */
2321 dest = rhs - lhs - !CFLAG;
2322 if ((rhs >= lhs) || ((rhs | lhs) >> 31))
2324 ARMul_SubCarry (state, rhs, lhs, dest);
2325 ARMul_SubOverflow (state, rhs, lhs, dest);
2335 case 0x30: /* MOVW immed */
2336 dest = BITS (0, 11);
2337 dest |= (BITS (16, 19) << 12);
2341 case 0x31: /* TSTP immed */
2346 state->Cpsr = GETSPSR (state->Bank);
2347 ARMul_CPSRAltered (state);
2349 temp = LHS & DPImmRHS;
2358 ARMul_NegZero (state, dest);
2362 case 0x32: /* TEQ immed and MSR immed to CPSR */
2364 /* MSR immed to CPSR. */
2365 ARMul_FixCPSR (state, instr, DPImmRHS);
2370 case 0x33: /* TEQP immed */
2375 state->Cpsr = GETSPSR (state->Bank);
2376 ARMul_CPSRAltered (state);
2378 temp = LHS ^ DPImmRHS;
2384 DPSImmRHS; /* TEQ immed */
2386 ARMul_NegZero (state, dest);
2390 case 0x34: /* MOVT immed */
2391 dest = BITS (0, 11);
2392 dest |= (BITS (16, 19) << 12);
2393 DEST |= (dest << 16);
2396 case 0x35: /* CMPP immed */
2401 state->Cpsr = GETSPSR (state->Bank);
2402 ARMul_CPSRAltered (state);
2404 temp = LHS - DPImmRHS;
2415 ARMul_NegZero (state, dest);
2417 if ((lhs >= rhs) || ((rhs | lhs) >> 31))
2419 ARMul_SubCarry (state, lhs, rhs, dest);
2420 ARMul_SubOverflow (state, lhs, rhs, dest);
2430 case 0x36: /* CMN immed and MSR immed to SPSR */
2432 ARMul_FixSPSR (state, instr, DPImmRHS);
2437 case 0x37: /* CMNP immed. */
2442 state->Cpsr = GETSPSR (state->Bank);
2443 ARMul_CPSRAltered (state);
2445 temp = LHS + DPImmRHS;
2456 ASSIGNZ (dest == 0);
2457 if ((lhs | rhs) >> 30)
2459 /* Possible C,V,N to set. */
2460 ASSIGNN (NEG (dest));
2461 ARMul_AddCarry (state, lhs, rhs, dest);
2462 ARMul_AddOverflow (state, lhs, rhs, dest);
2473 case 0x38: /* ORR immed. */
2474 dest = LHS | DPImmRHS;
2478 case 0x39: /* ORRS immed. */
2484 case 0x3a: /* MOV immed. */
2489 case 0x3b: /* MOVS immed. */
2494 case 0x3c: /* BIC immed. */
2495 dest = LHS & ~DPImmRHS;
2499 case 0x3d: /* BICS immed. */
2505 case 0x3e: /* MVN immed. */
2510 case 0x3f: /* MVNS immed. */
2516 /* Single Data Transfer Immediate RHS Instructions. */
2518 case 0x40: /* Store Word, No WriteBack, Post Dec, Immed. */
2520 if (StoreWord (state, instr, lhs))
2521 LSBase = lhs - LSImmRHS;
2524 case 0x41: /* Load Word, No WriteBack, Post Dec, Immed. */
2526 if (LoadWord (state, instr, lhs))
2527 LSBase = lhs - LSImmRHS;
2530 case 0x42: /* Store Word, WriteBack, Post Dec, Immed. */
2531 UNDEF_LSRBaseEQDestWb;
2534 temp = lhs - LSImmRHS;
2535 state->NtransSig = LOW;
2536 if (StoreWord (state, instr, lhs))
2538 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2541 case 0x43: /* Load Word, WriteBack, Post Dec, Immed. */
2542 UNDEF_LSRBaseEQDestWb;
2545 state->NtransSig = LOW;
2546 if (LoadWord (state, instr, lhs))
2547 LSBase = lhs - LSImmRHS;
2548 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2551 case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed. */
2553 if (StoreByte (state, instr, lhs))
2554 LSBase = lhs - LSImmRHS;
2557 case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed. */
2559 if (LoadByte (state, instr, lhs, LUNSIGNED))
2560 LSBase = lhs - LSImmRHS;
2563 case 0x46: /* Store Byte, WriteBack, Post Dec, Immed. */
2564 UNDEF_LSRBaseEQDestWb;
2567 state->NtransSig = LOW;
2568 if (StoreByte (state, instr, lhs))
2569 LSBase = lhs - LSImmRHS;
2570 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2573 case 0x47: /* Load Byte, WriteBack, Post Dec, Immed. */
2574 UNDEF_LSRBaseEQDestWb;
2577 state->NtransSig = LOW;
2578 if (LoadByte (state, instr, lhs, LUNSIGNED))
2579 LSBase = lhs - LSImmRHS;
2580 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2583 case 0x48: /* Store Word, No WriteBack, Post Inc, Immed. */
2585 if (StoreWord (state, instr, lhs))
2586 LSBase = lhs + LSImmRHS;
2589 case 0x49: /* Load Word, No WriteBack, Post Inc, Immed. */
2591 if (LoadWord (state, instr, lhs))
2592 LSBase = lhs + LSImmRHS;
2595 case 0x4a: /* Store Word, WriteBack, Post Inc, Immed. */
2596 UNDEF_LSRBaseEQDestWb;
2599 state->NtransSig = LOW;
2600 if (StoreWord (state, instr, lhs))
2601 LSBase = lhs + LSImmRHS;
2602 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2605 case 0x4b: /* Load Word, WriteBack, Post Inc, Immed. */
2606 UNDEF_LSRBaseEQDestWb;
2609 state->NtransSig = LOW;
2610 if (LoadWord (state, instr, lhs))
2611 LSBase = lhs + LSImmRHS;
2612 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2615 case 0x4c: /* Store Byte, No WriteBack, Post Inc, Immed. */
2617 if (StoreByte (state, instr, lhs))
2618 LSBase = lhs + LSImmRHS;
2621 case 0x4d: /* Load Byte, No WriteBack, Post Inc, Immed. */
2623 if (LoadByte (state, instr, lhs, LUNSIGNED))
2624 LSBase = lhs + LSImmRHS;
2627 case 0x4e: /* Store Byte, WriteBack, Post Inc, Immed. */
2628 UNDEF_LSRBaseEQDestWb;
2631 state->NtransSig = LOW;
2632 if (StoreByte (state, instr, lhs))
2633 LSBase = lhs + LSImmRHS;
2634 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2637 case 0x4f: /* Load Byte, WriteBack, Post Inc, Immed. */
2638 UNDEF_LSRBaseEQDestWb;
2641 state->NtransSig = LOW;
2642 if (LoadByte (state, instr, lhs, LUNSIGNED))
2643 LSBase = lhs + LSImmRHS;
2644 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2648 case 0x50: /* Store Word, No WriteBack, Pre Dec, Immed. */
2649 (void) StoreWord (state, instr, LHS - LSImmRHS);
2652 case 0x51: /* Load Word, No WriteBack, Pre Dec, Immed. */
2653 (void) LoadWord (state, instr, LHS - LSImmRHS);
2656 case 0x52: /* Store Word, WriteBack, Pre Dec, Immed. */
2657 UNDEF_LSRBaseEQDestWb;
2659 temp = LHS - LSImmRHS;
2660 if (StoreWord (state, instr, temp))
2664 case 0x53: /* Load Word, WriteBack, Pre Dec, Immed. */
2665 UNDEF_LSRBaseEQDestWb;
2667 temp = LHS - LSImmRHS;
2668 if (LoadWord (state, instr, temp))
2672 case 0x54: /* Store Byte, No WriteBack, Pre Dec, Immed. */
2673 (void) StoreByte (state, instr, LHS - LSImmRHS);
2676 case 0x55: /* Load Byte, No WriteBack, Pre Dec, Immed. */
2677 (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED);
2680 case 0x56: /* Store Byte, WriteBack, Pre Dec, Immed. */
2681 UNDEF_LSRBaseEQDestWb;
2683 temp = LHS - LSImmRHS;
2684 if (StoreByte (state, instr, temp))
2688 case 0x57: /* Load Byte, WriteBack, Pre Dec, Immed. */
2689 UNDEF_LSRBaseEQDestWb;
2691 temp = LHS - LSImmRHS;
2692 if (LoadByte (state, instr, temp, LUNSIGNED))
2696 case 0x58: /* Store Word, No WriteBack, Pre Inc, Immed. */
2697 (void) StoreWord (state, instr, LHS + LSImmRHS);
2700 case 0x59: /* Load Word, No WriteBack, Pre Inc, Immed. */
2701 (void) LoadWord (state, instr, LHS + LSImmRHS);
2704 case 0x5a: /* Store Word, WriteBack, Pre Inc, Immed. */
2705 UNDEF_LSRBaseEQDestWb;
2707 temp = LHS + LSImmRHS;
2708 if (StoreWord (state, instr, temp))
2712 case 0x5b: /* Load Word, WriteBack, Pre Inc, Immed. */
2713 UNDEF_LSRBaseEQDestWb;
2715 temp = LHS + LSImmRHS;
2716 if (LoadWord (state, instr, temp))
2720 case 0x5c: /* Store Byte, No WriteBack, Pre Inc, Immed. */
2721 (void) StoreByte (state, instr, LHS + LSImmRHS);
2724 case 0x5d: /* Load Byte, No WriteBack, Pre Inc, Immed. */
2725 (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED);
2728 case 0x5e: /* Store Byte, WriteBack, Pre Inc, Immed. */
2729 UNDEF_LSRBaseEQDestWb;
2731 temp = LHS + LSImmRHS;
2732 if (StoreByte (state, instr, temp))
2736 case 0x5f: /* Load Byte, WriteBack, Pre Inc, Immed. */
2737 UNDEF_LSRBaseEQDestWb;
2739 temp = LHS + LSImmRHS;
2740 if (LoadByte (state, instr, temp, LUNSIGNED))
2745 /* Single Data Transfer Register RHS Instructions. */
2747 case 0x60: /* Store Word, No WriteBack, Post Dec, Reg. */
2750 ARMul_UndefInstr (state, instr);
2753 UNDEF_LSRBaseEQOffWb;
2754 UNDEF_LSRBaseEQDestWb;
2758 if (StoreWord (state, instr, lhs))
2759 LSBase = lhs - LSRegRHS;
2762 case 0x61: /* Load Word, No WriteBack, Post Dec, Reg. */
2767 && handle_v6_insn (state, instr))
2770 ARMul_UndefInstr (state, instr);
2773 UNDEF_LSRBaseEQOffWb;
2774 UNDEF_LSRBaseEQDestWb;
2778 temp = lhs - LSRegRHS;
2779 if (LoadWord (state, instr, lhs))
2783 case 0x62: /* Store Word, WriteBack, Post Dec, Reg. */
2788 && handle_v6_insn (state, instr))
2791 ARMul_UndefInstr (state, instr);
2794 UNDEF_LSRBaseEQOffWb;
2795 UNDEF_LSRBaseEQDestWb;
2799 state->NtransSig = LOW;
2800 if (StoreWord (state, instr, lhs))
2801 LSBase = lhs - LSRegRHS;
2802 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2805 case 0x63: /* Load Word, WriteBack, Post Dec, Reg. */
2810 && handle_v6_insn (state, instr))
2813 ARMul_UndefInstr (state, instr);
2816 UNDEF_LSRBaseEQOffWb;
2817 UNDEF_LSRBaseEQDestWb;
2821 temp = lhs - LSRegRHS;
2822 state->NtransSig = LOW;
2823 if (LoadWord (state, instr, lhs))
2825 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2828 case 0x64: /* Store Byte, No WriteBack, Post Dec, Reg. */
2831 ARMul_UndefInstr (state, instr);
2834 UNDEF_LSRBaseEQOffWb;
2835 UNDEF_LSRBaseEQDestWb;
2839 if (StoreByte (state, instr, lhs))
2840 LSBase = lhs - LSRegRHS;
2843 case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg. */
2848 && handle_v6_insn (state, instr))
2851 ARMul_UndefInstr (state, instr);
2854 UNDEF_LSRBaseEQOffWb;
2855 UNDEF_LSRBaseEQDestWb;
2859 temp = lhs - LSRegRHS;
2860 if (LoadByte (state, instr, lhs, LUNSIGNED))
2864 case 0x66: /* Store Byte, WriteBack, Post Dec, Reg. */
2869 && handle_v6_insn (state, instr))
2872 ARMul_UndefInstr (state, instr);
2875 UNDEF_LSRBaseEQOffWb;
2876 UNDEF_LSRBaseEQDestWb;
2880 state->NtransSig = LOW;
2881 if (StoreByte (state, instr, lhs))
2882 LSBase = lhs - LSRegRHS;
2883 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2886 case 0x67: /* Load Byte, WriteBack, Post Dec, Reg. */
2891 && handle_v6_insn (state, instr))
2894 ARMul_UndefInstr (state, instr);
2897 UNDEF_LSRBaseEQOffWb;
2898 UNDEF_LSRBaseEQDestWb;
2902 temp = lhs - LSRegRHS;
2903 state->NtransSig = LOW;
2904 if (LoadByte (state, instr, lhs, LUNSIGNED))
2906 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2909 case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
2914 && handle_v6_insn (state, instr))
2917 ARMul_UndefInstr (state, instr);
2920 UNDEF_LSRBaseEQOffWb;
2921 UNDEF_LSRBaseEQDestWb;
2925 if (StoreWord (state, instr, lhs))
2926 LSBase = lhs + LSRegRHS;
2929 case 0x69: /* Load Word, No WriteBack, Post Inc, Reg. */
2932 ARMul_UndefInstr (state, instr);
2935 UNDEF_LSRBaseEQOffWb;
2936 UNDEF_LSRBaseEQDestWb;
2940 temp = lhs + LSRegRHS;
2941 if (LoadWord (state, instr, lhs))
2945 case 0x6a: /* Store Word, WriteBack, Post Inc, Reg. */
2950 && handle_v6_insn (state, instr))
2953 ARMul_UndefInstr (state, instr);
2956 UNDEF_LSRBaseEQOffWb;
2957 UNDEF_LSRBaseEQDestWb;
2961 state->NtransSig = LOW;
2962 if (StoreWord (state, instr, lhs))
2963 LSBase = lhs + LSRegRHS;
2964 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2967 case 0x6b: /* Load Word, WriteBack, Post Inc, Reg. */
2972 && handle_v6_insn (state, instr))
2975 ARMul_UndefInstr (state, instr);
2978 UNDEF_LSRBaseEQOffWb;
2979 UNDEF_LSRBaseEQDestWb;
2983 temp = lhs + LSRegRHS;
2984 state->NtransSig = LOW;
2985 if (LoadWord (state, instr, lhs))
2987 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
2990 case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg. */
2995 && handle_v6_insn (state, instr))
2998 ARMul_UndefInstr (state, instr);
3001 UNDEF_LSRBaseEQOffWb;
3002 UNDEF_LSRBaseEQDestWb;
3006 if (StoreByte (state, instr, lhs))
3007 LSBase = lhs + LSRegRHS;
3010 case 0x6d: /* Load Byte, No WriteBack, Post Inc, Reg. */
3013 ARMul_UndefInstr (state, instr);
3016 UNDEF_LSRBaseEQOffWb;
3017 UNDEF_LSRBaseEQDestWb;
3021 temp = lhs + LSRegRHS;
3022 if (LoadByte (state, instr, lhs, LUNSIGNED))
3026 case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg. */
3031 && handle_v6_insn (state, instr))
3034 ARMul_UndefInstr (state, instr);
3037 UNDEF_LSRBaseEQOffWb;
3038 UNDEF_LSRBaseEQDestWb;
3042 state->NtransSig = LOW;
3043 if (StoreByte (state, instr, lhs))
3044 LSBase = lhs + LSRegRHS;
3045 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3048 case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg. */
3053 && handle_v6_insn (state, instr))
3056 ARMul_UndefInstr (state, instr);
3059 UNDEF_LSRBaseEQOffWb;
3060 UNDEF_LSRBaseEQDestWb;
3064 temp = lhs + LSRegRHS;
3065 state->NtransSig = LOW;
3066 if (LoadByte (state, instr, lhs, LUNSIGNED))
3068 state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
3072 case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg. */
3077 && handle_v6_insn (state, instr))
3080 ARMul_UndefInstr (state, instr);
3083 (void) StoreWord (state, instr, LHS - LSRegRHS);
3086 case 0x71: /* Load Word, No WriteBack, Pre Dec, Reg. */
3089 ARMul_UndefInstr (state, instr);
3092 (void) LoadWord (state, instr, LHS - LSRegRHS);
3095 case 0x72: /* Store Word, WriteBack, Pre Dec, Reg. */
3098 ARMul_UndefInstr (state, instr);
3101 UNDEF_LSRBaseEQOffWb;
3102 UNDEF_LSRBaseEQDestWb;
3105 temp = LHS - LSRegRHS;
3106 if (StoreWord (state, instr, temp))
3110 case 0x73: /* Load Word, WriteBack, Pre Dec, Reg. */
3113 ARMul_UndefInstr (state, instr);
3116 UNDEF_LSRBaseEQOffWb;
3117 UNDEF_LSRBaseEQDestWb;
3120 temp = LHS - LSRegRHS;
3121 if (LoadWord (state, instr, temp))
3125 case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg. */
3130 && handle_v6_insn (state, instr))
3133 ARMul_UndefInstr (state, instr);
3136 (void) StoreByte (state, instr, LHS - LSRegRHS);
3139 case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg. */
3144 && handle_v6_insn (state, instr))
3147 ARMul_UndefInstr (state, instr);
3150 (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED);
3153 case 0x76: /* Store Byte, WriteBack, Pre Dec, Reg. */
3156 ARMul_UndefInstr (state, instr);
3159 UNDEF_LSRBaseEQOffWb;
3160 UNDEF_LSRBaseEQDestWb;
3163 temp = LHS - LSRegRHS;
3164 if (StoreByte (state, instr, temp))
3168 case 0x77: /* Load Byte, WriteBack, Pre Dec, Reg. */
3171 ARMul_UndefInstr (state, instr);
3174 UNDEF_LSRBaseEQOffWb;
3175 UNDEF_LSRBaseEQDestWb;
3178 temp = LHS - LSRegRHS;
3179 if (LoadByte (state, instr, temp, LUNSIGNED))
3183 case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg. */
3188 && handle_v6_insn (state, instr))
3191 ARMul_UndefInstr (state, instr);
3194 (void) StoreWord (state, instr, LHS + LSRegRHS);
3197 case 0x79: /* Load Word, No WriteBack, Pre Inc, Reg. */
3200 ARMul_UndefInstr (state, instr);
3203 (void) LoadWord (state, instr, LHS + LSRegRHS);
3206 case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg. */
3211 && handle_v6_insn (state, instr))
3214 ARMul_UndefInstr (state, instr);
3217 UNDEF_LSRBaseEQOffWb;
3218 UNDEF_LSRBaseEQDestWb;
3221 temp = LHS + LSRegRHS;
3222 if (StoreWord (state, instr, temp))
3226 case 0x7b: /* Load Word, WriteBack, Pre Inc, Reg. */
3229 ARMul_UndefInstr (state, instr);
3232 UNDEF_LSRBaseEQOffWb;
3233 UNDEF_LSRBaseEQDestWb;
3236 temp = LHS + LSRegRHS;
3237 if (LoadWord (state, instr, temp))
3241 case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg. */
3246 && handle_v6_insn (state, instr))
3249 ARMul_UndefInstr (state, instr);
3252 (void) StoreByte (state, instr, LHS + LSRegRHS);
3255 case 0x7d: /* Load Byte, No WriteBack, Pre Inc, Reg. */
3258 ARMul_UndefInstr (state, instr);
3261 (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED);
3264 case 0x7e: /* Store Byte, WriteBack, Pre Inc, Reg. */
3267 ARMul_UndefInstr (state, instr);
3270 UNDEF_LSRBaseEQOffWb;
3271 UNDEF_LSRBaseEQDestWb;
3274 temp = LHS + LSRegRHS;
3275 if (StoreByte (state, instr, temp))
3279 case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg. */
3282 /* Check for the special breakpoint opcode.
3283 This value should correspond to the value defined
3284 as ARM_BE_BREAKPOINT in gdb/arm/tm-arm.h. */
3285 if (BITS (0, 19) == 0xfdefe)
3287 if (!ARMul_OSHandleSWI (state, SWI_Breakpoint))
3288 ARMul_Abort (state, ARMul_SWIV);
3291 ARMul_UndefInstr (state, instr);
3294 UNDEF_LSRBaseEQOffWb;
3295 UNDEF_LSRBaseEQDestWb;
3298 temp = LHS + LSRegRHS;
3299 if (LoadByte (state, instr, temp, LUNSIGNED))
3304 /* Multiple Data Transfer Instructions. */
3306 case 0x80: /* Store, No WriteBack, Post Dec. */
3307 STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
3310 case 0x81: /* Load, No WriteBack, Post Dec. */
3311 LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
3314 case 0x82: /* Store, WriteBack, Post Dec. */
3315 temp = LSBase - LSMNumRegs;
3316 STOREMULT (instr, temp + 4L, temp);
3319 case 0x83: /* Load, WriteBack, Post Dec. */
3320 temp = LSBase - LSMNumRegs;
3321 LOADMULT (instr, temp + 4L, temp);
3324 case 0x84: /* Store, Flags, No WriteBack, Post Dec. */
3325 STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
3328 case 0x85: /* Load, Flags, No WriteBack, Post Dec. */
3329 LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
3332 case 0x86: /* Store, Flags, WriteBack, Post Dec. */
3333 temp = LSBase - LSMNumRegs;
3334 STORESMULT (instr, temp + 4L, temp);
3337 case 0x87: /* Load, Flags, WriteBack, Post Dec. */
3338 temp = LSBase - LSMNumRegs;
3339 LOADSMULT (instr, temp + 4L, temp);
3342 case 0x88: /* Store, No WriteBack, Post Inc. */
3343 STOREMULT (instr, LSBase, 0L);
3346 case 0x89: /* Load, No WriteBack, Post Inc. */
3347 LOADMULT (instr, LSBase, 0L);
3350 case 0x8a: /* Store, WriteBack, Post Inc. */
3352 STOREMULT (instr, temp, temp + LSMNumRegs);
3355 case 0x8b: /* Load, WriteBack, Post Inc. */
3357 LOADMULT (instr, temp, temp + LSMNumRegs);
3360 case 0x8c: /* Store, Flags, No WriteBack, Post Inc. */
3361 STORESMULT (instr, LSBase, 0L);
3364 case 0x8d: /* Load, Flags, No WriteBack, Post Inc. */
3365 LOADSMULT (instr, LSBase, 0L);
3368 case 0x8e: /* Store, Flags, WriteBack, Post Inc. */
3370 STORESMULT (instr, temp, temp + LSMNumRegs);
3373 case 0x8f: /* Load, Flags, WriteBack, Post Inc. */
3375 LOADSMULT (instr, temp, temp + LSMNumRegs);
3378 case 0x90: /* Store, No WriteBack, Pre Dec. */
3379 STOREMULT (instr, LSBase - LSMNumRegs, 0L);
3382 case 0x91: /* Load, No WriteBack, Pre Dec. */
3383 LOADMULT (instr, LSBase - LSMNumRegs, 0L);
3386 case 0x92: /* Store, WriteBack, Pre Dec. */
3387 temp = LSBase - LSMNumRegs;
3388 STOREMULT (instr, temp, temp);
3391 case 0x93: /* Load, WriteBack, Pre Dec. */
3392 temp = LSBase - LSMNumRegs;
3393 LOADMULT (instr, temp, temp);
3396 case 0x94: /* Store, Flags, No WriteBack, Pre Dec. */
3397 STORESMULT (instr, LSBase - LSMNumRegs, 0L);
3400 case 0x95: /* Load, Flags, No WriteBack, Pre Dec. */
3401 LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
3404 case 0x96: /* Store, Flags, WriteBack, Pre Dec. */
3405 temp = LSBase - LSMNumRegs;
3406 STORESMULT (instr, temp, temp);
3409 case 0x97: /* Load, Flags, WriteBack, Pre Dec. */
3410 temp = LSBase - LSMNumRegs;
3411 LOADSMULT (instr, temp, temp);
3414 case 0x98: /* Store, No WriteBack, Pre Inc. */
3415 STOREMULT (instr, LSBase + 4L, 0L);
3418 case 0x99: /* Load, No WriteBack, Pre Inc. */
3419 LOADMULT (instr, LSBase + 4L, 0L);
3422 case 0x9a: /* Store, WriteBack, Pre Inc. */
3424 STOREMULT (instr, temp + 4L, temp + LSMNumRegs);
3427 case 0x9b: /* Load, WriteBack, Pre Inc. */
3429 LOADMULT (instr, temp + 4L, temp + LSMNumRegs);
3432 case 0x9c: /* Store, Flags, No WriteBack, Pre Inc. */
3433 STORESMULT (instr, LSBase + 4L, 0L);
3436 case 0x9d: /* Load, Flags, No WriteBack, Pre Inc. */
3437 LOADSMULT (instr, LSBase + 4L, 0L);
3440 case 0x9e: /* Store, Flags, WriteBack, Pre Inc. */
3442 STORESMULT (instr, temp + 4L, temp + LSMNumRegs);
3445 case 0x9f: /* Load, Flags, WriteBack, Pre Inc. */
3447 LOADSMULT (instr, temp + 4L, temp + LSMNumRegs);
3451 /* Branch forward. */
3460 state->Reg[15] = pc + 8 + POSBRANCH;
3465 /* Branch backward. */
3474 state->Reg[15] = pc + 8 + NEGBRANCH;
3478 /* Branch and Link forward. */
3487 /* Put PC into Link. */
3489 state->Reg[14] = pc + 4;
3491 state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
3493 state->Reg[15] = pc + 8 + POSBRANCH;
3496 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
3499 /* Branch and Link backward. */
3508 /* Put PC into Link. */
3510 state->Reg[14] = pc + 4;
3512 state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE;
3514 state->Reg[15] = pc + 8 + NEGBRANCH;
3517 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
3520 /* Co-Processor Data Transfers. */
3524 /* Reading from R15 is UNPREDICTABLE. */
3525 if (BITS (12, 15) == 15 || BITS (16, 19) == 15)
3526 ARMul_UndefInstr (state, instr);
3527 /* Is access to coprocessor 0 allowed ? */
3528 else if (! CP_ACCESS_ALLOWED (state, CPNum))
3529 ARMul_UndefInstr (state, instr);
3530 /* Special treatment for XScale coprocessors. */
3531 else if (state->is_XScale)
3533 /* Only opcode 0 is supported. */
3534 if (BITS (4, 7) != 0x00)
3535 ARMul_UndefInstr (state, instr);
3536 /* Only coporcessor 0 is supported. */
3537 else if (CPNum != 0x00)
3538 ARMul_UndefInstr (state, instr);
3539 /* Only accumulator 0 is supported. */
3540 else if (BITS (0, 3) != 0x00)
3541 ARMul_UndefInstr (state, instr);
3544 /* XScale MAR insn. Move two registers into accumulator. */
3545 state->Accumulator = state->Reg[BITS (12, 15)];
3546 state->Accumulator += (ARMdword) state->Reg[BITS (16, 19)] << 32;
3550 /* FIXME: Not sure what to do for other v5 processors. */
3551 ARMul_UndefInstr (state, instr);
3556 case 0xc0: /* Store , No WriteBack , Post Dec. */
3557 ARMul_STC (state, instr, LHS);
3563 /* Writes to R15 are UNPREDICATABLE. */
3564 if (DESTReg == 15 || LHSReg == 15)
3565 ARMul_UndefInstr (state, instr);
3566 /* Is access to the coprocessor allowed ? */
3567 else if (! CP_ACCESS_ALLOWED (state, CPNum))
3568 ARMul_UndefInstr (state, instr);
3569 /* Special handling for XScale coprcoessors. */
3570 else if (state->is_XScale)
3572 /* Only opcode 0 is supported. */
3573 if (BITS (4, 7) != 0x00)
3574 ARMul_UndefInstr (state, instr);
3575 /* Only coprocessor 0 is supported. */
3576 else if (CPNum != 0x00)
3577 ARMul_UndefInstr (state, instr);
3578 /* Only accumulator 0 is supported. */
3579 else if (BITS (0, 3) != 0x00)
3580 ARMul_UndefInstr (state, instr);
3583 /* XScale MRA insn. Move accumulator into two registers. */
3584 ARMword t1 = (state->Accumulator >> 32) & 255;
3589 state->Reg[BITS (12, 15)] = state->Accumulator;
3590 state->Reg[BITS (16, 19)] = t1;
3595 /* FIXME: Not sure what to do for other v5 processors. */
3596 ARMul_UndefInstr (state, instr);
3601 case 0xc1: /* Load , No WriteBack , Post Dec. */
3602 ARMul_LDC (state, instr, LHS);
3606 case 0xc6: /* Store , WriteBack , Post Dec. */
3608 state->Base = lhs - LSCOff;
3609 ARMul_STC (state, instr, lhs);
3613 case 0xc7: /* Load , WriteBack , Post Dec. */
3615 state->Base = lhs - LSCOff;
3616 ARMul_LDC (state, instr, lhs);
3620 case 0xcc: /* Store , No WriteBack , Post Inc. */
3621 ARMul_STC (state, instr, LHS);
3625 case 0xcd: /* Load , No WriteBack , Post Inc. */
3626 ARMul_LDC (state, instr, LHS);
3630 case 0xce: /* Store , WriteBack , Post Inc. */
3632 state->Base = lhs + LSCOff;
3633 ARMul_STC (state, instr, LHS);
3637 case 0xcf: /* Load , WriteBack , Post Inc. */
3639 state->Base = lhs + LSCOff;
3640 ARMul_LDC (state, instr, LHS);
3644 case 0xd4: /* Store , No WriteBack , Pre Dec. */
3645 ARMul_STC (state, instr, LHS - LSCOff);
3649 case 0xd5: /* Load , No WriteBack , Pre Dec. */
3650 ARMul_LDC (state, instr, LHS - LSCOff);
3654 case 0xd6: /* Store , WriteBack , Pre Dec. */
3657 ARMul_STC (state, instr, lhs);
3661 case 0xd7: /* Load , WriteBack , Pre Dec. */
3664 ARMul_LDC (state, instr, lhs);
3668 case 0xdc: /* Store , No WriteBack , Pre Inc. */
3669 ARMul_STC (state, instr, LHS + LSCOff);
3673 case 0xdd: /* Load , No WriteBack , Pre Inc. */
3674 ARMul_LDC (state, instr, LHS + LSCOff);
3678 case 0xde: /* Store , WriteBack , Pre Inc. */
3681 ARMul_STC (state, instr, lhs);
3685 case 0xdf: /* Load , WriteBack , Pre Inc. */
3688 ARMul_LDC (state, instr, lhs);
3692 /* Co-Processor Register Transfers (MCR) and Data Ops. */
3695 if (! CP_ACCESS_ALLOWED (state, CPNum))
3697 ARMul_UndefInstr (state, instr);
3700 if (state->is_XScale)
3701 switch (BITS (18, 19))
3704 if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
3706 /* XScale MIA instruction. Signed multiplication of
3707 two 32 bit values and addition to 40 bit accumulator. */
3708 ARMsdword Rm = state->Reg[MULLHSReg];
3709 ARMsdword Rs = state->Reg[MULACCReg];
3715 state->Accumulator += Rm * Rs;
3721 if (BITS (4, 11) == 1 && BITS (16, 17) == 0)
3723 /* XScale MIAPH instruction. */
3724 ARMword t1 = state->Reg[MULLHSReg] >> 16;
3725 ARMword t2 = state->Reg[MULACCReg] >> 16;
3726 ARMword t3 = state->Reg[MULLHSReg] & 0xffff;
3727 ARMword t4 = state->Reg[MULACCReg] & 0xffff;
3742 state->Accumulator += t5;
3747 state->Accumulator += t5;
3753 if (BITS (4, 11) == 1)
3755 /* XScale MIAxy instruction. */
3761 t1 = state->Reg[MULLHSReg] >> 16;
3763 t1 = state->Reg[MULLHSReg] & 0xffff;
3766 t2 = state->Reg[MULACCReg] >> 16;
3768 t2 = state->Reg[MULACCReg] & 0xffff;
3778 state->Accumulator += t5;
3802 ARMul_MCR (state, instr, state->Reg[15] + isize);
3804 ARMul_MCR (state, instr, ECC | ER15INT | EMODE |
3805 ((state->Reg[15] + isize) & R15PCBITS));
3809 ARMul_MCR (state, instr, DEST);
3813 ARMul_CDP (state, instr);
3817 /* Co-Processor Register Transfers (MRC) and Data Ops. */
3829 temp = ARMul_MRC (state, instr);
3832 ASSIGNN ((temp & NBIT) != 0);
3833 ASSIGNZ ((temp & ZBIT) != 0);
3834 ASSIGNC ((temp & CBIT) != 0);
3835 ASSIGNV ((temp & VBIT) != 0);
3842 ARMul_CDP (state, instr);
3846 /* SWI instruction. */
3863 if (instr == ARMul_ABORTWORD && state->AbortAddr == pc)
3865 /* A prefetch abort. */
3866 XScale_set_fsr_far (state, ARMul_CP15_R5_MMU_EXCPT, pc);
3867 ARMul_Abort (state, ARMul_PrefetchAbortV);
3871 if (!ARMul_OSHandleSWI (state, BITS (0, 23)))
3872 ARMul_Abort (state, ARMul_SWIV);
3882 #ifdef NEED_UI_LOOP_HOOK
3883 if (deprecated_ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
3885 ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
3886 deprecated_ui_loop_hook (0);
3888 #endif /* NEED_UI_LOOP_HOOK */
3890 if (state->Emulate == ONCE)
3891 state->Emulate = STOP;
3892 /* If we have changed mode, allow the PC to advance before stopping. */
3893 else if (state->Emulate == CHANGEMODE)
3895 else if (state->Emulate != RUN)
3898 while (!stop_simulator);
3900 state->decoded = decoded;
3901 state->loaded = loaded;
3907 /* This routine evaluates most Data Processing register RHS's with the S
3908 bit clear. It is intended to be called from the macro DPRegRHS, which
3909 filters the common case of an unshifted register with in line code. */
3912 GetDPRegRHS (ARMul_State * state, ARMword instr)
3914 ARMword shamt, base;
3919 /* Shift amount in a register. */
3924 base = ECC | ER15INT | R15PC | EMODE;
3927 base = state->Reg[base];
3928 ARMul_Icycles (state, 1, 0L);
3929 shamt = state->Reg[BITS (8, 11)] & 0xff;
3930 switch ((int) BITS (5, 6))
3935 else if (shamt >= 32)
3938 return (base << shamt);
3942 else if (shamt >= 32)
3945 return (base >> shamt);
3949 else if (shamt >= 32)
3950 return ((ARMword) ((ARMsword) base >> 31L));
3952 return ((ARMword) ((ARMsword) base >> (int) shamt));
3958 return ((base << (32 - shamt)) | (base >> shamt));
3963 /* Shift amount is a constant. */
3966 base = ECC | ER15INT | R15PC | EMODE;
3969 base = state->Reg[base];
3970 shamt = BITS (7, 11);
3971 switch ((int) BITS (5, 6))
3974 return (base << shamt);
3979 return (base >> shamt);
3982 return ((ARMword) ((ARMsword) base >> 31L));
3984 return ((ARMword) ((ARMsword) base >> (int) shamt));
3988 return ((base >> 1) | (CFLAG << 31));
3990 return ((base << (32 - shamt)) | (base >> shamt));
3997 /* This routine evaluates most Logical Data Processing register RHS's
3998 with the S bit set. It is intended to be called from the macro
3999 DPSRegRHS, which filters the common case of an unshifted register
4000 with in line code. */
4003 GetDPSRegRHS (ARMul_State * state, ARMword instr)
4005 ARMword shamt, base;
4010 /* Shift amount in a register. */
4015 base = ECC | ER15INT | R15PC | EMODE;
4018 base = state->Reg[base];
4019 ARMul_Icycles (state, 1, 0L);
4020 shamt = state->Reg[BITS (8, 11)] & 0xff;
4021 switch ((int) BITS (5, 6))
4026 else if (shamt == 32)
4031 else if (shamt > 32)
4038 ASSIGNC ((base >> (32 - shamt)) & 1);
4039 return (base << shamt);
4044 else if (shamt == 32)
4046 ASSIGNC (base >> 31);
4049 else if (shamt > 32)
4056 ASSIGNC ((base >> (shamt - 1)) & 1);
4057 return (base >> shamt);
4062 else if (shamt >= 32)
4064 ASSIGNC (base >> 31L);
4065 return ((ARMword) ((ARMsword) base >> 31L));
4069 ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1);
4070 return ((ARMword) ((ARMsword) base >> (int) shamt));
4078 ASSIGNC (base >> 31);
4083 ASSIGNC ((base >> (shamt - 1)) & 1);
4084 return ((base << (32 - shamt)) | (base >> shamt));
4090 /* Shift amount is a constant. */
4093 base = ECC | ER15INT | R15PC | EMODE;
4096 base = state->Reg[base];
4097 shamt = BITS (7, 11);
4099 switch ((int) BITS (5, 6))
4102 ASSIGNC ((base >> (32 - shamt)) & 1);
4103 return (base << shamt);
4107 ASSIGNC (base >> 31);
4112 ASSIGNC ((base >> (shamt - 1)) & 1);
4113 return (base >> shamt);
4118 ASSIGNC (base >> 31L);
4119 return ((ARMword) ((ARMsword) base >> 31L));
4123 ASSIGNC ((ARMword) ((ARMsword) base >> (int) (shamt - 1)) & 1);
4124 return ((ARMword) ((ARMsword) base >> (int) shamt));
4132 return ((base >> 1) | (shamt << 31));
4136 ASSIGNC ((base >> (shamt - 1)) & 1);
4137 return ((base << (32 - shamt)) | (base >> shamt));
4145 /* This routine handles writes to register 15 when the S bit is not set. */
4148 WriteR15 (ARMul_State * state, ARMword src)
4150 /* The ARM documentation states that the two least significant bits
4151 are discarded when setting PC, except in the cases handled by
4152 WriteR15Branch() below. It's probably an oversight: in THUMB
4153 mode, the second least significant bit should probably not be
4163 state->Reg[15] = src & PCBITS;
4165 state->Reg[15] = (src & R15PCBITS) | ECC | ER15INT | EMODE;
4166 ARMul_R15Altered (state);
4171 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
4174 /* This routine handles writes to register 15 when the S bit is set. */
4177 WriteSR15 (ARMul_State * state, ARMword src)
4180 if (state->Bank > 0)
4182 state->Cpsr = state->Spsr[state->Bank];
4183 ARMul_CPSRAltered (state);
4191 state->Reg[15] = src & PCBITS;
4195 /* ARMul_R15Altered would have to support it. */
4201 if (state->Bank == USERBANK)
4202 state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
4204 state->Reg[15] = src;
4206 ARMul_R15Altered (state);
4210 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
4213 /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
4214 will switch to Thumb mode if the least significant bit is set. */
4217 WriteR15Branch (ARMul_State * state, ARMword src)
4224 state->Reg[15] = src & 0xfffffffe;
4229 state->Reg[15] = src & 0xfffffffc;
4233 fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
4235 WriteR15 (state, src);
4239 /* Before ARM_v5 LDR and LDM of pc did not change mode. */
4242 WriteR15Load (ARMul_State * state, ARMword src)
4245 WriteR15Branch (state, src);
4247 WriteR15 (state, src);
4250 /* This routine evaluates most Load and Store register RHS's. It is
4251 intended to be called from the macro LSRegRHS, which filters the
4252 common case of an unshifted register with in line code. */
4255 GetLSRegRHS (ARMul_State * state, ARMword instr)
4257 ARMword shamt, base;
4262 /* Now forbidden, but ... */
4263 base = ECC | ER15INT | R15PC | EMODE;
4266 base = state->Reg[base];
4268 shamt = BITS (7, 11);
4269 switch ((int) BITS (5, 6))
4272 return (base << shamt);
4277 return (base >> shamt);
4280 return ((ARMword) ((ARMsword) base >> 31L));
4282 return ((ARMword) ((ARMsword) base >> (int) shamt));
4286 return ((base >> 1) | (CFLAG << 31));
4288 return ((base << (32 - shamt)) | (base >> shamt));
4295 /* This routine evaluates the ARM7T halfword and signed transfer RHS's. */
4298 GetLS7RHS (ARMul_State * state, ARMword instr)
4305 /* Now forbidden, but ... */
4306 return ECC | ER15INT | R15PC | EMODE;
4308 return state->Reg[RHSReg];
4312 return BITS (0, 3) | (BITS (8, 11) << 4);
4315 /* This function does the work of loading a word for a LDR instruction. */
4318 LoadWord (ARMul_State * state, ARMword instr, ARMword address)
4324 if (ADDREXCEPT (address))
4325 INTERNALABORT (address);
4328 dest = ARMul_LoadWordN (state, address);
4333 return state->lateabtSig;
4336 dest = ARMul_Align (state, address, dest);
4338 ARMul_Icycles (state, 1, 0L);
4340 return (DESTReg != LHSReg);
4344 /* This function does the work of loading a halfword. */
4347 LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
4354 if (ADDREXCEPT (address))
4355 INTERNALABORT (address);
4357 dest = ARMul_LoadHalfWord (state, address);
4361 return state->lateabtSig;
4365 if (dest & 1 << (16 - 1))
4366 dest = (dest & ((1 << 16) - 1)) - (1 << 16);
4369 ARMul_Icycles (state, 1, 0L);
4370 return (DESTReg != LHSReg);
4375 /* This function does the work of loading a byte for a LDRB instruction. */
4378 LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend)
4384 if (ADDREXCEPT (address))
4385 INTERNALABORT (address);
4387 dest = ARMul_LoadByte (state, address);
4391 return state->lateabtSig;
4395 if (dest & 1 << (8 - 1))
4396 dest = (dest & ((1 << 8) - 1)) - (1 << 8);
4399 ARMul_Icycles (state, 1, 0L);
4401 return (DESTReg != LHSReg);
4404 /* This function does the work of loading two words for a LDRD instruction. */
4407 Handle_Load_Double (ARMul_State * state, ARMword instr)
4411 ARMword write_back = BIT (21);
4412 ARMword immediate = BIT (22);
4413 ARMword add_to_base = BIT (23);
4414 ARMword pre_indexed = BIT (24);
4424 /* If the writeback bit is set, the pre-index bit must be clear. */
4425 if (write_back && ! pre_indexed)
4427 ARMul_UndefInstr (state, instr);
4431 /* Extract the base address register. */
4434 /* Extract the destination register and check it. */
4437 /* Destination register must be even. */
4439 /* Destination register cannot be LR. */
4440 || (dest_reg == 14))
4442 ARMul_UndefInstr (state, instr);
4446 /* Compute the base address. */
4447 base = state->Reg[addr_reg];
4449 /* Compute the offset. */
4450 offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
4452 /* Compute the sum of the two. */
4454 sum = base + offset;
4456 sum = base - offset;
4458 /* If this is a pre-indexed mode use the sum. */
4464 /* The address must be aligned on a 8 byte boundary. */
4468 ARMul_DATAABORT (addr);
4470 ARMul_UndefInstr (state, instr);
4475 /* For pre indexed or post indexed addressing modes,
4476 check that the destination registers do not overlap
4477 the address registers. */
4478 if ((! pre_indexed || write_back)
4479 && ( addr_reg == dest_reg
4480 || addr_reg == dest_reg + 1))
4482 ARMul_UndefInstr (state, instr);
4486 /* Load the words. */
4487 value1 = ARMul_LoadWordN (state, addr);
4488 value2 = ARMul_LoadWordN (state, addr + 4);
4490 /* Check for data aborts. */
4497 ARMul_Icycles (state, 2, 0L);
4499 /* Store the values. */
4500 state->Reg[dest_reg] = value1;
4501 state->Reg[dest_reg + 1] = value2;
4503 /* Do the post addressing and writeback. */
4507 if (! pre_indexed || write_back)
4508 state->Reg[addr_reg] = addr;
4511 /* This function does the work of storing two words for a STRD instruction. */
4514 Handle_Store_Double (ARMul_State * state, ARMword instr)
4518 ARMword write_back = BIT (21);
4519 ARMword immediate = BIT (22);
4520 ARMword add_to_base = BIT (23);
4521 ARMword pre_indexed = BIT (24);
4529 /* If the writeback bit is set, the pre-index bit must be clear. */
4530 if (write_back && ! pre_indexed)
4532 ARMul_UndefInstr (state, instr);
4536 /* Extract the base address register. */
4539 /* Base register cannot be PC. */
4542 ARMul_UndefInstr (state, instr);
4546 /* Extract the source register. */
4549 /* Source register must be even. */
4552 ARMul_UndefInstr (state, instr);
4556 /* Compute the base address. */
4557 base = state->Reg[addr_reg];
4559 /* Compute the offset. */
4560 offset = immediate ? ((BITS (8, 11) << 4) | BITS (0, 3)) : state->Reg[RHSReg];
4562 /* Compute the sum of the two. */
4564 sum = base + offset;
4566 sum = base - offset;
4568 /* If this is a pre-indexed mode use the sum. */
4574 /* The address must be aligned on a 8 byte boundary. */
4578 ARMul_DATAABORT (addr);
4580 ARMul_UndefInstr (state, instr);
4585 /* For pre indexed or post indexed addressing modes,
4586 check that the destination registers do not overlap
4587 the address registers. */
4588 if ((! pre_indexed || write_back)
4589 && ( addr_reg == src_reg
4590 || addr_reg == src_reg + 1))
4592 ARMul_UndefInstr (state, instr);
4596 /* Load the words. */
4597 ARMul_StoreWordN (state, addr, state->Reg[src_reg]);
4598 ARMul_StoreWordN (state, addr + 4, state->Reg[src_reg + 1]);
4606 /* Do the post addressing and writeback. */
4610 if (! pre_indexed || write_back)
4611 state->Reg[addr_reg] = addr;
4614 /* This function does the work of storing a word from a STR instruction. */
4617 StoreWord (ARMul_State * state, ARMword instr, ARMword address)
4622 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4625 ARMul_StoreWordN (state, address, DEST);
4627 if (VECTORACCESS (address) || ADDREXCEPT (address))
4629 INTERNALABORT (address);
4630 (void) ARMul_LoadWordN (state, address);
4633 ARMul_StoreWordN (state, address, DEST);
4638 return state->lateabtSig;
4644 /* This function does the work of storing a byte for a STRH instruction. */
4647 StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
4653 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4657 ARMul_StoreHalfWord (state, address, DEST);
4659 if (VECTORACCESS (address) || ADDREXCEPT (address))
4661 INTERNALABORT (address);
4662 (void) ARMul_LoadHalfWord (state, address);
4665 ARMul_StoreHalfWord (state, address, DEST);
4671 return state->lateabtSig;
4678 /* This function does the work of storing a byte for a STRB instruction. */
4681 StoreByte (ARMul_State * state, ARMword instr, ARMword address)
4686 state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
4689 ARMul_StoreByte (state, address, DEST);
4691 if (VECTORACCESS (address) || ADDREXCEPT (address))
4693 INTERNALABORT (address);
4694 (void) ARMul_LoadByte (state, address);
4697 ARMul_StoreByte (state, address, DEST);
4702 return state->lateabtSig;
4708 /* This function does the work of loading the registers listed in an LDM
4709 instruction, when the S bit is clear. The code here is always increment
4710 after, it's up to the caller to get the input address correct and to
4711 handle base register modification. */
4714 LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
4720 UNDEF_LSMBaseInListWb;
4723 if (ADDREXCEPT (address))
4724 INTERNALABORT (address);
4726 if (BIT (21) && LHSReg != 15)
4729 /* N cycle first. */
4730 for (temp = 0; !BIT (temp); temp++)
4733 dest = ARMul_LoadWordN (state, address);
4735 if (!state->abortSig && !state->Aborted)
4736 state->Reg[temp++] = dest;
4737 else if (!state->Aborted)
4739 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4740 state->Aborted = ARMul_DataAbortV;
4743 /* S cycles from here on. */
4744 for (; temp < 16; temp ++)
4747 /* Load this register. */
4749 dest = ARMul_LoadWordS (state, address);
4751 if (!state->abortSig && !state->Aborted)
4752 state->Reg[temp] = dest;
4753 else if (!state->Aborted)
4755 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4756 state->Aborted = ARMul_DataAbortV;
4760 if (BIT (15) && !state->Aborted)
4761 /* PC is in the reg list. */
4762 WriteR15Load (state, PC);
4764 /* To write back the final register. */
4765 ARMul_Icycles (state, 1, 0L);
4769 if (BIT (21) && LHSReg != 15)
4775 /* This function does the work of loading the registers listed in an LDM
4776 instruction, when the S bit is set. The code here is always increment
4777 after, it's up to the caller to get the input address correct and to
4778 handle base register modification. */
4781 LoadSMult (ARMul_State * state,
4790 UNDEF_LSMBaseInListWb;
4795 if (ADDREXCEPT (address))
4796 INTERNALABORT (address);
4799 if (BIT (21) && LHSReg != 15)
4802 if (!BIT (15) && state->Bank != USERBANK)
4804 /* Temporary reg bank switch. */
4805 (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
4806 UNDEF_LSMUserBankWb;
4809 /* N cycle first. */
4810 for (temp = 0; !BIT (temp); temp ++)
4813 dest = ARMul_LoadWordN (state, address);
4815 if (!state->abortSig)
4816 state->Reg[temp++] = dest;
4817 else if (!state->Aborted)
4819 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4820 state->Aborted = ARMul_DataAbortV;
4823 /* S cycles from here on. */
4824 for (; temp < 16; temp++)
4827 /* Load this register. */
4829 dest = ARMul_LoadWordS (state, address);
4831 if (!state->abortSig && !state->Aborted)
4832 state->Reg[temp] = dest;
4833 else if (!state->Aborted)
4835 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4836 state->Aborted = ARMul_DataAbortV;
4840 if (BIT (15) && !state->Aborted)
4842 /* PC is in the reg list. */
4844 if (state->Mode != USER26MODE && state->Mode != USER32MODE)
4846 state->Cpsr = GETSPSR (state->Bank);
4847 ARMul_CPSRAltered (state);
4850 WriteR15 (state, PC);
4852 if (state->Mode == USER26MODE || state->Mode == USER32MODE)
4854 /* Protect bits in user mode. */
4855 ASSIGNN ((state->Reg[15] & NBIT) != 0);
4856 ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
4857 ASSIGNC ((state->Reg[15] & CBIT) != 0);
4858 ASSIGNV ((state->Reg[15] & VBIT) != 0);
4861 ARMul_R15Altered (state);
4867 if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE)
4868 /* Restore the correct bank. */
4869 (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
4871 /* To write back the final register. */
4872 ARMul_Icycles (state, 1, 0L);
4876 if (BIT (21) && LHSReg != 15)
4883 /* This function does the work of storing the registers listed in an STM
4884 instruction, when the S bit is clear. The code here is always increment
4885 after, it's up to the caller to get the input address correct and to
4886 handle base register modification. */
4889 StoreMult (ARMul_State * state,
4898 UNDEF_LSMBaseInListWb;
4901 /* N-cycle, increment the PC and update the NextInstr state. */
4905 if (VECTORACCESS (address) || ADDREXCEPT (address))
4906 INTERNALABORT (address);
4912 /* N cycle first. */
4913 for (temp = 0; !BIT (temp); temp ++)
4917 ARMul_StoreWordN (state, address, state->Reg[temp++]);
4921 (void) ARMul_LoadWordN (state, address);
4923 /* Fake the Stores as Loads. */
4924 for (; temp < 16; temp++)
4927 /* Save this register. */
4929 (void) ARMul_LoadWordS (state, address);
4932 if (BIT (21) && LHSReg != 15)
4938 ARMul_StoreWordN (state, address, state->Reg[temp++]);
4941 if (state->abortSig && !state->Aborted)
4943 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4944 state->Aborted = ARMul_DataAbortV;
4947 if (BIT (21) && LHSReg != 15)
4950 /* S cycles from here on. */
4951 for (; temp < 16; temp ++)
4954 /* Save this register. */
4957 ARMul_StoreWordS (state, address, state->Reg[temp]);
4959 if (state->abortSig && !state->Aborted)
4961 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
4962 state->Aborted = ARMul_DataAbortV;
4970 /* This function does the work of storing the registers listed in an STM
4971 instruction when the S bit is set. The code here is always increment
4972 after, it's up to the caller to get the input address correct and to
4973 handle base register modification. */
4976 StoreSMult (ARMul_State * state,
4985 UNDEF_LSMBaseInListWb;
4990 if (VECTORACCESS (address) || ADDREXCEPT (address))
4991 INTERNALABORT (address);
4997 if (state->Bank != USERBANK)
4999 /* Force User Bank. */
5000 (void) ARMul_SwitchMode (state, state->Mode, USER26MODE);
5001 UNDEF_LSMUserBankWb;
5004 for (temp = 0; !BIT (temp); temp++)
5005 ; /* N cycle first. */
5008 ARMul_StoreWordN (state, address, state->Reg[temp++]);
5012 (void) ARMul_LoadWordN (state, address);
5014 for (; temp < 16; temp++)
5015 /* Fake the Stores as Loads. */
5018 /* Save this register. */
5021 (void) ARMul_LoadWordS (state, address);
5024 if (BIT (21) && LHSReg != 15)
5031 ARMul_StoreWordN (state, address, state->Reg[temp++]);
5034 if (state->abortSig && !state->Aborted)
5036 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5037 state->Aborted = ARMul_DataAbortV;
5040 /* S cycles from here on. */
5041 for (; temp < 16; temp++)
5044 /* Save this register. */
5047 ARMul_StoreWordS (state, address, state->Reg[temp]);
5049 if (state->abortSig && !state->Aborted)
5051 XScale_set_fsr_far (state, ARMul_CP15_R5_ST_ALIGN, address);
5052 state->Aborted = ARMul_DataAbortV;
5056 if (state->Mode != USER26MODE && state->Mode != USER32MODE)
5057 /* Restore the correct bank. */
5058 (void) ARMul_SwitchMode (state, USER26MODE, state->Mode);
5060 if (BIT (21) && LHSReg != 15)
5067 /* This function does the work of adding two 32bit values
5068 together, and calculating if a carry has occurred. */
5071 Add32 (ARMword a1, ARMword a2, int *carry)
5073 ARMword result = (a1 + a2);
5074 unsigned int uresult = (unsigned int) result;
5075 unsigned int ua1 = (unsigned int) a1;
5077 /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
5078 or (result > RdLo) then we have no carry. */
5079 if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
5087 /* This function does the work of multiplying
5088 two 32bit values to give a 64bit result. */
5091 Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
5093 /* Operand register numbers. */
5094 int nRdHi, nRdLo, nRs, nRm;
5095 ARMword RdHi = 0, RdLo = 0, Rm;
5099 nRdHi = BITS (16, 19);
5100 nRdLo = BITS (12, 15);
5104 /* Needed to calculate the cycle count. */
5105 Rm = state->Reg[nRm];
5107 /* Check for illegal operand combinations first. */
5116 /* Intermediate results. */
5117 ARMword lo, mid1, mid2, hi;
5119 ARMword Rs = state->Reg[nRs];
5124 /* Compute sign of result and adjust operands if necessary. */
5125 sign = (Rm ^ Rs) & 0x80000000;
5127 if (((ARMsword) Rm) < 0)
5130 if (((ARMsword) Rs) < 0)
5134 /* We can split the 32x32 into four 16x16 operations. This
5135 ensures that we do not lose precision on 32bit only hosts. */
5136 lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
5137 mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
5138 mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
5139 hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
5141 /* We now need to add all of these results together, taking
5142 care to propogate the carries from the additions. */
5143 RdLo = Add32 (lo, (mid1 << 16), &carry);
5145 RdLo = Add32 (RdLo, (mid2 << 16), &carry);
5147 (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
5151 /* Negate result if necessary. */
5154 if (RdLo == 0xFFFFFFFF)
5163 state->Reg[nRdLo] = RdLo;
5164 state->Reg[nRdHi] = RdHi;
5167 fprintf (stderr, "sim: MULTIPLY64 - INVALID ARGUMENTS\n");
5170 /* Ensure that both RdHi and RdLo are used to compute Z,
5171 but don't let RdLo's sign bit make it to N. */
5172 ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
5174 /* The cycle count depends on whether the instruction is a signed or
5175 unsigned multiply, and what bits are clear in the multiplier. */
5176 if (msigned && (Rm & ((unsigned) 1 << 31)))
5177 /* Invert the bits to make the check against zero. */
5180 if ((Rm & 0xFFFFFF00) == 0)
5182 else if ((Rm & 0xFFFF0000) == 0)
5184 else if ((Rm & 0xFF000000) == 0)
5192 /* This function does the work of multiplying two 32bit
5193 values and adding a 64bit value to give a 64bit result. */
5196 MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc)
5203 nRdHi = BITS (16, 19);
5204 nRdLo = BITS (12, 15);
5206 RdHi = state->Reg[nRdHi];
5207 RdLo = state->Reg[nRdLo];
5209 scount = Multiply64 (state, instr, msigned, LDEFAULT);
5211 RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry);
5212 RdHi = (RdHi + state->Reg[nRdHi]) + carry;
5214 state->Reg[nRdLo] = RdLo;
5215 state->Reg[nRdHi] = RdHi;
5218 /* Ensure that both RdHi and RdLo are used to compute Z,
5219 but don't let RdLo's sign bit make it to N. */
5220 ARMul_NegZero (state, RdHi | (RdLo >> 16) | (RdLo & 0xFFFF));
5222 /* Extra cycle for addition. */