summaryrefslogtreecommitdiff
path: root/sim/arm/armemu.c
diff options
context:
space:
mode:
Diffstat (limited to 'sim/arm/armemu.c')
-rw-r--r--sim/arm/armemu.c3877
1 files changed, 0 insertions, 3877 deletions
diff --git a/sim/arm/armemu.c b/sim/arm/armemu.c
deleted file mode 100644
index 83853f1599c..00000000000
--- a/sim/arm/armemu.c
+++ /dev/null
@@ -1,3877 +0,0 @@
-/* armemu.c -- Main instruction emulation: ARM7 Instruction Emulator.
- Copyright (C) 1994 Advanced RISC Machines Ltd.
- Modifications to add arch. v4 support by <jsmith@cygnus.com>.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#include "armdefs.h"
-#include "armemu.h"
-#include "armos.h"
-
-static ARMword GetDPRegRHS (ARMul_State * state, ARMword instr);
-static ARMword GetDPSRegRHS (ARMul_State * state, ARMword instr);
-static void WriteR15 (ARMul_State * state, ARMword src);
-static void WriteSR15 (ARMul_State * state, ARMword src);
-static ARMword GetLSRegRHS (ARMul_State * state, ARMword instr);
-static ARMword GetLS7RHS (ARMul_State * state, ARMword instr);
-static unsigned LoadWord (ARMul_State * state, ARMword instr,
- ARMword address);
-static unsigned LoadHalfWord (ARMul_State * state, ARMword instr,
- ARMword address, int signextend);
-static unsigned LoadByte (ARMul_State * state, ARMword instr, ARMword address,
- int signextend);
-static unsigned StoreWord (ARMul_State * state, ARMword instr,
- ARMword address);
-static unsigned StoreHalfWord (ARMul_State * state, ARMword instr,
- ARMword address);
-static unsigned StoreByte (ARMul_State * state, ARMword instr,
- ARMword address);
-static void LoadMult (ARMul_State * state, ARMword address, ARMword instr,
- ARMword WBBase);
-static void StoreMult (ARMul_State * state, ARMword address, ARMword instr,
- ARMword WBBase);
-static void LoadSMult (ARMul_State * state, ARMword address, ARMword instr,
- ARMword WBBase);
-static void StoreSMult (ARMul_State * state, ARMword address, ARMword instr,
- ARMword WBBase);
-static unsigned Multiply64 (ARMul_State * state, ARMword instr,
- int signextend, int scc);
-static unsigned MultiplyAdd64 (ARMul_State * state, ARMword instr,
- int signextend, int scc);
-
-#define LUNSIGNED (0) /* unsigned operation */
-#define LSIGNED (1) /* signed operation */
-#define LDEFAULT (0) /* default : do nothing */
-#define LSCC (1) /* set condition codes on result */
-
-#ifdef NEED_UI_LOOP_HOOK
-/* How often to run the ui_loop update, when in use */
-#define UI_LOOP_POLL_INTERVAL 0x32000
-
-/* Counter for the ui_loop_hook update */
-static long ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
-
-/* Actual hook to call to run through gdb's gui event loop */
-extern int (*ui_loop_hook) (int);
-#endif /* NEED_UI_LOOP_HOOK */
-
-extern int stop_simulator;
-
-/***************************************************************************\
-* short-hand macros for LDR/STR *
-\***************************************************************************/
-
-/* store post decrement writeback */
-#define SHDOWNWB() \
- lhs = LHS ; \
- if (StoreHalfWord(state, instr, lhs)) \
- LSBase = lhs - GetLS7RHS(state, instr) ;
-
-/* store post increment writeback */
-#define SHUPWB() \
- lhs = LHS ; \
- if (StoreHalfWord(state, instr, lhs)) \
- LSBase = lhs + GetLS7RHS(state, instr) ;
-
-/* store pre decrement */
-#define SHPREDOWN() \
- (void)StoreHalfWord(state, instr, LHS - GetLS7RHS(state, instr)) ;
-
-/* store pre decrement writeback */
-#define SHPREDOWNWB() \
- temp = LHS - GetLS7RHS(state, instr) ; \
- if (StoreHalfWord(state, instr, temp)) \
- LSBase = temp ;
-
-/* store pre increment */
-#define SHPREUP() \
- (void)StoreHalfWord(state, instr, LHS + GetLS7RHS(state, instr)) ;
-
-/* store pre increment writeback */
-#define SHPREUPWB() \
- temp = LHS + GetLS7RHS(state, instr) ; \
- if (StoreHalfWord(state, instr, temp)) \
- LSBase = temp ;
-
-/* load post decrement writeback */
-#define LHPOSTDOWN() \
-{ \
- int done = 1 ; \
- lhs = LHS ; \
- switch (BITS(5,6)) { \
- case 1: /* H */ \
- if (LoadHalfWord(state,instr,lhs,LUNSIGNED)) \
- LSBase = lhs - GetLS7RHS(state,instr) ; \
- break ; \
- case 2: /* SB */ \
- if (LoadByte(state,instr,lhs,LSIGNED)) \
- LSBase = lhs - GetLS7RHS(state,instr) ; \
- break ; \
- case 3: /* SH */ \
- if (LoadHalfWord(state,instr,lhs,LSIGNED)) \
- LSBase = lhs - GetLS7RHS(state,instr) ; \
- break ; \
- case 0: /* SWP handled elsewhere */ \
- default: \
- done = 0 ; \
- break ; \
- } \
- if (done) \
- break ; \
-}
-
-/* load post increment writeback */
-#define LHPOSTUP() \
-{ \
- int done = 1 ; \
- lhs = LHS ; \
- switch (BITS(5,6)) { \
- case 1: /* H */ \
- if (LoadHalfWord(state,instr,lhs,LUNSIGNED)) \
- LSBase = lhs + GetLS7RHS(state,instr) ; \
- break ; \
- case 2: /* SB */ \
- if (LoadByte(state,instr,lhs,LSIGNED)) \
- LSBase = lhs + GetLS7RHS(state,instr) ; \
- break ; \
- case 3: /* SH */ \
- if (LoadHalfWord(state,instr,lhs,LSIGNED)) \
- LSBase = lhs + GetLS7RHS(state,instr) ; \
- break ; \
- case 0: /* SWP handled elsewhere */ \
- default: \
- done = 0 ; \
- break ; \
- } \
- if (done) \
- break ; \
-}
-
-/* load pre decrement */
-#define LHPREDOWN() \
-{ \
- int done = 1 ; \
- temp = LHS - GetLS7RHS(state,instr) ; \
- switch (BITS(5,6)) { \
- case 1: /* H */ \
- (void)LoadHalfWord(state,instr,temp,LUNSIGNED) ; \
- break ; \
- case 2: /* SB */ \
- (void)LoadByte(state,instr,temp,LSIGNED) ; \
- break ; \
- case 3: /* SH */ \
- (void)LoadHalfWord(state,instr,temp,LSIGNED) ; \
- break ; \
- case 0: /* SWP handled elsewhere */ \
- default: \
- done = 0 ; \
- break ; \
- } \
- if (done) \
- break ; \
-}
-
-/* load pre decrement writeback */
-#define LHPREDOWNWB() \
-{ \
- int done = 1 ; \
- temp = LHS - GetLS7RHS(state, instr) ; \
- switch (BITS(5,6)) { \
- case 1: /* H */ \
- if (LoadHalfWord(state,instr,temp,LUNSIGNED)) \
- LSBase = temp ; \
- break ; \
- case 2: /* SB */ \
- if (LoadByte(state,instr,temp,LSIGNED)) \
- LSBase = temp ; \
- break ; \
- case 3: /* SH */ \
- if (LoadHalfWord(state,instr,temp,LSIGNED)) \
- LSBase = temp ; \
- break ; \
- case 0: /* SWP handled elsewhere */ \
- default: \
- done = 0 ; \
- break ; \
- } \
- if (done) \
- break ; \
-}
-
-/* load pre increment */
-#define LHPREUP() \
-{ \
- int done = 1 ; \
- temp = LHS + GetLS7RHS(state,instr) ; \
- switch (BITS(5,6)) { \
- case 1: /* H */ \
- (void)LoadHalfWord(state,instr,temp,LUNSIGNED) ; \
- break ; \
- case 2: /* SB */ \
- (void)LoadByte(state,instr,temp,LSIGNED) ; \
- break ; \
- case 3: /* SH */ \
- (void)LoadHalfWord(state,instr,temp,LSIGNED) ; \
- break ; \
- case 0: /* SWP handled elsewhere */ \
- default: \
- done = 0 ; \
- break ; \
- } \
- if (done) \
- break ; \
-}
-
-/* load pre increment writeback */
-#define LHPREUPWB() \
-{ \
- int done = 1 ; \
- temp = LHS + GetLS7RHS(state, instr) ; \
- switch (BITS(5,6)) { \
- case 1: /* H */ \
- if (LoadHalfWord(state,instr,temp,LUNSIGNED)) \
- LSBase = temp ; \
- break ; \
- case 2: /* SB */ \
- if (LoadByte(state,instr,temp,LSIGNED)) \
- LSBase = temp ; \
- break ; \
- case 3: /* SH */ \
- if (LoadHalfWord(state,instr,temp,LSIGNED)) \
- LSBase = temp ; \
- break ; \
- case 0: /* SWP handled elsewhere */ \
- default: \
- done = 0 ; \
- break ; \
- } \
- if (done) \
- break ; \
-}
-
-/***************************************************************************\
-* EMULATION of ARM6 *
-\***************************************************************************/
-
-/* The PC pipeline value depends on whether ARM or Thumb instructions
- are being executed: */
-ARMword isize;
-
-#ifdef MODE32
-ARMword
-ARMul_Emulate32 (register ARMul_State * state)
-{
-#else
-ARMword
-ARMul_Emulate26 (register ARMul_State * state)
-{
-#endif
- register ARMword instr, /* the current instruction */
- dest = 0, /* almost the DestBus */
- temp, /* ubiquitous third hand */
- pc = 0; /* the address of the current instruction */
- ARMword lhs, rhs; /* almost the ABus and BBus */
- ARMword decoded = 0, loaded = 0; /* instruction pipeline */
-
-/***************************************************************************\
-* Execute the next instruction *
-\***************************************************************************/
-
- if (state->NextInstr < PRIMEPIPE)
- {
- decoded = state->decoded;
- loaded = state->loaded;
- pc = state->pc;
- }
-
- do
- { /* just keep going */
-#ifdef MODET
- if (TFLAG)
- {
- isize = 2;
- }
- else
-#endif
- isize = 4;
- switch (state->NextInstr)
- {
- case SEQ:
- state->Reg[15] += isize; /* Advance the pipeline, and an S cycle */
- pc += isize;
- instr = decoded;
- decoded = loaded;
- loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
- break;
-
- case NONSEQ:
- state->Reg[15] += isize; /* Advance the pipeline, and an N cycle */
- pc += isize;
- instr = decoded;
- decoded = loaded;
- loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
- NORMALCYCLE;
- break;
-
- case PCINCEDSEQ:
- pc += isize; /* Program counter advanced, and an S cycle */
- instr = decoded;
- decoded = loaded;
- loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
- NORMALCYCLE;
- break;
-
- case PCINCEDNONSEQ:
- pc += isize; /* Program counter advanced, and an N cycle */
- instr = decoded;
- decoded = loaded;
- loaded = ARMul_LoadInstrN (state, pc + (isize * 2), isize);
- NORMALCYCLE;
- break;
-
- case RESUME: /* The program counter has been changed */
- pc = state->Reg[15];
-#ifndef MODE32
- pc = pc & R15PCBITS;
-#endif
- state->Reg[15] = pc + (isize * 2);
- state->Aborted = 0;
- instr = ARMul_ReLoadInstr (state, pc, isize);
- decoded = ARMul_ReLoadInstr (state, pc + isize, isize);
- loaded = ARMul_ReLoadInstr (state, pc + isize * 2, isize);
- NORMALCYCLE;
- break;
-
- default: /* The program counter has been changed */
- pc = state->Reg[15];
-#ifndef MODE32
- pc = pc & R15PCBITS;
-#endif
- state->Reg[15] = pc + (isize * 2);
- state->Aborted = 0;
- instr = ARMul_LoadInstrN (state, pc, isize);
- decoded = ARMul_LoadInstrS (state, pc + (isize), isize);
- loaded = ARMul_LoadInstrS (state, pc + (isize * 2), isize);
- NORMALCYCLE;
- break;
- }
- if (state->EventSet)
- ARMul_EnvokeEvent (state);
-
-#if 0
- /* Enable this for a helpful bit of debugging when tracing is needed. */
- fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
- if (instr == 0)
- abort ();
-#endif
-
- if (state->Exception)
- { /* Any exceptions */
- if (state->NresetSig == LOW)
- {
- ARMul_Abort (state, ARMul_ResetV);
- break;
- }
- else if (!state->NfiqSig && !FFLAG)
- {
- ARMul_Abort (state, ARMul_FIQV);
- break;
- }
- else if (!state->NirqSig && !IFLAG)
- {
- ARMul_Abort (state, ARMul_IRQV);
- break;
- }
- }
-
- if (state->CallDebug > 0)
- {
- instr = ARMul_Debug (state, pc, instr);
- if (state->Emulate < ONCE)
- {
- state->NextInstr = RESUME;
- break;
- }
- if (state->Debug)
- {
- fprintf (stderr, "At %08lx Instr %08lx Mode %02lx\n", pc, instr,
- state->Mode);
- (void) fgetc (stdin);
- }
- }
- else if (state->Emulate < ONCE)
- {
- state->NextInstr = RESUME;
- break;
- }
-
- state->NumInstrs++;
-
-#ifdef MODET
- /* Provide Thumb instruction decoding. If the processor is in Thumb
- mode, then we can simply decode the Thumb instruction, and map it
- to the corresponding ARM instruction (by directly loading the
- instr variable, and letting the normal ARM simulator
- execute). There are some caveats to ensure that the correct
- pipelined PC value is used when executing Thumb code, and also for
- dealing with the BL instruction. */
- if (TFLAG)
- { /* check if in Thumb mode */
- ARMword new;
- switch (ARMul_ThumbDecode (state, pc, instr, &new))
- {
- case t_undefined:
- ARMul_UndefInstr (state, instr); /* This is a Thumb instruction */
- break;
-
- case t_branch: /* already processed */
- goto donext;
-
- case t_decoded: /* ARM instruction available */
- instr = new; /* so continue instruction decoding */
- break;
- }
- }
-#endif
-
-/***************************************************************************\
-* Check the condition codes *
-\***************************************************************************/
- if ((temp = TOPBITS (28)) == AL)
- goto mainswitch; /* vile deed in the need for speed */
-
- switch ((int) TOPBITS (28))
- { /* check the condition code */
- case AL:
- temp = TRUE;
- break;
- case NV:
- temp = FALSE;
- break;
- case EQ:
- temp = ZFLAG;
- break;
- case NE:
- temp = !ZFLAG;
- break;
- case VS:
- temp = VFLAG;
- break;
- case VC:
- temp = !VFLAG;
- break;
- case MI:
- temp = NFLAG;
- break;
- case PL:
- temp = !NFLAG;
- break;
- case CS:
- temp = CFLAG;
- break;
- case CC:
- temp = !CFLAG;
- break;
- case HI:
- temp = (CFLAG && !ZFLAG);
- break;
- case LS:
- temp = (!CFLAG || ZFLAG);
- break;
- case GE:
- temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG));
- break;
- case LT:
- temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG));
- break;
- case GT:
- temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG));
- break;
- case LE:
- temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG;
- break;
- } /* cc check */
-
-/***************************************************************************\
-* Actual execution of instructions begins here *
-\***************************************************************************/
-
- if (temp)
- { /* if the condition codes don't match, stop here */
- mainswitch:
-
-
- switch ((int) BITS (20, 27))
- {
-
-/***************************************************************************\
-* Data Processing Register RHS Instructions *
-\***************************************************************************/
-
- case 0x00: /* AND reg and MUL */
-#ifdef MODET
- if (BITS (4, 11) == 0xB)
- {
- /* STRH register offset, no write-back, down, post indexed */
- SHDOWNWB ();
- break;
- }
- /* TODO: CHECK: should 0xD and 0xF generate undefined intruction aborts? */
-#endif
- if (BITS (4, 7) == 9)
- { /* MUL */
- rhs = state->Reg[MULRHSReg];
- if (MULLHSReg == MULDESTReg)
- {
- UNDEF_MULDestEQOp1;
- state->Reg[MULDESTReg] = 0;
- }
- else if (MULDESTReg != 15)
- state->Reg[MULDESTReg] = state->Reg[MULLHSReg] * rhs;
- else
- {
- UNDEF_MULPCDest;
- }
- for (dest = 0, temp = 0; dest < 32; dest++)
- if (rhs & (1L << dest))
- temp = dest; /* mult takes this many/2 I cycles */
- ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
- }
- else
- { /* AND reg */
- rhs = DPRegRHS;
- dest = LHS & rhs;
- WRITEDEST (dest);
- }
- break;
-
- case 0x01: /* ANDS reg and MULS */
-#ifdef MODET
- if ((BITS (4, 11) & 0xF9) == 0x9)
- {
- /* LDR register offset, no write-back, down, post indexed */
- LHPOSTDOWN ();
- /* fall through to rest of decoding */
- }
-#endif
- if (BITS (4, 7) == 9)
- { /* MULS */
- rhs = state->Reg[MULRHSReg];
- if (MULLHSReg == MULDESTReg)
- {
- UNDEF_MULDestEQOp1;
- state->Reg[MULDESTReg] = 0;
- CLEARN;
- SETZ;
- }
- else if (MULDESTReg != 15)
- {
- dest = state->Reg[MULLHSReg] * rhs;
- ARMul_NegZero (state, dest);
- state->Reg[MULDESTReg] = dest;
- }
- else
- {
- UNDEF_MULPCDest;
- }
- for (dest = 0, temp = 0; dest < 32; dest++)
- if (rhs & (1L << dest))
- temp = dest; /* mult takes this many/2 I cycles */
- ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
- }
- else
- { /* ANDS reg */
- rhs = DPSRegRHS;
- dest = LHS & rhs;
- WRITESDEST (dest);
- }
- break;
-
- case 0x02: /* EOR reg and MLA */
-#ifdef MODET
- if (BITS (4, 11) == 0xB)
- {
- /* STRH register offset, write-back, down, post indexed */
- SHDOWNWB ();
- break;
- }
-#endif
- if (BITS (4, 7) == 9)
- { /* MLA */
- rhs = state->Reg[MULRHSReg];
- if (MULLHSReg == MULDESTReg)
- {
- UNDEF_MULDestEQOp1;
- state->Reg[MULDESTReg] = state->Reg[MULACCReg];
- }
- else if (MULDESTReg != 15)
- state->Reg[MULDESTReg] =
- state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
- else
- {
- UNDEF_MULPCDest;
- }
- for (dest = 0, temp = 0; dest < 32; dest++)
- if (rhs & (1L << dest))
- temp = dest; /* mult takes this many/2 I cycles */
- ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
- }
- else
- {
- rhs = DPRegRHS;
- dest = LHS ^ rhs;
- WRITEDEST (dest);
- }
- break;
-
- case 0x03: /* EORS reg and MLAS */
-#ifdef MODET
- if ((BITS (4, 11) & 0xF9) == 0x9)
- {
- /* LDR register offset, write-back, down, post-indexed */
- LHPOSTDOWN ();
- /* fall through to rest of the decoding */
- }
-#endif
- if (BITS (4, 7) == 9)
- { /* MLAS */
- rhs = state->Reg[MULRHSReg];
- if (MULLHSReg == MULDESTReg)
- {
- UNDEF_MULDestEQOp1;
- dest = state->Reg[MULACCReg];
- ARMul_NegZero (state, dest);
- state->Reg[MULDESTReg] = dest;
- }
- else if (MULDESTReg != 15)
- {
- dest =
- state->Reg[MULLHSReg] * rhs + state->Reg[MULACCReg];
- ARMul_NegZero (state, dest);
- state->Reg[MULDESTReg] = dest;
- }
- else
- {
- UNDEF_MULPCDest;
- }
- for (dest = 0, temp = 0; dest < 32; dest++)
- if (rhs & (1L << dest))
- temp = dest; /* mult takes this many/2 I cycles */
- ARMul_Icycles (state, ARMul_MultTable[temp], 0L);
- }
- else
- { /* EORS Reg */
- rhs = DPSRegRHS;
- dest = LHS ^ rhs;
- WRITESDEST (dest);
- }
- break;
-
- case 0x04: /* SUB reg */
-#ifdef MODET
- if (BITS (4, 7) == 0xB)
- {
- /* STRH immediate offset, no write-back, down, post indexed */
- SHDOWNWB ();
- break;
- }
-#endif
- rhs = DPRegRHS;
- dest = LHS - rhs;
- WRITEDEST (dest);
- break;
-
- case 0x05: /* SUBS reg */
-#ifdef MODET
- if ((BITS (4, 7) & 0x9) == 0x9)
- {
- /* LDR immediate offset, no write-back, down, post indexed */
- LHPOSTDOWN ();
- /* fall through to the rest of the instruction decoding */
- }
-#endif
- lhs = LHS;
- rhs = DPRegRHS;
- dest = lhs - rhs;
- if ((lhs >= rhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, lhs, rhs, dest);
- ARMul_SubOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x06: /* RSB reg */
-#ifdef MODET
- if (BITS (4, 7) == 0xB)
- {
- /* STRH immediate offset, write-back, down, post indexed */
- SHDOWNWB ();
- break;
- }
-#endif
- rhs = DPRegRHS;
- dest = rhs - LHS;
- WRITEDEST (dest);
- break;
-
- case 0x07: /* RSBS reg */
-#ifdef MODET
- if ((BITS (4, 7) & 0x9) == 0x9)
- {
- /* LDR immediate offset, write-back, down, post indexed */
- LHPOSTDOWN ();
- /* fall through to remainder of instruction decoding */
- }
-#endif
- lhs = LHS;
- rhs = DPRegRHS;
- dest = rhs - lhs;
- if ((rhs >= lhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, rhs, lhs, dest);
- ARMul_SubOverflow (state, rhs, lhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x08: /* ADD reg */
-#ifdef MODET
- if (BITS (4, 11) == 0xB)
- {
- /* STRH register offset, no write-back, up, post indexed */
- SHUPWB ();
- break;
- }
-#endif
-#ifdef MODET
- if (BITS (4, 7) == 0x9)
- { /* MULL */
- /* 32x32 = 64 */
- ARMul_Icycles (state,
- Multiply64 (state, instr, LUNSIGNED,
- LDEFAULT), 0L);
- break;
- }
-#endif
- rhs = DPRegRHS;
- dest = LHS + rhs;
- WRITEDEST (dest);
- break;
-
- case 0x09: /* ADDS reg */
-#ifdef MODET
- if ((BITS (4, 11) & 0xF9) == 0x9)
- {
- /* LDR register offset, no write-back, up, post indexed */
- LHPOSTUP ();
- /* fall through to remaining instruction decoding */
- }
-#endif
-#ifdef MODET
- if (BITS (4, 7) == 0x9)
- { /* MULL */
- /* 32x32=64 */
- ARMul_Icycles (state,
- Multiply64 (state, instr, LUNSIGNED, LSCC),
- 0L);
- break;
- }
-#endif
- lhs = LHS;
- rhs = DPRegRHS;
- dest = lhs + rhs;
- ASSIGNZ (dest == 0);
- if ((lhs | rhs) >> 30)
- { /* possible C,V,N to set */
- ASSIGNN (NEG (dest));
- ARMul_AddCarry (state, lhs, rhs, dest);
- ARMul_AddOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARN;
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x0a: /* ADC reg */
-#ifdef MODET
- if (BITS (4, 11) == 0xB)
- {
- /* STRH register offset, write-back, up, post-indexed */
- SHUPWB ();
- break;
- }
-#endif
-#ifdef MODET
- if (BITS (4, 7) == 0x9)
- { /* MULL */
- /* 32x32=64 */
- ARMul_Icycles (state,
- MultiplyAdd64 (state, instr, LUNSIGNED,
- LDEFAULT), 0L);
- break;
- }
-#endif
- rhs = DPRegRHS;
- dest = LHS + rhs + CFLAG;
- WRITEDEST (dest);
- break;
-
- case 0x0b: /* ADCS reg */
-#ifdef MODET
- if ((BITS (4, 11) & 0xF9) == 0x9)
- {
- /* LDR register offset, write-back, up, post indexed */
- LHPOSTUP ();
- /* fall through to remaining instruction decoding */
- }
-#endif
-#ifdef MODET
- if (BITS (4, 7) == 0x9)
- { /* MULL */
- /* 32x32=64 */
- ARMul_Icycles (state,
- MultiplyAdd64 (state, instr, LUNSIGNED,
- LSCC), 0L);
- break;
- }
-#endif
- lhs = LHS;
- rhs = DPRegRHS;
- dest = lhs + rhs + CFLAG;
- ASSIGNZ (dest == 0);
- if ((lhs | rhs) >> 30)
- { /* possible C,V,N to set */
- ASSIGNN (NEG (dest));
- ARMul_AddCarry (state, lhs, rhs, dest);
- ARMul_AddOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARN;
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x0c: /* SBC reg */
-#ifdef MODET
- if (BITS (4, 7) == 0xB)
- {
- /* STRH immediate offset, no write-back, up post indexed */
- SHUPWB ();
- break;
- }
-#endif
-#ifdef MODET
- if (BITS (4, 7) == 0x9)
- { /* MULL */
- /* 32x32=64 */
- ARMul_Icycles (state,
- Multiply64 (state, instr, LSIGNED, LDEFAULT),
- 0L);
- break;
- }
-#endif
- rhs = DPRegRHS;
- dest = LHS - rhs - !CFLAG;
- WRITEDEST (dest);
- break;
-
- case 0x0d: /* SBCS reg */
-#ifdef MODET
- if ((BITS (4, 7) & 0x9) == 0x9)
- {
- /* LDR immediate offset, no write-back, up, post indexed */
- LHPOSTUP ();
- }
-#endif
-#ifdef MODET
- if (BITS (4, 7) == 0x9)
- { /* MULL */
- /* 32x32=64 */
- ARMul_Icycles (state,
- Multiply64 (state, instr, LSIGNED, LSCC),
- 0L);
- break;
- }
-#endif
- lhs = LHS;
- rhs = DPRegRHS;
- dest = lhs - rhs - !CFLAG;
- if ((lhs >= rhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, lhs, rhs, dest);
- ARMul_SubOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x0e: /* RSC reg */
-#ifdef MODET
- if (BITS (4, 7) == 0xB)
- {
- /* STRH immediate offset, write-back, up, post indexed */
- SHUPWB ();
- break;
- }
-#endif
-#ifdef MODET
- if (BITS (4, 7) == 0x9)
- { /* MULL */
- /* 32x32=64 */
- ARMul_Icycles (state,
- MultiplyAdd64 (state, instr, LSIGNED,
- LDEFAULT), 0L);
- break;
- }
-#endif
- rhs = DPRegRHS;
- dest = rhs - LHS - !CFLAG;
- WRITEDEST (dest);
- break;
-
- case 0x0f: /* RSCS reg */
-#ifdef MODET
- if ((BITS (4, 7) & 0x9) == 0x9)
- {
- /* LDR immediate offset, write-back, up, post indexed */
- LHPOSTUP ();
- /* fall through to remaining instruction decoding */
- }
-#endif
-#ifdef MODET
- if (BITS (4, 7) == 0x9)
- { /* MULL */
- /* 32x32=64 */
- ARMul_Icycles (state,
- MultiplyAdd64 (state, instr, LSIGNED, LSCC),
- 0L);
- break;
- }
-#endif
- lhs = LHS;
- rhs = DPRegRHS;
- dest = rhs - lhs - !CFLAG;
- if ((rhs >= lhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, rhs, lhs, dest);
- ARMul_SubOverflow (state, rhs, lhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x10: /* TST reg and MRS CPSR and SWP word */
-#ifdef MODET
- if (BITS (4, 11) == 0xB)
- {
- /* STRH register offset, no write-back, down, pre indexed */
- SHPREDOWN ();
- break;
- }
-#endif
- if (BITS (4, 11) == 9)
- { /* SWP */
- UNDEF_SWPPC;
- temp = LHS;
- BUSUSEDINCPCS;
-#ifndef MODE32
- if (VECTORACCESS (temp) || ADDREXCEPT (temp))
- {
- INTERNALABORT (temp);
- (void) ARMul_LoadWordN (state, temp);
- (void) ARMul_LoadWordN (state, temp);
- }
- else
-#endif
- dest = ARMul_SwapWord (state, temp, state->Reg[RHSReg]);
- if (temp & 3)
- DEST = ARMul_Align (state, temp, dest);
- else
- DEST = dest;
- if (state->abortSig || state->Aborted)
- {
- TAKEABORT;
- }
- }
- else if ((BITS (0, 11) == 0) && (LHSReg == 15))
- { /* MRS CPSR */
- UNDEF_MRSPC;
- DEST = ECC | EINT | EMODE;
- }
- else
- {
- UNDEF_Test;
- }
- break;
-
- case 0x11: /* TSTP reg */
-#ifdef MODET
- if ((BITS (4, 11) & 0xF9) == 0x9)
- {
- /* LDR register offset, no write-back, down, pre indexed */
- LHPREDOWN ();
- /* continue with remaining instruction decode */
- }
-#endif
- if (DESTReg == 15)
- { /* TSTP reg */
-#ifdef MODE32
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
-#else
- rhs = DPRegRHS;
- temp = LHS & rhs;
- SETR15PSR (temp);
-#endif
- }
- else
- { /* TST reg */
- rhs = DPSRegRHS;
- dest = LHS & rhs;
- ARMul_NegZero (state, dest);
- }
- break;
-
- case 0x12: /* TEQ reg and MSR reg to CPSR (ARM6) */
-#ifdef MODET
- if (BITS (4, 11) == 0xB)
- {
- /* STRH register offset, write-back, down, pre indexed */
- SHPREDOWNWB ();
- break;
- }
-#endif
-#ifdef MODET
- if (BITS (4, 27) == 0x12FFF1)
- { /* BX */
- /* Branch to the address in RHSReg. If bit0 of
- destination address is 1 then switch to Thumb mode: */
- ARMword addr = state->Reg[RHSReg];
-
- /* If we read the PC then the bottom bit is clear */
- if (RHSReg == 15)
- addr &= ~1;
-
- /* Enable this for a helpful bit of debugging when
- GDB is not yet fully working...
- fprintf (stderr, "BX at %x to %x (go %s)\n",
- state->Reg[15], addr, (addr & 1) ? "thumb": "arm" ); */
-
- if (addr & (1 << 0))
- { /* Thumb bit */
- SETT;
- state->Reg[15] = addr & 0xfffffffe;
- /* NOTE: The other CPSR flag setting blocks do not
- seem to update the state->Cpsr state, but just do
- the explicit flag. The copy from the seperate
- flags to the register must happen later. */
- FLUSHPIPE;
- }
- else
- {
- CLEART;
- state->Reg[15] = addr & 0xfffffffc;
- FLUSHPIPE;
- }
- }
-#endif
- if (DESTReg == 15 && BITS (17, 18) == 0)
- { /* MSR reg to CPSR */
- UNDEF_MSRPC;
- temp = DPRegRHS;
- ARMul_FixCPSR (state, instr, temp);
- }
- else
- {
- UNDEF_Test;
- }
- break;
-
- case 0x13: /* TEQP reg */
-#ifdef MODET
- if ((BITS (4, 11) & 0xF9) == 0x9)
- {
- /* LDR register offset, write-back, down, pre indexed */
- LHPREDOWNWB ();
- /* continue with remaining instruction decode */
- }
-#endif
- if (DESTReg == 15)
- { /* TEQP reg */
-#ifdef MODE32
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
-#else
- rhs = DPRegRHS;
- temp = LHS ^ rhs;
- SETR15PSR (temp);
-#endif
- }
- else
- { /* TEQ Reg */
- rhs = DPSRegRHS;
- dest = LHS ^ rhs;
- ARMul_NegZero (state, dest);
- }
- break;
-
- case 0x14: /* CMP reg and MRS SPSR and SWP byte */
-#ifdef MODET
- if (BITS (4, 7) == 0xB)
- {
- /* STRH immediate offset, no write-back, down, pre indexed */
- SHPREDOWN ();
- break;
- }
-#endif
- if (BITS (4, 11) == 9)
- { /* SWP */
- UNDEF_SWPPC;
- temp = LHS;
- BUSUSEDINCPCS;
-#ifndef MODE32
- if (VECTORACCESS (temp) || ADDREXCEPT (temp))
- {
- INTERNALABORT (temp);
- (void) ARMul_LoadByte (state, temp);
- (void) ARMul_LoadByte (state, temp);
- }
- else
-#endif
- DEST = ARMul_SwapByte (state, temp, state->Reg[RHSReg]);
- if (state->abortSig || state->Aborted)
- {
- TAKEABORT;
- }
- }
- else if ((BITS (0, 11) == 0) && (LHSReg == 15))
- { /* MRS SPSR */
- UNDEF_MRSPC;
- DEST = GETSPSR (state->Bank);
- }
- else
- {
- UNDEF_Test;
- }
- break;
-
- case 0x15: /* CMPP reg */
-#ifdef MODET
- if ((BITS (4, 7) & 0x9) == 0x9)
- {
- /* LDR immediate offset, no write-back, down, pre indexed */
- LHPREDOWN ();
- /* continue with remaining instruction decode */
- }
-#endif
- if (DESTReg == 15)
- { /* CMPP reg */
-#ifdef MODE32
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
-#else
- rhs = DPRegRHS;
- temp = LHS - rhs;
- SETR15PSR (temp);
-#endif
- }
- else
- { /* CMP reg */
- lhs = LHS;
- rhs = DPRegRHS;
- dest = lhs - rhs;
- ARMul_NegZero (state, dest);
- if ((lhs >= rhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, lhs, rhs, dest);
- ARMul_SubOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- }
- break;
-
- case 0x16: /* CMN reg and MSR reg to SPSR */
-#ifdef MODET
- if (BITS (4, 7) == 0xB)
- {
- /* STRH immediate offset, write-back, down, pre indexed */
- SHPREDOWNWB ();
- break;
- }
-#endif
- if (DESTReg == 15 && BITS (17, 18) == 0)
- { /* MSR */
- UNDEF_MSRPC;
- ARMul_FixSPSR (state, instr, DPRegRHS);
- }
- else
- {
- UNDEF_Test;
- }
- break;
-
- case 0x17: /* CMNP reg */
-#ifdef MODET
- if ((BITS (4, 7) & 0x9) == 0x9)
- {
- /* LDR immediate offset, write-back, down, pre indexed */
- LHPREDOWNWB ();
- /* continue with remaining instruction decoding */
- }
-#endif
- if (DESTReg == 15)
- {
-#ifdef MODE32
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
-#else
- rhs = DPRegRHS;
- temp = LHS + rhs;
- SETR15PSR (temp);
-#endif
- break;
- }
- else
- { /* CMN reg */
- lhs = LHS;
- rhs = DPRegRHS;
- dest = lhs + rhs;
- ASSIGNZ (dest == 0);
- if ((lhs | rhs) >> 30)
- { /* possible C,V,N to set */
- ASSIGNN (NEG (dest));
- ARMul_AddCarry (state, lhs, rhs, dest);
- ARMul_AddOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARN;
- CLEARC;
- CLEARV;
- }
- }
- break;
-
- case 0x18: /* ORR reg */
-#ifdef MODET
- if (BITS (4, 11) == 0xB)
- {
- /* STRH register offset, no write-back, up, pre indexed */
- SHPREUP ();
- break;
- }
-#endif
- rhs = DPRegRHS;
- dest = LHS | rhs;
- WRITEDEST (dest);
- break;
-
- case 0x19: /* ORRS reg */
-#ifdef MODET
- if ((BITS (4, 11) & 0xF9) == 0x9)
- {
- /* LDR register offset, no write-back, up, pre indexed */
- LHPREUP ();
- /* continue with remaining instruction decoding */
- }
-#endif
- rhs = DPSRegRHS;
- dest = LHS | rhs;
- WRITESDEST (dest);
- break;
-
- case 0x1a: /* MOV reg */
-#ifdef MODET
- if (BITS (4, 11) == 0xB)
- {
- /* STRH register offset, write-back, up, pre indexed */
- SHPREUPWB ();
- break;
- }
-#endif
- dest = DPRegRHS;
- WRITEDEST (dest);
- break;
-
- case 0x1b: /* MOVS reg */
-#ifdef MODET
- if ((BITS (4, 11) & 0xF9) == 0x9)
- {
- /* LDR register offset, write-back, up, pre indexed */
- LHPREUPWB ();
- /* continue with remaining instruction decoding */
- }
-#endif
- dest = DPSRegRHS;
- WRITESDEST (dest);
- break;
-
- case 0x1c: /* BIC reg */
-#ifdef MODET
- if (BITS (4, 7) == 0xB)
- {
- /* STRH immediate offset, no write-back, up, pre indexed */
- SHPREUP ();
- break;
- }
-#endif
- rhs = DPRegRHS;
- dest = LHS & ~rhs;
- WRITEDEST (dest);
- break;
-
- case 0x1d: /* BICS reg */
-#ifdef MODET
- if ((BITS (4, 7) & 0x9) == 0x9)
- {
- /* LDR immediate offset, no write-back, up, pre indexed */
- LHPREUP ();
- /* continue with instruction decoding */
- }
-#endif
- rhs = DPSRegRHS;
- dest = LHS & ~rhs;
- WRITESDEST (dest);
- break;
-
- case 0x1e: /* MVN reg */
-#ifdef MODET
- if (BITS (4, 7) == 0xB)
- {
- /* STRH immediate offset, write-back, up, pre indexed */
- SHPREUPWB ();
- break;
- }
-#endif
- dest = ~DPRegRHS;
- WRITEDEST (dest);
- break;
-
- case 0x1f: /* MVNS reg */
-#ifdef MODET
- if ((BITS (4, 7) & 0x9) == 0x9)
- {
- /* LDR immediate offset, write-back, up, pre indexed */
- LHPREUPWB ();
- /* continue instruction decoding */
- }
-#endif
- dest = ~DPSRegRHS;
- WRITESDEST (dest);
- break;
-
-/***************************************************************************\
-* Data Processing Immediate RHS Instructions *
-\***************************************************************************/
-
- case 0x20: /* AND immed */
- dest = LHS & DPImmRHS;
- WRITEDEST (dest);
- break;
-
- case 0x21: /* ANDS immed */
- DPSImmRHS;
- dest = LHS & rhs;
- WRITESDEST (dest);
- break;
-
- case 0x22: /* EOR immed */
- dest = LHS ^ DPImmRHS;
- WRITEDEST (dest);
- break;
-
- case 0x23: /* EORS immed */
- DPSImmRHS;
- dest = LHS ^ rhs;
- WRITESDEST (dest);
- break;
-
- case 0x24: /* SUB immed */
- dest = LHS - DPImmRHS;
- WRITEDEST (dest);
- break;
-
- case 0x25: /* SUBS immed */
- lhs = LHS;
- rhs = DPImmRHS;
- dest = lhs - rhs;
- if ((lhs >= rhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, lhs, rhs, dest);
- ARMul_SubOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x26: /* RSB immed */
- dest = DPImmRHS - LHS;
- WRITEDEST (dest);
- break;
-
- case 0x27: /* RSBS immed */
- lhs = LHS;
- rhs = DPImmRHS;
- dest = rhs - lhs;
- if ((rhs >= lhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, rhs, lhs, dest);
- ARMul_SubOverflow (state, rhs, lhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x28: /* ADD immed */
- dest = LHS + DPImmRHS;
- WRITEDEST (dest);
- break;
-
- case 0x29: /* ADDS immed */
- lhs = LHS;
- rhs = DPImmRHS;
- dest = lhs + rhs;
- ASSIGNZ (dest == 0);
- if ((lhs | rhs) >> 30)
- { /* possible C,V,N to set */
- ASSIGNN (NEG (dest));
- ARMul_AddCarry (state, lhs, rhs, dest);
- ARMul_AddOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARN;
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x2a: /* ADC immed */
- dest = LHS + DPImmRHS + CFLAG;
- WRITEDEST (dest);
- break;
-
- case 0x2b: /* ADCS immed */
- lhs = LHS;
- rhs = DPImmRHS;
- dest = lhs + rhs + CFLAG;
- ASSIGNZ (dest == 0);
- if ((lhs | rhs) >> 30)
- { /* possible C,V,N to set */
- ASSIGNN (NEG (dest));
- ARMul_AddCarry (state, lhs, rhs, dest);
- ARMul_AddOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARN;
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x2c: /* SBC immed */
- dest = LHS - DPImmRHS - !CFLAG;
- WRITEDEST (dest);
- break;
-
- case 0x2d: /* SBCS immed */
- lhs = LHS;
- rhs = DPImmRHS;
- dest = lhs - rhs - !CFLAG;
- if ((lhs >= rhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, lhs, rhs, dest);
- ARMul_SubOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x2e: /* RSC immed */
- dest = DPImmRHS - LHS - !CFLAG;
- WRITEDEST (dest);
- break;
-
- case 0x2f: /* RSCS immed */
- lhs = LHS;
- rhs = DPImmRHS;
- dest = rhs - lhs - !CFLAG;
- if ((rhs >= lhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, rhs, lhs, dest);
- ARMul_SubOverflow (state, rhs, lhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- WRITESDEST (dest);
- break;
-
- case 0x30: /* TST immed */
- UNDEF_Test;
- break;
-
- case 0x31: /* TSTP immed */
- if (DESTReg == 15)
- { /* TSTP immed */
-#ifdef MODE32
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
-#else
- temp = LHS & DPImmRHS;
- SETR15PSR (temp);
-#endif
- }
- else
- {
- DPSImmRHS; /* TST immed */
- dest = LHS & rhs;
- ARMul_NegZero (state, dest);
- }
- break;
-
- case 0x32: /* TEQ immed and MSR immed to CPSR */
- if (DESTReg == 15 && BITS (17, 18) == 0)
- { /* MSR immed to CPSR */
- ARMul_FixCPSR (state, instr, DPImmRHS);
- }
- else
- {
- UNDEF_Test;
- }
- break;
-
- case 0x33: /* TEQP immed */
- if (DESTReg == 15)
- { /* TEQP immed */
-#ifdef MODE32
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
-#else
- temp = LHS ^ DPImmRHS;
- SETR15PSR (temp);
-#endif
- }
- else
- {
- DPSImmRHS; /* TEQ immed */
- dest = LHS ^ rhs;
- ARMul_NegZero (state, dest);
- }
- break;
-
- case 0x34: /* CMP immed */
- UNDEF_Test;
- break;
-
- case 0x35: /* CMPP immed */
- if (DESTReg == 15)
- { /* CMPP immed */
-#ifdef MODE32
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
-#else
- temp = LHS - DPImmRHS;
- SETR15PSR (temp);
-#endif
- break;
- }
- else
- {
- lhs = LHS; /* CMP immed */
- rhs = DPImmRHS;
- dest = lhs - rhs;
- ARMul_NegZero (state, dest);
- if ((lhs >= rhs) || ((rhs | lhs) >> 31))
- {
- ARMul_SubCarry (state, lhs, rhs, dest);
- ARMul_SubOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARC;
- CLEARV;
- }
- }
- break;
-
- case 0x36: /* CMN immed and MSR immed to SPSR */
- if (DESTReg == 15 && BITS (17, 18) == 0) /* MSR */
- ARMul_FixSPSR (state, instr, DPImmRHS);
- else
- {
- UNDEF_Test;
- }
- break;
-
- case 0x37: /* CMNP immed */
- if (DESTReg == 15)
- { /* CMNP immed */
-#ifdef MODE32
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
-#else
- temp = LHS + DPImmRHS;
- SETR15PSR (temp);
-#endif
- break;
- }
- else
- {
- lhs = LHS; /* CMN immed */
- rhs = DPImmRHS;
- dest = lhs + rhs;
- ASSIGNZ (dest == 0);
- if ((lhs | rhs) >> 30)
- { /* possible C,V,N to set */
- ASSIGNN (NEG (dest));
- ARMul_AddCarry (state, lhs, rhs, dest);
- ARMul_AddOverflow (state, lhs, rhs, dest);
- }
- else
- {
- CLEARN;
- CLEARC;
- CLEARV;
- }
- }
- break;
-
- case 0x38: /* ORR immed */
- dest = LHS | DPImmRHS;
- WRITEDEST (dest);
- break;
-
- case 0x39: /* ORRS immed */
- DPSImmRHS;
- dest = LHS | rhs;
- WRITESDEST (dest);
- break;
-
- case 0x3a: /* MOV immed */
- dest = DPImmRHS;
- WRITEDEST (dest);
- break;
-
- case 0x3b: /* MOVS immed */
- DPSImmRHS;
- WRITESDEST (rhs);
- break;
-
- case 0x3c: /* BIC immed */
- dest = LHS & ~DPImmRHS;
- WRITEDEST (dest);
- break;
-
- case 0x3d: /* BICS immed */
- DPSImmRHS;
- dest = LHS & ~rhs;
- WRITESDEST (dest);
- break;
-
- case 0x3e: /* MVN immed */
- dest = ~DPImmRHS;
- WRITEDEST (dest);
- break;
-
- case 0x3f: /* MVNS immed */
- DPSImmRHS;
- WRITESDEST (~rhs);
- break;
-
-/***************************************************************************\
-* Single Data Transfer Immediate RHS Instructions *
-\***************************************************************************/
-
- case 0x40: /* Store Word, No WriteBack, Post Dec, Immed */
- lhs = LHS;
- if (StoreWord (state, instr, lhs))
- LSBase = lhs - LSImmRHS;
- break;
-
- case 0x41: /* Load Word, No WriteBack, Post Dec, Immed */
- lhs = LHS;
- if (LoadWord (state, instr, lhs))
- LSBase = lhs - LSImmRHS;
- break;
-
- case 0x42: /* Store Word, WriteBack, Post Dec, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- lhs = LHS;
- temp = lhs - LSImmRHS;
- state->NtransSig = LOW;
- if (StoreWord (state, instr, lhs))
- LSBase = temp;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x43: /* Load Word, WriteBack, Post Dec, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (LoadWord (state, instr, lhs))
- LSBase = lhs - LSImmRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x44: /* Store Byte, No WriteBack, Post Dec, Immed */
- lhs = LHS;
- if (StoreByte (state, instr, lhs))
- LSBase = lhs - LSImmRHS;
- break;
-
- case 0x45: /* Load Byte, No WriteBack, Post Dec, Immed */
- lhs = LHS;
- if (LoadByte (state, instr, lhs, LUNSIGNED))
- LSBase = lhs - LSImmRHS;
- break;
-
- case 0x46: /* Store Byte, WriteBack, Post Dec, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (StoreByte (state, instr, lhs))
- LSBase = lhs - LSImmRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x47: /* Load Byte, WriteBack, Post Dec, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (LoadByte (state, instr, lhs, LUNSIGNED))
- LSBase = lhs - LSImmRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x48: /* Store Word, No WriteBack, Post Inc, Immed */
- lhs = LHS;
- if (StoreWord (state, instr, lhs))
- LSBase = lhs + LSImmRHS;
- break;
-
- case 0x49: /* Load Word, No WriteBack, Post Inc, Immed */
- lhs = LHS;
- if (LoadWord (state, instr, lhs))
- LSBase = lhs + LSImmRHS;
- break;
-
- case 0x4a: /* Store Word, WriteBack, Post Inc, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (StoreWord (state, instr, lhs))
- LSBase = lhs + LSImmRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x4b: /* Load Word, WriteBack, Post Inc, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (LoadWord (state, instr, lhs))
- LSBase = lhs + LSImmRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x4c: /* Store Byte, No WriteBack, Post Inc, Immed */
- lhs = LHS;
- if (StoreByte (state, instr, lhs))
- LSBase = lhs + LSImmRHS;
- break;
-
- case 0x4d: /* Load Byte, No WriteBack, Post Inc, Immed */
- lhs = LHS;
- if (LoadByte (state, instr, lhs, LUNSIGNED))
- LSBase = lhs + LSImmRHS;
- break;
-
- case 0x4e: /* Store Byte, WriteBack, Post Inc, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (StoreByte (state, instr, lhs))
- LSBase = lhs + LSImmRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x4f: /* Load Byte, WriteBack, Post Inc, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (LoadByte (state, instr, lhs, LUNSIGNED))
- LSBase = lhs + LSImmRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
-
- case 0x50: /* Store Word, No WriteBack, Pre Dec, Immed */
- (void) StoreWord (state, instr, LHS - LSImmRHS);
- break;
-
- case 0x51: /* Load Word, No WriteBack, Pre Dec, Immed */
- (void) LoadWord (state, instr, LHS - LSImmRHS);
- break;
-
- case 0x52: /* Store Word, WriteBack, Pre Dec, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- temp = LHS - LSImmRHS;
- if (StoreWord (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x53: /* Load Word, WriteBack, Pre Dec, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- temp = LHS - LSImmRHS;
- if (LoadWord (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x54: /* Store Byte, No WriteBack, Pre Dec, Immed */
- (void) StoreByte (state, instr, LHS - LSImmRHS);
- break;
-
- case 0x55: /* Load Byte, No WriteBack, Pre Dec, Immed */
- (void) LoadByte (state, instr, LHS - LSImmRHS, LUNSIGNED);
- break;
-
- case 0x56: /* Store Byte, WriteBack, Pre Dec, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- temp = LHS - LSImmRHS;
- if (StoreByte (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x57: /* Load Byte, WriteBack, Pre Dec, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- temp = LHS - LSImmRHS;
- if (LoadByte (state, instr, temp, LUNSIGNED))
- LSBase = temp;
- break;
-
- case 0x58: /* Store Word, No WriteBack, Pre Inc, Immed */
- (void) StoreWord (state, instr, LHS + LSImmRHS);
- break;
-
- case 0x59: /* Load Word, No WriteBack, Pre Inc, Immed */
- (void) LoadWord (state, instr, LHS + LSImmRHS);
- break;
-
- case 0x5a: /* Store Word, WriteBack, Pre Inc, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- temp = LHS + LSImmRHS;
- if (StoreWord (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x5b: /* Load Word, WriteBack, Pre Inc, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- temp = LHS + LSImmRHS;
- if (LoadWord (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x5c: /* Store Byte, No WriteBack, Pre Inc, Immed */
- (void) StoreByte (state, instr, LHS + LSImmRHS);
- break;
-
- case 0x5d: /* Load Byte, No WriteBack, Pre Inc, Immed */
- (void) LoadByte (state, instr, LHS + LSImmRHS, LUNSIGNED);
- break;
-
- case 0x5e: /* Store Byte, WriteBack, Pre Inc, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- temp = LHS + LSImmRHS;
- if (StoreByte (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x5f: /* Load Byte, WriteBack, Pre Inc, Immed */
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- temp = LHS + LSImmRHS;
- if (LoadByte (state, instr, temp, LUNSIGNED))
- LSBase = temp;
- break;
-
-/***************************************************************************\
-* Single Data Transfer Register RHS Instructions *
-\***************************************************************************/
-
- case 0x60: /* Store Word, No WriteBack, Post Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- if (StoreWord (state, instr, lhs))
- LSBase = lhs - LSRegRHS;
- break;
-
- case 0x61: /* Load Word, No WriteBack, Post Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- if (LoadWord (state, instr, lhs))
- LSBase = lhs - LSRegRHS;
- break;
-
- case 0x62: /* Store Word, WriteBack, Post Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (StoreWord (state, instr, lhs))
- LSBase = lhs - LSRegRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x63: /* Load Word, WriteBack, Post Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (LoadWord (state, instr, lhs))
- LSBase = lhs - LSRegRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x64: /* Store Byte, No WriteBack, Post Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- if (StoreByte (state, instr, lhs))
- LSBase = lhs - LSRegRHS;
- break;
-
- case 0x65: /* Load Byte, No WriteBack, Post Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- if (LoadByte (state, instr, lhs, LUNSIGNED))
- LSBase = lhs - LSRegRHS;
- break;
-
- case 0x66: /* Store Byte, WriteBack, Post Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (StoreByte (state, instr, lhs))
- LSBase = lhs - LSRegRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x67: /* Load Byte, WriteBack, Post Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (LoadByte (state, instr, lhs, LUNSIGNED))
- LSBase = lhs - LSRegRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x68: /* Store Word, No WriteBack, Post Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- if (StoreWord (state, instr, lhs))
- LSBase = lhs + LSRegRHS;
- break;
-
- case 0x69: /* Load Word, No WriteBack, Post Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- if (LoadWord (state, instr, lhs))
- LSBase = lhs + LSRegRHS;
- break;
-
- case 0x6a: /* Store Word, WriteBack, Post Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (StoreWord (state, instr, lhs))
- LSBase = lhs + LSRegRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x6b: /* Load Word, WriteBack, Post Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (LoadWord (state, instr, lhs))
- LSBase = lhs + LSRegRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x6c: /* Store Byte, No WriteBack, Post Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- if (StoreByte (state, instr, lhs))
- LSBase = lhs + LSRegRHS;
- break;
-
- case 0x6d: /* Load Byte, No WriteBack, Post Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- if (LoadByte (state, instr, lhs, LUNSIGNED))
- LSBase = lhs + LSRegRHS;
- break;
-
- case 0x6e: /* Store Byte, WriteBack, Post Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (StoreByte (state, instr, lhs))
- LSBase = lhs + LSRegRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
- case 0x6f: /* Load Byte, WriteBack, Post Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- lhs = LHS;
- state->NtransSig = LOW;
- if (LoadByte (state, instr, lhs, LUNSIGNED))
- LSBase = lhs + LSRegRHS;
- state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
- break;
-
-
- case 0x70: /* Store Word, No WriteBack, Pre Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- (void) StoreWord (state, instr, LHS - LSRegRHS);
- break;
-
- case 0x71: /* Load Word, No WriteBack, Pre Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- (void) LoadWord (state, instr, LHS - LSRegRHS);
- break;
-
- case 0x72: /* Store Word, WriteBack, Pre Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- temp = LHS - LSRegRHS;
- if (StoreWord (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x73: /* Load Word, WriteBack, Pre Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- temp = LHS - LSRegRHS;
- if (LoadWord (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x74: /* Store Byte, No WriteBack, Pre Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- (void) StoreByte (state, instr, LHS - LSRegRHS);
- break;
-
- case 0x75: /* Load Byte, No WriteBack, Pre Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- (void) LoadByte (state, instr, LHS - LSRegRHS, LUNSIGNED);
- break;
-
- case 0x76: /* Store Byte, WriteBack, Pre Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- temp = LHS - LSRegRHS;
- if (StoreByte (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x77: /* Load Byte, WriteBack, Pre Dec, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- temp = LHS - LSRegRHS;
- if (LoadByte (state, instr, temp, LUNSIGNED))
- LSBase = temp;
- break;
-
- case 0x78: /* Store Word, No WriteBack, Pre Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- (void) StoreWord (state, instr, LHS + LSRegRHS);
- break;
-
- case 0x79: /* Load Word, No WriteBack, Pre Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- (void) LoadWord (state, instr, LHS + LSRegRHS);
- break;
-
- case 0x7a: /* Store Word, WriteBack, Pre Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- temp = LHS + LSRegRHS;
- if (StoreWord (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x7b: /* Load Word, WriteBack, Pre Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- temp = LHS + LSRegRHS;
- if (LoadWord (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x7c: /* Store Byte, No WriteBack, Pre Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- (void) StoreByte (state, instr, LHS + LSRegRHS);
- break;
-
- case 0x7d: /* Load Byte, No WriteBack, Pre Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- (void) LoadByte (state, instr, LHS + LSRegRHS, LUNSIGNED);
- break;
-
- case 0x7e: /* Store Byte, WriteBack, Pre Inc, Reg */
- if (BIT (4))
- {
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- temp = LHS + LSRegRHS;
- if (StoreByte (state, instr, temp))
- LSBase = temp;
- break;
-
- case 0x7f: /* Load Byte, WriteBack, Pre Inc, Reg */
- if (BIT (4))
- {
- /* Check for the special breakpoint opcode.
- This value should correspond to the value defined
- as ARM_BE_BREAKPOINT in gdb/arm-tdep.c. */
- if (BITS (0, 19) == 0xfdefe)
- {
- if (!ARMul_OSHandleSWI (state, SWI_Breakpoint))
- ARMul_Abort (state, ARMul_SWIV);
- }
- else
- ARMul_UndefInstr (state, instr);
- break;
- }
- UNDEF_LSRBaseEQOffWb;
- UNDEF_LSRBaseEQDestWb;
- UNDEF_LSRPCBaseWb;
- UNDEF_LSRPCOffWb;
- temp = LHS + LSRegRHS;
- if (LoadByte (state, instr, temp, LUNSIGNED))
- LSBase = temp;
- break;
-
-/***************************************************************************\
-* Multiple Data Transfer Instructions *
-\***************************************************************************/
-
- case 0x80: /* Store, No WriteBack, Post Dec */
- STOREMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
- break;
-
- case 0x81: /* Load, No WriteBack, Post Dec */
- LOADMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
- break;
-
- case 0x82: /* Store, WriteBack, Post Dec */
- temp = LSBase - LSMNumRegs;
- STOREMULT (instr, temp + 4L, temp);
- break;
-
- case 0x83: /* Load, WriteBack, Post Dec */
- temp = LSBase - LSMNumRegs;
- LOADMULT (instr, temp + 4L, temp);
- break;
-
- case 0x84: /* Store, Flags, No WriteBack, Post Dec */
- STORESMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
- break;
-
- case 0x85: /* Load, Flags, No WriteBack, Post Dec */
- LOADSMULT (instr, LSBase - LSMNumRegs + 4L, 0L);
- break;
-
- case 0x86: /* Store, Flags, WriteBack, Post Dec */
- temp = LSBase - LSMNumRegs;
- STORESMULT (instr, temp + 4L, temp);
- break;
-
- case 0x87: /* Load, Flags, WriteBack, Post Dec */
- temp = LSBase - LSMNumRegs;
- LOADSMULT (instr, temp + 4L, temp);
- break;
-
-
- case 0x88: /* Store, No WriteBack, Post Inc */
- STOREMULT (instr, LSBase, 0L);
- break;
-
- case 0x89: /* Load, No WriteBack, Post Inc */
- LOADMULT (instr, LSBase, 0L);
- break;
-
- case 0x8a: /* Store, WriteBack, Post Inc */
- temp = LSBase;
- STOREMULT (instr, temp, temp + LSMNumRegs);
- break;
-
- case 0x8b: /* Load, WriteBack, Post Inc */
- temp = LSBase;
- LOADMULT (instr, temp, temp + LSMNumRegs);
- break;
-
- case 0x8c: /* Store, Flags, No WriteBack, Post Inc */
- STORESMULT (instr, LSBase, 0L);
- break;
-
- case 0x8d: /* Load, Flags, No WriteBack, Post Inc */
- LOADSMULT (instr, LSBase, 0L);
- break;
-
- case 0x8e: /* Store, Flags, WriteBack, Post Inc */
- temp = LSBase;
- STORESMULT (instr, temp, temp + LSMNumRegs);
- break;
-
- case 0x8f: /* Load, Flags, WriteBack, Post Inc */
- temp = LSBase;
- LOADSMULT (instr, temp, temp + LSMNumRegs);
- break;
-
-
- case 0x90: /* Store, No WriteBack, Pre Dec */
- STOREMULT (instr, LSBase - LSMNumRegs, 0L);
- break;
-
- case 0x91: /* Load, No WriteBack, Pre Dec */
- LOADMULT (instr, LSBase - LSMNumRegs, 0L);
- break;
-
- case 0x92: /* Store, WriteBack, Pre Dec */
- temp = LSBase - LSMNumRegs;
- STOREMULT (instr, temp, temp);
- break;
-
- case 0x93: /* Load, WriteBack, Pre Dec */
- temp = LSBase - LSMNumRegs;
- LOADMULT (instr, temp, temp);
- break;
-
- case 0x94: /* Store, Flags, No WriteBack, Pre Dec */
- STORESMULT (instr, LSBase - LSMNumRegs, 0L);
- break;
-
- case 0x95: /* Load, Flags, No WriteBack, Pre Dec */
- LOADSMULT (instr, LSBase - LSMNumRegs, 0L);
- break;
-
- case 0x96: /* Store, Flags, WriteBack, Pre Dec */
- temp = LSBase - LSMNumRegs;
- STORESMULT (instr, temp, temp);
- break;
-
- case 0x97: /* Load, Flags, WriteBack, Pre Dec */
- temp = LSBase - LSMNumRegs;
- LOADSMULT (instr, temp, temp);
- break;
-
-
- case 0x98: /* Store, No WriteBack, Pre Inc */
- STOREMULT (instr, LSBase + 4L, 0L);
- break;
-
- case 0x99: /* Load, No WriteBack, Pre Inc */
- LOADMULT (instr, LSBase + 4L, 0L);
- break;
-
- case 0x9a: /* Store, WriteBack, Pre Inc */
- temp = LSBase;
- STOREMULT (instr, temp + 4L, temp + LSMNumRegs);
- break;
-
- case 0x9b: /* Load, WriteBack, Pre Inc */
- temp = LSBase;
- LOADMULT (instr, temp + 4L, temp + LSMNumRegs);
- break;
-
- case 0x9c: /* Store, Flags, No WriteBack, Pre Inc */
- STORESMULT (instr, LSBase + 4L, 0L);
- break;
-
- case 0x9d: /* Load, Flags, No WriteBack, Pre Inc */
- LOADSMULT (instr, LSBase + 4L, 0L);
- break;
-
- case 0x9e: /* Store, Flags, WriteBack, Pre Inc */
- temp = LSBase;
- STORESMULT (instr, temp + 4L, temp + LSMNumRegs);
- break;
-
- case 0x9f: /* Load, Flags, WriteBack, Pre Inc */
- temp = LSBase;
- LOADSMULT (instr, temp + 4L, temp + LSMNumRegs);
- break;
-
-/***************************************************************************\
-* Branch forward *
-\***************************************************************************/
-
- case 0xa0:
- case 0xa1:
- case 0xa2:
- case 0xa3:
- case 0xa4:
- case 0xa5:
- case 0xa6:
- case 0xa7:
- state->Reg[15] = pc + 8 + POSBRANCH;
- FLUSHPIPE;
- break;
-
-/***************************************************************************\
-* Branch backward *
-\***************************************************************************/
-
- case 0xa8:
- case 0xa9:
- case 0xaa:
- case 0xab:
- case 0xac:
- case 0xad:
- case 0xae:
- case 0xaf:
- state->Reg[15] = pc + 8 + NEGBRANCH;
- FLUSHPIPE;
- break;
-
-/***************************************************************************\
-* Branch and Link forward *
-\***************************************************************************/
-
- case 0xb0:
- case 0xb1:
- case 0xb2:
- case 0xb3:
- case 0xb4:
- case 0xb5:
- case 0xb6:
- case 0xb7:
-#ifdef MODE32
- state->Reg[14] = pc + 4; /* put PC into Link */
-#else
- state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE; /* put PC into Link */
-#endif
- state->Reg[15] = pc + 8 + POSBRANCH;
- FLUSHPIPE;
- break;
-
-/***************************************************************************\
-* Branch and Link backward *
-\***************************************************************************/
-
- case 0xb8:
- case 0xb9:
- case 0xba:
- case 0xbb:
- case 0xbc:
- case 0xbd:
- case 0xbe:
- case 0xbf:
-#ifdef MODE32
- state->Reg[14] = pc + 4; /* put PC into Link */
-#else
- state->Reg[14] = (pc + 4) | ECC | ER15INT | EMODE; /* put PC into Link */
-#endif
- state->Reg[15] = pc + 8 + NEGBRANCH;
- FLUSHPIPE;
- break;
-
-/***************************************************************************\
-* Co-Processor Data Transfers *
-\***************************************************************************/
-
- case 0xc4:
- case 0xc0: /* Store , No WriteBack , Post Dec */
- ARMul_STC (state, instr, LHS);
- break;
-
- case 0xc5:
- case 0xc1: /* Load , No WriteBack , Post Dec */
- ARMul_LDC (state, instr, LHS);
- break;
-
- case 0xc2:
- case 0xc6: /* Store , WriteBack , Post Dec */
- lhs = LHS;
- state->Base = lhs - LSCOff;
- ARMul_STC (state, instr, lhs);
- break;
-
- case 0xc3:
- case 0xc7: /* Load , WriteBack , Post Dec */
- lhs = LHS;
- state->Base = lhs - LSCOff;
- ARMul_LDC (state, instr, lhs);
- break;
-
- case 0xc8:
- case 0xcc: /* Store , No WriteBack , Post Inc */
- ARMul_STC (state, instr, LHS);
- break;
-
- case 0xc9:
- case 0xcd: /* Load , No WriteBack , Post Inc */
- ARMul_LDC (state, instr, LHS);
- break;
-
- case 0xca:
- case 0xce: /* Store , WriteBack , Post Inc */
- lhs = LHS;
- state->Base = lhs + LSCOff;
- ARMul_STC (state, instr, LHS);
- break;
-
- case 0xcb:
- case 0xcf: /* Load , WriteBack , Post Inc */
- lhs = LHS;
- state->Base = lhs + LSCOff;
- ARMul_LDC (state, instr, LHS);
- break;
-
-
- case 0xd0:
- case 0xd4: /* Store , No WriteBack , Pre Dec */
- ARMul_STC (state, instr, LHS - LSCOff);
- break;
-
- case 0xd1:
- case 0xd5: /* Load , No WriteBack , Pre Dec */
- ARMul_LDC (state, instr, LHS - LSCOff);
- break;
-
- case 0xd2:
- case 0xd6: /* Store , WriteBack , Pre Dec */
- lhs = LHS - LSCOff;
- state->Base = lhs;
- ARMul_STC (state, instr, lhs);
- break;
-
- case 0xd3:
- case 0xd7: /* Load , WriteBack , Pre Dec */
- lhs = LHS - LSCOff;
- state->Base = lhs;
- ARMul_LDC (state, instr, lhs);
- break;
-
- case 0xd8:
- case 0xdc: /* Store , No WriteBack , Pre Inc */
- ARMul_STC (state, instr, LHS + LSCOff);
- break;
-
- case 0xd9:
- case 0xdd: /* Load , No WriteBack , Pre Inc */
- ARMul_LDC (state, instr, LHS + LSCOff);
- break;
-
- case 0xda:
- case 0xde: /* Store , WriteBack , Pre Inc */
- lhs = LHS + LSCOff;
- state->Base = lhs;
- ARMul_STC (state, instr, lhs);
- break;
-
- case 0xdb:
- case 0xdf: /* Load , WriteBack , Pre Inc */
- lhs = LHS + LSCOff;
- state->Base = lhs;
- ARMul_LDC (state, instr, lhs);
- break;
-
-/***************************************************************************\
-* Co-Processor Register Transfers (MCR) and Data Ops *
-\***************************************************************************/
-
- case 0xe2:
- case 0xe0:
- case 0xe4:
- case 0xe6:
- case 0xe8:
- case 0xea:
- case 0xec:
- case 0xee:
- if (BIT (4))
- { /* MCR */
- if (DESTReg == 15)
- {
- UNDEF_MCRPC;
-#ifdef MODE32
- ARMul_MCR (state, instr, state->Reg[15] + isize);
-#else
- ARMul_MCR (state, instr, ECC | ER15INT | EMODE |
- ((state->Reg[15] + isize) & R15PCBITS));
-#endif
- }
- else
- ARMul_MCR (state, instr, DEST);
- }
- else /* CDP Part 1 */
- ARMul_CDP (state, instr);
- break;
-
-/***************************************************************************\
-* Co-Processor Register Transfers (MRC) and Data Ops *
-\***************************************************************************/
-
- case 0xe1:
- case 0xe3:
- case 0xe5:
- case 0xe7:
- case 0xe9:
- case 0xeb:
- case 0xed:
- case 0xef:
- if (BIT (4))
- { /* MRC */
- temp = ARMul_MRC (state, instr);
- if (DESTReg == 15)
- {
- ASSIGNN ((temp & NBIT) != 0);
- ASSIGNZ ((temp & ZBIT) != 0);
- ASSIGNC ((temp & CBIT) != 0);
- ASSIGNV ((temp & VBIT) != 0);
- }
- else
- DEST = temp;
- }
- else /* CDP Part 2 */
- ARMul_CDP (state, instr);
- break;
-
-/***************************************************************************\
-* SWI instruction *
-\***************************************************************************/
-
- case 0xf0:
- case 0xf1:
- case 0xf2:
- case 0xf3:
- case 0xf4:
- case 0xf5:
- case 0xf6:
- case 0xf7:
- case 0xf8:
- case 0xf9:
- case 0xfa:
- case 0xfb:
- case 0xfc:
- case 0xfd:
- case 0xfe:
- case 0xff:
- if (instr == ARMul_ABORTWORD && state->AbortAddr == pc)
- { /* a prefetch abort */
- ARMul_Abort (state, ARMul_PrefetchAbortV);
- break;
- }
-
- if (!ARMul_OSHandleSWI (state, BITS (0, 23)))
- {
- ARMul_Abort (state, ARMul_SWIV);
- }
- break;
- } /* 256 way main switch */
- } /* if temp */
-
-#ifdef MODET
- donext:
-#endif
-
-#ifdef NEED_UI_LOOP_HOOK
- if (ui_loop_hook != NULL && ui_loop_hook_counter-- < 0)
- {
- ui_loop_hook_counter = UI_LOOP_POLL_INTERVAL;
- ui_loop_hook (0);
- }
-#endif /* NEED_UI_LOOP_HOOK */
-
- if (state->Emulate == ONCE)
- state->Emulate = STOP;
- else if (state->Emulate != RUN)
- break;
- }
- while (!stop_simulator); /* do loop */
-
- state->decoded = decoded;
- state->loaded = loaded;
- state->pc = pc;
- return (pc);
-} /* Emulate 26/32 in instruction based mode */
-
-
-/***************************************************************************\
-* This routine evaluates most Data Processing register RHS's with the S *
-* bit clear. It is intended to be called from the macro DPRegRHS, which *
-* filters the common case of an unshifted register with in line code *
-\***************************************************************************/
-
-static ARMword
-GetDPRegRHS (ARMul_State * state, ARMword instr)
-{
- ARMword shamt, base;
-
- base = RHSReg;
- if (BIT (4))
- { /* shift amount in a register */
- UNDEF_Shift;
- INCPC;
-#ifndef MODE32
- if (base == 15)
- base = ECC | ER15INT | R15PC | EMODE;
- else
-#endif
- base = state->Reg[base];
- ARMul_Icycles (state, 1, 0L);
- shamt = state->Reg[BITS (8, 11)] & 0xff;
- switch ((int) BITS (5, 6))
- {
- case LSL:
- if (shamt == 0)
- return (base);
- else if (shamt >= 32)
- return (0);
- else
- return (base << shamt);
- case LSR:
- if (shamt == 0)
- return (base);
- else if (shamt >= 32)
- return (0);
- else
- return (base >> shamt);
- case ASR:
- if (shamt == 0)
- return (base);
- else if (shamt >= 32)
- return ((ARMword) ((long int) base >> 31L));
- else
- return ((ARMword) ((long int) base >> (int) shamt));
- case ROR:
- shamt &= 0x1f;
- if (shamt == 0)
- return (base);
- else
- return ((base << (32 - shamt)) | (base >> shamt));
- }
- }
- else
- { /* shift amount is a constant */
-#ifndef MODE32
- if (base == 15)
- base = ECC | ER15INT | R15PC | EMODE;
- else
-#endif
- base = state->Reg[base];
- shamt = BITS (7, 11);
- switch ((int) BITS (5, 6))
- {
- case LSL:
- return (base << shamt);
- case LSR:
- if (shamt == 0)
- return (0);
- else
- return (base >> shamt);
- case ASR:
- if (shamt == 0)
- return ((ARMword) ((long int) base >> 31L));
- else
- return ((ARMword) ((long int) base >> (int) shamt));
- case ROR:
- if (shamt == 0) /* its an RRX */
- return ((base >> 1) | (CFLAG << 31));
- else
- return ((base << (32 - shamt)) | (base >> shamt));
- }
- }
- return (0); /* just to shut up lint */
-}
-
-/***************************************************************************\
-* This routine evaluates most Logical Data Processing register RHS's *
-* with the S bit set. It is intended to be called from the macro *
-* DPSRegRHS, which filters the common case of an unshifted register *
-* with in line code *
-\***************************************************************************/
-
-static ARMword
-GetDPSRegRHS (ARMul_State * state, ARMword instr)
-{
- ARMword shamt, base;
-
- base = RHSReg;
- if (BIT (4))
- { /* shift amount in a register */
- UNDEF_Shift;
- INCPC;
-#ifndef MODE32
- if (base == 15)
- base = ECC | ER15INT | R15PC | EMODE;
- else
-#endif
- base = state->Reg[base];
- ARMul_Icycles (state, 1, 0L);
- shamt = state->Reg[BITS (8, 11)] & 0xff;
- switch ((int) BITS (5, 6))
- {
- case LSL:
- if (shamt == 0)
- return (base);
- else if (shamt == 32)
- {
- ASSIGNC (base & 1);
- return (0);
- }
- else if (shamt > 32)
- {
- CLEARC;
- return (0);
- }
- else
- {
- ASSIGNC ((base >> (32 - shamt)) & 1);
- return (base << shamt);
- }
- case LSR:
- if (shamt == 0)
- return (base);
- else if (shamt == 32)
- {
- ASSIGNC (base >> 31);
- return (0);
- }
- else if (shamt > 32)
- {
- CLEARC;
- return (0);
- }
- else
- {
- ASSIGNC ((base >> (shamt - 1)) & 1);
- return (base >> shamt);
- }
- case ASR:
- if (shamt == 0)
- return (base);
- else if (shamt >= 32)
- {
- ASSIGNC (base >> 31L);
- return ((ARMword) ((long int) base >> 31L));
- }
- else
- {
- ASSIGNC ((ARMword) ((long int) base >> (int) (shamt - 1)) & 1);
- return ((ARMword) ((long int) base >> (int) shamt));
- }
- case ROR:
- if (shamt == 0)
- return (base);
- shamt &= 0x1f;
- if (shamt == 0)
- {
- ASSIGNC (base >> 31);
- return (base);
- }
- else
- {
- ASSIGNC ((base >> (shamt - 1)) & 1);
- return ((base << (32 - shamt)) | (base >> shamt));
- }
- }
- }
- else
- { /* shift amount is a constant */
-#ifndef MODE32
- if (base == 15)
- base = ECC | ER15INT | R15PC | EMODE;
- else
-#endif
- base = state->Reg[base];
- shamt = BITS (7, 11);
- switch ((int) BITS (5, 6))
- {
- case LSL:
- ASSIGNC ((base >> (32 - shamt)) & 1);
- return (base << shamt);
- case LSR:
- if (shamt == 0)
- {
- ASSIGNC (base >> 31);
- return (0);
- }
- else
- {
- ASSIGNC ((base >> (shamt - 1)) & 1);
- return (base >> shamt);
- }
- case ASR:
- if (shamt == 0)
- {
- ASSIGNC (base >> 31L);
- return ((ARMword) ((long int) base >> 31L));
- }
- else
- {
- ASSIGNC ((ARMword) ((long int) base >> (int) (shamt - 1)) & 1);
- return ((ARMword) ((long int) base >> (int) shamt));
- }
- case ROR:
- if (shamt == 0)
- { /* its an RRX */
- shamt = CFLAG;
- ASSIGNC (base & 1);
- return ((base >> 1) | (shamt << 31));
- }
- else
- {
- ASSIGNC ((base >> (shamt - 1)) & 1);
- return ((base << (32 - shamt)) | (base >> shamt));
- }
- }
- }
- return (0); /* just to shut up lint */
-}
-
-/***************************************************************************\
-* This routine handles writes to register 15 when the S bit is not set. *
-\***************************************************************************/
-
-static void
-WriteR15 (ARMul_State * state, ARMword src)
-{
- /* The ARM documentation implies (but doe snot state) that the bottom bit of the PC is never set */
-#ifdef MODE32
- state->Reg[15] = src & PCBITS & ~0x1;
-#else
- state->Reg[15] = (src & R15PCBITS & ~0x1) | ECC | ER15INT | EMODE;
- ARMul_R15Altered (state);
-#endif
- FLUSHPIPE;
-}
-
-/***************************************************************************\
-* This routine handles writes to register 15 when the S bit is set. *
-\***************************************************************************/
-
-static void
-WriteSR15 (ARMul_State * state, ARMword src)
-{
-#ifdef MODE32
- state->Reg[15] = src & PCBITS;
- if (state->Bank > 0)
- {
- state->Cpsr = state->Spsr[state->Bank];
- ARMul_CPSRAltered (state);
- }
-#else
- if (state->Bank == USERBANK)
- state->Reg[15] = (src & (CCBITS | R15PCBITS)) | ER15INT | EMODE;
- else
- state->Reg[15] = src;
- ARMul_R15Altered (state);
-#endif
- FLUSHPIPE;
-}
-
-/***************************************************************************\
-* This routine evaluates most Load and Store register RHS's. It is *
-* intended to be called from the macro LSRegRHS, which filters the *
-* common case of an unshifted register with in line code *
-\***************************************************************************/
-
-static ARMword
-GetLSRegRHS (ARMul_State * state, ARMword instr)
-{
- ARMword shamt, base;
-
- base = RHSReg;
-#ifndef MODE32
- if (base == 15)
- base = ECC | ER15INT | R15PC | EMODE; /* Now forbidden, but .... */
- else
-#endif
- base = state->Reg[base];
-
- shamt = BITS (7, 11);
- switch ((int) BITS (5, 6))
- {
- case LSL:
- return (base << shamt);
- case LSR:
- if (shamt == 0)
- return (0);
- else
- return (base >> shamt);
- case ASR:
- if (shamt == 0)
- return ((ARMword) ((long int) base >> 31L));
- else
- return ((ARMword) ((long int) base >> (int) shamt));
- case ROR:
- if (shamt == 0) /* its an RRX */
- return ((base >> 1) | (CFLAG << 31));
- else
- return ((base << (32 - shamt)) | (base >> shamt));
- }
- return (0); /* just to shut up lint */
-}
-
-/***************************************************************************\
-* This routine evaluates the ARM7T halfword and signed transfer RHS's. *
-\***************************************************************************/
-
-static ARMword
-GetLS7RHS (ARMul_State * state, ARMword instr)
-{
- if (BIT (22) == 0)
- { /* register */
-#ifndef MODE32
- if (RHSReg == 15)
- return ECC | ER15INT | R15PC | EMODE; /* Now forbidden, but ... */
-#endif
- return state->Reg[RHSReg];
- }
-
- /* else immediate */
- return BITS (0, 3) | (BITS (8, 11) << 4);
-}
-
-/***************************************************************************\
-* This function does the work of loading a word for a LDR instruction. *
-\***************************************************************************/
-
-static unsigned
-LoadWord (ARMul_State * state, ARMword instr, ARMword address)
-{
- ARMword dest;
-
- BUSUSEDINCPCS;
-#ifndef MODE32
- if (ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- }
-#endif
- dest = ARMul_LoadWordN (state, address);
- if (state->Aborted)
- {
- TAKEABORT;
- return (state->lateabtSig);
- }
- if (address & 3)
- dest = ARMul_Align (state, address, dest);
- WRITEDEST (dest);
- ARMul_Icycles (state, 1, 0L);
-
- return (DESTReg != LHSReg);
-}
-
-#ifdef MODET
-/***************************************************************************\
-* This function does the work of loading a halfword. *
-\***************************************************************************/
-
-static unsigned
-LoadHalfWord (ARMul_State * state, ARMword instr, ARMword address,
- int signextend)
-{
- ARMword dest;
-
- BUSUSEDINCPCS;
-#ifndef MODE32
- if (ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- }
-#endif
- dest = ARMul_LoadHalfWord (state, address);
- if (state->Aborted)
- {
- TAKEABORT;
- return (state->lateabtSig);
- }
- UNDEF_LSRBPC;
- if (signextend)
- {
- if (dest & 1 << (16 - 1))
- dest = (dest & ((1 << 16) - 1)) - (1 << 16);
- }
- WRITEDEST (dest);
- ARMul_Icycles (state, 1, 0L);
- return (DESTReg != LHSReg);
-}
-
-#endif /* MODET */
-
-/***************************************************************************\
-* This function does the work of loading a byte for a LDRB instruction. *
-\***************************************************************************/
-
-static unsigned
-LoadByte (ARMul_State * state, ARMword instr, ARMword address, int signextend)
-{
- ARMword dest;
-
- BUSUSEDINCPCS;
-#ifndef MODE32
- if (ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- }
-#endif
- dest = ARMul_LoadByte (state, address);
- if (state->Aborted)
- {
- TAKEABORT;
- return (state->lateabtSig);
- }
- UNDEF_LSRBPC;
- if (signextend)
- {
- if (dest & 1 << (8 - 1))
- dest = (dest & ((1 << 8) - 1)) - (1 << 8);
- }
- WRITEDEST (dest);
- ARMul_Icycles (state, 1, 0L);
- return (DESTReg != LHSReg);
-}
-
-/***************************************************************************\
-* This function does the work of storing a word from a STR instruction. *
-\***************************************************************************/
-
-static unsigned
-StoreWord (ARMul_State * state, ARMword instr, ARMword address)
-{
- BUSUSEDINCPCN;
-#ifndef MODE32
- if (DESTReg == 15)
- state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
-#endif
-#ifdef MODE32
- ARMul_StoreWordN (state, address, DEST);
-#else
- if (VECTORACCESS (address) || ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- (void) ARMul_LoadWordN (state, address);
- }
- else
- ARMul_StoreWordN (state, address, DEST);
-#endif
- if (state->Aborted)
- {
- TAKEABORT;
- return (state->lateabtSig);
- }
- return (TRUE);
-}
-
-#ifdef MODET
-/***************************************************************************\
-* This function does the work of storing a byte for a STRH instruction. *
-\***************************************************************************/
-
-static unsigned
-StoreHalfWord (ARMul_State * state, ARMword instr, ARMword address)
-{
- BUSUSEDINCPCN;
-
-#ifndef MODE32
- if (DESTReg == 15)
- state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
-#endif
-
-#ifdef MODE32
- ARMul_StoreHalfWord (state, address, DEST);
-#else
- if (VECTORACCESS (address) || ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- (void) ARMul_LoadHalfWord (state, address);
- }
- else
- ARMul_StoreHalfWord (state, address, DEST);
-#endif
-
- if (state->Aborted)
- {
- TAKEABORT;
- return (state->lateabtSig);
- }
-
- return (TRUE);
-}
-
-#endif /* MODET */
-
-/***************************************************************************\
-* This function does the work of storing a byte for a STRB instruction. *
-\***************************************************************************/
-
-static unsigned
-StoreByte (ARMul_State * state, ARMword instr, ARMword address)
-{
- BUSUSEDINCPCN;
-#ifndef MODE32
- if (DESTReg == 15)
- state->Reg[15] = ECC | ER15INT | R15PC | EMODE;
-#endif
-#ifdef MODE32
- ARMul_StoreByte (state, address, DEST);
-#else
- if (VECTORACCESS (address) || ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- (void) ARMul_LoadByte (state, address);
- }
- else
- ARMul_StoreByte (state, address, DEST);
-#endif
- if (state->Aborted)
- {
- TAKEABORT;
- return (state->lateabtSig);
- }
- UNDEF_LSRBPC;
- return (TRUE);
-}
-
-/***************************************************************************\
-* This function does the work of loading the registers listed in an LDM *
-* instruction, when the S bit is clear. The code here is always increment *
-* after, it's up to the caller to get the input address correct and to *
-* handle base register modification. *
-\***************************************************************************/
-
-static void
-LoadMult (ARMul_State * state, ARMword instr, ARMword address, ARMword WBBase)
-{
- ARMword dest, temp;
-
- UNDEF_LSMNoRegs;
- UNDEF_LSMPCBase;
- UNDEF_LSMBaseInListWb;
- BUSUSEDINCPCS;
-#ifndef MODE32
- if (ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- }
-#endif
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
-
- for (temp = 0; !BIT (temp); temp++); /* N cycle first */
- dest = ARMul_LoadWordN (state, address);
- if (!state->abortSig && !state->Aborted)
- state->Reg[temp++] = dest;
- else if (!state->Aborted)
- state->Aborted = ARMul_DataAbortV;
-
- for (; temp < 16; temp++) /* S cycles from here on */
- if (BIT (temp))
- { /* load this register */
- address += 4;
- dest = ARMul_LoadWordS (state, address);
- if (!state->abortSig && !state->Aborted)
- state->Reg[temp] = dest;
- else if (!state->Aborted)
- state->Aborted = ARMul_DataAbortV;
- }
-
- if (BIT (15))
- { /* PC is in the reg list */
-#ifdef MODE32
- state->Reg[15] = PC;
-#endif
- FLUSHPIPE;
- }
-
- ARMul_Icycles (state, 1, 0L); /* to write back the final register */
-
- if (state->Aborted)
- {
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
- TAKEABORT;
- }
-}
-
-/***************************************************************************\
-* This function does the work of loading the registers listed in an LDM *
-* instruction, when the S bit is set. The code here is always increment *
-* after, it's up to the caller to get the input address correct and to *
-* handle base register modification. *
-\***************************************************************************/
-
-static void
-LoadSMult (ARMul_State * state, ARMword instr,
- ARMword address, ARMword WBBase)
-{
- ARMword dest, temp;
-
- UNDEF_LSMNoRegs;
- UNDEF_LSMPCBase;
- UNDEF_LSMBaseInListWb;
- BUSUSEDINCPCS;
-#ifndef MODE32
- if (ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- }
-#endif
-
- if (!BIT (15) && state->Bank != USERBANK)
- {
- (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); /* temporary reg bank switch */
- UNDEF_LSMUserBankWb;
- }
-
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
-
- for (temp = 0; !BIT (temp); temp++); /* N cycle first */
- dest = ARMul_LoadWordN (state, address);
- if (!state->abortSig)
- state->Reg[temp++] = dest;
- else if (!state->Aborted)
- state->Aborted = ARMul_DataAbortV;
-
- for (; temp < 16; temp++) /* S cycles from here on */
- if (BIT (temp))
- { /* load this register */
- address += 4;
- dest = ARMul_LoadWordS (state, address);
- if (!state->abortSig || state->Aborted)
- state->Reg[temp] = dest;
- else if (!state->Aborted)
- state->Aborted = ARMul_DataAbortV;
- }
-
- if (BIT (15))
- { /* PC is in the reg list */
-#ifdef MODE32
- if (state->Mode != USER26MODE && state->Mode != USER32MODE)
- {
- state->Cpsr = GETSPSR (state->Bank);
- ARMul_CPSRAltered (state);
- }
- state->Reg[15] = PC;
-#else
- if (state->Mode == USER26MODE || state->Mode == USER32MODE)
- { /* protect bits in user mode */
- ASSIGNN ((state->Reg[15] & NBIT) != 0);
- ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
- ASSIGNC ((state->Reg[15] & CBIT) != 0);
- ASSIGNV ((state->Reg[15] & VBIT) != 0);
- }
- else
- ARMul_R15Altered (state);
-#endif
- FLUSHPIPE;
- }
-
- if (!BIT (15) && state->Mode != USER26MODE && state->Mode != USER32MODE)
- (void) ARMul_SwitchMode (state, USER26MODE, state->Mode); /* restore the correct bank */
-
- ARMul_Icycles (state, 1, 0L); /* to write back the final register */
-
- if (state->Aborted)
- {
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
- TAKEABORT;
- }
-
-}
-
-/***************************************************************************\
-* This function does the work of storing the registers listed in an STM *
-* instruction, when the S bit is clear. The code here is always increment *
-* after, it's up to the caller to get the input address correct and to *
-* handle base register modification. *
-\***************************************************************************/
-
-static void
-StoreMult (ARMul_State * state, ARMword instr,
- ARMword address, ARMword WBBase)
-{
- ARMword temp;
-
- UNDEF_LSMNoRegs;
- UNDEF_LSMPCBase;
- UNDEF_LSMBaseInListWb;
- if (!TFLAG)
- {
- BUSUSEDINCPCN; /* N-cycle, increment the PC and update the NextInstr state */
- }
-
-#ifndef MODE32
- if (VECTORACCESS (address) || ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- }
- if (BIT (15))
- PATCHR15;
-#endif
-
- for (temp = 0; !BIT (temp); temp++); /* N cycle first */
-#ifdef MODE32
- ARMul_StoreWordN (state, address, state->Reg[temp++]);
-#else
- if (state->Aborted)
- {
- (void) ARMul_LoadWordN (state, address);
- for (; temp < 16; temp++) /* Fake the Stores as Loads */
- if (BIT (temp))
- { /* save this register */
- address += 4;
- (void) ARMul_LoadWordS (state, address);
- }
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
- TAKEABORT;
- return;
- }
- else
- ARMul_StoreWordN (state, address, state->Reg[temp++]);
-#endif
- if (state->abortSig && !state->Aborted)
- state->Aborted = ARMul_DataAbortV;
-
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
-
- for (; temp < 16; temp++) /* S cycles from here on */
- if (BIT (temp))
- { /* save this register */
- address += 4;
- ARMul_StoreWordS (state, address, state->Reg[temp]);
- if (state->abortSig && !state->Aborted)
- state->Aborted = ARMul_DataAbortV;
- }
- if (state->Aborted)
- {
- TAKEABORT;
- }
-}
-
-/***************************************************************************\
-* This function does the work of storing the registers listed in an STM *
-* instruction when the S bit is set. The code here is always increment *
-* after, it's up to the caller to get the input address correct and to *
-* handle base register modification. *
-\***************************************************************************/
-
-static void
-StoreSMult (ARMul_State * state, ARMword instr,
- ARMword address, ARMword WBBase)
-{
- ARMword temp;
-
- UNDEF_LSMNoRegs;
- UNDEF_LSMPCBase;
- UNDEF_LSMBaseInListWb;
- BUSUSEDINCPCN;
-#ifndef MODE32
- if (VECTORACCESS (address) || ADDREXCEPT (address))
- {
- INTERNALABORT (address);
- }
- if (BIT (15))
- PATCHR15;
-#endif
-
- if (state->Bank != USERBANK)
- {
- (void) ARMul_SwitchMode (state, state->Mode, USER26MODE); /* Force User Bank */
- UNDEF_LSMUserBankWb;
- }
-
- for (temp = 0; !BIT (temp); temp++); /* N cycle first */
-#ifdef MODE32
- ARMul_StoreWordN (state, address, state->Reg[temp++]);
-#else
- if (state->Aborted)
- {
- (void) ARMul_LoadWordN (state, address);
- for (; temp < 16; temp++) /* Fake the Stores as Loads */
- if (BIT (temp))
- { /* save this register */
- address += 4;
- (void) ARMul_LoadWordS (state, address);
- }
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
- TAKEABORT;
- return;
- }
- else
- ARMul_StoreWordN (state, address, state->Reg[temp++]);
-#endif
- if (state->abortSig && !state->Aborted)
- state->Aborted = ARMul_DataAbortV;
-
- if (BIT (21) && LHSReg != 15)
- LSBase = WBBase;
-
- for (; temp < 16; temp++) /* S cycles from here on */
- if (BIT (temp))
- { /* save this register */
- address += 4;
- ARMul_StoreWordS (state, address, state->Reg[temp]);
- if (state->abortSig && !state->Aborted)
- state->Aborted = ARMul_DataAbortV;
- }
-
- if (state->Mode != USER26MODE && state->Mode != USER32MODE)
- (void) ARMul_SwitchMode (state, USER26MODE, state->Mode); /* restore the correct bank */
-
- if (state->Aborted)
- {
- TAKEABORT;
- }
-}
-
-/***************************************************************************\
-* This function does the work of adding two 32bit values together, and *
-* calculating if a carry has occurred. *
-\***************************************************************************/
-
-static ARMword
-Add32 (ARMword a1, ARMword a2, int *carry)
-{
- ARMword result = (a1 + a2);
- unsigned int uresult = (unsigned int) result;
- unsigned int ua1 = (unsigned int) a1;
-
- /* If (result == RdLo) and (state->Reg[nRdLo] == 0),
- or (result > RdLo) then we have no carry: */
- if ((uresult == ua1) ? (a2 != 0) : (uresult < ua1))
- *carry = 1;
- else
- *carry = 0;
-
- return (result);
-}
-
-/***************************************************************************\
-* This function does the work of multiplying two 32bit values to give a *
-* 64bit result. *
-\***************************************************************************/
-
-static unsigned
-Multiply64 (ARMul_State * state, ARMword instr, int msigned, int scc)
-{
- int nRdHi, nRdLo, nRs, nRm; /* operand register numbers */
- ARMword RdHi = 0, RdLo = 0, Rm;
- int scount; /* cycle count */
-
- nRdHi = BITS (16, 19);
- nRdLo = BITS (12, 15);
- nRs = BITS (8, 11);
- nRm = BITS (0, 3);
-
- /* Needed to calculate the cycle count: */
- Rm = state->Reg[nRm];
-
- /* Check for illegal operand combinations first: */
- if (nRdHi != 15
- && nRdLo != 15
- && nRs != 15
- && nRm != 15 && nRdHi != nRdLo && nRdHi != nRm && nRdLo != nRm)
- {
- ARMword lo, mid1, mid2, hi; /* intermediate results */
- int carry;
- ARMword Rs = state->Reg[nRs];
- int sign = 0;
-
- if (msigned)
- {
- /* Compute sign of result and adjust operands if necessary. */
-
- sign = (Rm ^ Rs) & 0x80000000;
-
- if (((signed long) Rm) < 0)
- Rm = -Rm;
-
- if (((signed long) Rs) < 0)
- Rs = -Rs;
- }
-
- /* We can split the 32x32 into four 16x16 operations. This ensures
- that we do not lose precision on 32bit only hosts: */
- lo = ((Rs & 0xFFFF) * (Rm & 0xFFFF));
- mid1 = ((Rs & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
- mid2 = (((Rs >> 16) & 0xFFFF) * (Rm & 0xFFFF));
- hi = (((Rs >> 16) & 0xFFFF) * ((Rm >> 16) & 0xFFFF));
-
- /* We now need to add all of these results together, taking care
- to propogate the carries from the additions: */
- RdLo = Add32 (lo, (mid1 << 16), &carry);
- RdHi = carry;
- RdLo = Add32 (RdLo, (mid2 << 16), &carry);
- RdHi +=
- (carry + ((mid1 >> 16) & 0xFFFF) + ((mid2 >> 16) & 0xFFFF) + hi);
-
- if (sign)
- {
- /* Negate result if necessary. */
-
- RdLo = ~RdLo;
- RdHi = ~RdHi;
- if (RdLo == 0xFFFFFFFF)
- {
- RdLo = 0;
- RdHi += 1;
- }
- else
- RdLo += 1;
- }
-
- state->Reg[nRdLo] = RdLo;
- state->Reg[nRdHi] = RdHi;
- } /* else undefined result */
- else
- fprintf (stderr, "MULTIPLY64 - INVALID ARGUMENTS\n");
-
- if (scc)
- {
- if ((RdHi == 0) && (RdLo == 0))
- ARMul_NegZero (state, RdHi); /* zero value */
- else
- ARMul_NegZero (state, scc); /* non-zero value */
- }
-
- /* The cycle count depends on whether the instruction is a signed or
- unsigned multiply, and what bits are clear in the multiplier: */
- if (msigned && (Rm & ((unsigned) 1 << 31)))
- Rm = ~Rm; /* invert the bits to make the check against zero */
-
- if ((Rm & 0xFFFFFF00) == 0)
- scount = 1;
- else if ((Rm & 0xFFFF0000) == 0)
- scount = 2;
- else if ((Rm & 0xFF000000) == 0)
- scount = 3;
- else
- scount = 4;
-
- return 2 + scount;
-}
-
-/***************************************************************************\
-* This function does the work of multiplying two 32bit values and adding *
-* a 64bit value to give a 64bit result. *
-\***************************************************************************/
-
-static unsigned
-MultiplyAdd64 (ARMul_State * state, ARMword instr, int msigned, int scc)
-{
- unsigned scount;
- ARMword RdLo, RdHi;
- int nRdHi, nRdLo;
- int carry = 0;
-
- nRdHi = BITS (16, 19);
- nRdLo = BITS (12, 15);
-
- RdHi = state->Reg[nRdHi];
- RdLo = state->Reg[nRdLo];
-
- scount = Multiply64 (state, instr, msigned, LDEFAULT);
-
- RdLo = Add32 (RdLo, state->Reg[nRdLo], &carry);
- RdHi = (RdHi + state->Reg[nRdHi]) + carry;
-
- state->Reg[nRdLo] = RdLo;
- state->Reg[nRdHi] = RdHi;
-
- if (scc)
- {
- if ((RdHi == 0) && (RdLo == 0))
- ARMul_NegZero (state, RdHi); /* zero value */
- else
- ARMul_NegZero (state, scc); /* non-zero value */
- }
-
- return scount + 1; /* extra cycle for addition */
-}