diff options
Diffstat (limited to 'src/core/arm/dyncom')
-rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 407 |
1 files changed, 196 insertions, 211 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index b79fd1719..034f4d570 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp @@ -13,6 +13,7 @@ #include "core/memory.h" #include "core/hle/svc.h" #include "core/arm/disassembler/arm_disasm.h" +#include "core/arm/dyncom/arm_dyncom_dec.h" #include "core/arm/dyncom/arm_dyncom_interpreter.h" #include "core/arm/dyncom/arm_dyncom_thumb.h" #include "core/arm/dyncom/arm_dyncom_run.h" @@ -68,6 +69,67 @@ static void remove_exclusive(ARMul_State* state, ARMword addr){ state->exclusive_tag = 0xFFFFFFFF; } +static int CondPassed(ARMul_State* cpu, unsigned int cond) { + const u32 NFLAG = cpu->NFlag; + const u32 ZFLAG = cpu->ZFlag; + const u32 CFLAG = cpu->CFlag; + const u32 VFLAG = cpu->VFlag; + + int temp = 0; + + switch (cond) { + case 0x0: + temp = ZFLAG; + break; + case 0x1: // NE + temp = !ZFLAG; + break; + case 0x2: // CS + temp = CFLAG; + break; + case 0x3: // CC + temp = !CFLAG; + break; + case 0x4: // MI + temp = NFLAG; + break; + case 0x5: // PL + temp = !NFLAG; + break; + case 0x6: // VS + temp = VFLAG; + break; + case 0x7: // VC + temp = !VFLAG; + break; + case 0x8: // HI + temp = (CFLAG && !ZFLAG); + break; + case 0x9: // LS + temp = (!CFLAG || ZFLAG); + break; + case 0xa: // GE + temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); + break; + case 0xb: // LT + temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); + break; + case 0xc: // GT + temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)); + break; + case 0xd: // LE + temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; + break; + case 0xe: // AL + temp = 1; + break; + case 0xf: + temp = 1; + break; + } + return temp; +} + static unsigned int DPO(Immediate)(ARMul_State* cpu, unsigned int sht_oper) { unsigned int immed_8 = BITS(sht_oper, 0, 7); unsigned int rotate_imm = BITS(sht_oper, 8, 11); @@ -224,14 +286,12 @@ static unsigned int DPO(RotateRightByRegister)(ARMul_State* cpu, unsigned int sh typedef void (*get_addr_fp_t)(ARMul_State *cpu, unsigned int inst, unsigned int &virt_addr, unsigned int rw); -typedef struct _ldst_inst { +struct ldst_inst { unsigned int inst; get_addr_fp_t get_addr; -} ldst_inst; +}; #define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0) -int CondPassed(ARMul_State* cpu, unsigned int cond); - #define LnSWoUB(s) glue(LnSWoUB, s) #define MLnS(s) glue(MLnS, s) #define LdnStM(s) glue(LdnStM, s) @@ -647,255 +707,248 @@ static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst, u virt_addr = addr; } -typedef struct _arm_inst { +struct arm_inst { unsigned int idx; unsigned int cond; int br; int load_r15; char component[0]; -} arm_inst; +}; -typedef struct generic_arm_inst { +struct generic_arm_inst { u32 Ra; u32 Rm; u32 Rn; u32 Rd; u8 op1; u8 op2; -} generic_arm_inst; +}; -typedef struct _adc_inst { +struct adc_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} adc_inst; +}; -typedef struct _add_inst { +struct add_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} add_inst; +}; -typedef struct _orr_inst { +struct orr_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} orr_inst; +}; -typedef struct _and_inst { +struct and_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} and_inst; +}; -typedef struct _eor_inst { +struct eor_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} eor_inst; +}; -typedef struct _bbl_inst { +struct bbl_inst { unsigned int L; int signed_immed_24; unsigned int next_addr; unsigned int jmp_addr; -} bbl_inst; +}; -typedef struct _bx_inst { +struct bx_inst { unsigned int Rm; -} bx_inst; +}; -typedef struct _blx_inst { +struct blx_inst { union { int32_t signed_immed_24; uint32_t Rm; } val; unsigned int inst; -} blx_inst; +}; -typedef struct _clz_inst { +struct clz_inst { unsigned int Rm; unsigned int Rd; -} clz_inst; +}; -typedef struct _cps_inst { +struct cps_inst { unsigned int imod0; unsigned int imod1; unsigned int mmod; unsigned int A, I, F; unsigned int mode; -} cps_inst; +}; -typedef struct _clrex_inst { -} clrex_inst; +struct clrex_inst { +}; -typedef struct _cpy_inst { +struct cpy_inst { unsigned int Rm; unsigned int Rd; -} cpy_inst; +}; -typedef struct _bic_inst { +struct bic_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} bic_inst; +}; -typedef struct _sub_inst { +struct sub_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} sub_inst; +}; -typedef struct _tst_inst { +struct tst_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} tst_inst; +}; -typedef struct _cmn_inst { +struct cmn_inst { unsigned int I; unsigned int Rn; unsigned int shifter_operand; shtop_fp_t shtop_func; -} cmn_inst; +}; -typedef struct _teq_inst { +struct teq_inst { unsigned int I; unsigned int Rn; unsigned int shifter_operand; shtop_fp_t shtop_func; -} teq_inst; +}; -typedef struct _stm_inst { +struct stm_inst { unsigned int inst; -} stm_inst; +}; struct bkpt_inst { u32 imm; }; -struct blx1_inst { - unsigned int addr; +struct stc_inst { }; -struct blx2_inst { - unsigned int Rm; +struct ldc_inst { }; -typedef struct _stc_inst { -} stc_inst; - -typedef struct _ldc_inst { -} ldc_inst; - -typedef struct _swi_inst { +struct swi_inst { unsigned int num; -} swi_inst; +}; -typedef struct _cmp_inst { +struct cmp_inst { unsigned int I; unsigned int Rn; unsigned int shifter_operand; shtop_fp_t shtop_func; -} cmp_inst; +}; -typedef struct _mov_inst { +struct mov_inst { unsigned int I; unsigned int S; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} mov_inst; +}; -typedef struct _mvn_inst { +struct mvn_inst { unsigned int I; unsigned int S; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} mvn_inst; +}; -typedef struct _rev_inst { +struct rev_inst { unsigned int Rd; unsigned int Rm; unsigned int op1; unsigned int op2; -} rev_inst; +}; -typedef struct _rsb_inst { +struct rsb_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} rsb_inst; +}; -typedef struct _rsc_inst { +struct rsc_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} rsc_inst; +}; -typedef struct _sbc_inst { +struct sbc_inst { unsigned int I; unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int shifter_operand; shtop_fp_t shtop_func; -} sbc_inst; +}; -typedef struct _mul_inst { +struct mul_inst { unsigned int S; unsigned int Rd; unsigned int Rs; unsigned int Rm; -} mul_inst; +}; -typedef struct _smul_inst { +struct smul_inst { unsigned int Rd; unsigned int Rs; unsigned int Rm; unsigned int x; unsigned int y; -} smul_inst; +}; -typedef struct _umull_inst { +struct umull_inst { unsigned int S; unsigned int RdHi; unsigned int RdLo; unsigned int Rs; unsigned int Rm; -} umull_inst; -typedef struct _smlad_inst { +}; + +struct smlad_inst { unsigned int m; unsigned int Rm; unsigned int Rd; @@ -903,58 +956,58 @@ typedef struct _smlad_inst { unsigned int Rn; unsigned int op1; unsigned int op2; -} smlad_inst; +}; -typedef struct _smla_inst { +struct smla_inst { unsigned int x; unsigned int y; unsigned int Rm; unsigned int Rd; unsigned int Rs; unsigned int Rn; -} smla_inst; +}; -typedef struct smlalxy_inst { +struct smlalxy_inst { unsigned int x; unsigned int y; unsigned int RdLo; unsigned int RdHi; unsigned int Rm; unsigned int Rn; -} smlalxy_inst; +}; -typedef struct ssat_inst { +struct ssat_inst { unsigned int Rn; unsigned int Rd; unsigned int imm5; unsigned int sat_imm; unsigned int shift_type; -} ssat_inst; +}; -typedef struct umaal_inst { +struct umaal_inst { unsigned int Rn; unsigned int Rm; unsigned int RdHi; unsigned int RdLo; -} umaal_inst; +}; -typedef struct _umlal_inst { +struct umlal_inst { unsigned int S; unsigned int Rm; unsigned int Rs; unsigned int RdHi; unsigned int RdLo; -} umlal_inst; +}; -typedef struct _smlal_inst { +struct smlal_inst { unsigned int S; unsigned int Rm; unsigned int Rs; unsigned int RdHi; unsigned int RdLo; -} smlal_inst; +}; -typedef struct smlald_inst { +struct smlald_inst { unsigned int RdLo; unsigned int RdHi; unsigned int Rm; @@ -962,17 +1015,17 @@ typedef struct smlald_inst { unsigned int swap; unsigned int op1; unsigned int op2; -} smlald_inst; +}; -typedef struct _mla_inst { +struct mla_inst { unsigned int S; unsigned int Rn; unsigned int Rd; unsigned int Rs; unsigned int Rm; -} mla_inst; +}; -typedef struct _mrc_inst { +struct mrc_inst { unsigned int opcode_1; unsigned int opcode_2; unsigned int cp_num; @@ -980,9 +1033,9 @@ typedef struct _mrc_inst { unsigned int crm; unsigned int Rd; unsigned int inst; -} mrc_inst; +}; -typedef struct _mcr_inst { +struct mcr_inst { unsigned int opcode_1; unsigned int opcode_2; unsigned int cp_num; @@ -990,77 +1043,77 @@ typedef struct _mcr_inst { unsigned int crm; unsigned int Rd; unsigned int inst; -} mcr_inst; +}; -typedef struct mcrr_inst { +struct mcrr_inst { unsigned int opcode_1; unsigned int cp_num; unsigned int crm; unsigned int rt; unsigned int rt2; -} mcrr_inst; +}; -typedef struct _mrs_inst { +struct mrs_inst { unsigned int R; unsigned int Rd; -} mrs_inst; +}; -typedef struct _msr_inst { +struct msr_inst { unsigned int field_mask; unsigned int R; unsigned int inst; -} msr_inst; +}; -typedef struct _pld_inst { -} pld_inst; +struct pld_inst { +}; -typedef struct _sxtb_inst { +struct sxtb_inst { unsigned int Rd; unsigned int Rm; unsigned int rotate; -} sxtb_inst; +}; -typedef struct _sxtab_inst { +struct sxtab_inst { unsigned int Rd; unsigned int Rn; unsigned int Rm; unsigned rotate; -} sxtab_inst; +}; -typedef struct _sxtah_inst { +struct sxtah_inst { unsigned int Rd; unsigned int Rn; unsigned int Rm; unsigned int rotate; -} sxtah_inst; +}; -typedef struct _sxth_inst { +struct sxth_inst { unsigned int Rd; unsigned int Rm; unsigned int rotate; -} sxth_inst; +}; -typedef struct _uxtab_inst { +struct uxtab_inst { unsigned int Rn; unsigned int Rd; unsigned int rotate; unsigned int Rm; -} uxtab_inst; +}; -typedef struct _uxtah_inst { +struct uxtah_inst { unsigned int Rn; unsigned int Rd; unsigned int rotate; unsigned int Rm; -} uxtah_inst; +}; -typedef struct _uxth_inst { +struct uxth_inst { unsigned int Rd; unsigned int Rm; unsigned int rotate; -} uxth_inst; +}; -typedef struct _cdp_inst { +struct cdp_inst { unsigned int opcode_1; unsigned int CRn; unsigned int CRd; @@ -1068,56 +1121,56 @@ typedef struct _cdp_inst { unsigned int opcode_2; unsigned int CRm; unsigned int inst; -}cdp_inst; +}; -typedef struct _uxtb_inst { +struct uxtb_inst { unsigned int Rd; unsigned int Rm; unsigned int rotate; -} uxtb_inst; +}; -typedef struct _swp_inst { +struct swp_inst { unsigned int Rn; unsigned int Rd; unsigned int Rm; -} swp_inst; +}; -typedef struct setend_inst { +struct setend_inst { unsigned int set_bigend; -} setend_inst; +}; -typedef struct _b_2_thumb { +struct b_2_thumb { unsigned int imm; -}b_2_thumb; -typedef struct _b_cond_thumb { +}; +struct b_cond_thumb { unsigned int imm; unsigned int cond; -}b_cond_thumb; +}; -typedef struct _bl_1_thumb { +struct bl_1_thumb { unsigned int imm; -}bl_1_thumb; -typedef struct _bl_2_thumb { +}; +struct bl_2_thumb { unsigned int imm; -}bl_2_thumb; -typedef struct _blx_1_thumb { +}; +struct blx_1_thumb { unsigned int imm; unsigned int instr; -}blx_1_thumb; +}; -typedef struct _pkh_inst { +struct pkh_inst { unsigned int Rm; unsigned int Rn; unsigned int Rd; unsigned char imm; -} pkh_inst; +}; typedef arm_inst * ARM_INST_PTR; #define CACHE_BUFFER_SIZE (64 * 1024 * 2000) -char inst_buf[CACHE_BUFFER_SIZE]; -int top = 0; -inline void *AllocBuffer(unsigned int size) { +static char inst_buf[CACHE_BUFFER_SIZE]; +static int top = 0; +static inline void *AllocBuffer(unsigned int size) { int start = top; top += size; if (top > CACHE_BUFFER_SIZE) { @@ -1127,74 +1180,6 @@ inline void *AllocBuffer(unsigned int size) { return (void *)&inst_buf[start]; } -int CondPassed(ARMul_State* cpu, unsigned int cond) { - #define NFLAG cpu->NFlag - #define ZFLAG cpu->ZFlag - #define CFLAG cpu->CFlag - #define VFLAG cpu->VFlag - - int temp = 0; - - switch (cond) { - case 0x0: - temp = ZFLAG; - break; - case 0x1: // NE - temp = !ZFLAG; - break; - case 0x6: // VS - temp = VFLAG; - break; - case 0x7: // VC - temp = !VFLAG; - break; - case 0x4: // MI - temp = NFLAG; - break; - case 0x5: // PL - temp = !NFLAG; - break; - case 0x2: // CS - temp = CFLAG; - break; - case 0x3: // CC - temp = !CFLAG; - break; - case 0x8: // HI - temp = (CFLAG && !ZFLAG); - break; - case 0x9: // LS - temp = (!CFLAG || ZFLAG); - break; - case 0xa: // GE - temp = ((!NFLAG && !VFLAG) || (NFLAG && VFLAG)); - break; - case 0xb: // LT - temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)); - break; - case 0xc: // GT - temp = ((!NFLAG && !VFLAG && !ZFLAG) || (NFLAG && VFLAG && !ZFLAG)); - break; - case 0xd: // LE - temp = ((NFLAG && !VFLAG) || (!NFLAG && VFLAG)) || ZFLAG; - break; - case 0xe: // AL - temp = 1; - break; - case 0xf: - temp = 1; - break; - } - return temp; -} - -enum DECODE_STATUS { - DECODE_SUCCESS, - DECODE_FAILURE -}; - -int decode_arm_instr(uint32_t instr, int32_t *idx); - static shtop_fp_t get_shtop(unsigned int inst) { if (BIT(inst, 25)) { return DPO(Immediate); |