summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt16
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp2719
-rw-r--r--src/core/arm/dyncom/arm_dyncom_trans.cpp2178
-rw-r--r--src/core/arm/dyncom/arm_dyncom_trans.h493
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp64
-rw-r--r--src/core/gdbstub/gdbstub.cpp2
-rw-r--r--src/core/hle/function_wrappers.h10
-rw-r--r--src/core/hle/kernel/client_port.cpp16
-rw-r--r--src/core/hle/kernel/client_port.h36
-rw-r--r--src/core/hle/kernel/kernel.h7
-rw-r--r--src/core/hle/kernel/server_port.cpp41
-rw-r--r--src/core/hle/kernel/server_port.h46
-rw-r--r--src/core/hle/kernel/session.h4
-rw-r--r--src/core/hle/kernel/thread.cpp49
-rw-r--r--src/core/hle/result.h1
-rw-r--r--src/core/hle/service/dlp/dlp.cpp24
-rw-r--r--src/core/hle/service/dlp/dlp.h15
-rw-r--r--src/core/hle/service/dlp/dlp_clnt.cpp20
-rw-r--r--src/core/hle/service/dlp/dlp_clnt.h22
-rw-r--r--src/core/hle/service/dlp/dlp_fkcl.cpp20
-rw-r--r--src/core/hle/service/dlp/dlp_fkcl.h22
-rw-r--r--src/core/hle/service/dlp/dlp_srvr.cpp (renamed from src/core/hle/service/dlp_srvr.cpp)22
-rw-r--r--src/core/hle/service/dlp/dlp_srvr.h (renamed from src/core/hle/service/dlp_srvr.h)13
-rw-r--r--src/core/hle/service/gsp_gpu.cpp36
-rw-r--r--src/core/hle/service/hid/hid.cpp70
-rw-r--r--src/core/hle/service/hid/hid.h3
-rw-r--r--src/core/hle/service/service.cpp5
-rw-r--r--src/core/hle/service/srv.cpp136
-rw-r--r--src/core/hle/svc.cpp21
-rw-r--r--src/core/settings.h22
30 files changed, 3309 insertions, 2824 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index ed80cf0e4..02d902bb5 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -5,6 +5,7 @@ set(SRCS
arm/dyncom/arm_dyncom_dec.cpp
arm/dyncom/arm_dyncom_interpreter.cpp
arm/dyncom/arm_dyncom_thumb.cpp
+ arm/dyncom/arm_dyncom_trans.cpp
arm/skyeye_common/armstate.cpp
arm/skyeye_common/armsupp.cpp
arm/skyeye_common/vfp/vfp.cpp
@@ -29,6 +30,7 @@ set(SRCS
hle/applets/mii_selector.cpp
hle/applets/swkbd.cpp
hle/kernel/address_arbiter.cpp
+ hle/kernel/client_port.cpp
hle/kernel/event.cpp
hle/kernel/kernel.cpp
hle/kernel/memory.cpp
@@ -36,6 +38,7 @@ set(SRCS
hle/kernel/process.cpp
hle/kernel/resource_limit.cpp
hle/kernel/semaphore.cpp
+ hle/kernel/server_port.cpp
hle/kernel/session.cpp
hle/kernel/shared_memory.cpp
hle/kernel/thread.cpp
@@ -70,7 +73,10 @@ set(SRCS
hle/service/cfg/cfg_s.cpp
hle/service/cfg/cfg_u.cpp
hle/service/csnd_snd.cpp
- hle/service/dlp_srvr.cpp
+ hle/service/dlp/dlp.cpp
+ hle/service/dlp/dlp_clnt.cpp
+ hle/service/dlp/dlp_fkcl.cpp
+ hle/service/dlp/dlp_srvr.cpp
hle/service/dsp_dsp.cpp
hle/service/err_f.cpp
hle/service/frd/frd.cpp
@@ -137,6 +143,7 @@ set(HEADERS
arm/dyncom/arm_dyncom_interpreter.h
arm/dyncom/arm_dyncom_run.h
arm/dyncom/arm_dyncom_thumb.h
+ arm/dyncom/arm_dyncom_trans.h
arm/skyeye_common/arm_regformat.h
arm/skyeye_common/armstate.h
arm/skyeye_common/armsupp.h
@@ -164,6 +171,7 @@ set(HEADERS
hle/applets/mii_selector.h
hle/applets/swkbd.h
hle/kernel/address_arbiter.h
+ hle/kernel/client_port.h
hle/kernel/event.h
hle/kernel/kernel.h
hle/kernel/memory.h
@@ -171,6 +179,7 @@ set(HEADERS
hle/kernel/process.h
hle/kernel/resource_limit.h
hle/kernel/semaphore.h
+ hle/kernel/server_port.h
hle/kernel/session.h
hle/kernel/shared_memory.h
hle/kernel/thread.h
@@ -206,7 +215,10 @@ set(HEADERS
hle/service/cfg/cfg_s.h
hle/service/cfg/cfg_u.h
hle/service/csnd_snd.h
- hle/service/dlp_srvr.h
+ hle/service/dlp/dlp.h
+ hle/service/dlp/dlp_clnt.h
+ hle/service/dlp/dlp_fkcl.h
+ hle/service/dlp/dlp_srvr.h
hle/service/dsp_dsp.h
hle/service/err_f.h
hle/service/frd/frd.h
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index cfc67287f..01d5d478e 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -17,6 +17,7 @@
#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_trans.h"
#include "core/arm/dyncom/arm_dyncom_run.h"
#include "core/arm/skyeye_common/armstate.h"
#include "core/arm/skyeye_common/armsupp.h"
@@ -24,18 +25,6 @@
#include "core/gdbstub/gdbstub.h"
-enum {
- COND = (1 << 0),
- NON_BRANCH = (1 << 1),
- DIRECT_BRANCH = (1 << 2),
- INDIRECT_BRANCH = (1 << 3),
- CALL = (1 << 4),
- RET = (1 << 5),
- END_OF_PAGE = (1 << 6),
- THUMB = (1 << 7),
- SINGLE_STEP = (1 << 8)
-};
-
#define RM BITS(sht_oper, 0, 3)
#define RS BITS(sht_oper, 8, 11)
@@ -46,8 +35,6 @@ enum {
#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
-typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
-
static bool CondPassed(const ARMul_State* cpu, unsigned int cond) {
const bool n_flag = cpu->NFlag != 0;
const bool z_flag = cpu->ZFlag != 0;
@@ -245,12 +232,6 @@ static unsigned int DPO(RotateRightByRegister)(ARMul_State* cpu, unsigned int sh
return shifter_operand;
}
-typedef void (*get_addr_fp_t)(ARMul_State *cpu, unsigned int inst, unsigned int &virt_addr);
-
-struct ldst_inst {
- unsigned int inst;
- get_addr_fp_t get_addr;
-};
#define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0)
#define LnSWoUB(s) glue(LnSWoUB, s)
@@ -668,479 +649,7 @@ static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst, u
virt_addr = addr;
}
-struct arm_inst {
- unsigned int idx;
- unsigned int cond;
- int br;
- char component[0];
-};
-
-struct generic_arm_inst {
- u32 Ra;
- u32 Rm;
- u32 Rn;
- u32 Rd;
- u8 op1;
- u8 op2;
-};
-
-struct adc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct add_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct orr_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct and_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct eor_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct bbl_inst {
- unsigned int L;
- int signed_immed_24;
- unsigned int next_addr;
- unsigned int jmp_addr;
-};
-
-struct bx_inst {
- unsigned int Rm;
-};
-
-struct blx_inst {
- union {
- s32 signed_immed_24;
- u32 Rm;
- } val;
- unsigned int inst;
-};
-
-struct clz_inst {
- unsigned int Rm;
- unsigned int Rd;
-};
-
-struct cps_inst {
- unsigned int imod0;
- unsigned int imod1;
- unsigned int mmod;
- unsigned int A, I, F;
- unsigned int mode;
-};
-
-struct clrex_inst {
-};
-
-struct cpy_inst {
- unsigned int Rm;
- unsigned int Rd;
-};
-
-struct bic_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct sub_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct tst_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct cmn_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct teq_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct stm_inst {
- unsigned int inst;
-};
-
-struct bkpt_inst {
- u32 imm;
-};
-
-struct stc_inst {
-};
-
-struct ldc_inst {
-};
-
-struct swi_inst {
- unsigned int num;
-};
-
-struct cmp_inst {
- unsigned int I;
- unsigned int Rn;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct mov_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct mvn_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct rev_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int op1;
- unsigned int op2;
-};
-
-struct rsb_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct rsc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct sbc_inst {
- unsigned int I;
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int shifter_operand;
- shtop_fp_t shtop_func;
-};
-
-struct mul_inst {
- unsigned int S;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
-};
-
-struct smul_inst {
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
- unsigned int x;
- unsigned int y;
-};
-
-struct umull_inst {
- unsigned int S;
- unsigned int RdHi;
- unsigned int RdLo;
- unsigned int Rs;
- unsigned int Rm;
-};
-
-struct smlad_inst {
- unsigned int m;
- unsigned int Rm;
- unsigned int Rd;
- unsigned int Ra;
- unsigned int Rn;
- unsigned int op1;
- unsigned int op2;
-};
-
-struct smla_inst {
- unsigned int x;
- unsigned int y;
- unsigned int Rm;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rn;
-};
-
-struct smlalxy_inst {
- unsigned int x;
- unsigned int y;
- unsigned int RdLo;
- unsigned int RdHi;
- unsigned int Rm;
- unsigned int Rn;
-};
-
-struct ssat_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int imm5;
- unsigned int sat_imm;
- unsigned int shift_type;
-};
-
-struct umaal_inst {
- unsigned int Rn;
- unsigned int Rm;
- unsigned int RdHi;
- unsigned int RdLo;
-};
-
-struct umlal_inst {
- unsigned int S;
- unsigned int Rm;
- unsigned int Rs;
- unsigned int RdHi;
- unsigned int RdLo;
-};
-
-struct smlal_inst {
- unsigned int S;
- unsigned int Rm;
- unsigned int Rs;
- unsigned int RdHi;
- unsigned int RdLo;
-};
-
-struct smlald_inst {
- unsigned int RdLo;
- unsigned int RdHi;
- unsigned int Rm;
- unsigned int Rn;
- unsigned int swap;
- unsigned int op1;
- unsigned int op2;
-};
-
-struct mla_inst {
- unsigned int S;
- unsigned int Rn;
- unsigned int Rd;
- unsigned int Rs;
- unsigned int Rm;
-};
-
-struct mrc_inst {
- unsigned int opcode_1;
- unsigned int opcode_2;
- unsigned int cp_num;
- unsigned int crn;
- unsigned int crm;
- unsigned int Rd;
- unsigned int inst;
-};
-
-struct mcr_inst {
- unsigned int opcode_1;
- unsigned int opcode_2;
- unsigned int cp_num;
- unsigned int crn;
- unsigned int crm;
- unsigned int Rd;
- unsigned int inst;
-};
-
-struct mcrr_inst {
- unsigned int opcode_1;
- unsigned int cp_num;
- unsigned int crm;
- unsigned int rt;
- unsigned int rt2;
-};
-
-struct mrs_inst {
- unsigned int R;
- unsigned int Rd;
-};
-
-struct msr_inst {
- unsigned int field_mask;
- unsigned int R;
- unsigned int inst;
-};
-
-struct pld_inst {
-};
-
-struct sxtb_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct sxtab_inst {
- unsigned int Rd;
- unsigned int Rn;
- unsigned int Rm;
- unsigned rotate;
-};
-
-struct sxtah_inst {
- unsigned int Rd;
- unsigned int Rn;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct sxth_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct uxtab_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int rotate;
- unsigned int Rm;
-};
-
-struct uxtah_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int rotate;
- unsigned int Rm;
-};
-
-struct uxth_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct cdp_inst {
- unsigned int opcode_1;
- unsigned int CRn;
- unsigned int CRd;
- unsigned int cp_num;
- unsigned int opcode_2;
- unsigned int CRm;
- unsigned int inst;
-};
-
-struct uxtb_inst {
- unsigned int Rd;
- unsigned int Rm;
- unsigned int rotate;
-};
-
-struct swp_inst {
- unsigned int Rn;
- unsigned int Rd;
- unsigned int Rm;
-};
-
-struct setend_inst {
- unsigned int set_bigend;
-};
-
-struct b_2_thumb {
- unsigned int imm;
-};
-struct b_cond_thumb {
- unsigned int imm;
- unsigned int cond;
-};
-
-struct bl_1_thumb {
- unsigned int imm;
-};
-struct bl_2_thumb {
- unsigned int imm;
-};
-struct blx_1_thumb {
- unsigned int imm;
- unsigned int instr;
-};
-
-struct pkh_inst {
- unsigned int Rm;
- unsigned int Rn;
- unsigned int Rd;
- unsigned char imm;
-};
-
-typedef arm_inst * ARM_INST_PTR;
-
-#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
-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) {
- LOG_ERROR(Core_ARM11, "inst_buf is full");
- CITRA_IGNORE_EXIT(-1);
- }
- return (void *)&inst_buf[start];
-}
-
-static shtop_fp_t get_shtop(unsigned int inst) {
+shtop_fp_t GetShifterOp(unsigned int inst) {
if (BIT(inst, 25)) {
return DPO(Immediate);
} else if (BITS(inst, 4, 11) == 0) {
@@ -1165,7 +674,7 @@ static shtop_fp_t get_shtop(unsigned int inst) {
return nullptr;
}
-static get_addr_fp_t get_calc_addr_op(unsigned int inst) {
+get_addr_fp_t GetAddressingOp(unsigned int inst) {
if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
return LnSWoUB(ImmediateOffset);
} else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
@@ -1208,2201 +717,21 @@ static get_addr_fp_t get_calc_addr_op(unsigned int inst) {
return nullptr;
}
-#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
- adc_inst *inst_cream = (adc_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
- add_inst *inst_cream = (add_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
- and_inst *inst_cream = (and_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index)
-{
- #define POSBRANCH ((inst & 0x7fffff) << 2)
- #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
-
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
- bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
-
- if (BIT(inst, 24))
- inst_base->br = CALL;
- if (BITS(inst, 28, 31) <= 0xe)
- inst_base->br |= COND;
-
- inst_cream->L = BIT(inst, 24);
- inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
- bic_inst *inst_cream = (bic_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bkpt_inst));
- bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->imm = (BITS(inst, 8, 19) << 4) | BITS(inst, 0, 3);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
- blx_inst *inst_cream = (blx_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
-
- inst_cream->inst = inst;
- if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
- inst_cream->val.Rm = BITS(inst, 0, 3);
- } else {
- inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
- }
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
- bx_inst *inst_cream = (bx_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(bx)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index) {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
- cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->CRm = BITS(inst, 0, 3);
- inst_cream->CRd = BITS(inst, 12, 15);
- inst_cream->CRn = BITS(inst, 16, 19);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->opcode_1 = BITS(inst, 20, 23);
- inst_cream->inst = inst;
-
- LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index);
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
- clz_inst *inst_cream = (clz_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
- cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
- cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
- cps_inst *inst_cream = (cps_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->imod0 = BIT(inst, 18);
- inst_cream->imod1 = BIT(inst, 19);
- inst_cream->mmod = BIT(inst, 17);
- inst_cream->A = BIT(inst, 8);
- inst_cream->I = BIT(inst, 7);
- inst_cream->F = BIT(inst, 6);
- inst_cream->mode = BITS(inst, 0, 4);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
- mov_inst *inst_cream = (mov_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
- eor_inst *inst_cream = (eor_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- if (BIT(inst, 15)) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
- sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->rotate = BITS(inst, 10, 11);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- if (BITS(inst, 12, 15) == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- if (BITS(inst, 12, 15) == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
- uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
- uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
-{
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- if (BITS(inst, 25, 27) == 2) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 25, 27) == 3) {
- inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed);
- } else {
- DEBUG_MSG;
- }
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = (BITS(inst, 12, 15) == 15) ? INDIRECT_BRANCH : NON_BRANCH; // Branch if dest is R15
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(ldrex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
-{
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
+// Specialized for LDRT, LDRBT, STRT, and STRBT, which have specific addressing mode requirements
+get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst) {
if (BITS(inst, 25, 27) == 2) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 25, 27) == 3) {
- inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed);
- } else {
- // Reaching this would indicate the thumb version
- // of this instruction, however the 3DS CPU doesn't
- // support this variant (the 3DS CPU is only ARMv6K,
- // while this variant is added in ARMv6T2).
- // So it's sufficient for citra to not implement this.
- DEBUG_MSG;
- }
-
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
- mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->crn = BITS(inst, 16, 19);
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 21, 23);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->inst = inst;
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mcrr_inst));
- mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 4, 7);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->rt = BITS(inst, 12, 15);
- inst_cream->rt2 = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
- mla_inst *inst_cream = (mla_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 12, 15);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
- mov_inst *inst_cream = (mov_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
- mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->crn = BITS(inst, 16, 19);
- inst_cream->crm = BITS(inst, 0, 3);
- inst_cream->opcode_1 = BITS(inst, 21, 23);
- inst_cream->opcode_2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->cp_num = BITS(inst, 8, 11);
- inst_cream->inst = inst;
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(mcrr)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
- mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->R = BIT(inst, 22);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
- msr_inst *inst_cream = (msr_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->field_mask = BITS(inst, 16, 19);
- inst_cream->R = BIT(inst, 22);
- inst_cream->inst = inst;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
- mul_inst *inst_cream = (mul_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
- mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
-
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
- orr_inst *inst_cream = (orr_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-
-// NOP introduced in ARMv6K.
-static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
- pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->imm = BITS(inst, 7, 11);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 21, 22);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(qadd)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(qadd8)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
- rev_inst* const inst_cream = (rev_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(rev)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(rev)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
- rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
- rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(sadd8)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
- sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(setend_inst));
- setend_inst* const inst_cream = (setend_inst*)inst_base->component;
-
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->set_bigend = BIT(inst, 9);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(shadd8)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
- smla_inst *inst_cream = (smla_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rn = BITS(inst, 12, 15);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->m = BIT(inst, 5);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(smlad)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
- umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlalxy_inst));
- smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->Rn = BITS(inst, 0, 4);
- inst_cream->Rm = BITS(inst, 8, 11);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->m = BIT(inst, 6);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlald_inst));
- smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->swap = BIT(inst, 5);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(smlald)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->m = BIT(inst, 5);
- inst_cream->Ra = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->op1 = BITS(inst, 20, 22);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(smmla)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(smmla)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
- smul_inst *inst_cream = (smul_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- inst_cream->x = BIT(inst, 5);
- inst_cream->y = BIT(inst, 6);
-
- return inst_base;
-
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
- umull_inst *inst_cream = (umull_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->m = BIT(inst, 6);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = AL;
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->imm5 = BITS(inst, 7, 11);
- inst_cream->sat_imm = BITS(inst, 16, 20);
- inst_cream->shift_type = BIT(inst, 6);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
- ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->sat_imm = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
- sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->rotate = BITS(inst, 10, 11);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
- uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
- uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
-{
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
-
- if (BITS(inst, 25, 27) == 2) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
- } else if (BITS(inst, 25, 27) == 3) {
- inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed);
- } else {
- DEBUG_MSG;
- }
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(strex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(strex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(strex)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
-{
- arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- if (BITS(inst, 25, 27) == 2) {
- inst_cream->get_addr = LnSWoUB(ImmediatePostIndexed);
+ return LnSWoUB(ImmediatePostIndexed);
} else if (BITS(inst, 25, 27) == 3) {
- inst_cream->get_addr = LnSWoUB(ScaledRegisterPostIndexed);
- } else {
- // Reaching this would indicate the thumb version
- // of this instruction, however the 3DS CPU doesn't
- // support this variant (the 3DS CPU is only ARMv6K,
- // while this variant is added in ARMv6T2).
- // So it's sufficient for citra to not implement this.
- DEBUG_MSG;
+ return LnSWoUB(ScaledRegisterPostIndexed);
}
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
- sub_inst *inst_cream = (sub_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- if (inst_cream->Rd == 15)
- inst_base->br = INDIRECT_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
- swi_inst *inst_cream = (swi_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->num = BITS(inst, 0, 23);
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
- swp_inst *inst_cream = (swp_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
- swp_inst *inst_cream = (swp_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->Rm = BITS(inst, 0, 3);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
- sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
- sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(sxtab16)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index) {
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
- sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
- teq_inst *inst_cream = (teq_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
- tst_inst *inst_cream = (tst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->I = BIT(inst, 25);
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->shifter_operand = BITS(inst, 0, 11);
- inst_cream->shtop_func = get_shtop(inst);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uadd8)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst));
- umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->RdLo = BITS(inst, 12, 15);
- inst_cream->RdHi = BITS(inst, 16, 19);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
- umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
- umull_inst *inst_cream = (umull_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->S = BIT(inst, 20);
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rs = BITS(inst, 8, 11);
- inst_cream->RdHi = BITS(inst, 16, 19);
- inst_cream->RdLo = BITS(inst, 12, 15);
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
- b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
-
- inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
-
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
- b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
-
- inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
- inst_cream->cond = ((tinst >> 8) & 0xf);
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
-
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
- bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
-
- inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
-
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
- bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
-
- inst_cream->imm = (tinst & 0x07FF) << 1;
-
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
-{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
- blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
-
- inst_cream->imm = (tinst & 0x07FF) << 1;
- inst_cream->instr = tinst;
-
- inst_base->idx = index;
- inst_base->br = DIRECT_BRANCH;
- return inst_base;
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->op1 = BITS(inst, 20, 21);
- inst_cream->op2 = BITS(inst, 5, 7);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
- generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->op1 = BITS(inst, 20, 24);
- inst_cream->op2 = BITS(inst, 5, 7);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Ra = BITS(inst, 12, 15);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(usada8)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(ssat)(inst, index);
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(ssat16)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
- uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->Rm = BITS(inst, 0, 3);
- inst_cream->Rn = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->rotate = BITS(inst, 10, 11);
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
-}
-
-static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
-}
-static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index)
-{
- arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- return inst_base;
+ // Reaching this would indicate the thumb version
+ // of this instruction, however the 3DS CPU doesn't
+ // support this variant (the 3DS CPU is only ARMv6K,
+ // while this variant is added in ARMv6T2).
+ // So it's sufficient for citra to not implement this.
+ return nullptr;
}
-// Floating point VFPv3 structures and instructions
-
-#define VFP_INTERPRETER_STRUCT
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_INTERPRETER_STRUCT
-
-#define VFP_INTERPRETER_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_INTERPRETER_TRANS
-
-typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
-
-const transop_fp_t arm_instruction_trans[] = {
- INTERPRETER_TRANSLATE(vmla),
- INTERPRETER_TRANSLATE(vmls),
- INTERPRETER_TRANSLATE(vnmla),
- INTERPRETER_TRANSLATE(vnmls),
- INTERPRETER_TRANSLATE(vnmul),
- INTERPRETER_TRANSLATE(vmul),
- INTERPRETER_TRANSLATE(vadd),
- INTERPRETER_TRANSLATE(vsub),
- INTERPRETER_TRANSLATE(vdiv),
- INTERPRETER_TRANSLATE(vmovi),
- INTERPRETER_TRANSLATE(vmovr),
- INTERPRETER_TRANSLATE(vabs),
- INTERPRETER_TRANSLATE(vneg),
- INTERPRETER_TRANSLATE(vsqrt),
- INTERPRETER_TRANSLATE(vcmp),
- INTERPRETER_TRANSLATE(vcmp2),
- INTERPRETER_TRANSLATE(vcvtbds),
- INTERPRETER_TRANSLATE(vcvtbff),
- INTERPRETER_TRANSLATE(vcvtbfi),
- INTERPRETER_TRANSLATE(vmovbrs),
- INTERPRETER_TRANSLATE(vmsr),
- INTERPRETER_TRANSLATE(vmovbrc),
- INTERPRETER_TRANSLATE(vmrs),
- INTERPRETER_TRANSLATE(vmovbcr),
- INTERPRETER_TRANSLATE(vmovbrrss),
- INTERPRETER_TRANSLATE(vmovbrrd),
- INTERPRETER_TRANSLATE(vstr),
- INTERPRETER_TRANSLATE(vpush),
- INTERPRETER_TRANSLATE(vstm),
- INTERPRETER_TRANSLATE(vpop),
- INTERPRETER_TRANSLATE(vldr),
- INTERPRETER_TRANSLATE(vldm),
-
- INTERPRETER_TRANSLATE(srs),
- INTERPRETER_TRANSLATE(rfe),
- INTERPRETER_TRANSLATE(bkpt),
- INTERPRETER_TRANSLATE(blx),
- INTERPRETER_TRANSLATE(cps),
- INTERPRETER_TRANSLATE(pld),
- INTERPRETER_TRANSLATE(setend),
- INTERPRETER_TRANSLATE(clrex),
- INTERPRETER_TRANSLATE(rev16),
- INTERPRETER_TRANSLATE(usad8),
- INTERPRETER_TRANSLATE(sxtb),
- INTERPRETER_TRANSLATE(uxtb),
- INTERPRETER_TRANSLATE(sxth),
- INTERPRETER_TRANSLATE(sxtb16),
- INTERPRETER_TRANSLATE(uxth),
- INTERPRETER_TRANSLATE(uxtb16),
- INTERPRETER_TRANSLATE(cpy),
- INTERPRETER_TRANSLATE(uxtab),
- INTERPRETER_TRANSLATE(ssub8),
- INTERPRETER_TRANSLATE(shsub8),
- INTERPRETER_TRANSLATE(ssubaddx),
- INTERPRETER_TRANSLATE(strex),
- INTERPRETER_TRANSLATE(strexb),
- INTERPRETER_TRANSLATE(swp),
- INTERPRETER_TRANSLATE(swpb),
- INTERPRETER_TRANSLATE(ssub16),
- INTERPRETER_TRANSLATE(ssat16),
- INTERPRETER_TRANSLATE(shsubaddx),
- INTERPRETER_TRANSLATE(qsubaddx),
- INTERPRETER_TRANSLATE(shaddsubx),
- INTERPRETER_TRANSLATE(shadd8),
- INTERPRETER_TRANSLATE(shadd16),
- INTERPRETER_TRANSLATE(sel),
- INTERPRETER_TRANSLATE(saddsubx),
- INTERPRETER_TRANSLATE(sadd8),
- INTERPRETER_TRANSLATE(sadd16),
- INTERPRETER_TRANSLATE(shsub16),
- INTERPRETER_TRANSLATE(umaal),
- INTERPRETER_TRANSLATE(uxtab16),
- INTERPRETER_TRANSLATE(usubaddx),
- INTERPRETER_TRANSLATE(usub8),
- INTERPRETER_TRANSLATE(usub16),
- INTERPRETER_TRANSLATE(usat16),
- INTERPRETER_TRANSLATE(usada8),
- INTERPRETER_TRANSLATE(uqsubaddx),
- INTERPRETER_TRANSLATE(uqsub8),
- INTERPRETER_TRANSLATE(uqsub16),
- INTERPRETER_TRANSLATE(uqaddsubx),
- INTERPRETER_TRANSLATE(uqadd8),
- INTERPRETER_TRANSLATE(uqadd16),
- INTERPRETER_TRANSLATE(sxtab),
- INTERPRETER_TRANSLATE(uhsubaddx),
- INTERPRETER_TRANSLATE(uhsub8),
- INTERPRETER_TRANSLATE(uhsub16),
- INTERPRETER_TRANSLATE(uhaddsubx),
- INTERPRETER_TRANSLATE(uhadd8),
- INTERPRETER_TRANSLATE(uhadd16),
- INTERPRETER_TRANSLATE(uaddsubx),
- INTERPRETER_TRANSLATE(uadd8),
- INTERPRETER_TRANSLATE(uadd16),
- INTERPRETER_TRANSLATE(sxtah),
- INTERPRETER_TRANSLATE(sxtab16),
- INTERPRETER_TRANSLATE(qadd8),
- INTERPRETER_TRANSLATE(bxj),
- INTERPRETER_TRANSLATE(clz),
- INTERPRETER_TRANSLATE(uxtah),
- INTERPRETER_TRANSLATE(bx),
- INTERPRETER_TRANSLATE(rev),
- INTERPRETER_TRANSLATE(blx),
- INTERPRETER_TRANSLATE(revsh),
- INTERPRETER_TRANSLATE(qadd),
- INTERPRETER_TRANSLATE(qadd16),
- INTERPRETER_TRANSLATE(qaddsubx),
- INTERPRETER_TRANSLATE(ldrex),
- INTERPRETER_TRANSLATE(qdadd),
- INTERPRETER_TRANSLATE(qdsub),
- INTERPRETER_TRANSLATE(qsub),
- INTERPRETER_TRANSLATE(ldrexb),
- INTERPRETER_TRANSLATE(qsub8),
- INTERPRETER_TRANSLATE(qsub16),
- INTERPRETER_TRANSLATE(smuad),
- INTERPRETER_TRANSLATE(smmul),
- INTERPRETER_TRANSLATE(smusd),
- INTERPRETER_TRANSLATE(smlsd),
- INTERPRETER_TRANSLATE(smlsld),
- INTERPRETER_TRANSLATE(smmla),
- INTERPRETER_TRANSLATE(smmls),
- INTERPRETER_TRANSLATE(smlald),
- INTERPRETER_TRANSLATE(smlad),
- INTERPRETER_TRANSLATE(smlaw),
- INTERPRETER_TRANSLATE(smulw),
- INTERPRETER_TRANSLATE(pkhtb),
- INTERPRETER_TRANSLATE(pkhbt),
- INTERPRETER_TRANSLATE(smul),
- INTERPRETER_TRANSLATE(smlalxy),
- INTERPRETER_TRANSLATE(smla),
- INTERPRETER_TRANSLATE(mcrr),
- INTERPRETER_TRANSLATE(mrrc),
- INTERPRETER_TRANSLATE(cmp),
- INTERPRETER_TRANSLATE(tst),
- INTERPRETER_TRANSLATE(teq),
- INTERPRETER_TRANSLATE(cmn),
- INTERPRETER_TRANSLATE(smull),
- INTERPRETER_TRANSLATE(umull),
- INTERPRETER_TRANSLATE(umlal),
- INTERPRETER_TRANSLATE(smlal),
- INTERPRETER_TRANSLATE(mul),
- INTERPRETER_TRANSLATE(mla),
- INTERPRETER_TRANSLATE(ssat),
- INTERPRETER_TRANSLATE(usat),
- INTERPRETER_TRANSLATE(mrs),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(and),
- INTERPRETER_TRANSLATE(bic),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(eor),
- INTERPRETER_TRANSLATE(add),
- INTERPRETER_TRANSLATE(rsb),
- INTERPRETER_TRANSLATE(rsc),
- INTERPRETER_TRANSLATE(sbc),
- INTERPRETER_TRANSLATE(adc),
- INTERPRETER_TRANSLATE(sub),
- INTERPRETER_TRANSLATE(orr),
- INTERPRETER_TRANSLATE(mvn),
- INTERPRETER_TRANSLATE(mov),
- INTERPRETER_TRANSLATE(stm),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(ldrsh),
- INTERPRETER_TRANSLATE(stm),
- INTERPRETER_TRANSLATE(ldm),
- INTERPRETER_TRANSLATE(ldrsb),
- INTERPRETER_TRANSLATE(strd),
- INTERPRETER_TRANSLATE(ldrh),
- INTERPRETER_TRANSLATE(strh),
- INTERPRETER_TRANSLATE(ldrd),
- INTERPRETER_TRANSLATE(strt),
- INTERPRETER_TRANSLATE(strbt),
- INTERPRETER_TRANSLATE(ldrbt),
- INTERPRETER_TRANSLATE(ldrt),
- INTERPRETER_TRANSLATE(mrc),
- INTERPRETER_TRANSLATE(mcr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(msr),
- INTERPRETER_TRANSLATE(ldrb),
- INTERPRETER_TRANSLATE(strb),
- INTERPRETER_TRANSLATE(ldr),
- INTERPRETER_TRANSLATE(ldrcond),
- INTERPRETER_TRANSLATE(str),
- INTERPRETER_TRANSLATE(cdp),
- INTERPRETER_TRANSLATE(stc),
- INTERPRETER_TRANSLATE(ldc),
- INTERPRETER_TRANSLATE(ldrexd),
- INTERPRETER_TRANSLATE(strexd),
- INTERPRETER_TRANSLATE(ldrexh),
- INTERPRETER_TRANSLATE(strexh),
- INTERPRETER_TRANSLATE(nop),
- INTERPRETER_TRANSLATE(yield),
- INTERPRETER_TRANSLATE(wfe),
- INTERPRETER_TRANSLATE(wfi),
- INTERPRETER_TRANSLATE(sev),
- INTERPRETER_TRANSLATE(swi),
- INTERPRETER_TRANSLATE(bbl),
-
- // All the thumb instructions should be placed the end of table
- INTERPRETER_TRANSLATE(b_2_thumb),
- INTERPRETER_TRANSLATE(b_cond_thumb),
- INTERPRETER_TRANSLATE(bl_1_thumb),
- INTERPRETER_TRANSLATE(bl_2_thumb),
- INTERPRETER_TRANSLATE(blx_1_thumb)
-};
-
enum {
FETCH_SUCCESS,
FETCH_FAILURE
@@ -3413,7 +742,7 @@ static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_ins
ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
if (ret == ThumbDecodeStatus::BRANCH) {
int inst_index;
- int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
+ int table_length = arm_instruction_trans_len;
u32 tinstr = GetThumbInstruction(inst, addr);
switch ((tinstr & 0xF800) >> 11) {
@@ -3499,14 +828,14 @@ static int InterpreterTranslateBlock(ARMul_State* cpu, int& bb_start, u32 addr)
// Go on next, until terminal instruction
// Save start addr of basicblock in CreamCache
ARM_INST_PTR inst_base = nullptr;
- int ret = NON_BRANCH;
+ TransExtData ret = TransExtData::NON_BRANCH;
int size = 0; // instruction size of basic block
- bb_start = top;
+ bb_start = trans_cache_buf_top;
u32 phys_addr = addr;
u32 pc_start = cpu->Reg[15];
- while (ret == NON_BRANCH) {
+ while (ret == TransExtData::NON_BRANCH) {
unsigned int inst_size = InterpreterTranslateInstruction(cpu, phys_addr, inst_base);
size++;
@@ -3514,7 +843,7 @@ static int InterpreterTranslateBlock(ARMul_State* cpu, int& bb_start, u32 addr)
phys_addr += inst_size;
if ((phys_addr & 0xfff) == 0) {
- inst_base->br = END_OF_PAGE;
+ inst_base->br = TransExtData::END_OF_PAGE;
}
ret = inst_base->br;
};
@@ -3528,15 +857,15 @@ static int InterpreterTranslateSingle(ARMul_State* cpu, int& bb_start, u32 addr)
MICROPROFILE_SCOPE(DynCom_Decode);
ARM_INST_PTR inst_base = nullptr;
- bb_start = top;
+ bb_start = trans_cache_buf_top;
u32 phys_addr = addr;
u32 pc_start = cpu->Reg[15];
InterpreterTranslateInstruction(cpu, phys_addr, inst_base);
- if (inst_base->br == NON_BRANCH) {
- inst_base->br = SINGLE_STEP;
+ if (inst_base->br == TransExtData::NON_BRANCH) {
+ inst_base->br = TransExtData::SINGLE_STEP;
}
cpu->instruction_cache[pc_start] = bb_start;
@@ -3581,8 +910,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
#define SET_PC (cpu->Reg[15] = cpu->Reg[15] + 8 + inst_cream->signed_immed_24)
#define SHIFTER_OPERAND inst_cream->shtop_func(cpu, inst_cream->shifter_operand)
- #define FETCH_INST if (inst_base->br != NON_BRANCH) goto DISPATCH; \
- inst_base = (arm_inst *)&inst_buf[ptr]
+ #define FETCH_INST if (inst_base->br != TransExtData::NON_BRANCH) goto DISPATCH; \
+ inst_base = (arm_inst *)&trans_cache_buf[ptr]
#define INC_PC(l) ptr += sizeof(arm_inst) + l
#define INC_PC_STUB ptr += sizeof(arm_inst)
@@ -3905,7 +1234,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
breakpoint_data = GDBStub::GetNextBreakpointFromAddress(cpu->Reg[15], GDBStub::BreakpointType::Execute);
}
- inst_base = (arm_inst *)&inst_buf[ptr];
+ inst_base = (arm_inst *)&trans_cache_buf[ptr];
GOTO_NEXT_INST;
}
ADC_INST:
diff --git a/src/core/arm/dyncom/arm_dyncom_trans.cpp b/src/core/arm/dyncom/arm_dyncom_trans.cpp
new file mode 100644
index 000000000..00b42c246
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_trans.cpp
@@ -0,0 +1,2178 @@
+#include <cstdlib>
+
+#include "common/assert.h"
+#include "common/common_types.h"
+
+#include "core/arm/dyncom/arm_dyncom_interpreter.h"
+#include "core/arm/dyncom/arm_dyncom_trans.h"
+#include "core/arm/skyeye_common/armstate.h"
+#include "core/arm/skyeye_common/armsupp.h"
+#include "core/arm/skyeye_common/vfp/vfp.h"
+
+char trans_cache_buf[TRANS_CACHE_SIZE];
+size_t trans_cache_buf_top = 0;
+
+static void* AllocBuffer(size_t size) {
+ size_t start = trans_cache_buf_top;
+ trans_cache_buf_top += size;
+ ASSERT_MSG(trans_cache_buf_top <= TRANS_CACHE_SIZE, "Translation cache is full!");
+ return static_cast<void*>(&trans_cache_buf[start]);
+}
+
+#define glue(x, y) x ## y
+#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
+
+shtop_fp_t GetShifterOp(unsigned int inst);
+get_addr_fp_t GetAddressingOp(unsigned int inst);
+get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst);
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
+ adc_inst *inst_cream = (adc_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(add)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(add_inst));
+ add_inst *inst_cream = (add_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(and)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(and_inst));
+ and_inst *inst_cream = (and_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(bbl)(unsigned int inst, int index)
+{
+ #define POSBRANCH ((inst & 0x7fffff) << 2)
+ #define NEGBRANCH ((0xff000000 |(inst & 0xffffff)) << 2)
+
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bbl_inst));
+ bbl_inst *inst_cream = (bbl_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::DIRECT_BRANCH;
+
+ if (BIT(inst, 24))
+ inst_base->br = TransExtData::CALL;
+
+ inst_cream->L = BIT(inst, 24);
+ inst_cream->signed_immed_24 = BIT(inst, 23) ? NEGBRANCH : POSBRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(bic)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bic_inst));
+ bic_inst *inst_cream = (bic_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(bkpt)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(bkpt_inst));
+ bkpt_inst* const inst_cream = (bkpt_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->imm = (BITS(inst, 8, 19) << 4) | BITS(inst, 0, 3);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(blx)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_inst));
+ blx_inst *inst_cream = (blx_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ inst_cream->inst = inst;
+ if (BITS(inst, 20, 27) == 0x12 && BITS(inst, 4, 7) == 0x3) {
+ inst_cream->val.Rm = BITS(inst, 0, 3);
+ } else {
+ inst_cream->val.signed_immed_24 = BITS(inst, 0, 23);
+ }
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
+ bx_inst *inst_cream = (bx_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(bx)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index) {
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
+ cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->CRm = BITS(inst, 0, 3);
+ inst_cream->CRd = BITS(inst, 12, 15);
+ inst_cream->CRn = BITS(inst, 16, 19);
+ inst_cream->cp_num = BITS(inst, 8, 11);
+ inst_cream->opcode_2 = BITS(inst, 5, 7);
+ inst_cream->opcode_1 = BITS(inst, 20, 23);
+ inst_cream->inst = inst;
+
+ LOG_TRACE(Core_ARM11, "inst %x index %x", inst, index);
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(clrex)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clrex_inst));
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(clz)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(clz_inst));
+ clz_inst *inst_cream = (clz_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(cmn)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmn_inst));
+ cmn_inst *inst_cream = (cmn_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(cmp)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cmp_inst));
+ cmp_inst *inst_cream = (cmp_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(cps)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cps_inst));
+ cps_inst *inst_cream = (cps_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->imod0 = BIT(inst, 18);
+ inst_cream->imod1 = BIT(inst, 19);
+ inst_cream->mmod = BIT(inst, 17);
+ inst_cream->A = BIT(inst, 8);
+ inst_cream->I = BIT(inst, 7);
+ inst_cream->F = BIT(inst, 6);
+ inst_cream->mode = BITS(inst, 0, 4);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(cpy)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
+ mov_inst *inst_cream = (mov_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15) {
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+ }
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(eor)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(eor_inst));
+ eor_inst *inst_cream = (eor_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldc)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldc_inst));
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldm)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ if (BIT(inst, 15)) {
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+ }
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sxth)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
+ sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->rotate = BITS(inst, 10, 11);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldr)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ if (BITS(inst, 12, 15) == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrcond)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ if (BITS(inst, 12, 15) == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uxth)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
+ uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtah)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtah_inst));
+ uxtah_inst *inst_cream = (uxtah_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrb)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrbt)(unsigned int inst, int index)
+{
+ arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOpLoadStoreT(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = (BITS(inst, 12, 15) == 15) ? TransExtData::INDIRECT_BRANCH : TransExtData::NON_BRANCH; // Branch if dest is R15
+
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(ldrex)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(ldrex)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(ldrex)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsb)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrsh)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ldrt)(unsigned int inst, int index)
+{
+ arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOpLoadStoreT(inst);
+
+ if (BITS(inst, 12, 15) == 15) {
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+ }
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mcr)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mcr_inst));
+ mcr_inst *inst_cream = (mcr_inst *)inst_base->component;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->crn = BITS(inst, 16, 19);
+ inst_cream->crm = BITS(inst, 0, 3);
+ inst_cream->opcode_1 = BITS(inst, 21, 23);
+ inst_cream->opcode_2 = BITS(inst, 5, 7);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->cp_num = BITS(inst, 8, 11);
+ inst_cream->inst = inst;
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mcrr)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(mcrr_inst));
+ mcrr_inst* const inst_cream = (mcrr_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->crm = BITS(inst, 0, 3);
+ inst_cream->opcode_1 = BITS(inst, 4, 7);
+ inst_cream->cp_num = BITS(inst, 8, 11);
+ inst_cream->rt = BITS(inst, 12, 15);
+ inst_cream->rt2 = BITS(inst, 16, 19);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mla)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mla_inst));
+ mla_inst *inst_cream = (mla_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 12, 15);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mov)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mov_inst));
+ mov_inst *inst_cream = (mov_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15) {
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+ }
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mrc)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrc_inst));
+ mrc_inst *inst_cream = (mrc_inst *)inst_base->component;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->crn = BITS(inst, 16, 19);
+ inst_cream->crm = BITS(inst, 0, 3);
+ inst_cream->opcode_1 = BITS(inst, 21, 23);
+ inst_cream->opcode_2 = BITS(inst, 5, 7);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->cp_num = BITS(inst, 8, 11);
+ inst_cream->inst = inst;
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mrrc)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(mcrr)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mrs)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mrs_inst));
+ mrs_inst *inst_cream = (mrs_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->R = BIT(inst, 22);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(msr)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(msr_inst));
+ msr_inst *inst_cream = (msr_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->field_mask = BITS(inst, 16, 19);
+ inst_cream->R = BIT(inst, 22);
+ inst_cream->inst = inst;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mul)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mul_inst));
+ mul_inst *inst_cream = (mul_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->Rd = BITS(inst, 16, 19);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(mvn)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(mvn_inst));
+ mvn_inst *inst_cream = (mvn_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15) {
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+ }
+ return inst_base;
+
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(orr_inst));
+ orr_inst *inst_cream = (orr_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+
+// NOP introduced in ARMv6K.
+static ARM_INST_PTR INTERPRETER_TRANSLATE(nop)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pkh_inst));
+ pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->imm = BITS(inst, 7, 11);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->op1 = BITS(inst, 21, 22);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qsub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd8)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
+ rev_inst* const inst_cream = (rev_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(rev)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(rev)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
+
+ inst_base->cond = AL;
+ inst_base->idx = index;
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsb_inst));
+ rsb_inst *inst_cream = (rsb_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rsc_inst));
+ rsc_inst *inst_cream = (rsc_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
+ sbc_inst *inst_cream = (sbc_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(setend_inst));
+ setend_inst* const inst_cream = (setend_inst*)inst_base->component;
+
+ inst_base->cond = AL;
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->set_bigend = BIT(inst, 9);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sev)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
+ smla_inst *inst_cream = (smla_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->x = BIT(inst, 5);
+ inst_cream->y = BIT(inst, 6);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Rn = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->m = BIT(inst, 5);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smlad)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smlad)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smlad)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
+ umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlalxy_inst));
+ smlalxy_inst* const inst_cream = (smlalxy_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->x = BIT(inst, 5);
+ inst_cream->y = BIT(inst, 6);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->Rn = BITS(inst, 0, 4);
+ inst_cream->Rm = BITS(inst, 8, 11);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->m = BIT(inst, 6);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlald_inst));
+ smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->swap = BIT(inst, 5);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smlald)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->m = BIT(inst, 5);
+ inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smmla)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smmla)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
+ smul_inst *inst_cream = (smul_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ inst_cream->x = BIT(inst, 5);
+ inst_cream->y = BIT(inst, 6);
+
+ return inst_base;
+
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smull)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
+ umull_inst *inst_cream = (umull_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->m = BIT(inst, 6);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 16, 19);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst* const inst_cream = (ldst_inst*)inst_base->component;
+
+ inst_base->cond = AL;
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
+ ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->imm5 = BITS(inst, 7, 11);
+ inst_cream->sat_imm = BITS(inst, 16, 20);
+ inst_cream->shift_type = BIT(inst, 6);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ssat_inst));
+ ssat_inst* const inst_cream = (ssat_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->sat_imm = BITS(inst, 16, 19);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(stm)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtb_inst));
+ sxtb_inst *inst_cream = (sxtb_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->rotate = BITS(inst, 10, 11);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(str)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxth_inst));
+ uxth_inst *inst_cream = (uxth_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
+ uxtab_inst *inst_cream = (uxtab_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strb)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strbt)(unsigned int inst, int index)
+{
+ arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOpLoadStoreT(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(strex)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(strex)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(strex)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(strt)(unsigned int inst, int index)
+{
+ arm_inst* inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
+ ldst_inst* inst_cream = (ldst_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->inst = inst;
+ inst_cream->get_addr = GetAddressingOpLoadStoreT(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sub)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sub_inst));
+ sub_inst *inst_cream = (sub_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ if (inst_cream->Rd == 15)
+ inst_base->br = TransExtData::INDIRECT_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(swi)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swi_inst));
+ swi_inst *inst_cream = (swi_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->num = BITS(inst, 0, 23);
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(swp)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
+ swp_inst *inst_cream = (swp_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(swpb)(unsigned int inst, int index){
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(swp_inst));
+ swp_inst *inst_cream = (swp_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
+ sxtab_inst *inst_cream = (sxtab_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
+ sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sxtab16)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index) {
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
+ sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
+ teq_inst *inst_cream = (teq_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(tst_inst));
+ tst_inst *inst_cream = (tst_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->I = BIT(inst, 25);
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->shifter_operand = BITS(inst, 0, 11);
+ inst_cream->shtop_func = GetShifterOp(inst);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uadd8)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(umaal)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(umaal_inst));
+ umaal_inst* const inst_cream = (umaal_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(umlal)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
+ umlal_inst *inst_cream = (umlal_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(umull)(unsigned int inst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umull_inst));
+ umull_inst *inst_cream = (umull_inst *)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->S = BIT(inst, 20);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rs = BITS(inst, 8, 11);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(b_2_thumb)(unsigned int tinst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_2_thumb));
+ b_2_thumb *inst_cream = (b_2_thumb *)inst_base->component;
+
+ inst_cream->imm = ((tinst & 0x3FF) << 1) | ((tinst & (1 << 10)) ? 0xFFFFF800 : 0);
+
+ inst_base->idx = index;
+ inst_base->br = TransExtData::DIRECT_BRANCH;
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(b_cond_thumb)(unsigned int tinst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(b_cond_thumb));
+ b_cond_thumb *inst_cream = (b_cond_thumb *)inst_base->component;
+
+ inst_cream->imm = (((tinst & 0x7F) << 1) | ((tinst & (1 << 7)) ? 0xFFFFFF00 : 0));
+ inst_cream->cond = ((tinst >> 8) & 0xf);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::DIRECT_BRANCH;
+
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_1_thumb)(unsigned int tinst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_1_thumb));
+ bl_1_thumb *inst_cream = (bl_1_thumb *)inst_base->component;
+
+ inst_cream->imm = (((tinst & 0x07FF) << 12) | ((tinst & (1 << 10)) ? 0xFF800000 : 0));
+
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(bl_2_thumb)(unsigned int tinst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bl_2_thumb));
+ bl_2_thumb *inst_cream = (bl_2_thumb *)inst_base->component;
+
+ inst_cream->imm = (tinst & 0x07FF) << 1;
+
+ inst_base->idx = index;
+ inst_base->br = TransExtData::DIRECT_BRANCH;
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
+{
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(blx_1_thumb));
+ blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
+
+ inst_cream->imm = (tinst & 0x07FF) << 1;
+ inst_cream->instr = tinst;
+
+ inst_base->idx = index;
+ inst_base->br = TransExtData::DIRECT_BRANCH;
+ return inst_base;
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 21);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->op1 = BITS(inst, 20, 24);
+ inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Ra = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(usada8)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(ssat)(inst, index);
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(ssat16)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
+ uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->rotate = BITS(inst, 10, 11);
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
+}
+
+static ARM_INST_PTR INTERPRETER_TRANSLATE(wfe)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(wfi)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst));
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = TransExtData::NON_BRANCH;
+
+ return inst_base;
+}
+
+// Floating point VFPv3 instructions
+#define VFP_INTERPRETER_TRANS
+#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+#undef VFP_INTERPRETER_TRANS
+
+const transop_fp_t arm_instruction_trans[] = {
+ INTERPRETER_TRANSLATE(vmla),
+ INTERPRETER_TRANSLATE(vmls),
+ INTERPRETER_TRANSLATE(vnmla),
+ INTERPRETER_TRANSLATE(vnmls),
+ INTERPRETER_TRANSLATE(vnmul),
+ INTERPRETER_TRANSLATE(vmul),
+ INTERPRETER_TRANSLATE(vadd),
+ INTERPRETER_TRANSLATE(vsub),
+ INTERPRETER_TRANSLATE(vdiv),
+ INTERPRETER_TRANSLATE(vmovi),
+ INTERPRETER_TRANSLATE(vmovr),
+ INTERPRETER_TRANSLATE(vabs),
+ INTERPRETER_TRANSLATE(vneg),
+ INTERPRETER_TRANSLATE(vsqrt),
+ INTERPRETER_TRANSLATE(vcmp),
+ INTERPRETER_TRANSLATE(vcmp2),
+ INTERPRETER_TRANSLATE(vcvtbds),
+ INTERPRETER_TRANSLATE(vcvtbff),
+ INTERPRETER_TRANSLATE(vcvtbfi),
+ INTERPRETER_TRANSLATE(vmovbrs),
+ INTERPRETER_TRANSLATE(vmsr),
+ INTERPRETER_TRANSLATE(vmovbrc),
+ INTERPRETER_TRANSLATE(vmrs),
+ INTERPRETER_TRANSLATE(vmovbcr),
+ INTERPRETER_TRANSLATE(vmovbrrss),
+ INTERPRETER_TRANSLATE(vmovbrrd),
+ INTERPRETER_TRANSLATE(vstr),
+ INTERPRETER_TRANSLATE(vpush),
+ INTERPRETER_TRANSLATE(vstm),
+ INTERPRETER_TRANSLATE(vpop),
+ INTERPRETER_TRANSLATE(vldr),
+ INTERPRETER_TRANSLATE(vldm),
+
+ INTERPRETER_TRANSLATE(srs),
+ INTERPRETER_TRANSLATE(rfe),
+ INTERPRETER_TRANSLATE(bkpt),
+ INTERPRETER_TRANSLATE(blx),
+ INTERPRETER_TRANSLATE(cps),
+ INTERPRETER_TRANSLATE(pld),
+ INTERPRETER_TRANSLATE(setend),
+ INTERPRETER_TRANSLATE(clrex),
+ INTERPRETER_TRANSLATE(rev16),
+ INTERPRETER_TRANSLATE(usad8),
+ INTERPRETER_TRANSLATE(sxtb),
+ INTERPRETER_TRANSLATE(uxtb),
+ INTERPRETER_TRANSLATE(sxth),
+ INTERPRETER_TRANSLATE(sxtb16),
+ INTERPRETER_TRANSLATE(uxth),
+ INTERPRETER_TRANSLATE(uxtb16),
+ INTERPRETER_TRANSLATE(cpy),
+ INTERPRETER_TRANSLATE(uxtab),
+ INTERPRETER_TRANSLATE(ssub8),
+ INTERPRETER_TRANSLATE(shsub8),
+ INTERPRETER_TRANSLATE(ssubaddx),
+ INTERPRETER_TRANSLATE(strex),
+ INTERPRETER_TRANSLATE(strexb),
+ INTERPRETER_TRANSLATE(swp),
+ INTERPRETER_TRANSLATE(swpb),
+ INTERPRETER_TRANSLATE(ssub16),
+ INTERPRETER_TRANSLATE(ssat16),
+ INTERPRETER_TRANSLATE(shsubaddx),
+ INTERPRETER_TRANSLATE(qsubaddx),
+ INTERPRETER_TRANSLATE(shaddsubx),
+ INTERPRETER_TRANSLATE(shadd8),
+ INTERPRETER_TRANSLATE(shadd16),
+ INTERPRETER_TRANSLATE(sel),
+ INTERPRETER_TRANSLATE(saddsubx),
+ INTERPRETER_TRANSLATE(sadd8),
+ INTERPRETER_TRANSLATE(sadd16),
+ INTERPRETER_TRANSLATE(shsub16),
+ INTERPRETER_TRANSLATE(umaal),
+ INTERPRETER_TRANSLATE(uxtab16),
+ INTERPRETER_TRANSLATE(usubaddx),
+ INTERPRETER_TRANSLATE(usub8),
+ INTERPRETER_TRANSLATE(usub16),
+ INTERPRETER_TRANSLATE(usat16),
+ INTERPRETER_TRANSLATE(usada8),
+ INTERPRETER_TRANSLATE(uqsubaddx),
+ INTERPRETER_TRANSLATE(uqsub8),
+ INTERPRETER_TRANSLATE(uqsub16),
+ INTERPRETER_TRANSLATE(uqaddsubx),
+ INTERPRETER_TRANSLATE(uqadd8),
+ INTERPRETER_TRANSLATE(uqadd16),
+ INTERPRETER_TRANSLATE(sxtab),
+ INTERPRETER_TRANSLATE(uhsubaddx),
+ INTERPRETER_TRANSLATE(uhsub8),
+ INTERPRETER_TRANSLATE(uhsub16),
+ INTERPRETER_TRANSLATE(uhaddsubx),
+ INTERPRETER_TRANSLATE(uhadd8),
+ INTERPRETER_TRANSLATE(uhadd16),
+ INTERPRETER_TRANSLATE(uaddsubx),
+ INTERPRETER_TRANSLATE(uadd8),
+ INTERPRETER_TRANSLATE(uadd16),
+ INTERPRETER_TRANSLATE(sxtah),
+ INTERPRETER_TRANSLATE(sxtab16),
+ INTERPRETER_TRANSLATE(qadd8),
+ INTERPRETER_TRANSLATE(bxj),
+ INTERPRETER_TRANSLATE(clz),
+ INTERPRETER_TRANSLATE(uxtah),
+ INTERPRETER_TRANSLATE(bx),
+ INTERPRETER_TRANSLATE(rev),
+ INTERPRETER_TRANSLATE(blx),
+ INTERPRETER_TRANSLATE(revsh),
+ INTERPRETER_TRANSLATE(qadd),
+ INTERPRETER_TRANSLATE(qadd16),
+ INTERPRETER_TRANSLATE(qaddsubx),
+ INTERPRETER_TRANSLATE(ldrex),
+ INTERPRETER_TRANSLATE(qdadd),
+ INTERPRETER_TRANSLATE(qdsub),
+ INTERPRETER_TRANSLATE(qsub),
+ INTERPRETER_TRANSLATE(ldrexb),
+ INTERPRETER_TRANSLATE(qsub8),
+ INTERPRETER_TRANSLATE(qsub16),
+ INTERPRETER_TRANSLATE(smuad),
+ INTERPRETER_TRANSLATE(smmul),
+ INTERPRETER_TRANSLATE(smusd),
+ INTERPRETER_TRANSLATE(smlsd),
+ INTERPRETER_TRANSLATE(smlsld),
+ INTERPRETER_TRANSLATE(smmla),
+ INTERPRETER_TRANSLATE(smmls),
+ INTERPRETER_TRANSLATE(smlald),
+ INTERPRETER_TRANSLATE(smlad),
+ INTERPRETER_TRANSLATE(smlaw),
+ INTERPRETER_TRANSLATE(smulw),
+ INTERPRETER_TRANSLATE(pkhtb),
+ INTERPRETER_TRANSLATE(pkhbt),
+ INTERPRETER_TRANSLATE(smul),
+ INTERPRETER_TRANSLATE(smlalxy),
+ INTERPRETER_TRANSLATE(smla),
+ INTERPRETER_TRANSLATE(mcrr),
+ INTERPRETER_TRANSLATE(mrrc),
+ INTERPRETER_TRANSLATE(cmp),
+ INTERPRETER_TRANSLATE(tst),
+ INTERPRETER_TRANSLATE(teq),
+ INTERPRETER_TRANSLATE(cmn),
+ INTERPRETER_TRANSLATE(smull),
+ INTERPRETER_TRANSLATE(umull),
+ INTERPRETER_TRANSLATE(umlal),
+ INTERPRETER_TRANSLATE(smlal),
+ INTERPRETER_TRANSLATE(mul),
+ INTERPRETER_TRANSLATE(mla),
+ INTERPRETER_TRANSLATE(ssat),
+ INTERPRETER_TRANSLATE(usat),
+ INTERPRETER_TRANSLATE(mrs),
+ INTERPRETER_TRANSLATE(msr),
+ INTERPRETER_TRANSLATE(and),
+ INTERPRETER_TRANSLATE(bic),
+ INTERPRETER_TRANSLATE(ldm),
+ INTERPRETER_TRANSLATE(eor),
+ INTERPRETER_TRANSLATE(add),
+ INTERPRETER_TRANSLATE(rsb),
+ INTERPRETER_TRANSLATE(rsc),
+ INTERPRETER_TRANSLATE(sbc),
+ INTERPRETER_TRANSLATE(adc),
+ INTERPRETER_TRANSLATE(sub),
+ INTERPRETER_TRANSLATE(orr),
+ INTERPRETER_TRANSLATE(mvn),
+ INTERPRETER_TRANSLATE(mov),
+ INTERPRETER_TRANSLATE(stm),
+ INTERPRETER_TRANSLATE(ldm),
+ INTERPRETER_TRANSLATE(ldrsh),
+ INTERPRETER_TRANSLATE(stm),
+ INTERPRETER_TRANSLATE(ldm),
+ INTERPRETER_TRANSLATE(ldrsb),
+ INTERPRETER_TRANSLATE(strd),
+ INTERPRETER_TRANSLATE(ldrh),
+ INTERPRETER_TRANSLATE(strh),
+ INTERPRETER_TRANSLATE(ldrd),
+ INTERPRETER_TRANSLATE(strt),
+ INTERPRETER_TRANSLATE(strbt),
+ INTERPRETER_TRANSLATE(ldrbt),
+ INTERPRETER_TRANSLATE(ldrt),
+ INTERPRETER_TRANSLATE(mrc),
+ INTERPRETER_TRANSLATE(mcr),
+ INTERPRETER_TRANSLATE(msr),
+ INTERPRETER_TRANSLATE(msr),
+ INTERPRETER_TRANSLATE(msr),
+ INTERPRETER_TRANSLATE(msr),
+ INTERPRETER_TRANSLATE(msr),
+ INTERPRETER_TRANSLATE(ldrb),
+ INTERPRETER_TRANSLATE(strb),
+ INTERPRETER_TRANSLATE(ldr),
+ INTERPRETER_TRANSLATE(ldrcond),
+ INTERPRETER_TRANSLATE(str),
+ INTERPRETER_TRANSLATE(cdp),
+ INTERPRETER_TRANSLATE(stc),
+ INTERPRETER_TRANSLATE(ldc),
+ INTERPRETER_TRANSLATE(ldrexd),
+ INTERPRETER_TRANSLATE(strexd),
+ INTERPRETER_TRANSLATE(ldrexh),
+ INTERPRETER_TRANSLATE(strexh),
+ INTERPRETER_TRANSLATE(nop),
+ INTERPRETER_TRANSLATE(yield),
+ INTERPRETER_TRANSLATE(wfe),
+ INTERPRETER_TRANSLATE(wfi),
+ INTERPRETER_TRANSLATE(sev),
+ INTERPRETER_TRANSLATE(swi),
+ INTERPRETER_TRANSLATE(bbl),
+
+ // All the thumb instructions should be placed the end of table
+ INTERPRETER_TRANSLATE(b_2_thumb),
+ INTERPRETER_TRANSLATE(b_cond_thumb),
+ INTERPRETER_TRANSLATE(bl_1_thumb),
+ INTERPRETER_TRANSLATE(bl_2_thumb),
+ INTERPRETER_TRANSLATE(blx_1_thumb)
+};
+
+const size_t arm_instruction_trans_len = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
diff --git a/src/core/arm/dyncom/arm_dyncom_trans.h b/src/core/arm/dyncom/arm_dyncom_trans.h
new file mode 100644
index 000000000..7af71f4e3
--- /dev/null
+++ b/src/core/arm/dyncom/arm_dyncom_trans.h
@@ -0,0 +1,493 @@
+struct ARMul_State;
+typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
+
+enum class TransExtData {
+ COND = (1 << 0),
+ NON_BRANCH = (1 << 1),
+ DIRECT_BRANCH = (1 << 2),
+ INDIRECT_BRANCH = (1 << 3),
+ CALL = (1 << 4),
+ RET = (1 << 5),
+ END_OF_PAGE = (1 << 6),
+ THUMB = (1 << 7),
+ SINGLE_STEP = (1 << 8)
+};
+
+struct arm_inst {
+ unsigned int idx;
+ unsigned int cond;
+ TransExtData br;
+ char component[0];
+};
+
+struct generic_arm_inst {
+ u32 Ra;
+ u32 Rm;
+ u32 Rn;
+ u32 Rd;
+ u8 op1;
+ u8 op2;
+};
+
+struct adc_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct add_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct orr_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct and_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct eor_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct bbl_inst {
+ unsigned int L;
+ int signed_immed_24;
+ unsigned int next_addr;
+ unsigned int jmp_addr;
+};
+
+struct bx_inst {
+ unsigned int Rm;
+};
+
+struct blx_inst {
+ union {
+ s32 signed_immed_24;
+ u32 Rm;
+ } val;
+ unsigned int inst;
+};
+
+struct clz_inst {
+ unsigned int Rm;
+ unsigned int Rd;
+};
+
+struct cps_inst {
+ unsigned int imod0;
+ unsigned int imod1;
+ unsigned int mmod;
+ unsigned int A, I, F;
+ unsigned int mode;
+};
+
+struct clrex_inst {
+};
+
+struct cpy_inst {
+ unsigned int Rm;
+ unsigned int Rd;
+};
+
+struct bic_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct sub_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct tst_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct cmn_inst {
+ unsigned int I;
+ unsigned int Rn;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct teq_inst {
+ unsigned int I;
+ unsigned int Rn;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct stm_inst {
+ unsigned int inst;
+};
+
+struct bkpt_inst {
+ u32 imm;
+};
+
+struct stc_inst {
+};
+
+struct ldc_inst {
+};
+
+struct swi_inst {
+ unsigned int num;
+};
+
+struct cmp_inst {
+ unsigned int I;
+ unsigned int Rn;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct mov_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct mvn_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct rev_inst {
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int op1;
+ unsigned int op2;
+};
+
+struct rsb_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct rsc_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct sbc_inst {
+ unsigned int I;
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int shifter_operand;
+ shtop_fp_t shtop_func;
+};
+
+struct mul_inst {
+ unsigned int S;
+ unsigned int Rd;
+ unsigned int Rs;
+ unsigned int Rm;
+};
+
+struct smul_inst {
+ unsigned int Rd;
+ unsigned int Rs;
+ unsigned int Rm;
+ unsigned int x;
+ unsigned int y;
+};
+
+struct umull_inst {
+ unsigned int S;
+ unsigned int RdHi;
+ unsigned int RdLo;
+ unsigned int Rs;
+ unsigned int Rm;
+};
+
+struct smlad_inst {
+ unsigned int m;
+ unsigned int Rm;
+ unsigned int Rd;
+ unsigned int Ra;
+ unsigned int Rn;
+ unsigned int op1;
+ unsigned int op2;
+};
+
+struct smla_inst {
+ unsigned int x;
+ unsigned int y;
+ unsigned int Rm;
+ unsigned int Rd;
+ unsigned int Rs;
+ unsigned int Rn;
+};
+
+struct smlalxy_inst {
+ unsigned int x;
+ unsigned int y;
+ unsigned int RdLo;
+ unsigned int RdHi;
+ unsigned int Rm;
+ unsigned int Rn;
+};
+
+struct ssat_inst {
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int imm5;
+ unsigned int sat_imm;
+ unsigned int shift_type;
+};
+
+struct umaal_inst {
+ unsigned int Rn;
+ unsigned int Rm;
+ unsigned int RdHi;
+ unsigned int RdLo;
+};
+
+struct umlal_inst {
+ unsigned int S;
+ unsigned int Rm;
+ unsigned int Rs;
+ unsigned int RdHi;
+ unsigned int RdLo;
+};
+
+struct smlal_inst {
+ unsigned int S;
+ unsigned int Rm;
+ unsigned int Rs;
+ unsigned int RdHi;
+ unsigned int RdLo;
+};
+
+struct smlald_inst {
+ unsigned int RdLo;
+ unsigned int RdHi;
+ unsigned int Rm;
+ unsigned int Rn;
+ unsigned int swap;
+ unsigned int op1;
+ unsigned int op2;
+};
+
+struct mla_inst {
+ unsigned int S;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int Rs;
+ unsigned int Rm;
+};
+
+struct mrc_inst {
+ unsigned int opcode_1;
+ unsigned int opcode_2;
+ unsigned int cp_num;
+ unsigned int crn;
+ unsigned int crm;
+ unsigned int Rd;
+ unsigned int inst;
+};
+
+struct mcr_inst {
+ unsigned int opcode_1;
+ unsigned int opcode_2;
+ unsigned int cp_num;
+ unsigned int crn;
+ unsigned int crm;
+ unsigned int Rd;
+ unsigned int inst;
+};
+
+struct mcrr_inst {
+ unsigned int opcode_1;
+ unsigned int cp_num;
+ unsigned int crm;
+ unsigned int rt;
+ unsigned int rt2;
+};
+
+struct mrs_inst {
+ unsigned int R;
+ unsigned int Rd;
+};
+
+struct msr_inst {
+ unsigned int field_mask;
+ unsigned int R;
+ unsigned int inst;
+};
+
+struct pld_inst {
+};
+
+struct sxtb_inst {
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int rotate;
+};
+
+struct sxtab_inst {
+ unsigned int Rd;
+ unsigned int Rn;
+ unsigned int Rm;
+ unsigned rotate;
+};
+
+struct sxtah_inst {
+ unsigned int Rd;
+ unsigned int Rn;
+ unsigned int Rm;
+ unsigned int rotate;
+};
+
+struct sxth_inst {
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int rotate;
+};
+
+struct uxtab_inst {
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int rotate;
+ unsigned int Rm;
+};
+
+struct uxtah_inst {
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int rotate;
+ unsigned int Rm;
+};
+
+struct uxth_inst {
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int rotate;
+};
+
+struct cdp_inst {
+ unsigned int opcode_1;
+ unsigned int CRn;
+ unsigned int CRd;
+ unsigned int cp_num;
+ unsigned int opcode_2;
+ unsigned int CRm;
+ unsigned int inst;
+};
+
+struct uxtb_inst {
+ unsigned int Rd;
+ unsigned int Rm;
+ unsigned int rotate;
+};
+
+struct swp_inst {
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned int Rm;
+};
+
+struct setend_inst {
+ unsigned int set_bigend;
+};
+
+struct b_2_thumb {
+ unsigned int imm;
+};
+struct b_cond_thumb {
+ unsigned int imm;
+ unsigned int cond;
+};
+
+struct bl_1_thumb {
+ unsigned int imm;
+};
+struct bl_2_thumb {
+ unsigned int imm;
+};
+struct blx_1_thumb {
+ unsigned int imm;
+ unsigned int instr;
+};
+
+struct pkh_inst {
+ unsigned int Rm;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned char imm;
+};
+
+// Floating point VFPv3 structures
+#define VFP_INTERPRETER_STRUCT
+#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
+#undef VFP_INTERPRETER_STRUCT
+
+typedef void (*get_addr_fp_t)(ARMul_State *cpu, unsigned int inst, unsigned int &virt_addr);
+
+struct ldst_inst {
+ unsigned int inst;
+ get_addr_fp_t get_addr;
+};
+
+typedef arm_inst* ARM_INST_PTR;
+typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
+
+extern const transop_fp_t arm_instruction_trans[];
+extern const size_t arm_instruction_trans_len;
+
+#define TRANS_CACHE_SIZE (64 * 1024 * 2000)
+extern char trans_cache_buf[TRANS_CACHE_SIZE];
+extern size_t trans_cache_buf_top;
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index 4f9083515..1a98d0114 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -26,7 +26,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -75,7 +75,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -124,7 +124,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -174,7 +174,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -223,7 +223,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -272,7 +272,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -321,7 +321,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -370,7 +370,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -419,7 +419,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -470,7 +470,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->single = BIT(inst, 8) == 0;
inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
@@ -518,7 +518,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->single = BIT(inst, 8) == 0;
inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
@@ -560,7 +560,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -610,7 +610,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -659,7 +659,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -708,7 +708,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -757,7 +757,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -806,7 +806,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -857,7 +857,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -906,7 +906,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->dp_operation = BIT(inst, 8);
inst_cream->instr = inst;
@@ -962,7 +962,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->to_arm = BIT(inst, 20) == 1;
inst_cream->t = BITS(inst, 12, 15);
@@ -1006,7 +1006,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->reg = BITS(inst, 16, 19);
inst_cream->Rt = BITS(inst, 12, 15);
@@ -1069,7 +1069,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
inst_cream->t = BITS(inst, 12, 15);
@@ -1115,7 +1115,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->reg = BITS(inst, 16, 19);
inst_cream->Rt = BITS(inst, 12, 15);
@@ -1200,7 +1200,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
inst_cream->t = BITS(inst, 12, 15);
@@ -1253,7 +1253,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int inde
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->to_arm = BIT(inst, 20) == 1;
inst_cream->t = BITS(inst, 12, 15);
@@ -1301,7 +1301,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->to_arm = BIT(inst, 20) == 1;
inst_cream->t = BITS(inst, 12, 15);
@@ -1354,7 +1354,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->single = BIT(inst, 8) == 0;
inst_cream->add = BIT(inst, 23);
@@ -1420,7 +1420,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->single = BIT(inst, 8) == 0;
inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
@@ -1495,7 +1495,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->single = BIT(inst, 8) == 0;
inst_cream->add = BIT(inst, 23);
@@ -1580,7 +1580,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->single = BIT(inst, 8) == 0;
inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4));
@@ -1653,7 +1653,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->single = BIT(inst, 8) == 0;
inst_cream->add = BIT(inst, 23);
@@ -1722,7 +1722,7 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index)
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->br = TransExtData::NON_BRANCH;
inst_cream->single = BIT(inst, 8) == 0;
inst_cream->add = BIT(inst, 23);
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp
index 820b19e1a..28d403158 100644
--- a/src/core/gdbstub/gdbstub.cpp
+++ b/src/core/gdbstub/gdbstub.cpp
@@ -646,7 +646,7 @@ static void ReadMemory() {
u8* data = Memory::GetPointer(addr);
if (!data) {
- return SendReply("E0");
+ return SendReply("E00");
}
MemToGdbHex(reply, data, len);
diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index bf7f875b6..8839ce482 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -194,6 +194,16 @@ template<ResultCode func(Handle, u32)> void Wrap() {
FuncReturn(func(PARAM(0), PARAM(1)).raw);
}
+template<ResultCode func(Handle*, Handle*, const char*, u32)> void Wrap() {
+ Handle param_1 = 0;
+ Handle param_2 = 0;
+ u32 retval = func(&param_1, &param_2, reinterpret_cast<const char*>(Memory::GetPointer(PARAM(2))), PARAM(3)).raw;
+ // The first out parameter is moved into R2 and the second is moved into R1.
+ Core::g_app_core->SetReg(1, param_2);
+ Core::g_app_core->SetReg(2, param_1);
+ FuncReturn(retval);
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// Function wrappers that return type u32
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp
new file mode 100644
index 000000000..444ce8d45
--- /dev/null
+++ b/src/core/hle/kernel/client_port.cpp
@@ -0,0 +1,16 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/assert.h"
+
+#include "core/hle/kernel/client_port.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/server_port.h"
+
+namespace Kernel {
+
+ClientPort::ClientPort() {}
+ClientPort::~ClientPort() {}
+
+} // namespace
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
new file mode 100644
index 000000000..480b6ddae
--- /dev/null
+++ b/src/core/hle/kernel/client_port.h
@@ -0,0 +1,36 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <string>
+
+#include "common/common_types.h"
+
+#include "core/hle/kernel/kernel.h"
+
+namespace Kernel {
+
+class ServerPort;
+
+class ClientPort : public Object {
+public:
+ friend class ServerPort;
+ std::string GetTypeName() const override { return "ClientPort"; }
+ std::string GetName() const override { return name; }
+
+ static const HandleType HANDLE_TYPE = HandleType::ClientPort;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
+
+ SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
+ u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have
+ u32 active_sessions; ///< Number of currently open sessions to this port
+ std::string name; ///< Name of client port (optional)
+
+protected:
+ ClientPort();
+ ~ClientPort() override;
+};
+
+} // namespace
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 4d4276f7a..27ba3f912 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -35,7 +35,7 @@ enum KernelHandle : Handle {
enum class HandleType : u32 {
Unknown = 0,
- Port = 1,
+
Session = 2,
Event = 3,
Mutex = 4,
@@ -48,6 +48,8 @@ enum class HandleType : u32 {
Timer = 11,
ResourceLimit = 12,
CodeSet = 13,
+ ClientPort = 14,
+ ServerPort = 15,
};
enum {
@@ -72,6 +74,7 @@ public:
bool IsWaitable() const {
switch (GetHandleType()) {
case HandleType::Session:
+ case HandleType::ServerPort:
case HandleType::Event:
case HandleType::Mutex:
case HandleType::Thread:
@@ -80,13 +83,13 @@ public:
return true;
case HandleType::Unknown:
- case HandleType::Port:
case HandleType::SharedMemory:
case HandleType::Redirection:
case HandleType::Process:
case HandleType::AddressArbiter:
case HandleType::ResourceLimit:
case HandleType::CodeSet:
+ case HandleType::ClientPort:
return false;
}
}
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp
new file mode 100644
index 000000000..fcc684a20
--- /dev/null
+++ b/src/core/hle/kernel/server_port.cpp
@@ -0,0 +1,41 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <tuple>
+
+#include "common/assert.h"
+
+#include "core/hle/kernel/client_port.h"
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/server_port.h"
+#include "core/hle/kernel/thread.h"
+
+namespace Kernel {
+
+ServerPort::ServerPort() {}
+ServerPort::~ServerPort() {}
+
+bool ServerPort::ShouldWait() {
+ // If there are no pending sessions, we wait until a new one is added.
+ return pending_sessions.size() == 0;
+}
+
+void ServerPort::Acquire() {
+ ASSERT_MSG(!ShouldWait(), "object unavailable!");
+}
+
+std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair(u32 max_sessions, std::string name) {
+ SharedPtr<ServerPort> server_port(new ServerPort);
+ SharedPtr<ClientPort> client_port(new ClientPort);
+
+ server_port->name = name + "_Server";
+ client_port->name = name + "_Client";
+ client_port->server_port = server_port;
+ client_port->max_sessions = max_sessions;
+ client_port->active_sessions = 0;
+
+ return std::make_tuple(std::move(server_port), std::move(client_port));
+}
+
+} // namespace
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
new file mode 100644
index 000000000..e9c972ce6
--- /dev/null
+++ b/src/core/hle/kernel/server_port.h
@@ -0,0 +1,46 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <string>
+#include <tuple>
+
+#include "common/common_types.h"
+
+#include "core/hle/kernel/kernel.h"
+
+namespace Kernel {
+
+class ClientPort;
+
+class ServerPort final : public WaitObject {
+public:
+ /**
+ * Creates a pair of ServerPort and an associated ClientPort.
+ * @param max_sessions Maximum number of sessions to the port
+ * @param name Optional name of the ports
+ * @return The created port tuple
+ */
+ static std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair(u32 max_sessions, std::string name = "UnknownPort");
+
+ std::string GetTypeName() const override { return "ServerPort"; }
+ std::string GetName() const override { return name; }
+
+ static const HandleType HANDLE_TYPE = HandleType::ServerPort;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
+
+ std::string name; ///< Name of port (optional)
+
+ std::vector<SharedPtr<WaitObject>> pending_sessions; ///< ServerSessions waiting to be accepted by the port
+
+ bool ShouldWait() override;
+ void Acquire() override;
+
+private:
+ ServerPort();
+ ~ServerPort() override;
+};
+
+} // namespace
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index 6ddaf970e..26b086f87 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -32,6 +32,10 @@ constexpr u32 CallingPidDesc() {
return 0x20;
}
+constexpr u32 TransferHandleDesc() {
+ return 0x20;
+}
+
constexpr u32 StaticBufferDesc(u32 size, unsigned int buffer_id) {
return 0x2 | (size << 14) | ((buffer_id & 0xF) << 10);
}
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index db2728a7b..9dea995f4 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -182,6 +182,48 @@ static void PriorityBoostStarvedThreads() {
}
/**
+ * Gets the registers for timeout parameter of the next WaitSynchronization call.
+ * @param thread a pointer to the thread that is ready to call WaitSynchronization
+ * @returns a tuple of two register pointers to low and high part of the timeout parameter
+ */
+static std::tuple<u32*, u32*> GetWaitSynchTimeoutParameterRegister(Thread* thread) {
+ bool thumb_mode = (thread->context.cpsr & TBIT) != 0;
+ u16 thumb_inst = Memory::Read16(thread->context.pc & 0xFFFFFFFE);
+ u32 inst = Memory::Read32(thread->context.pc & 0xFFFFFFFC) & 0x0FFFFFFF;
+
+ if ((thumb_mode && thumb_inst == 0xDF24) || (!thumb_mode && inst == 0x0F000024)) {
+ // svc #0x24 (WaitSynchronization1)
+ return std::make_tuple(&thread->context.cpu_registers[2], &thread->context.cpu_registers[3]);
+ } else if ((thumb_mode && thumb_inst == 0xDF25) || (!thumb_mode && inst == 0x0F000025)) {
+ // svc #0x25 (WaitSynchronizationN)
+ return std::make_tuple(&thread->context.cpu_registers[0], &thread->context.cpu_registers[4]);
+ }
+
+ UNREACHABLE();
+}
+
+/**
+ * Updates the WaitSynchronization timeout paramter according to the difference
+ * between ticks of the last WaitSynchronization call and the incoming one.
+ * @param timeout_low a pointer to the register for the low part of the timeout parameter
+ * @param timeout_high a pointer to the register for the high part of the timeout parameter
+ * @param last_tick tick of the last WaitSynchronization call
+ */
+static void UpdateTimeoutParameter(u32* timeout_low, u32* timeout_high, u64 last_tick) {
+ s64 timeout = ((s64)*timeout_high << 32) | *timeout_low;
+
+ if (timeout != -1) {
+ timeout -= cyclesToUs(CoreTiming::GetTicks() - last_tick) * 1000; // in nanoseconds
+
+ if (timeout < 0)
+ timeout = 0;
+
+ *timeout_low = timeout & 0xFFFFFFFF;
+ *timeout_high = timeout >> 32;
+ }
+}
+
+/**
* Switches the CPU's active thread context to that of the specified thread
* @param new_thread The thread to switch to
*/
@@ -219,6 +261,13 @@ static void SwitchContext(Thread* new_thread) {
// SVC instruction is 2 bytes for THUMB, 4 bytes for ARM
new_thread->context.pc -= thumb_mode ? 2 : 4;
+
+ // Get the register for timeout parameter
+ u32* timeout_low, *timeout_high;
+ std::tie(timeout_low, timeout_high) = GetWaitSynchTimeoutParameterRegister(new_thread);
+
+ // Update the timeout parameter
+ UpdateTimeoutParameter(timeout_low, timeout_high, new_thread->last_running_ticks);
}
// Clean up the thread's wait_objects, they'll be restored if needed during
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index bfb3327ce..57dedcb22 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -26,6 +26,7 @@ enum class ErrorDescription : u32 {
FS_NotAFile = 250,
FS_NotFormatted = 340, ///< This is used by the FS service when creating a SaveData archive
OutofRangeOrMisalignedAddress = 513, // TODO(purpasmart): Check if this name fits its actual usage
+ GPU_FirstInitialization = 519,
FS_InvalidPath = 702,
InvalidSection = 1000,
TooLarge = 1001,
diff --git a/src/core/hle/service/dlp/dlp.cpp b/src/core/hle/service/dlp/dlp.cpp
new file mode 100644
index 000000000..7c8db794b
--- /dev/null
+++ b/src/core/hle/service/dlp/dlp.cpp
@@ -0,0 +1,24 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/service.h"
+#include "core/hle/service/dlp/dlp.h"
+#include "core/hle/service/dlp/dlp_clnt.h"
+#include "core/hle/service/dlp/dlp_fkcl.h"
+#include "core/hle/service/dlp/dlp_srvr.h"
+
+namespace Service {
+namespace DLP {
+
+void Init() {
+ AddService(new DLP_CLNT_Interface);
+ AddService(new DLP_FKCL_Interface);
+ AddService(new DLP_SRVR_Interface);
+}
+
+void Shutdown() {
+}
+
+} // namespace DLP
+} // namespace Service
diff --git a/src/core/hle/service/dlp/dlp.h b/src/core/hle/service/dlp/dlp.h
new file mode 100644
index 000000000..ec2fe46e8
--- /dev/null
+++ b/src/core/hle/service/dlp/dlp.h
@@ -0,0 +1,15 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+namespace Service {
+namespace DLP {
+
+/// Initializes the DLP services.
+void Init();
+
+/// Shuts down the DLP services.
+void Shutdown();
+
+} // namespace DLP
+} // namespace Service
diff --git a/src/core/hle/service/dlp/dlp_clnt.cpp b/src/core/hle/service/dlp/dlp_clnt.cpp
new file mode 100644
index 000000000..0b31d47df
--- /dev/null
+++ b/src/core/hle/service/dlp/dlp_clnt.cpp
@@ -0,0 +1,20 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/dlp/dlp_clnt.h"
+
+namespace Service {
+namespace DLP {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x000100C3, nullptr, "Initialize"},
+ {0x00110000, nullptr, "GetWirelessRebootPassphrase"},
+};
+
+DLP_CLNT_Interface::DLP_CLNT_Interface() {
+ Register(FunctionTable);
+}
+
+} // namespace DLP
+} // namespace Service
diff --git a/src/core/hle/service/dlp/dlp_clnt.h b/src/core/hle/service/dlp/dlp_clnt.h
new file mode 100644
index 000000000..067f11e37
--- /dev/null
+++ b/src/core/hle/service/dlp/dlp_clnt.h
@@ -0,0 +1,22 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace DLP {
+
+class DLP_CLNT_Interface final : public Interface {
+public:
+ DLP_CLNT_Interface();
+
+ std::string GetPortName() const override {
+ return "dlp:CLNT";
+ }
+};
+
+} // namespace DLP
+} // namespace Service
diff --git a/src/core/hle/service/dlp/dlp_fkcl.cpp b/src/core/hle/service/dlp/dlp_fkcl.cpp
new file mode 100644
index 000000000..a845260e5
--- /dev/null
+++ b/src/core/hle/service/dlp/dlp_fkcl.cpp
@@ -0,0 +1,20 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "core/hle/service/dlp/dlp_fkcl.h"
+
+namespace Service {
+namespace DLP {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010083, nullptr, "Initialize"},
+ {0x000F0000, nullptr, "GetWirelessRebootPassphrase"},
+};
+
+DLP_FKCL_Interface::DLP_FKCL_Interface() {
+ Register(FunctionTable);
+}
+
+} // namespace DLP
+} // namespace Service
diff --git a/src/core/hle/service/dlp/dlp_fkcl.h b/src/core/hle/service/dlp/dlp_fkcl.h
new file mode 100644
index 000000000..e4837a167
--- /dev/null
+++ b/src/core/hle/service/dlp/dlp_fkcl.h
@@ -0,0 +1,22 @@
+// Copyright 2016 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+namespace Service {
+namespace DLP {
+
+class DLP_FKCL_Interface final : public Interface {
+public:
+ DLP_FKCL_Interface();
+
+ std::string GetPortName() const override {
+ return "dlp:FKCL";
+ }
+};
+
+} // namespace DLP
+} // namespace Service
diff --git a/src/core/hle/service/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp
index 1f30188da..da9b30f56 100644
--- a/src/core/hle/service/dlp_srvr.cpp
+++ b/src/core/hle/service/dlp/dlp_srvr.cpp
@@ -2,16 +2,15 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include "common/common_types.h"
#include "common/logging/log.h"
-#include "core/hle/hle.h"
-#include "core/hle/service/dlp_srvr.h"
+#include "core/hle/result.h"
+#include "core/hle/service/dlp/dlp_srvr.h"
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace DLP_SRVR
+namespace Service {
+namespace DLP {
-namespace DLP_SRVR {
-
-static void unk_0x000E0040(Service::Interface* self) {
+static void unk_0x000E0040(Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
cmd_buff[1] = RESULT_SUCCESS.raw;
@@ -23,14 +22,13 @@ static void unk_0x000E0040(Service::Interface* self) {
const Interface::FunctionInfo FunctionTable[] = {
{0x00010183, nullptr, "Initialize"},
{0x00020000, nullptr, "Finalize"},
+ {0x000800C0, nullptr, "SendWirelessRebootPassphrase"},
{0x000E0040, unk_0x000E0040, "unk_0x000E0040"},
};
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Interface class
-
-Interface::Interface() {
+DLP_SRVR_Interface::DLP_SRVR_Interface() {
Register(FunctionTable);
}
-} // namespace
+} // namespace DLP
+} // namespace Service
diff --git a/src/core/hle/service/dlp_srvr.h b/src/core/hle/service/dlp/dlp_srvr.h
index d65d00814..19fe17840 100644
--- a/src/core/hle/service/dlp_srvr.h
+++ b/src/core/hle/service/dlp/dlp_srvr.h
@@ -6,18 +6,17 @@
#include "core/hle/service/service.h"
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace DLP_SRVR
+namespace Service {
+namespace DLP {
-namespace DLP_SRVR {
-
-class Interface : public Service::Interface {
+class DLP_SRVR_Interface final : public Interface {
public:
- Interface();
+ DLP_SRVR_Interface();
std::string GetPortName() const override {
return "dlp:SRVR";
}
};
-} // namespace
+} // namespace DLP
+} // namespace Service
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index f3c7b7df3..ec565f46d 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -44,7 +44,7 @@ Kernel::SharedPtr<Kernel::SharedMemory> g_shared_memory;
u32 g_thread_id = 0;
static bool gpu_right_acquired = false;
-
+static bool first_initialization = true;
/// Gets a pointer to a thread command buffer in GSP shared memory
static inline u8* GetCommandBuffer(u32 thread_id) {
return g_shared_memory->GetPointer(0x800 + (thread_id * sizeof(CommandBuffer)));
@@ -347,24 +347,25 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) {
u32 flags = cmd_buff[1];
g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]);
+ // TODO(mailwl): return right error code instead assert
ASSERT_MSG((g_interrupt_event != nullptr), "handle is not valid!");
g_interrupt_event->name = "GSP_GPU::interrupt_event";
- using Kernel::MemoryPermission;
- g_shared_memory = Kernel::SharedMemory::Create(nullptr, 0x1000,
- MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
- 0, Kernel::MemoryRegion::BASE, "GSP:SharedMemory");
-
- Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom();
-
- // This specific code is required for a successful initialization, rather than 0
- cmd_buff[1] = ResultCode((ErrorDescription)519, ErrorModule::GX,
- ErrorSummary::Success, ErrorLevel::Success).raw;
+ if (first_initialization) {
+ // This specific code is required for a successful initialization, rather than 0
+ first_initialization = false;
+ cmd_buff[1] = ResultCode(ErrorDescription::GPU_FirstInitialization, ErrorModule::GX,
+ ErrorSummary::Success, ErrorLevel::Success).raw;
+ } else {
+ cmd_buff[1] = RESULT_SUCCESS.raw;
+ }
cmd_buff[2] = g_thread_id++; // Thread ID
- cmd_buff[4] = shmem_handle; // GSP shared memory
+ cmd_buff[4] = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); // GSP shared memory
g_interrupt_event->Signal(); // TODO(bunnei): Is this correct?
+
+ LOG_WARNING(Service_GSP, "called, flags=0x%08X", flags);
}
/**
@@ -375,12 +376,12 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) {
static void UnregisterInterruptRelayQueue(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- g_shared_memory = nullptr;
+ g_thread_id = 0;
g_interrupt_event = nullptr;
cmd_buff[1] = RESULT_SUCCESS.raw;
- LOG_WARNING(Service_GSP, "called");
+ LOG_WARNING(Service_GSP, "(STUBBED) called");
}
/**
@@ -718,10 +719,15 @@ Interface::Interface() {
Register(FunctionTable);
g_interrupt_event = nullptr;
- g_shared_memory = nullptr;
+
+ using Kernel::MemoryPermission;
+ g_shared_memory = Kernel::SharedMemory::Create(nullptr, 0x1000,
+ MemoryPermission::ReadWrite, MemoryPermission::ReadWrite,
+ 0, Kernel::MemoryRegion::BASE, "GSP:SharedMemory");
g_thread_id = 0;
gpu_right_acquired = false;
+ first_initialization = true;
}
Interface::~Interface() {
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index d216cecb4..cdec11388 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cmath>
+
#include "common/logging/log.h"
#include "common/emu_window.h"
@@ -19,8 +21,6 @@
namespace Service {
namespace HID {
-static const int MAX_CIRCLEPAD_POS = 0x9C; ///< Max value for a circle pad position
-
// Handle to shared memory region designated to HID_User service
static Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
@@ -39,38 +39,48 @@ static u32 next_gyroscope_index;
static int enable_accelerometer_count = 0; // positive means enabled
static int enable_gyroscope_count = 0; // positive means enabled
-const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = {{
- Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y,
- Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR,
- Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE,
- Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT,
- Service::HID::PAD_CIRCLE_UP, Service::HID::PAD_CIRCLE_DOWN, Service::HID::PAD_CIRCLE_LEFT, Service::HID::PAD_CIRCLE_RIGHT,
- Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT
-}};
-
-
-// TODO(peachum):
-// Add a method for setting analog input from joystick device for the circle Pad.
-//
-// This method should:
-// * Be called after both PadButton<Press, Release>().
-// * Be called before PadUpdateComplete()
-// * Set current PadEntry.circle_pad_<axis> using analog data
-// * Set PadData.raw_circle_pad_data
-// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_x >= 41
-// * Set PadData.current_state.circle_up = 1 if current PadEntry.circle_pad_y >= 41
-// * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41
-// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
+static PadState GetCirclePadDirectionState(s16 circle_pad_x, s16 circle_pad_y) {
+ constexpr float TAN30 = 0.577350269, TAN60 = 1 / TAN30; // 30 degree and 60 degree are angular thresholds for directions
+ constexpr int CIRCLE_PAD_THRESHOLD_SQUARE = 40 * 40; // a circle pad radius greater than 40 will trigger circle pad direction
+ PadState state;
+ state.hex = 0;
+
+ if (circle_pad_x * circle_pad_x + circle_pad_y * circle_pad_y > CIRCLE_PAD_THRESHOLD_SQUARE) {
+ float t = std::abs(static_cast<float>(circle_pad_y) / circle_pad_x);
+
+ if (circle_pad_x != 0 && t < TAN60) {
+ if (circle_pad_x > 0)
+ state.circle_right.Assign(1);
+ else
+ state.circle_left.Assign(1);
+ }
+
+ if (circle_pad_x == 0 || t > TAN30) {
+ if (circle_pad_y > 0)
+ state.circle_up.Assign(1);
+ else
+ state.circle_down.Assign(1);
+ }
+ }
+
+ return state;
+}
void Update() {
SharedMem* mem = reinterpret_cast<SharedMem*>(shared_mem->GetPointer());
- const PadState state = VideoCore::g_emu_window->GetPadState();
if (mem == nullptr) {
LOG_DEBUG(Service_HID, "Cannot update HID prior to mapping shared memory!");
return;
}
+ PadState state = VideoCore::g_emu_window->GetPadState();
+
+ // Get current circle pad position and update circle pad direction
+ s16 circle_pad_x, circle_pad_y;
+ std::tie(circle_pad_x, circle_pad_y) = VideoCore::g_emu_window->GetCirclePadState();
+ state.hex |= GetCirclePadDirectionState(circle_pad_x, circle_pad_y).hex;
+
mem->pad.current_state.hex = state.hex;
mem->pad.index = next_pad_index;
next_pad_index = (next_pad_index + 1) % mem->pad.entries.size();
@@ -88,13 +98,9 @@ void Update() {
// Update entry properties
pad_entry.current_state.hex = state.hex;
pad_entry.delta_additions.hex = changed.hex & state.hex;
- pad_entry.delta_removals.hex = changed.hex & old_state.hex;;
-
- // Set circle Pad
- pad_entry.circle_pad_x = state.circle_left ? -MAX_CIRCLEPAD_POS :
- state.circle_right ? MAX_CIRCLEPAD_POS : 0x0;
- pad_entry.circle_pad_y = state.circle_down ? -MAX_CIRCLEPAD_POS :
- state.circle_up ? MAX_CIRCLEPAD_POS : 0x0;
+ pad_entry.delta_removals.hex = changed.hex & old_state.hex;
+ pad_entry.circle_pad_x = circle_pad_x;
+ pad_entry.circle_pad_y = circle_pad_y;
// If we just updated index 0, provide a new timestamp
if (mem->pad.index == 0) {
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 170d19ea8..669b1f723 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -215,9 +215,6 @@ const PadState PAD_CIRCLE_LEFT = {{1u << 29}};
const PadState PAD_CIRCLE_UP = {{1u << 30}};
const PadState PAD_CIRCLE_DOWN = {{1u << 31}};
-
-extern const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping;
-
/**
* HID::GetIPCHandles service function
* Inputs:
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index d7e7d4fe3..395880843 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -10,7 +10,6 @@
#include "core/hle/service/act_a.h"
#include "core/hle/service/act_u.h"
#include "core/hle/service/csnd_snd.h"
-#include "core/hle/service/dlp_srvr.h"
#include "core/hle/service/dsp_dsp.h"
#include "core/hle/service/err_f.h"
#include "core/hle/service/gsp_gpu.h"
@@ -31,6 +30,7 @@
#include "core/hle/service/boss/boss.h"
#include "core/hle/service/cam/cam.h"
#include "core/hle/service/cecd/cecd.h"
+#include "core/hle/service/dlp/dlp.h"
#include "core/hle/service/frd/frd.h"
#include "core/hle/service/fs/archive.h"
#include "core/hle/service/cfg/cfg.h"
@@ -111,6 +111,7 @@ void Init() {
Service::CAM::Init();
Service::CECD::Init();
Service::CFG::Init();
+ Service::DLP::Init();
Service::FRD::Init();
Service::HID::Init();
Service::IR::Init();
@@ -123,7 +124,6 @@ void Init() {
AddService(new ACT_A::Interface);
AddService(new ACT_U::Interface);
AddService(new CSND_SND::Interface);
- AddService(new DLP_SRVR::Interface);
AddService(new DSP_DSP::Interface);
AddService(new GSP_GPU::Interface);
AddService(new GSP_LCD::Interface);
@@ -150,6 +150,7 @@ void Shutdown() {
Service::IR::Shutdown();
Service::HID::Shutdown();
Service::FRD::Shutdown();
+ Service::DLP::Shutdown();
Service::CFG::Shutdown();
Service::CECD::Shutdown();
Service::CAM::Shutdown();
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index aae955bf8..8bd36d5ea 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -1,4 +1,4 @@
-// Copyright 2014 Citra Emulator Project
+// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@@ -15,23 +15,64 @@ namespace SRV {
static Kernel::SharedPtr<Kernel::Event> event_handle;
-static void Initialize(Service::Interface* self) {
+/**
+ * SRV::RegisterClient service function
+ * Inputs:
+ * 0: 0x00010002
+ * 1: ProcessId Header (must be 0x20)
+ * Outputs:
+ * 0: 0x00010040
+ * 1: ResultCode
+ */
+static void RegisterClient(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- cmd_buff[1] = 0; // No error
+ if (cmd_buff[1] != IPC::CallingPidDesc()) {
+ cmd_buff[0] = IPC::MakeHeader(0x0, 0x1, 0); //0x40
+ cmd_buff[1] = ResultCode(ErrorDescription::OS_InvalidBufferDescriptor, ErrorModule::OS,
+ ErrorSummary::WrongArgument, ErrorLevel::Permanent).raw;
+ return;
+ }
+ cmd_buff[0] = IPC::MakeHeader(0x1, 0x1, 0); //0x10040
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_SRV, "(STUBBED) called");
}
-static void GetProcSemaphore(Service::Interface* self) {
+/**
+ * SRV::EnableNotification service function
+ * Inputs:
+ * 0: 0x00020000
+ * Outputs:
+ * 0: 0x00020042
+ * 1: ResultCode
+ * 2: Translation descriptor: 0x20
+ * 3: Handle to semaphore signaled on process notification
+ */
+static void EnableNotification(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
// TODO(bunnei): Change to a semaphore once these have been implemented
event_handle = Kernel::Event::Create(Kernel::ResetType::OneShot, "SRV:Event");
event_handle->Clear();
- cmd_buff[1] = 0; // No error
+ cmd_buff[0] = IPC::MakeHeader(0x2, 0x1, 0x2); // 0x20042
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ cmd_buff[2] = IPC::TransferHandleDesc();
cmd_buff[3] = Kernel::g_handle_table.Create(event_handle).MoveFrom();
+ LOG_WARNING(Service_SRV, "(STUBBED) called");
}
+/**
+ * SRV::GetServiceHandle service function
+ * Inputs:
+ * 0: 0x00050100
+ * 1-2: 8-byte UTF-8 service name
+ * 3: Name length
+ * 4: Flags (bit0: if not set, return port-handle if session-handle unavailable)
+ * Outputs:
+ * 1: ResultCode
+ * 3: Service handle
+ */
static void GetServiceHandle(Service::Interface* self) {
ResultCode res = RESULT_SUCCESS;
u32* cmd_buff = Kernel::GetCommandBuffer();
@@ -49,16 +90,80 @@ static void GetServiceHandle(Service::Interface* self) {
cmd_buff[1] = res.raw;
}
+/**
+ * SRV::Subscribe service function
+ * Inputs:
+ * 0: 0x00090040
+ * 1: Notification ID
+ * Outputs:
+ * 0: 0x00090040
+ * 1: ResultCode
+ */
+static void Subscribe(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 notification_id = cmd_buff[1];
+
+ cmd_buff[0] = IPC::MakeHeader(0x9, 0x1, 0); // 0x90040
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id);
+}
+
+/**
+ * SRV::Unsubscribe service function
+ * Inputs:
+ * 0: 0x000A0040
+ * 1: Notification ID
+ * Outputs:
+ * 0: 0x000A0040
+ * 1: ResultCode
+ */
+static void Unsubscribe(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 notification_id = cmd_buff[1];
+
+ cmd_buff[0] = IPC::MakeHeader(0xA, 0x1, 0); // 0xA0040
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X", notification_id);
+}
+
+/**
+ * SRV::PublishToSubscriber service function
+ * Inputs:
+ * 0: 0x000C0080
+ * 1: Notification ID
+ * 2: Flags (bit0: only fire if not fired, bit1: report errors)
+ * Outputs:
+ * 0: 0x000C0040
+ * 1: ResultCode
+ */
+static void PublishToSubscriber(Service::Interface* self) {
+ u32* cmd_buff = Kernel::GetCommandBuffer();
+
+ u32 notification_id = cmd_buff[1];
+ u8 flags = cmd_buff[2] & 0xFF;
+
+ cmd_buff[0] = IPC::MakeHeader(0xC, 0x1, 0); // 0xC0040
+ cmd_buff[1] = RESULT_SUCCESS.raw; // No error
+ LOG_WARNING(Service_SRV, "(STUBBED) called, notification_id=0x%X, flags=%u", notification_id, flags);
+}
+
const Interface::FunctionInfo FunctionTable[] = {
- {0x00010002, Initialize, "Initialize"},
- {0x00020000, GetProcSemaphore, "GetProcSemaphore"},
- {0x00030100, nullptr, "RegisterService"},
- {0x000400C0, nullptr, "UnregisterService"},
- {0x00050100, GetServiceHandle, "GetServiceHandle"},
- {0x000600C2, nullptr, "RegisterHandle"},
- {0x00090040, nullptr, "Subscribe"},
- {0x000B0000, nullptr, "ReceiveNotification"},
- {0x000C0080, nullptr, "PublishToSubscriber"},
+ {0x00010002, RegisterClient, "RegisterClient"},
+ {0x00020000, EnableNotification, "EnableNotification"},
+ {0x00030100, nullptr, "RegisterService"},
+ {0x000400C0, nullptr, "UnregisterService"},
+ {0x00050100, GetServiceHandle, "GetServiceHandle"},
+ {0x000600C2, nullptr, "RegisterPort"},
+ {0x000700C0, nullptr, "UnregisterPort"},
+ {0x00080100, nullptr, "GetPort"},
+ {0x00090040, Subscribe, "Subscribe"},
+ {0x000A0040, Unsubscribe, "Unsubscribe"},
+ {0x000B0000, nullptr, "ReceiveNotification"},
+ {0x000C0080, PublishToSubscriber, "PublishToSubscriber"},
+ {0x000D0040, nullptr, "PublishAndGetSubscriber"},
+ {0x000E00C0, nullptr, "IsServiceRegistered"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -66,10 +171,11 @@ const Interface::FunctionInfo FunctionTable[] = {
Interface::Interface() {
Register(FunctionTable);
+ event_handle = nullptr;
}
Interface::~Interface() {
event_handle = nullptr;
}
-} // namespace
+} // namespace SRV
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 0ce72de87..5d71d5619 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -14,12 +14,14 @@
#include "core/arm/arm_interface.h"
#include "core/hle/kernel/address_arbiter.h"
+#include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/memory.h"
#include "core/hle/kernel/mutex.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/resource_limit.h"
#include "core/hle/kernel/semaphore.h"
+#include "core/hle/kernel/server_port.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/kernel/timer.h"
@@ -834,6 +836,23 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32
return RESULT_SUCCESS;
}
+static ResultCode CreatePort(Handle* server_port, Handle* client_port, const char* name, u32 max_sessions) {
+ // TODO(Subv): Implement named ports.
+ ASSERT_MSG(name == nullptr, "Named ports are currently unimplemented");
+
+ using Kernel::ServerPort;
+ using Kernel::ClientPort;
+ using Kernel::SharedPtr;
+
+ auto ports = ServerPort::CreatePortPair(max_sessions);
+ CASCADE_RESULT(*client_port, Kernel::g_handle_table.Create(std::move(std::get<SharedPtr<ClientPort>>(ports))));
+ // Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be created.
+ CASCADE_RESULT(*server_port, Kernel::g_handle_table.Create(std::move(std::get<SharedPtr<ServerPort>>(ports))));
+
+ LOG_TRACE(Kernel_SVC, "called max_sessions=%u", max_sessions);
+ return RESULT_SUCCESS;
+}
+
static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) {
using Kernel::MemoryRegion;
@@ -1011,7 +1030,7 @@ static const FunctionDef SVC_Table[] = {
{0x44, nullptr, "Unknown"},
{0x45, nullptr, "Unknown"},
{0x46, nullptr, "Unknown"},
- {0x47, nullptr, "CreatePort"},
+ {0x47, HLE::Wrap<CreatePort>, "CreatePort"},
{0x48, nullptr, "CreateSessionToPort"},
{0x49, nullptr, "CreateSession"},
{0x4A, nullptr, "AcceptSession"},
diff --git a/src/core/settings.h b/src/core/settings.h
index ea72f4d9c..f95e62390 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -13,29 +13,40 @@ namespace Settings {
namespace NativeInput {
enum Values {
+ // directly mapped keys
A, B, X, Y,
L, R, ZL, ZR,
START, SELECT, HOME,
DUP, DDOWN, DLEFT, DRIGHT,
- SUP, SDOWN, SLEFT, SRIGHT,
CUP, CDOWN, CLEFT, CRIGHT,
+
+ // indirectly mapped keys
+ CIRCLE_UP, CIRCLE_DOWN, CIRCLE_LEFT, CIRCLE_RIGHT,
+ CIRCLE_MODIFIER,
+
NUM_INPUTS
};
+
static const std::array<const char*, NUM_INPUTS> Mapping = {{
+ // directly mapped keys
"pad_a", "pad_b", "pad_x", "pad_y",
"pad_l", "pad_r", "pad_zl", "pad_zr",
"pad_start", "pad_select", "pad_home",
"pad_dup", "pad_ddown", "pad_dleft", "pad_dright",
- "pad_sup", "pad_sdown", "pad_sleft", "pad_sright",
- "pad_cup", "pad_cdown", "pad_cleft", "pad_cright"
+ "pad_cup", "pad_cdown", "pad_cleft", "pad_cright",
+
+ // indirectly mapped keys
+ "pad_circle_up", "pad_circle_down", "pad_circle_left", "pad_circle_right",
+ "pad_circle_modifier",
}};
static const std::array<Values, NUM_INPUTS> All = {{
A, B, X, Y,
L, R, ZL, ZR,
START, SELECT, HOME,
DUP, DDOWN, DLEFT, DRIGHT,
- SUP, SDOWN, SLEFT, SRIGHT,
- CUP, CDOWN, CLEFT, CRIGHT
+ CUP, CDOWN, CLEFT, CRIGHT,
+ CIRCLE_UP, CIRCLE_DOWN, CIRCLE_LEFT, CIRCLE_RIGHT,
+ CIRCLE_MODIFIER,
}};
}
@@ -46,6 +57,7 @@ struct Values {
// Controls
std::array<int, NativeInput::NUM_INPUTS> input_mappings;
+ float pad_circle_modifier_scale;
// Core
int frame_skip;