arm: Adios armemu
This commit is contained in:
parent
73a7a379d6
commit
f44781fd7b
19 changed files with 166 additions and 8603 deletions
|
@ -32,6 +32,9 @@
|
|||
#include "core/arm/skyeye_common/armmmu.h"
|
||||
#include "core/arm/skyeye_common/skyeye_defs.h"
|
||||
|
||||
#define BITS(s, a, b) ((s << ((sizeof(s) * 8 - 1) - b)) >> (sizeof(s) * 8 - b + a - 1))
|
||||
#define BIT(s, n) ((s >> (n)) & 1)
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
|
@ -287,15 +290,6 @@ enum {
|
|||
ARM620 = ARM6
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************************\
|
||||
* Macros to extract instruction fields *
|
||||
\***************************************************************************/
|
||||
|
||||
#define BIT(n) ( (ARMword)(instr>>(n))&1) /* bit n of instruction */
|
||||
#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) ) /* bits m to n of instr */
|
||||
#define TOPBITS(n) (instr >> (n)) /* bits 31 to n of instr */
|
||||
|
||||
/***************************************************************************\
|
||||
* The hardware vector addresses *
|
||||
\***************************************************************************/
|
||||
|
@ -339,13 +333,6 @@ enum {
|
|||
SYSTEM32MODE = 31
|
||||
};
|
||||
|
||||
#define ARM32BITMODE (state->Mode > 3)
|
||||
#define ARM26BITMODE (state->Mode <= 3)
|
||||
#define ARMMODE (state->Mode)
|
||||
#define ARMul_MODEBITS 0x1fL
|
||||
#define ARMul_MODE32BIT ARM32BITMODE
|
||||
#define ARMul_MODE26BIT ARM26BITMODE
|
||||
|
||||
enum {
|
||||
USERBANK = 0,
|
||||
FIQBANK = 1,
|
||||
|
@ -357,10 +344,6 @@ enum {
|
|||
SYSTEMBANK = USERBANK
|
||||
};
|
||||
|
||||
#define BANK_CAN_ACCESS_SPSR(bank) \
|
||||
((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK)
|
||||
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things in the emulator *
|
||||
\***************************************************************************/
|
||||
|
@ -372,85 +355,7 @@ extern void ARMul_Reset(ARMul_State* state);
|
|||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
extern ARMul_State *ARMul_NewState(ARMul_State* state);
|
||||
extern ARMword ARMul_DoProg(ARMul_State* state);
|
||||
extern ARMword ARMul_DoInstr(ARMul_State* state);
|
||||
|
||||
/***************************************************************************\
|
||||
* Useful support routines *
|
||||
\***************************************************************************/
|
||||
|
||||
extern ARMword ARMul_GetReg (ARMul_State* state, unsigned mode, unsigned reg);
|
||||
extern void ARMul_SetReg (ARMul_State* state, unsigned mode, unsigned reg, ARMword value);
|
||||
extern ARMword ARMul_GetPC(ARMul_State* state);
|
||||
extern ARMword ARMul_GetNextPC(ARMul_State* state);
|
||||
extern void ARMul_SetPC(ARMul_State* state, ARMword value);
|
||||
extern ARMword ARMul_GetR15(ARMul_State* state);
|
||||
extern void ARMul_SetR15(ARMul_State* state, ARMword value);
|
||||
|
||||
extern ARMword ARMul_GetCPSR(ARMul_State* state);
|
||||
extern void ARMul_SetCPSR(ARMul_State* state, ARMword value);
|
||||
extern ARMword ARMul_GetSPSR(ARMul_State* state, ARMword mode);
|
||||
extern void ARMul_SetSPSR(ARMul_State* state, ARMword mode, ARMword value);
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things to handle aborts *
|
||||
\***************************************************************************/
|
||||
|
||||
extern void ARMul_Abort(ARMul_State* state, ARMword address);
|
||||
#ifdef MODET
|
||||
#define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff) /* SWI -1 */
|
||||
#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
|
||||
state->AbortAddr = (address & (state->TFlag ? ~1L : ~3L))
|
||||
#else
|
||||
#define ARMul_ABORTWORD 0xefffffff /* SWI -1 */
|
||||
#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
|
||||
state->AbortAddr = (address & ~3L)
|
||||
#endif
|
||||
#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \
|
||||
state->Aborted = ARMul_DataAbortV ;
|
||||
#define ARMul_CLEARABORT state->abortSig = LOW
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things in the memory interface *
|
||||
\***************************************************************************/
|
||||
|
||||
extern unsigned ARMul_MemoryInit(ARMul_State* state, unsigned int initmemsize);
|
||||
extern void ARMul_MemoryExit(ARMul_State* state);
|
||||
|
||||
extern ARMword ARMul_LoadInstrS(ARMul_State* state, ARMword address, ARMword isize);
|
||||
extern ARMword ARMul_LoadInstrN(ARMul_State* state, ARMword address, ARMword isize);
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern ARMword ARMul_ReLoadInstr(ARMul_State* state, ARMword address, ARMword isize);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
extern ARMword ARMul_LoadWordS(ARMul_State* state, ARMword address);
|
||||
extern ARMword ARMul_LoadWordN(ARMul_State* state, ARMword address);
|
||||
extern ARMword ARMul_LoadHalfWord(ARMul_State* state, ARMword address);
|
||||
extern ARMword ARMul_LoadByte(ARMul_State* state, ARMword address);
|
||||
|
||||
extern void ARMul_StoreWordS(ARMul_State* state, ARMword address, ARMword data);
|
||||
extern void ARMul_StoreWordN(ARMul_State* state, ARMword address, ARMword data);
|
||||
extern void ARMul_StoreHalfWord(ARMul_State* state, ARMword address, ARMword data);
|
||||
extern void ARMul_StoreByte(ARMul_State* state, ARMword address, ARMword data);
|
||||
|
||||
extern ARMword ARMul_SwapWord(ARMul_State* state, ARMword address, ARMword data);
|
||||
extern ARMword ARMul_SwapByte(ARMul_State* state, ARMword address, ARMword data);
|
||||
|
||||
extern void ARMul_Icycles(ARMul_State* state, unsigned number, ARMword address);
|
||||
extern void ARMul_Ccycles(ARMul_State* state, unsigned number, ARMword address);
|
||||
|
||||
extern ARMword ARMul_ReadWord(ARMul_State* state, ARMword address);
|
||||
extern ARMword ARMul_ReadByte(ARMul_State* state, ARMword address);
|
||||
extern void ARMul_WriteWord(ARMul_State* state, ARMword address, ARMword data);
|
||||
extern void ARMul_WriteByte(ARMul_State* state, ARMword address, ARMword data);
|
||||
|
||||
extern ARMword ARMul_MemAccess(ARMul_State* state, ARMword, ARMword,
|
||||
ARMword, ARMword, ARMword, ARMword, ARMword,
|
||||
ARMword, ARMword, ARMword);
|
||||
extern ARMul_State* ARMul_NewState(ARMul_State* state);
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things in the co-processor interface *
|
||||
|
@ -495,37 +400,10 @@ enum {
|
|||
ARMul_CP15_DBCON_E0 = 0x0003
|
||||
};
|
||||
|
||||
extern unsigned ARMul_CoProInit(ARMul_State* state);
|
||||
extern void ARMul_CoProExit(ARMul_State* state);
|
||||
extern void ARMul_CoProAttach (ARMul_State* state, unsigned number,
|
||||
ARMul_CPInits* init, ARMul_CPExits* exit,
|
||||
ARMul_LDCs* ldc, ARMul_STCs* stc,
|
||||
ARMul_MRCs* mrc, ARMul_MCRs* mcr,
|
||||
ARMul_MRRCs* mrrc, ARMul_MCRRs* mcrr,
|
||||
ARMul_CDPs* cdp,
|
||||
ARMul_CPReads* read, ARMul_CPWrites* write);
|
||||
extern void ARMul_CoProDetach(ARMul_State* state, unsigned number);
|
||||
|
||||
/***************************************************************************\
|
||||
* Definitons of things in the host environment *
|
||||
\***************************************************************************/
|
||||
|
||||
extern unsigned ARMul_OSInit(ARMul_State* state);
|
||||
extern void ARMul_OSExit(ARMul_State* state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern unsigned ARMul_OSHandleSWI(ARMul_State* state, ARMword number);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
extern ARMword ARMul_OSLastErrorP(ARMul_State* state);
|
||||
extern ARMword ARMul_Debug(ARMul_State* state, ARMword pc, ARMword instr);
|
||||
extern unsigned ARMul_OSException(ARMul_State* state, ARMword vector, ARMword pc);
|
||||
|
||||
enum ConditionCode {
|
||||
EQ = 0,
|
||||
NE = 1,
|
||||
|
@ -545,40 +423,9 @@ enum ConditionCode {
|
|||
NV = 15,
|
||||
};
|
||||
|
||||
#ifndef NFLAG
|
||||
#define NFLAG state->NFlag
|
||||
#endif //NFLAG
|
||||
|
||||
#ifndef ZFLAG
|
||||
#define ZFLAG state->ZFlag
|
||||
#endif //ZFLAG
|
||||
|
||||
#ifndef CFLAG
|
||||
#define CFLAG state->CFlag
|
||||
#endif //CFLAG
|
||||
|
||||
#ifndef VFLAG
|
||||
#define VFLAG state->VFlag
|
||||
#endif //VFLAG
|
||||
|
||||
#ifndef IFLAG
|
||||
#define IFLAG (state->IFFlags >> 1)
|
||||
#endif //IFLAG
|
||||
|
||||
#ifndef FFLAG
|
||||
#define FFLAG (state->IFFlags & 1)
|
||||
#endif //FFLAG
|
||||
|
||||
#ifndef IFFLAGS
|
||||
#define IFFLAGS state->IFFlags
|
||||
#endif //VFLAG
|
||||
|
||||
extern bool AddOverflow(ARMword, ARMword, ARMword);
|
||||
extern bool SubOverflow(ARMword, ARMword, ARMword);
|
||||
|
||||
extern void ARMul_UndefInstr(ARMul_State*, ARMword);
|
||||
extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword);
|
||||
extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword);
|
||||
extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
|
||||
|
||||
extern u32 AddWithCarry(u32, u32, u32, bool*, bool*);
|
||||
|
|
|
@ -19,12 +19,6 @@
|
|||
|
||||
#include "core/arm/skyeye_common/armdefs.h"
|
||||
|
||||
/* Shift Opcodes. */
|
||||
#define LSL 0
|
||||
#define LSR 1
|
||||
#define ASR 2
|
||||
#define ROR 3
|
||||
|
||||
/* Macros to twiddle the status flags and mode. */
|
||||
#define NBIT ((unsigned)1L << 31)
|
||||
#define ZBIT (1L << 30)
|
||||
|
@ -38,73 +32,6 @@
|
|||
#define R15FBIT (1L << 26)
|
||||
#define R15IFBITS (3L << 26)
|
||||
|
||||
#ifdef MODET /* Thumb support. */
|
||||
/* ??? This bit is actually in the low order bit of the PC in the hardware.
|
||||
It isn't clear if the simulator needs to model that or not. */
|
||||
#define TBIT (1L << 5)
|
||||
#define TFLAG state->TFlag
|
||||
#define SETT state->TFlag = 1
|
||||
#define CLEART state->TFlag = 0
|
||||
#define ASSIGNT(res) state->TFlag = res
|
||||
#define INSN_SIZE (TFLAG ? 2 : 4)
|
||||
#else
|
||||
#define INSN_SIZE 4
|
||||
#endif
|
||||
|
||||
/*add armv6 CPSR feature*/
|
||||
#define EFLAG state->EFlag
|
||||
#define SETE state->EFlag = 1
|
||||
#define CLEARE state->EFlag = 0
|
||||
#define ASSIGNE(res) state->NFlag = res
|
||||
|
||||
#define AFLAG state->AFlag
|
||||
#define SETA state->AFlag = 1
|
||||
#define CLEARA state->AFlag = 0
|
||||
#define ASSIGNA(res) state->NFlag = res
|
||||
|
||||
#define QFLAG state->QFlag
|
||||
#define SETQ state->QFlag = 1
|
||||
#define CLEARQ state->AFlag = 0
|
||||
#define ASSIGNQ(res) state->QFlag = res
|
||||
|
||||
/* add end */
|
||||
|
||||
#define NFLAG state->NFlag
|
||||
#define SETN state->NFlag = 1
|
||||
#define CLEARN state->NFlag = 0
|
||||
#define ASSIGNN(res) state->NFlag = res
|
||||
|
||||
#define ZFLAG state->ZFlag
|
||||
#define SETZ state->ZFlag = 1
|
||||
#define CLEARZ state->ZFlag = 0
|
||||
#define ASSIGNZ(res) state->ZFlag = res
|
||||
|
||||
#define CFLAG state->CFlag
|
||||
#define SETC state->CFlag = 1
|
||||
#define CLEARC state->CFlag = 0
|
||||
#define ASSIGNC(res) state->CFlag = res
|
||||
|
||||
#define VFLAG state->VFlag
|
||||
#define SETV state->VFlag = 1
|
||||
#define CLEARV state->VFlag = 0
|
||||
#define ASSIGNV(res) state->VFlag = res
|
||||
|
||||
#define SFLAG state->SFlag
|
||||
#define SETS state->SFlag = 1
|
||||
#define CLEARS state->SFlag = 0
|
||||
#define ASSIGNS(res) state->SFlag = res
|
||||
|
||||
#define IFLAG (state->IFFlags >> 1)
|
||||
#define FFLAG (state->IFFlags & 1)
|
||||
#define IFFLAGS state->IFFlags
|
||||
#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3)
|
||||
#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ;
|
||||
|
||||
#define PSR_FBITS (0xff000000L)
|
||||
#define PSR_SBITS (0x00ff0000L)
|
||||
#define PSR_XBITS (0x0000ff00L)
|
||||
#define PSR_CBITS (0x000000ffL)
|
||||
|
||||
#if defined MODE32 || defined MODET
|
||||
#define CCBITS (0xf8000000L)
|
||||
#else
|
||||
|
@ -128,7 +55,6 @@
|
|||
#define R15PCBITS (0x03fffffcL)
|
||||
#endif
|
||||
|
||||
#define R15PCMODEBITS (0x03ffffffL)
|
||||
#define R15MODEBITS (0x3L)
|
||||
|
||||
#ifdef MODE32
|
||||
|
@ -149,106 +75,7 @@
|
|||
#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS))
|
||||
#define R15MODE (state->Reg[15] & R15MODEBITS)
|
||||
|
||||
#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (QFLAG << 27))
|
||||
#define EINT (IFFLAGS << 6)
|
||||
#define ER15INT (IFFLAGS << 26)
|
||||
#define EMODE (state->Mode)
|
||||
#define EGEBITS (state->GEFlag & 0x000F0000)
|
||||
|
||||
#ifdef MODET
|
||||
#define CPSR (ECC | EGEBITS | (EFLAG << 9) | (AFLAG << 8) | EINT | (TFLAG << 5) | EMODE)
|
||||
#else
|
||||
#define CPSR (ECC | EINT | EMODE)
|
||||
#endif
|
||||
|
||||
#ifdef MODE32
|
||||
#define PATCHR15
|
||||
#else
|
||||
#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC
|
||||
#endif
|
||||
|
||||
#define GETSPSR(bank) (ARMul_GetSPSR (state, EMODE))
|
||||
#define SETPSR_F(d,s) d = ((d) & ~PSR_FBITS) | ((s) & PSR_FBITS)
|
||||
#define SETPSR_S(d,s) d = ((d) & ~PSR_SBITS) | ((s) & PSR_SBITS)
|
||||
#define SETPSR_X(d,s) d = ((d) & ~PSR_XBITS) | ((s) & PSR_XBITS)
|
||||
#define SETPSR_C(d,s) d = ((d) & ~PSR_CBITS) | ((s) & PSR_CBITS)
|
||||
|
||||
#define SETR15PSR(s) \
|
||||
do \
|
||||
{ \
|
||||
if (state->Mode == USER26MODE) \
|
||||
{ \
|
||||
state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE; \
|
||||
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 \
|
||||
{ \
|
||||
state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS)); \
|
||||
ARMul_R15Altered (state); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define SETABORT(i, m, d) \
|
||||
do \
|
||||
{ \
|
||||
int SETABORT_mode = (m); \
|
||||
\
|
||||
ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state)); \
|
||||
ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT)) \
|
||||
| (i) | SETABORT_mode)); \
|
||||
state->Reg[14] = temp - (d); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#ifndef MODE32
|
||||
#define VECTORS 0x20
|
||||
#define LEGALADDR 0x03ffffff
|
||||
#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig)
|
||||
#define ADDREXCEPT(address) (address > LEGALADDR && !state->data32Sig)
|
||||
#endif
|
||||
|
||||
#define INTERNALABORT(address) \
|
||||
do \
|
||||
{ \
|
||||
if (address < VECTORS) \
|
||||
state->Aborted = ARMul_DataAbortV; \
|
||||
else \
|
||||
state->Aborted = ARMul_AddrExceptnV; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#ifdef MODE32
|
||||
#define TAKEABORT ARMul_Abort (state, ARMul_DataAbortV)
|
||||
#else
|
||||
#define TAKEABORT \
|
||||
do \
|
||||
{ \
|
||||
if (state->Aborted == ARMul_AddrExceptnV) \
|
||||
ARMul_Abort (state, ARMul_AddrExceptnV); \
|
||||
else \
|
||||
ARMul_Abort (state, ARMul_DataAbortV); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
#define CPTAKEABORT \
|
||||
do \
|
||||
{ \
|
||||
if (!state->Aborted) \
|
||||
ARMul_Abort (state, ARMul_UndefinedInstrV); \
|
||||
else if (state->Aborted == ARMul_AddrExceptnV) \
|
||||
ARMul_Abort (state, ARMul_AddrExceptnV); \
|
||||
else \
|
||||
ARMul_Abort (state, ARMul_DataAbortV); \
|
||||
} \
|
||||
while (0);
|
||||
|
||||
|
||||
/* Different ways to start the next instruction. */
|
||||
// Different ways to start the next instruction.
|
||||
#define SEQ 0
|
||||
#define NONSEQ 1
|
||||
#define PCINCEDSEQ 2
|
||||
|
@ -256,349 +83,23 @@
|
|||
#define PRIMEPIPE 4
|
||||
#define RESUME 8
|
||||
|
||||
/************************************/
|
||||
/* shenoubang 2012-3-11 */
|
||||
/* for armv7 DBG DMB DSB instr*/
|
||||
/************************************/
|
||||
#define MBReqTypes_Writes 0
|
||||
#define MBReqTypes_All 1
|
||||
|
||||
#define NORMALCYCLE state->NextInstr = 0
|
||||
#define BUSUSEDN state->NextInstr |= 1 /* The next fetch will be an N cycle. */
|
||||
#define BUSUSEDINCPCS \
|
||||
do \
|
||||
{ \
|
||||
if (! state->is_v4) \
|
||||
{ \
|
||||
/* A standard PC inc and an S cycle. */ \
|
||||
state->Reg[15] += INSN_SIZE; \
|
||||
state->NextInstr = (state->NextInstr & 0xff) | 2; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define BUSUSEDINCPCN \
|
||||
do \
|
||||
{ \
|
||||
if (state->is_v4) \
|
||||
BUSUSEDN; \
|
||||
else \
|
||||
{ \
|
||||
/* A standard PC inc and an N cycle. */ \
|
||||
state->Reg[15] += INSN_SIZE; \
|
||||
state->NextInstr |= 3; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define INCPC \
|
||||
do \
|
||||
{ \
|
||||
/* A standard PC inc. */ \
|
||||
state->Reg[15] += INSN_SIZE; \
|
||||
state->NextInstr |= 2; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define FLUSHPIPE state->NextInstr |= PRIMEPIPE
|
||||
|
||||
/* Cycle based emulation. */
|
||||
|
||||
#define OUTPUTCP(i,a,b)
|
||||
#define NCYCLE
|
||||
#define SCYCLE
|
||||
#define ICYCLE
|
||||
#define CCYCLE
|
||||
#define NEXTCYCLE(c)
|
||||
|
||||
/* Macros to extract parts of instructions. */
|
||||
#define DESTReg (BITS (12, 15))
|
||||
#define LHSReg (BITS (16, 19))
|
||||
#define RHSReg (BITS ( 0, 3))
|
||||
|
||||
#define DEST (state->Reg[DESTReg])
|
||||
|
||||
#ifdef MODE32
|
||||
#ifdef MODET
|
||||
#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[LHSReg]))
|
||||
#define RHS ((RHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[RHSReg]))
|
||||
#else
|
||||
#define LHS (state->Reg[LHSReg])
|
||||
#define RHS (state->Reg[RHSReg])
|
||||
#endif
|
||||
#else
|
||||
#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg]))
|
||||
#define RHS ((RHSReg == 15) ? R15PC : (state->Reg[RHSReg]))
|
||||
#endif
|
||||
|
||||
#define MULDESTReg (BITS (16, 19))
|
||||
#define MULLHSReg (BITS ( 0, 3))
|
||||
#define MULRHSReg (BITS ( 8, 11))
|
||||
#define MULACCReg (BITS (12, 15))
|
||||
|
||||
#define DPImmRHS (ARMul_ImmedTable[BITS(0, 11)])
|
||||
#define DPSImmRHS temp = BITS(0,11) ; \
|
||||
rhs = ARMul_ImmedTable[temp] ; \
|
||||
if (temp > 255) /* There was a shift. */ \
|
||||
ASSIGNC (rhs >> 31) ;
|
||||
|
||||
#ifdef MODE32
|
||||
#define DPRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
|
||||
: GetDPRegRHS (state, instr))
|
||||
#define DPSRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
|
||||
: GetDPSRegRHS (state, instr))
|
||||
#else
|
||||
#define DPRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
|
||||
: GetDPRegRHS (state, instr))
|
||||
#define DPSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
|
||||
: GetDPSRegRHS (state, instr))
|
||||
#endif
|
||||
|
||||
#define LSBase state->Reg[LHSReg]
|
||||
#define LSImmRHS (BITS(0,11))
|
||||
|
||||
#ifdef MODE32
|
||||
#define LSRegRHS ((BITS (4, 11) == 0) ? state->Reg[RHSReg] \
|
||||
: GetLSRegRHS (state, instr))
|
||||
#else
|
||||
#define LSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
|
||||
: GetLSRegRHS (state, instr))
|
||||
#endif
|
||||
|
||||
#define LSMNumRegs ((ARMword) ARMul_BitList[BITS (0, 7)] + \
|
||||
(ARMword) ARMul_BitList[BITS (8, 15)] )
|
||||
#define LSMBaseFirst ((LHSReg == 0 && BIT (0)) || \
|
||||
(BIT (LHSReg) && BITS (0, LHSReg - 1) == 0))
|
||||
|
||||
#define SWAPSRC (state->Reg[RHSReg])
|
||||
|
||||
#define LSCOff (BITS (0, 7) << 2)
|
||||
#define CPNum BITS (8, 11)
|
||||
|
||||
/* Determine if access to coprocessor CP is permitted.
|
||||
The XScale has a register in CP15 which controls access to CP0 - CP13. */
|
||||
//chy 2003-09-03, new CP_ACCESS_ALLOWED
|
||||
/*
|
||||
#define CP_ACCESS_ALLOWED(STATE, CP) \
|
||||
( ((CP) >= 14) \
|
||||
|| (! (STATE)->is_XScale) \
|
||||
|| (read_cp15_reg (15, 0, 1) & (1 << (CP))))
|
||||
*/
|
||||
#define CP_ACCESS_ALLOWED(STATE, CP) \
|
||||
( ((CP) >= 14) ) \
|
||||
|
||||
/* Macro to rotate n right by b bits. */
|
||||
// Macro to rotate n right by b bits.
|
||||
#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b))))
|
||||
|
||||
/* Macros to store results of instructions. */
|
||||
#define WRITEDEST(d) \
|
||||
do \
|
||||
{ \
|
||||
if (DESTReg == 15) \
|
||||
WriteR15 (state, d); \
|
||||
else \
|
||||
DEST = d; \
|
||||
} \
|
||||
while (0)
|
||||
// Values for Emulate.
|
||||
#define STOP 0 // stop
|
||||
#define CHANGEMODE 1 // change mode
|
||||
#define ONCE 2 // execute just one interation
|
||||
#define RUN 3 // continuous execution
|
||||
|
||||
#define WRITESDEST(d) \
|
||||
do \
|
||||
{ \
|
||||
if (DESTReg == 15) \
|
||||
WriteSR15 (state, d); \
|
||||
else \
|
||||
{ \
|
||||
DEST = d; \
|
||||
ARMul_NegZero (state, d); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
// Stuff that is shared across modes.
|
||||
extern unsigned ARMul_MultTable[]; // Number of I cycles for a mult.
|
||||
extern ARMword ARMul_ImmedTable[]; // Immediate DP LHS values.
|
||||
extern char ARMul_BitList[]; // Number of bits in a byte table.
|
||||
|
||||
#define WRITEDESTB(d) \
|
||||
do \
|
||||
{ \
|
||||
if (DESTReg == 15){ \
|
||||
WriteR15Branch (state, d); \
|
||||
} \
|
||||
else{ \
|
||||
DEST = d; \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define BYTETOBUS(data) ((data & 0xff) | \
|
||||
((data & 0xff) << 8) | \
|
||||
((data & 0xff) << 16) | \
|
||||
((data & 0xff) << 24))
|
||||
|
||||
#define BUSTOBYTE(address, data) \
|
||||
do \
|
||||
{ \
|
||||
if (state->bigendSig) \
|
||||
temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff; \
|
||||
else \
|
||||
temp = (data >> ((address & 3) << 3)) & 0xff; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
#define LOADMULT(instr, address, wb) LoadMult (state, instr, address, wb)
|
||||
#define LOADSMULT(instr, address, wb) LoadSMult (state, instr, address, wb)
|
||||
#define STOREMULT(instr, address, wb) StoreMult (state, instr, address, wb)
|
||||
#define STORESMULT(instr, address, wb) StoreSMult (state, instr, address, wb)
|
||||
|
||||
#define POSBRANCH ((instr & 0x7fffff) << 2)
|
||||
#define NEGBRANCH ((0xff000000 |(instr & 0xffffff)) << 2)
|
||||
|
||||
|
||||
/* Values for Emulate. */
|
||||
#define STOP 0 /* stop */
|
||||
#define CHANGEMODE 1 /* change mode */
|
||||
#define ONCE 2 /* execute just one interation */
|
||||
#define RUN 3 /* continuous execution */
|
||||
|
||||
/* Stuff that is shared across modes. */
|
||||
extern unsigned ARMul_MultTable[]; /* Number of I cycles for a mult. */
|
||||
extern ARMword ARMul_ImmedTable[]; /* Immediate DP LHS values. */
|
||||
extern char ARMul_BitList[]; /* Number of bits in a byte table. */
|
||||
|
||||
#define EVENTLISTSIZE 1024L
|
||||
|
||||
/* Thumb support. */
|
||||
typedef enum
|
||||
{
|
||||
t_undefined, /* Undefined Thumb instruction. */
|
||||
t_decoded, /* Instruction decoded to ARM equivalent. */
|
||||
t_branch /* Thumb branch (already processed). */
|
||||
}
|
||||
tdstate;
|
||||
|
||||
/*********************************************************************************
|
||||
* Check all the possible undef or unpredict behavior, Some of them probably is
|
||||
* out-of-updated with the newer ISA.
|
||||
* -- Michael.Kang
|
||||
********************************************************************************/
|
||||
#define UNDEF_WARNING LOG_WARNING(Core_ARM11, "undefined or unpredicted behavior for arm instruction.");
|
||||
|
||||
/* Macros to scrutinize instructions. */
|
||||
#define UNDEF_Test UNDEF_WARNING
|
||||
//#define UNDEF_Test
|
||||
|
||||
//#define UNDEF_Shift UNDEF_WARNING
|
||||
#define UNDEF_Shift
|
||||
|
||||
//#define UNDEF_MSRPC UNDEF_WARNING
|
||||
#define UNDEF_MSRPC
|
||||
|
||||
//#define UNDEF_MRSPC UNDEF_WARNING
|
||||
#define UNDEF_MRSPC
|
||||
|
||||
#define UNDEF_MULPCDest UNDEF_WARNING
|
||||
//#define UNDEF_MULPCDest
|
||||
|
||||
#define UNDEF_MULDestEQOp1 UNDEF_WARNING
|
||||
//#define UNDEF_MULDestEQOp1
|
||||
|
||||
//#define UNDEF_LSRBPC UNDEF_WARNING
|
||||
#define UNDEF_LSRBPC
|
||||
|
||||
//#define UNDEF_LSRBaseEQOffWb UNDEF_WARNING
|
||||
#define UNDEF_LSRBaseEQOffWb
|
||||
|
||||
//#define UNDEF_LSRBaseEQDestWb UNDEF_WARNING
|
||||
#define UNDEF_LSRBaseEQDestWb
|
||||
|
||||
//#define UNDEF_LSRPCBaseWb UNDEF_WARNING
|
||||
#define UNDEF_LSRPCBaseWb
|
||||
|
||||
//#define UNDEF_LSRPCOffWb UNDEF_WARNING
|
||||
#define UNDEF_LSRPCOffWb
|
||||
|
||||
//#define UNDEF_LSMNoRegs UNDEF_WARNING
|
||||
#define UNDEF_LSMNoRegs
|
||||
|
||||
//#define UNDEF_LSMPCBase UNDEF_WARNING
|
||||
#define UNDEF_LSMPCBase
|
||||
|
||||
//#define UNDEF_LSMUserBankWb UNDEF_WARNING
|
||||
#define UNDEF_LSMUserBankWb
|
||||
|
||||
//#define UNDEF_LSMBaseInListWb UNDEF_WARNING
|
||||
#define UNDEF_LSMBaseInListWb
|
||||
|
||||
#define UNDEF_SWPPC UNDEF_WARNING
|
||||
//#define UNDEF_SWPPC
|
||||
|
||||
#define UNDEF_CoProHS UNDEF_WARNING
|
||||
//#define UNDEF_CoProHS
|
||||
|
||||
#define UNDEF_MCRPC UNDEF_WARNING
|
||||
//#define UNDEF_MCRPC
|
||||
|
||||
//#define UNDEF_LSCPCBaseWb UNDEF_WARNING
|
||||
#define UNDEF_LSCPCBaseWb
|
||||
|
||||
#define UNDEF_UndefNotBounced UNDEF_WARNING
|
||||
//#define UNDEF_UndefNotBounced
|
||||
|
||||
#define UNDEF_ShortInt UNDEF_WARNING
|
||||
//#define UNDEF_ShortInt
|
||||
|
||||
#define UNDEF_IllegalMode UNDEF_WARNING
|
||||
//#define UNDEF_IllegalMode
|
||||
|
||||
#define UNDEF_Prog32SigChange UNDEF_WARNING
|
||||
//#define UNDEF_Prog32SigChange
|
||||
|
||||
#define UNDEF_Data32SigChange UNDEF_WARNING
|
||||
//#define UNDEF_Data32SigChange
|
||||
|
||||
/* Prototypes for exported functions. */
|
||||
extern unsigned ARMul_NthReg (ARMword, unsigned);
|
||||
|
||||
/* Prototypes for exported functions. */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern ARMword ARMul_Emulate26 (ARMul_State *);
|
||||
extern ARMword ARMul_Emulate32 (ARMul_State *);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
extern unsigned IntPending (ARMul_State *);
|
||||
extern void ARMul_CPSRAltered (ARMul_State *);
|
||||
extern void ARMul_R15Altered (ARMul_State *);
|
||||
extern ARMword ARMul_GetPC (ARMul_State *);
|
||||
extern ARMword ARMul_GetNextPC (ARMul_State *);
|
||||
extern ARMword ARMul_GetR15 (ARMul_State *);
|
||||
extern ARMword ARMul_GetCPSR (ARMul_State *);
|
||||
extern void ARMul_NegZero (ARMul_State *, ARMword);
|
||||
extern void ARMul_SetPC (ARMul_State *, ARMword);
|
||||
extern void ARMul_SetR15 (ARMul_State *, ARMword);
|
||||
extern void ARMul_SetCPSR (ARMul_State *, ARMword);
|
||||
extern ARMword ARMul_GetSPSR (ARMul_State *, ARMword);
|
||||
extern void ARMul_Abort26 (ARMul_State *, ARMword);
|
||||
extern void ARMul_Abort32 (ARMul_State *, ARMword);
|
||||
extern ARMword ARMul_MRC (ARMul_State *, ARMword);
|
||||
extern void ARMul_MRRC (ARMul_State *, ARMword, ARMword *, ARMword *);
|
||||
extern void ARMul_CDP (ARMul_State *, ARMword);
|
||||
extern void ARMul_LDC (ARMul_State *, ARMword, ARMword);
|
||||
extern void ARMul_STC (ARMul_State *, ARMword, ARMword);
|
||||
extern void ARMul_MCR (ARMul_State *, ARMword, ARMword);
|
||||
extern void ARMul_MCRR (ARMul_State *, ARMword, ARMword, ARMword);
|
||||
extern void ARMul_SetSPSR (ARMul_State *, ARMword, ARMword);
|
||||
extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
|
||||
extern ARMword ARMul_Align (ARMul_State *, ARMword, ARMword);
|
||||
extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
|
||||
extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword);
|
||||
extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword);
|
||||
extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword);
|
||||
extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword);
|
||||
extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword);
|
||||
extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *);
|
||||
extern ARMword ARMul_GetReg (ARMul_State *, unsigned, unsigned);
|
||||
extern void ARMul_SetReg (ARMul_State *, unsigned, unsigned, ARMword);
|
||||
|
||||
/* Coprocessor support functions. */
|
||||
// Coprocessor support functions.
|
||||
extern unsigned ARMul_CoProInit (ARMul_State *);
|
||||
extern void ARMul_CoProExit (ARMul_State *);
|
||||
extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *,
|
||||
|
@ -606,18 +107,3 @@ extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *,
|
|||
ARMul_MRCs *, ARMul_MCRs *, ARMul_MRRCs *, ARMul_MCRRs *,
|
||||
ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *);
|
||||
extern void ARMul_CoProDetach (ARMul_State *, unsigned);
|
||||
extern ARMword read_cp15_reg (unsigned, unsigned, unsigned);
|
||||
|
||||
extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword);
|
||||
extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword);
|
||||
extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *);
|
||||
extern unsigned DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *);
|
||||
extern unsigned DSPCDP4 (ARMul_State *, unsigned, ARMword);
|
||||
extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword);
|
||||
extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *);
|
||||
extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword);
|
||||
extern unsigned DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *);
|
||||
extern unsigned DSPCDP5 (ARMul_State *, unsigned, ARMword);
|
||||
extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword);
|
||||
extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *);
|
||||
extern unsigned DSPCDP6 (ARMul_State *, unsigned, ARMword);
|
||||
|
|
|
@ -43,12 +43,12 @@ unsigned VFPInit(ARMul_State* state)
|
|||
unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
|
||||
{
|
||||
/* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (21, 23);
|
||||
int Rt = BITS (12, 15);
|
||||
int CRn = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
int OPC_2 = BITS (5, 7);
|
||||
int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS(instr, 21, 23);
|
||||
int Rt = BITS(instr, 12, 15);
|
||||
int CRn = BITS(instr, 16, 19);
|
||||
int CRm = BITS(instr, 0, 3);
|
||||
int OPC_2 = BITS(instr, 5, 7);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
|
@ -60,7 +60,7 @@ unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
|
|||
{
|
||||
/* VMOV r to s */
|
||||
/* Transfering Rt is not mandatory, as the value of interest is pointed by value */
|
||||
VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value);
|
||||
VMOVBRS(state, BIT(instr, 20), Rt, BIT(instr, 7)|CRn<<1, value);
|
||||
return ARMul_DONE;
|
||||
}
|
||||
|
||||
|
@ -79,12 +79,12 @@ unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
|
|||
unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
|
||||
{
|
||||
/* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (21, 23);
|
||||
int Rt = BITS (12, 15);
|
||||
int CRn = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
int OPC_2 = BITS (5, 7);
|
||||
int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS(instr, 21, 23);
|
||||
int Rt = BITS(instr, 12, 15);
|
||||
int CRn = BITS(instr, 16, 19);
|
||||
int CRm = BITS(instr, 0, 3);
|
||||
int OPC_2 = BITS(instr, 5, 7);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
|
@ -95,7 +95,7 @@ unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
|
|||
{
|
||||
/* VMOV s to r */
|
||||
/* Transfering Rt is not mandatory, as the value of interest is pointed by value */
|
||||
VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value);
|
||||
VMOVBRS(state, BIT(instr, 20), Rt, BIT(instr, 7)|CRn<<1, &value);
|
||||
return ARMul_DONE;
|
||||
}
|
||||
|
||||
|
@ -126,24 +126,24 @@ unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
|
|||
unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2)
|
||||
{
|
||||
/* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (4, 7);
|
||||
int Rt = BITS (12, 15);
|
||||
int Rt2 = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS(instr, 4, 7);
|
||||
int Rt = BITS(instr, 12, 15);
|
||||
int Rt2 = BITS(instr, 16, 19);
|
||||
int CRm = BITS(instr, 0, 3);
|
||||
|
||||
if (CoProc == 10 || CoProc == 11)
|
||||
{
|
||||
if (CoProc == 10 && (OPC_1 & 0xD) == 1)
|
||||
{
|
||||
VMOVBRRSS(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2);
|
||||
VMOVBRRSS(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, value1, value2);
|
||||
return ARMul_DONE;
|
||||
}
|
||||
|
||||
if (CoProc == 11 && (OPC_1 & 0xD) == 1)
|
||||
{
|
||||
/* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
|
||||
VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2);
|
||||
VMOVBRRD(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, value1, value2);
|
||||
return ARMul_DONE;
|
||||
}
|
||||
}
|
||||
|
@ -156,11 +156,11 @@ unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32*
|
|||
unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2)
|
||||
{
|
||||
/* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (4, 7);
|
||||
int Rt = BITS (12, 15);
|
||||
int Rt2 = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS(instr, 4, 7);
|
||||
int Rt = BITS(instr, 12, 15);
|
||||
int Rt2 = BITS(instr, 16, 19);
|
||||
int CRm = BITS(instr, 0, 3);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
|
@ -170,14 +170,14 @@ unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 v
|
|||
{
|
||||
if (CoProc == 10 && (OPC_1 & 0xD) == 1)
|
||||
{
|
||||
VMOVBRRSS(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2);
|
||||
VMOVBRRSS(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, &value1, &value2);
|
||||
return ARMul_DONE;
|
||||
}
|
||||
|
||||
if (CoProc == 11 && (OPC_1 & 0xD) == 1)
|
||||
{
|
||||
/* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
|
||||
VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2);
|
||||
VMOVBRRD(state, BIT(instr, 20), Rt, Rt2, BIT(instr, 5)<<4|CRm, &value1, &value2);
|
||||
return ARMul_DONE;
|
||||
}
|
||||
}
|
||||
|
@ -190,14 +190,14 @@ unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 v
|
|||
unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value)
|
||||
{
|
||||
/* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int CRd = BITS (12, 15);
|
||||
int Rn = BITS (16, 19);
|
||||
int imm8 = BITS (0, 7);
|
||||
int P = BIT(24);
|
||||
int U = BIT(23);
|
||||
int D = BIT(22);
|
||||
int W = BIT(21);
|
||||
int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
|
||||
int CRd = BITS(instr, 12, 15);
|
||||
int Rn = BITS(instr, 16, 19);
|
||||
int imm8 = BITS(instr, 0, 7);
|
||||
int P = BIT(instr, 24);
|
||||
int U = BIT(instr, 23);
|
||||
int D = BIT(instr, 22);
|
||||
int W = BIT(instr, 21);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
|
@ -239,14 +239,14 @@ unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value)
|
|||
unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value)
|
||||
{
|
||||
/* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int CRd = BITS (12, 15);
|
||||
int Rn = BITS (16, 19);
|
||||
int imm8 = BITS (0, 7);
|
||||
int P = BIT(24);
|
||||
int U = BIT(23);
|
||||
int D = BIT(22);
|
||||
int W = BIT(21);
|
||||
int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
|
||||
int CRd = BITS(instr, 12, 15);
|
||||
int Rn = BITS(instr, 16, 19);
|
||||
int imm8 = BITS(instr, 0, 7);
|
||||
int P = BIT(instr, 24);
|
||||
int U = BIT(instr, 23);
|
||||
int D = BIT(instr, 22);
|
||||
int W = BIT(instr, 21);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
|
@ -277,57 +277,12 @@ unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value)
|
|||
unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
|
||||
{
|
||||
/* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
|
||||
int CoProc = BITS (8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS (20, 23);
|
||||
int CRd = BITS (12, 15);
|
||||
int CRn = BITS (16, 19);
|
||||
int CRm = BITS (0, 3);
|
||||
int OPC_2 = BITS (5, 7);
|
||||
|
||||
//ichfly
|
||||
/*if ((instr & 0x0FBF0FD0) == 0x0EB70AC0) //vcvt.f64.f32 d8, s16 (s is bit 0-3 and LSB bit 22) (d is bit 12 - 15 MSB is Bit 6)
|
||||
{
|
||||
struct vfp_double vdd;
|
||||
struct vfp_single vsd;
|
||||
int dn = BITS(12, 15) + (BIT(22) << 4);
|
||||
int sd = (BITS(0, 3) << 1) + BIT(5);
|
||||
s32 n = vfp_get_float(state, sd);
|
||||
vfp_single_unpack(&vsd, n);
|
||||
if (vsd.exponent & 0x80)
|
||||
{
|
||||
vdd.exponent = (vsd.exponent&~0x80) | 0x400;
|
||||
}
|
||||
else
|
||||
{
|
||||
vdd.exponent = vsd.exponent | 0x380;
|
||||
}
|
||||
vdd.sign = vsd.sign;
|
||||
vdd.significand = (u64)(vsd.significand & ~0xC0000000) << 32; // I have no idea why but the 2 uppern bits are not from the significand
|
||||
vfp_put_double(state, vfp_double_pack(&vdd), dn);
|
||||
return ARMul_DONE;
|
||||
}
|
||||
if ((instr & 0x0FBF0FD0) == 0x0EB70BC0) //vcvt.f32.f64 s15, d6
|
||||
{
|
||||
struct vfp_double vdd;
|
||||
struct vfp_single vsd;
|
||||
int sd = BITS(0, 3) + (BIT(5) << 4);
|
||||
int dn = (BITS(12, 15) << 1) + BIT(22);
|
||||
vfp_double_unpack(&vdd, vfp_get_double(state, sd));
|
||||
if (vdd.exponent & 0x400) //todo if the exponent is to low or to high for this convert
|
||||
{
|
||||
vsd.exponent = (vdd.exponent) | 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
vsd.exponent = vdd.exponent & ~0x80;
|
||||
}
|
||||
vsd.exponent &= 0xFF;
|
||||
// vsd.exponent = vdd.exponent >> 3;
|
||||
vsd.sign = vdd.sign;
|
||||
vsd.significand = ((u64)(vdd.significand ) >> 32)& ~0xC0000000;
|
||||
vfp_put_float(state, vfp_single_pack(&vsd), dn);
|
||||
return ARMul_DONE;
|
||||
}*/
|
||||
int CoProc = BITS(instr, 8, 11); /* 10 or 11 */
|
||||
int OPC_1 = BITS(instr, 20, 23);
|
||||
int CRd = BITS(instr, 12, 15);
|
||||
int CRn = BITS(instr, 16, 19);
|
||||
int CRm = BITS(instr, 0, 3);
|
||||
int OPC_2 = BITS(instr, 5, 7);
|
||||
|
||||
/* TODO check access permission */
|
||||
|
||||
|
@ -335,17 +290,17 @@ unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
|
|||
|
||||
if (CoProc == 10 || CoProc == 11)
|
||||
{
|
||||
if ((OPC_1 & 0xB) == 0xB && BITS(4, 7) == 0)
|
||||
if ((OPC_1 & 0xB) == 0xB && BITS(instr, 4, 7) == 0)
|
||||
{
|
||||
unsigned int single = BIT(8) == 0;
|
||||
unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
|
||||
unsigned int single = BIT(instr, 8) == 0;
|
||||
unsigned int d = (single ? BITS(instr, 12,15)<<1 | BIT(instr, 22) : BITS(instr, 12,15) | BIT(instr, 22)<<4);
|
||||
unsigned int imm;
|
||||
instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */
|
||||
instr = BITS(instr, 16, 19) << 4 | BITS(instr, 0, 3); // FIXME dirty workaround to get a correct imm
|
||||
|
||||
if (single)
|
||||
imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19;
|
||||
imm = BIT(instr, 7)<<31 | (BIT(instr, 6)==0)<<30 | (BIT(instr, 6) ? 0x1f : 0)<<25 | BITS(instr, 0, 5)<<19;
|
||||
else
|
||||
imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16;
|
||||
imm = BIT(instr, 7)<<31 | (BIT(instr, 6)==0)<<30 | (BIT(instr, 6) ? 0xff : 0)<<22 | BITS(instr, 0, 5)<<16;
|
||||
|
||||
VMOVI(state, single, d, imm);
|
||||
return ARMul_DONE;
|
||||
|
@ -353,9 +308,9 @@ unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
|
|||
|
||||
if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2)
|
||||
{
|
||||
unsigned int single = BIT(8) == 0;
|
||||
unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
|
||||
unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);;
|
||||
unsigned int single = BIT(instr, 8) == 0;
|
||||
unsigned int d = (single ? BITS(instr, 12,15)<<1 | BIT(instr, 22) : BITS(instr, 12,15) | BIT(instr, 22)<<4);
|
||||
unsigned int m = (single ? BITS(instr, 0, 3)<<1 | BIT(instr, 5) : BITS(instr, 0, 3) | BIT(instr, 5)<<4);
|
||||
VMOVR(state, single, d, m);
|
||||
return ARMul_DONE;
|
||||
}
|
||||
|
@ -477,11 +432,11 @@ int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value)
|
|||
static int single_reg, add, d, n, imm32, regs;
|
||||
if (type == ARMul_FIRST)
|
||||
{
|
||||
single_reg = BIT(8) == 0; /* Double precision */
|
||||
add = BIT(23); /* */
|
||||
imm32 = BITS(0,7)<<2; /* may not be used */
|
||||
d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
|
||||
n = BITS(16, 19); /* destination register */
|
||||
single_reg = BIT(instr, 8) == 0; // Double precision
|
||||
add = BIT(instr, 23);
|
||||
imm32 = BITS(instr, 0,7)<<2; // may not be used
|
||||
d = single_reg ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); /* Base register */
|
||||
n = BITS(instr, 16, 19); // destination register
|
||||
|
||||
i = 0;
|
||||
regs = 1;
|
||||
|
@ -519,10 +474,10 @@ int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value)
|
|||
static int single_regs, add, wback, d, n, imm32, regs;
|
||||
if (type == ARMul_FIRST)
|
||||
{
|
||||
single_regs = BIT(8) == 0; /* Single precision */
|
||||
d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
|
||||
imm32 = BITS(0,7)<<2; /* may not be used */
|
||||
regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */
|
||||
single_regs = BIT(instr, 8) == 0; // Single precision
|
||||
d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
|
||||
imm32 = BITS(instr, 0,7)<<2; // may not be used
|
||||
regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 1, 7); // FSTMX if regs is odd
|
||||
|
||||
state->Reg[R13] = state->Reg[R13] - imm32;
|
||||
|
||||
|
@ -561,13 +516,13 @@ int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value)
|
|||
static int single_regs, add, wback, d, n, imm32, regs;
|
||||
if (type == ARMul_FIRST)
|
||||
{
|
||||
single_regs = BIT(8) == 0; /* Single precision */
|
||||
add = BIT(23); /* */
|
||||
wback = BIT(21); /* write-back */
|
||||
d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
|
||||
n = BITS(16, 19); /* destination register */
|
||||
imm32 = BITS(0,7) * 4; /* may not be used */
|
||||
regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */
|
||||
single_regs = BIT(instr, 8) == 0; // Single precision
|
||||
add = BIT(instr, 23);
|
||||
wback = BIT(instr, 21); // write-back
|
||||
d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
|
||||
n = BITS(instr, 16, 19); // destination register
|
||||
imm32 = BITS(instr, 0,7) * 4; // may not be used
|
||||
regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 0, 7)>>1; // FSTMX if regs is odd
|
||||
|
||||
if (wback) {
|
||||
state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
|
||||
|
@ -610,10 +565,10 @@ int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value)
|
|||
static int single_regs, add, wback, d, n, imm32, regs;
|
||||
if (type == ARMul_FIRST)
|
||||
{
|
||||
single_regs = BIT(8) == 0; /* Single precision */
|
||||
d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
|
||||
imm32 = BITS(0,7)<<2; /* may not be used */
|
||||
regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */
|
||||
single_regs = BIT(instr, 8) == 0; // Single precision
|
||||
d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
|
||||
imm32 = BITS(instr, 0, 7)<<2; // may not be used
|
||||
regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 1, 7); // FLDMX if regs is odd
|
||||
|
||||
state->Reg[R13] = state->Reg[R13] + imm32;
|
||||
|
||||
|
@ -656,11 +611,11 @@ int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value)
|
|||
static int single_reg, add, d, n, imm32, regs;
|
||||
if (type == ARMul_FIRST)
|
||||
{
|
||||
single_reg = BIT(8) == 0; /* Double precision */
|
||||
add = BIT(23); /* */
|
||||
imm32 = BITS(0,7)<<2; /* may not be used */
|
||||
d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
|
||||
n = BITS(16, 19); /* destination register */
|
||||
single_reg = BIT(instr, 8) == 0; // Double precision
|
||||
add = BIT(instr, 23);
|
||||
imm32 = BITS(instr, 0, 7)<<2; // may not be used
|
||||
d = single_reg ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
|
||||
n = BITS(instr, 16, 19); // destination register
|
||||
|
||||
i = 0;
|
||||
regs = 1;
|
||||
|
@ -702,13 +657,13 @@ int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value)
|
|||
static int single_regs, add, wback, d, n, imm32, regs;
|
||||
if (type == ARMul_FIRST)
|
||||
{
|
||||
single_regs = BIT(8) == 0; /* Single precision */
|
||||
add = BIT(23); /* */
|
||||
wback = BIT(21); /* write-back */
|
||||
d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
|
||||
n = BITS(16, 19); /* destination register */
|
||||
imm32 = BITS(0,7) * 4; /* may not be used */
|
||||
regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */
|
||||
single_regs = BIT(instr, 8) == 0; // Single precision
|
||||
add = BIT(instr, 23);
|
||||
wback = BIT(instr, 21); // write-back
|
||||
d = single_regs ? BITS(instr, 12, 15)<<1|BIT(instr, 22) : BIT(instr, 22)<<4|BITS(instr, 12, 15); // Base register
|
||||
n = BITS(instr, 16, 19); // destination register
|
||||
imm32 = BITS(instr, 0, 7) * 4; // may not be used
|
||||
regs = single_regs ? BITS(instr, 0, 7) : BITS(instr, 0, 7)>>1; // FLDMX if regs is odd
|
||||
|
||||
if (wback) {
|
||||
state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
|
||||
|
@ -787,8 +742,7 @@ void vfp_put_float(arm_core_t* state, int32_t val, unsigned int reg)
|
|||
|
||||
uint64_t vfp_get_double(arm_core_t* state, unsigned int reg)
|
||||
{
|
||||
uint64_t result;
|
||||
result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2];
|
||||
uint64_t result = ((uint64_t) state->ExtReg[reg*2+1])<<32 | state->ExtReg[reg*2];
|
||||
LOG_TRACE(Core_ARM11, "VFP get double: s[%d-%d]=[%016llx]\n", reg * 2 + 1, reg * 2, result);
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue