summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra_qt/debugger/disassembler.cpp4
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp74
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp401
-rw-r--r--src/core/arm/interpreter/armemu.cpp535
-rw-r--r--src/core/arm/interpreter/armsupp.cpp50
-rw-r--r--src/core/arm/skyeye_common/armdefs.h6
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.cpp663
-rw-r--r--src/core/arm/skyeye_common/vfp/vfp.h6
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp1925
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp7
-rw-r--r--src/core/hle/kernel/event.cpp15
-rw-r--r--src/core/hle/kernel/kernel.cpp124
-rw-r--r--src/core/hle/kernel/kernel.h196
-rw-r--r--src/core/hle/kernel/mutex.cpp11
-rw-r--r--src/core/hle/kernel/semaphore.cpp9
-rw-r--r--src/core/hle/kernel/session.h4
-rw-r--r--src/core/hle/kernel/shared_memory.cpp11
-rw-r--r--src/core/hle/kernel/thread.cpp27
-rw-r--r--src/core/hle/kernel/thread.h3
-rw-r--r--src/core/hle/service/fs/archive.cpp10
-rw-r--r--src/core/hle/service/service.cpp5
-rw-r--r--src/core/hle/service/service.h5
-rw-r--r--src/core/hle/svc.cpp30
23 files changed, 1962 insertions, 2159 deletions
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp
index 2ee877743..14745f3bb 100644
--- a/src/citra_qt/debugger/disassembler.cpp
+++ b/src/citra_qt/debugger/disassembler.cpp
@@ -220,7 +220,9 @@ void DisassemblerWidget::OnPause()
emu_thread.SetCpuRunning(false);
// TODO: By now, the CPU might not have actually stopped...
- model->SetNextInstruction(Core::g_app_core->GetPC());
+ if (Core::g_app_core) {
+ model->SetNextInstruction(Core::g_app_core->GetPC());
+ }
}
void DisassemblerWidget::OnToggleStartStop()
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 5d174a08f..551bb77a6 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -28,9 +28,40 @@
#include "core/arm/dyncom/arm_dyncom_dec.h"
const ISEITEM arm_instruction[] = {
- #define VFP_DECODE
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_DECODE
+ {"vmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0},
+ {"vmls", 7, ARMVFP2, 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0},
+ {"vnmla", 4, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0},
+ {"vnmla", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
+ {"vnmls", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
+ {"vnmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
+ {"vmul", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
+ {"vadd", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
+ {"vsub", 5, ARMVFP2, 23, 27, 0x1C, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
+ {"vdiv", 5, ARMVFP2, 23, 27, 0x1D, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
+ {"vmov(i)", 4, ARMVFP3, 23, 27, 0x1D, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0},
+ {"vmov(r)", 5, ARMVFP3, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
+ {"vabs", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
+ {"vneg", 5, ARMVFP2, 23, 27, 0x1D, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
+ {"vsqrt", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
+ {"vcmp", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
+ {"vcmp2", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40},
+ {"vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1D, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
+ {"vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1D, 19, 21, 0x7, 17, 17, 0x1, 9, 11,5, 6, 6, 1},
+ {"vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1D, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
+ {"vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10},
+ {"vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10},
+ {"vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8, 11, 0xB, 0,4,0x10},
+ {"vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xA10},
+ {"vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11, 0xB, 0,4,0x10},
+ {"vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1},
+ {"vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2C, 4, 4, 1},
+ {"vstr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 0, 9, 11,5},
+ {"vpush", 3, ARMVFP2, 23, 27, 0x1A, 16, 21, 0x2D, 9, 11,5},
+ {"vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11,5},
+ {"vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3D, 9, 11,5},
+ {"vldr", 3, ARMVFP2, 24, 27, 0xD, 20, 21, 1, 9, 11,5},
+ {"vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11,5},
+
{"srs" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000001, 16, 20, 0x0000000d, 8, 11, 0x00000005},
{"rfe" , 4 , 6 , 25, 31, 0x0000007c, 22, 22, 0x00000000, 20, 20, 0x00000001, 8, 11, 0x0000000a},
{"bkpt" , 2 , 3 , 20, 31, 0x00000e12, 4, 7, 0x00000007},
@@ -187,9 +218,40 @@ const ISEITEM arm_instruction[] = {
};
const ISEITEM arm_exclusion_code[] = {
- #define VFP_DECODE_EXCLUSION
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_DECODE_EXCLUSION
+ {"vmla", 0, ARMVFP2, 0},
+ {"vmls", 0, ARMVFP2, 0},
+ {"vnmla", 0, ARMVFP2, 0},
+ {"vnmla", 0, ARMVFP2, 0},
+ {"vnmls", 0, ARMVFP2, 0},
+ {"vnmul", 0, ARMVFP2, 0},
+ {"vmul", 0, ARMVFP2, 0},
+ {"vadd", 0, ARMVFP2, 0},
+ {"vsub", 0, ARMVFP2, 0},
+ {"vdiv", 0, ARMVFP2, 0},
+ {"vmov(i)", 0, ARMVFP3, 0},
+ {"vmov(r)", 0, ARMVFP3, 0},
+ {"vabs", 0, ARMVFP2, 0},
+ {"vneg", 0, ARMVFP2, 0},
+ {"vsqrt", 0, ARMVFP2, 0},
+ {"vcmp", 0, ARMVFP2, 0},
+ {"vcmp2", 0, ARMVFP2, 0},
+ {"vcvt(bff)", 0, ARMVFP3, 4, 4, 1},
+ {"vcvt(bds)", 0, ARMVFP2, 0},
+ {"vcvt(bfi)", 0, ARMVFP2, 0},
+ {"vmovbrs", 0, ARMVFP2, 0},
+ {"vmsr", 0, ARMVFP2, 0},
+ {"vmovbrc", 0, ARMVFP2, 0},
+ {"vmrs", 0, ARMVFP2, 0},
+ {"vmovbcr", 0, ARMVFP2, 0},
+ {"vmovbrrss", 0, ARMVFP2, 0},
+ {"vmovbrrd", 0, ARMVFP2, 0},
+ {"vstr", 0, ARMVFP2, 0},
+ {"vpush", 0, ARMVFP2, 0},
+ {"vstm", 0, ARMVFP2, 0},
+ {"vpop", 0, ARMVFP2, 0},
+ {"vldr", 0, ARMVFP2, 0},
+ {"vldm", 0, ARMVFP2, 0},
+
{"srs" , 0 , 6 , 0},
{"rfe" , 0 , 6 , 0},
{"bkpt" , 0 , 3 , 0},
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 460001b1a..b4ee64203 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -1427,6 +1427,13 @@ typedef struct _blx_1_thumb {
unsigned int instr;
}blx_1_thumb;
+typedef struct _pkh_inst {
+ u32 Rm;
+ u32 Rn;
+ u32 Rd;
+ u8 imm;
+} pkh_inst;
+
typedef arm_inst * ARM_INST_PTR;
#define CACHE_BUFFER_SIZE (64 * 1024 * 2000)
@@ -2376,8 +2383,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(orr)(unsigned int inst, int index)
}
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(pkhbt)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("PKHBT"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("PKHTB"); }
+
+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_base->load_r15 = 0;
+
+ 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;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(pkhtb)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(pkhbt)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
{
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(pld_inst));
@@ -3086,15 +3115,47 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(tst)(unsigned int inst, int index)
inst_base->load_r15 = 1;
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(uadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD8"); }
+ARM_INST_PTR INTERPRETER_TRANSLATE(uadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADD16"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(uaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UADDSUBX"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADD16"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADD8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHADDSUBX"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUB16"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUB8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UHSUBADDX"); }
+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_base->load_r15 = 0;
+
+ 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;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhaddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhsub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uhsubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uhadd8)(inst, index);
+}
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));
@@ -3217,14 +3278,66 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(blx_1_thumb)(unsigned int tinst, int index)
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADD16"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADD8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQADDSUBX"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUB16"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUB8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UQSUBADDX"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAD8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(usada8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USADA8"); }
+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_base->load_r15 = 0;
+
+ 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;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqaddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqsub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uqsubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uqadd8)(inst, index);
+}
+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_base->load_r15 = 0;
+
+ inst_cream->op1 = BITS(inst, 20, 24);
+ inst_cream->op2 = BITS(inst, 5, 7);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Ra = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(usad8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(usada8)(inst, index);
+}
ARM_INST_PTR INTERPRETER_TRANSLATE(usat)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(usat16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USAT16"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(usub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB16"); }
@@ -3250,9 +3363,40 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) { UN
typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
const transop_fp_t arm_instruction_trans[] = {
- #define VFP_INTERPRETER_TABLE
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_INTERPRETER_TABLE
+ INTERPRETER_TRANSLATE(vmla),
+ INTERPRETER_TRANSLATE(vmls),
+ INTERPRETER_TRANSLATE(vnmla),
+ 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),
@@ -4093,10 +4237,12 @@ unsigned InterpreterMainLoop(ARMul_State* state)
// GCC and Clang have a C++ extension to support a lookup table of labels. Otherwise, fallback
// to a clunky switch statement.
#if defined __GNUC__ || defined __clang__
- void *InstLabel[] = {
- #define VFP_INTERPRETER_LABEL
- #include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
- #undef VFP_INTERPRETER_LABEL
+ void *InstLabel[] = {
+ &&VMLA_INST, &&VMLS_INST, &&VNMLA_INST, &&VNMLA_INST, &&VNMLS_INST, &&VNMUL_INST, &&VMUL_INST, &&VADD_INST, &&VSUB_INST,
+ &&VDIV_INST, &&VMOVI_INST, &&VMOVR_INST, &&VABS_INST, &&VNEG_INST, &&VSQRT_INST, &&VCMP_INST, &&VCMP2_INST, &&VCVTBDS_INST,
+ &&VCVTBFF_INST, &&VCVTBFI_INST, &&VMOVBRS_INST, &&VMSR_INST, &&VMOVBRC_INST, &&VMRS_INST, &&VMOVBCR_INST, &&VMOVBRRSS_INST,
+ &&VMOVBRRD_INST, &&VSTR_INST, &&VPUSH_INST, &&VSTM_INST, &&VPOP_INST, &&VLDR_INST, &&VLDM_INST,
+
&&SRS_INST,&&RFE_INST,&&BKPT_INST,&&BLX_INST,&&CPS_INST,&&PLD_INST,&&SETEND_INST,&&CLREX_INST,&&REV16_INST,&&USAD8_INST,&&SXTB_INST,
&&UXTB_INST,&&SXTH_INST,&&SXTB16_INST,&&UXTH_INST,&&UXTB16_INST,&&CPY_INST,&&UXTAB_INST,&&SSUB8_INST,&&SHSUB8_INST,&&SSUBADDX_INST,
&&STREX_INST,&&STREXB_INST,&&SWP_INST,&&SWPB_INST,&&SSUB16_INST,&&SSAT16_INST,&&SHSUBADDX_INST,&&QSUBADDX_INST,&&SHADDSUBX_INST,
@@ -4130,7 +4276,7 @@ unsigned InterpreterMainLoop(ARMul_State* state)
DISPATCH:
{
if (!cpu->NirqSig) {
- if (!(cpu->Cpsr & 0x80)) {
+ if (!(cpu->Cpsr & 0x80)) {
goto END;
}
}
@@ -5575,8 +5721,34 @@ unsigned InterpreterMainLoop(ARMul_State* state)
FETCH_INST;
GOTO_NEXT_INST;
}
+
PKHBT_INST:
+ {
+ INC_ICOUNTER;
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
+ RD = (RN & 0xFFFF) | ((RM << inst_cream->imm) & 0xFFFF0000);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(pkh_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
PKHTB_INST:
+ {
+ INC_ICOUNTER;
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ pkh_inst *inst_cream = (pkh_inst *)inst_base->component;
+ int shift_imm = inst_cream->imm ? inst_cream->imm : 31;
+ RD = ((static_cast<s32>(RM) >> shift_imm) & 0xFFFF) | (RN & 0xFFFF0000);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(pkh_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
PLD_INST:
{
INC_ICOUNTER;
@@ -6622,15 +6794,95 @@ unsigned InterpreterMainLoop(ARMul_State* state)
FETCH_INST;
GOTO_NEXT_INST;
}
- UADD16_INST:
UADD8_INST:
+ UADD16_INST:
UADDSUBX_INST:
- UHADD16_INST:
+
UHADD8_INST:
+ UHADD16_INST:
UHADDSUBX_INST:
- UHSUB16_INST:
- UHSUB8_INST:
UHSUBADDX_INST:
+ UHSUB8_INST:
+ UHSUB16_INST:
+ {
+ INC_ICOUNTER;
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+ const u8 op2 = inst_cream->op2;
+
+
+ if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
+ {
+ u32 lo_val = 0;
+ u32 hi_val = 0;
+
+ // UHADD16
+ if (op2 == 0x00) {
+ lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+ }
+ // UHASX
+ else if (op2 == 0x01) {
+ lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
+ }
+ // UHSAX
+ else if (op2 == 0x02) {
+ lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
+ }
+ // UHSUB16
+ else if (op2 == 0x03) {
+ lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+ }
+
+ lo_val >>= 1;
+ hi_val >>= 1;
+
+ RD = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
+ }
+ else if (op2 == 0x04 || op2 == 0x07) {
+ u32 sum1;
+ u32 sum2;
+ u32 sum3;
+ u32 sum4;
+
+ // UHADD8
+ if (op2 == 0x04) {
+ sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
+ sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
+ sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
+ sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
+ }
+ // UHSUB8
+ else {
+ sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
+ sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
+ sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
+ sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
+ }
+
+ sum1 >>= 1;
+ sum2 >>= 1;
+ sum3 >>= 1;
+ sum4 >>= 1;
+
+ RD = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
+ }
+
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+
UMAAL_INST:
{
INC_ICOUNTER;
@@ -6764,14 +7016,101 @@ unsigned InterpreterMainLoop(ARMul_State* state)
goto DISPATCH;
}
- UQADD16_INST:
UQADD8_INST:
+ UQADD16_INST:
UQADDSUBX_INST:
- UQSUB16_INST:
UQSUB8_INST:
+ UQSUB16_INST:
UQSUBADDX_INST:
+ {
+ INC_ICOUNTER;
+
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const u8 op2 = inst_cream->op2;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ u16 lo_val = 0;
+ u16 hi_val = 0;
+
+ // UQADD16
+ if (op2 == 0x00) {
+ lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ }
+ // UQASX
+ else if (op2 == 0x01) {
+ lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ }
+ // UQSAX
+ else if (op2 == 0x02) {
+ lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ }
+ // UQSUB16
+ else if (op2 == 0x03) {
+ lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ }
+ // UQADD8
+ else if (op2 == 0x04) {
+ lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
+ ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
+ hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
+ ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
+ }
+ // UQSUB8
+ else {
+ lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
+ ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
+ hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
+ ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
+ }
+
+ RD = ((lo_val & 0xFFFF) | hi_val << 16);
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
USAD8_INST:
USADA8_INST:
+ {
+ INC_ICOUNTER;
+
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+
+ const u8 ra_idx = inst_cream->Ra;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
+ const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
+ const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
+ const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
+
+ u32 finalDif = (diff1 + diff2 + diff3 + diff4);
+
+ // Op is USADA8 if true.
+ if (ra_idx != 15)
+ finalDif += cpu->Reg[ra_idx];
+
+ RD = finalDif;
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
USAT_INST:
USAT16_INST:
USUB16_INST:
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index d54dbeac5..f0d349de7 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -3100,7 +3100,6 @@ mainswitch:
break;
case 0x68: /* Store Word, No WriteBack, Post Inc, Reg. */
- //ichfly PKHBT PKHTB todo check this
if ((instr & 0x70) == 0x10) { //pkhbt
u8 idest = BITS(12, 15);
u8 rfis = BITS(16, 19);
@@ -3109,18 +3108,11 @@ mainswitch:
state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
break;
} else if ((instr & 0x70) == 0x50) { //pkhtb
- const u8 rd_idx = BITS(12, 15);
- const u8 rn_idx = BITS(16, 19);
- const u8 rm_idx = BITS(0, 3);
- const u8 imm5 = BITS(7, 11);
-
- ARMword val;
- if (imm5 >= 32)
- val = (state->Reg[rm_idx] >> 31);
- else
- val = (state->Reg[rm_idx] >> imm5);
-
- state->Reg[rd_idx] = (val & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
+ u8 rd_idx = BITS(12, 15);
+ u8 rn_idx = BITS(16, 19);
+ u8 rm_idx = BITS(0, 3);
+ u8 imm5 = BITS(7, 11) ? BITS(7, 11) : 31;
+ state->Reg[rd_idx] = ((static_cast<s32>(state->Reg[rm_idx]) >> imm5) & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
break;
} else if (BIT (4)) {
#ifdef MODE32
@@ -6117,30 +6109,130 @@ L_stm_s_takeabort:
}
printf("Unhandled v6 insn: uasx/usax\n");
break;
- case 0x66:
- if ((instr & 0x0FF00FF0) == 0x06600FF0) { //uqsub8
- u32 rd = (instr >> 12) & 0xF;
- u32 rm = (instr >> 16) & 0xF;
- u32 rn = (instr >> 0) & 0xF;
- u32 subfrom = state->Reg[rm];
- u32 tosub = state->Reg[rn];
-
- u8 b1 = (u8)((u8)(subfrom)-(u8)(tosub));
- if (b1 > (u8)(subfrom)) b1 = 0;
- u8 b2 = (u8)((u8)(subfrom >> 8) - (u8)(tosub >> 8));
- if (b2 > (u8)(subfrom >> 8)) b2 = 0;
- u8 b3 = (u8)((u8)(subfrom >> 16) - (u8)(tosub >> 16));
- if (b3 > (u8)(subfrom >> 16)) b3 = 0;
- u8 b4 = (u8)((u8)(subfrom >> 24) - (u8)(tosub >> 24));
- if (b4 > (u8)(subfrom >> 24)) b4 = 0;
- state->Reg[rd] = (u32)(b1 | b2 << 8 | b3 << 16 | b4 << 24);
+ case 0x66: // UQADD16, UQASX, UQSAX, UQSUB16, UQADD8, and UQSUB8
+ {
+ const u8 rd_idx = BITS(12, 15);
+ const u8 rm_idx = BITS(0, 3);
+ const u8 rn_idx = BITS(16, 19);
+ const u8 op2 = BITS(5, 7);
+ const u32 rm_val = state->Reg[rm_idx];
+ const u32 rn_val = state->Reg[rn_idx];
+
+ u16 lo_val = 0;
+ u16 hi_val = 0;
+
+ // UQADD16
+ if (op2 == 0x00) {
+ lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, rm_val & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ }
+ // UQASX
+ else if (op2 == 0x01) {
+ lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedAdd16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ }
+ // UQSAX
+ else if (op2 == 0x02) {
+ lo_val = ARMul_UnsignedSaturatedAdd16(rn_val & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, rm_val & 0xFFFF);
+ }
+ // UQSUB16
+ else if (op2 == 0x03) {
+ lo_val = ARMul_UnsignedSaturatedSub16(rn_val & 0xFFFF, rm_val & 0xFFFF);
+ hi_val = ARMul_UnsignedSaturatedSub16((rn_val >> 16) & 0xFFFF, (rm_val >> 16) & 0xFFFF);
+ }
+ // UQADD8
+ else if (op2 == 0x04) {
+ lo_val = ARMul_UnsignedSaturatedAdd8(rn_val, rm_val) |
+ ARMul_UnsignedSaturatedAdd8(rn_val >> 8, rm_val >> 8) << 8;
+ hi_val = ARMul_UnsignedSaturatedAdd8(rn_val >> 16, rm_val >> 16) |
+ ARMul_UnsignedSaturatedAdd8(rn_val >> 24, rm_val >> 24) << 8;
+ }
+ // UQSUB8
+ else {
+ lo_val = ARMul_UnsignedSaturatedSub8(rn_val, rm_val) |
+ ARMul_UnsignedSaturatedSub8(rn_val >> 8, rm_val >> 8) << 8;
+ hi_val = ARMul_UnsignedSaturatedSub8(rn_val >> 16, rm_val >> 16) |
+ ARMul_UnsignedSaturatedSub8(rn_val >> 24, rm_val >> 24) << 8;
+ }
+
+ state->Reg[rd_idx] = ((lo_val & 0xFFFF) | hi_val << 16);
return 1;
- } else {
- printf ("Unhandled v6 insn: uqsub16\n");
}
break;
- case 0x67:
- printf ("Unhandled v6 insn: uhadd/uhsub\n");
+ case 0x67: // UHADD16, UHASX, UHSAX, UHSUB16, UHADD8, and UHSUB8.
+ {
+ const u8 op2 = BITS(5, 7);
+
+ const u8 rm_idx = BITS(0, 3);
+ const u8 rn_idx = BITS(16, 19);
+ const u8 rd_idx = BITS(12, 15);
+
+ const u32 rm_val = state->Reg[rm_idx];
+ const u32 rn_val = state->Reg[rn_idx];
+
+ if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03)
+ {
+ u32 lo_val = 0;
+ u32 hi_val = 0;
+
+ // UHADD16
+ if (op2 == 0x00) {
+ lo_val = (rn_val & 0xFFFF) + (rm_val & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+ }
+ // UHASX
+ else if (op2 == 0x01) {
+ lo_val = (rn_val & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) + (rm_val & 0xFFFF);
+ }
+ // UHSAX
+ else if (op2 == 0x02) {
+ lo_val = (rn_val & 0xFFFF) + ((rm_val >> 16) & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) - (rm_val & 0xFFFF);
+ }
+ // UHSUB16
+ else if (op2 == 0x03) {
+ lo_val = (rn_val & 0xFFFF) - (rm_val & 0xFFFF);
+ hi_val = ((rn_val >> 16) & 0xFFFF) - ((rm_val >> 16) & 0xFFFF);
+ }
+
+ lo_val >>= 1;
+ hi_val >>= 1;
+
+ state->Reg[rd_idx] = (lo_val & 0xFFFF) | ((hi_val & 0xFFFF) << 16);
+ return 1;
+ }
+ else if (op2 == 0x04 || op2 == 0x07) {
+ u32 sum1;
+ u32 sum2;
+ u32 sum3;
+ u32 sum4;
+
+ // UHADD8
+ if (op2 == 0x04) {
+ sum1 = (rn_val & 0xFF) + (rm_val & 0xFF);
+ sum2 = ((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF);
+ sum3 = ((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF);
+ sum4 = ((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF);
+ }
+ // UHSUB8
+ else {
+ sum1 = (rn_val & 0xFF) - (rm_val & 0xFF);
+ sum2 = ((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF);
+ sum3 = ((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF);
+ sum4 = ((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF);
+ }
+
+ sum1 >>= 1;
+ sum2 >>= 1;
+ sum3 >>= 1;
+ sum4 >>= 1;
+
+ state->Reg[rd_idx] = (sum1 & 0xFF) | ((sum2 & 0xFF) << 8) | ((sum3 & 0xFF) << 16) | ((sum4 & 0xFF) << 24);
+ return 1;
+ }
+ }
break;
case 0x68:
{
@@ -6172,129 +6264,94 @@ L_stm_s_takeabort:
return 1;
}
}
- printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
- break;
- case 0x6a: {
- ARMword Rm;
- int ror = -1;
-
- switch (BITS(4, 11)) {
- case 0x07:
- ror = 0;
- break;
- case 0x47:
- ror = 8;
- break;
- case 0x87:
- ror = 16;
- break;
- case 0xc7:
- ror = 24;
- break;
-
- case 0x01:
- case 0xf3:
- //ichfly
- //SSAT16
- {
- const u8 rd_idx = BITS(12, 15);
- const u8 rn_idx = BITS(0, 3);
- const u8 num_bits = BITS(16, 19) + 1;
- const s16 min = -(0x8000 >> (16 - num_bits));
- const s16 max = (0x7FFF >> (16 - num_bits));
- s16 rn_lo = (state->Reg[rn_idx]);
- s16 rn_hi = (state->Reg[rn_idx] >> 16);
-
- if (rn_lo > max) {
- rn_lo = max;
- SETQ;
- } else if (rn_lo < min) {
- rn_lo = min;
- SETQ;
- }
-
- if (rn_hi > max) {
- rn_hi = max;
- SETQ;
- } else if (rn_hi < min) {
- rn_hi = min;
- SETQ;
- }
-
- state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
- return 1;
- }
+ printf("Unhandled v6 insn: pkh/sxtab/selsxtb\n");
+ break;
- default:
- break;
- }
+ case 0x6a: // SSAT, SSAT16, SXTB, and SXTAB
+ {
+ const u8 op2 = BITS(5, 7);
- if (ror == -1) {
- if (BITS(4, 6) == 0x7) {
- printf("Unhandled v6 insn: ssat\n");
- return 0;
+ // SSAT16
+ if (op2 == 0x01) {
+ const u8 rd_idx = BITS(12, 15);
+ const u8 rn_idx = BITS(0, 3);
+ const u8 num_bits = BITS(16, 19) + 1;
+ const s16 min = -(0x8000 >> (16 - num_bits));
+ const s16 max = (0x7FFF >> (16 - num_bits));
+ s16 rn_lo = (state->Reg[rn_idx]);
+ s16 rn_hi = (state->Reg[rn_idx] >> 16);
+
+ if (rn_lo > max) {
+ rn_lo = max;
+ SETQ;
+ } else if (rn_lo < min) {
+ rn_lo = min;
+ SETQ;
}
- break;
- }
- Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF);
- if (Rm & 0x80)
- Rm |= 0xffffff00;
+ if (rn_hi > max) {
+ rn_hi = max;
+ SETQ;
+ } else if (rn_hi < min) {
+ rn_hi = min;
+ SETQ;
+ }
- if (BITS(16, 19) == 0xf)
- /* SXTB */
- state->Reg[BITS(12, 15)] = Rm;
- else
- /* SXTAB */
- state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
+ state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi & 0xFFFF) << 16);
+ return 1;
+ }
+ else if (op2 == 0x03) {
+ const u8 rotation = BITS(10, 11) * 8;
+ u32 rm = ((state->Reg[BITS(0, 3)] >> rotation) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotation)) & 0xFF) & 0xFF);
+ if (rm & 0x80)
+ rm |= 0xffffff00;
+
+ // SXTB, otherwise SXTAB
+ if (BITS(16, 19) == 0xf)
+ state->Reg[BITS(12, 15)] = rm;
+ else
+ state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
- return 1;
+ return 1;
+ }
+ else {
+ printf("Unimplemented op: SSAT");
+ }
}
- case 0x6b:
+ break;
+
+ case 0x6b: // REV, REV16, SXTH, and SXTAH
{
- ARMword Rm;
- int ror = -1;
-
- switch (BITS(4, 11)) {
- case 0x07:
- ror = 0;
- break;
- case 0x47:
- ror = 8;
- break;
- case 0x87:
- ror = 16;
- break;
- case 0xc7:
- ror = 24;
- break;
-
- case 0xf3: // REV
- DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
- return 1;
- case 0xfb: // REV16
- DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
- return 1;
- default:
- break;
- }
+ const u8 op2 = BITS(5, 7);
- if (ror == -1)
- break;
+ // REV
+ if (op2 == 0x01) {
+ DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
+ return 1;
+ }
+ // REV16
+ else if (op2 == 0x05) {
+ DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
+ return 1;
+ }
+ else if (op2 == 0x03) {
+ const u8 rotate = BITS(10, 11) * 8;
- Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF);
- if (Rm & 0x8000)
- Rm |= 0xffff0000;
+ u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
+ if (rm & 0x8000)
+ rm |= 0xffff0000;
- if (BITS(16, 19) == 0xf)
- /* SXTH */
- state->Reg[BITS(12, 15)] = Rm;
- else
- /* SXTAH */
- state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
+ // SXTH, otherwise SXTAH
+ if (BITS(16, 19) == 15)
+ state->Reg[BITS(12, 15)] = rm;
+ else
+ state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
- return 1;
+ return 1;
+ }
}
+ break;
+
case 0x6c: // UXTB16 and UXTAB16
{
const u8 rm_idx = BITS(0, 3);
@@ -6322,132 +6379,84 @@ L_stm_s_takeabort:
return 1;
}
break;
- case 0x6e: {
- ARMword Rm;
- int ror = -1;
-
- switch (BITS(4, 11)) {
- case 0x07:
- ror = 0;
- break;
- case 0x47:
- ror = 8;
- break;
- case 0x87:
- ror = 16;
- break;
- case 0xc7:
- ror = 24;
- break;
-
- case 0x01:
- case 0xf3:
- //ichfly
- //USAT16
- {
- const u8 rd_idx = BITS(12, 15);
- const u8 rn_idx = BITS(0, 3);
- const u8 num_bits = BITS(16, 19);
- const s16 max = 0xFFFF >> (16 - num_bits);
- s16 rn_lo = (state->Reg[rn_idx]);
- s16 rn_hi = (state->Reg[rn_idx] >> 16);
-
- if (max < rn_lo) {
- rn_lo = max;
- SETQ;
- } else if (rn_lo < 0) {
- rn_lo = 0;
- SETQ;
- }
-
- if (max < rn_hi) {
- rn_hi = max;
- SETQ;
- } else if (rn_hi < 0) {
- rn_hi = 0;
- SETQ;
- }
-
- state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
- return 1;
- }
-
- default:
- break;
- }
+ case 0x6e: // USAT, USAT16, UXTB, and UXTAB
+ {
+ const u8 op2 = BITS(5, 7);
- if (ror == -1) {
- if (BITS(4, 6) == 0x7) {
- printf("Unhandled v6 insn: usat\n");
- return 0;
+ // USAT16
+ if (op2 == 0x01) {
+ const u8 rd_idx = BITS(12, 15);
+ const u8 rn_idx = BITS(0, 3);
+ const u8 num_bits = BITS(16, 19);
+ const s16 max = 0xFFFF >> (16 - num_bits);
+ s16 rn_lo = (state->Reg[rn_idx]);
+ s16 rn_hi = (state->Reg[rn_idx] >> 16);
+
+ if (max < rn_lo) {
+ rn_lo = max;
+ SETQ;
+ } else if (rn_lo < 0) {
+ rn_lo = 0;
+ SETQ;
+ }
+
+ if (max < rn_hi) {
+ rn_hi = max;
+ SETQ;
+ } else if (rn_hi < 0) {
+ rn_hi = 0;
+ SETQ;
}
- break;
+
+ state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
+ return 1;
}
-
- Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF);
-
- if (BITS(16, 19) == 0xf)
+ else if (op2 == 0x03) {
+ const u8 rotate = BITS(10, 11) * 8;
+ const u32 rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFF) & 0xFF);
+
+ if (BITS(16, 19) == 0xf)
/* UXTB */
- state->Reg[BITS(12, 15)] = Rm;
- else
+ state->Reg[BITS(12, 15)] = rm;
+ else
/* UXTAB */
- state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
+ state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
- return 1;
- }
-
- case 0x6f: {
- ARMword Rm;
- int ror = -1;
-
- switch (BITS(4, 11)) {
- case 0x07:
- ror = 0;
- break;
- case 0x47:
- ror = 8;
- break;
- case 0x87:
- ror = 16;
- break;
- case 0xc7:
- ror = 24;
- break;
-
- case 0xfb: // REVSH
- {
- DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
- if (DEST & 0x8000)
- DEST |= 0xffff0000;
- return 1;
- }
- default:
- break;
+ return 1;
}
+ else {
+ printf("Unimplemented op: USAT");
+ }
+ }
+ break;
- if (ror == -1)
- break;
-
- Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF);
+ case 0x6f: // UXTH, UXTAH, and REVSH.
+ {
+ const u8 op2 = BITS(5, 7);
- /* UXT */
- /* state->Reg[BITS (12, 15)] = Rm; */
- /* dyf add */
- if (BITS(16, 19) == 0xf) {
- state->Reg[BITS(12, 15)] = Rm;
- }
- else {
- /* UXTAH */
- /* state->Reg[BITS (12, 15)] = state->Reg [BITS (16, 19)] + Rm; */
- // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
- // , Rm, BITS(10, 11));
- // printf("icounter is %lld\n", state->NumInstrs);
- state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
- // printf("rd is %x\n", state->Reg[BITS (12, 15)]);
- // exit(-1);
+ // REVSH
+ if (op2 == 0x05) {
+ DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
+ if (DEST & 0x8000)
+ DEST |= 0xffff0000;
+ return 1;
}
+ // UXTH and UXTAH
+ else if (op2 == 0x03) {
+ const u8 rotate = BITS(10, 11) * 8;
+ const ARMword rm = ((state->Reg[BITS(0, 3)] >> rotate) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - rotate)) & 0xFFFF) & 0xFFFF);
+
+ // UXTH
+ if (BITS(16, 19) == 0xf) {
+ state->Reg[BITS(12, 15)] = rm;
+ }
+ // UXTAH
+ else {
+ state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
+ }
- return 1;
+ return 1;
+ }
}
case 0x70:
// ichfly
@@ -6572,10 +6581,10 @@ L_stm_s_takeabort:
const u32 rm_val = state->Reg[rm_idx];
const u32 rn_val = state->Reg[rn_idx];
- const u8 diff1 = (u8)std::labs((rn_val & 0xFF) - (rm_val & 0xFF));
- const u8 diff2 = (u8)std::labs(((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF));
- const u8 diff3 = (u8)std::labs(((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF));
- const u8 diff4 = (u8)std::labs(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF));
+ const u8 diff1 = ARMul_UnsignedAbsoluteDifference(rn_val & 0xFF, rm_val & 0xFF);
+ const u8 diff2 = ARMul_UnsignedAbsoluteDifference((rn_val >> 8) & 0xFF, (rm_val >> 8) & 0xFF);
+ const u8 diff3 = ARMul_UnsignedAbsoluteDifference((rn_val >> 16) & 0xFF, (rm_val >> 16) & 0xFF);
+ const u8 diff4 = ARMul_UnsignedAbsoluteDifference((rn_val >> 24) & 0xFF, (rm_val >> 24) & 0xFF);
u32 finalDif = (diff1 + diff2 + diff3 + diff4);
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 6774f8a74..8f158e2c8 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -392,6 +392,15 @@ ARMul_NthReg (ARMword instr, unsigned number)
return (bit - 1);
}
+/* Unsigned sum of absolute difference */
+u8 ARMul_UnsignedAbsoluteDifference(u8 left, u8 right)
+{
+ if (left > right)
+ return left - right;
+
+ return right - left;
+}
+
/* Assigns the N and Z flags depending on the value of result. */
void
@@ -469,6 +478,47 @@ ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
ASSIGNV (SubOverflow (a, b, result));
}
+/* 8-bit unsigned saturated addition */
+u8 ARMul_UnsignedSaturatedAdd8(u8 left, u8 right)
+{
+ u8 result = left + right;
+
+ if (result < left)
+ result = 0xFF;
+
+ return result;
+}
+
+/* 16-bit unsigned saturated addition */
+u16 ARMul_UnsignedSaturatedAdd16(u16 left, u16 right)
+{
+ u16 result = left + right;
+
+ if (result < left)
+ result = 0xFFFF;
+
+ return result;
+}
+
+/* 8-bit unsigned saturated subtraction */
+u8 ARMul_UnsignedSaturatedSub8(u8 left, u8 right)
+{
+ if (left <= right)
+ return 0;
+
+ return left - right;
+}
+
+/* 16-bit unsigned saturated subtraction */
+u16 ARMul_UnsignedSaturatedSub16(u16 left, u16 right)
+{
+ if (left <= right)
+ return 0;
+
+ return left - right;
+}
+
+
/* This function does the work of generating the addresses used in an
LDC instruction. The code here is always post-indexed, it's up to the
caller to get the input address correct and to handle base register
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 34eb5aaf7..c7509fcb2 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -790,6 +790,12 @@ extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword);
extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...);
extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
+extern u8 ARMul_UnsignedSaturatedAdd8(u8, u8);
+extern u16 ARMul_UnsignedSaturatedAdd16(u16, u16);
+extern u8 ARMul_UnsignedSaturatedSub8(u8, u8);
+extern u16 ARMul_UnsignedSaturatedSub16(u16, u16);
+extern u8 ARMul_UnsignedAbsoluteDifference(u8, u8);
+
#define DIFF_LOG 0
#define SAVE_LOG 0
diff --git a/src/core/arm/skyeye_common/vfp/vfp.cpp b/src/core/arm/skyeye_common/vfp/vfp.cpp
index 454f60099..5c036caeb 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfp.cpp
@@ -32,8 +32,7 @@
//ARMul_State* persistent_state; /* function calls from SoftFloat lib don't have an access to ARMul_state. */
-unsigned
-VFPInit (ARMul_State *state)
+unsigned VFPInit(ARMul_State* state)
{
state->VFP[VFP_OFFSET(VFP_FPSID)] = VFP_FPSID_IMPLMEN<<24 | VFP_FPSID_SW<<23 | VFP_FPSID_SUBARCH<<16 |
VFP_FPSID_PARTNUM<<8 | VFP_FPSID_VARIANT<<4 | VFP_FPSID_REVISION;
@@ -46,8 +45,7 @@ VFPInit (ARMul_State *state)
return 0;
}
-unsigned
-VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
+unsigned VFPMRC(ARMul_State* state, unsigned type, u32 instr, u32* value)
{
/* MRC<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -61,10 +59,21 @@ VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
/* CRn/opc1 CRm/opc2 */
- if (CoProc == 10 || CoProc == 11) {
-#define VFP_MRC_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_MRC_TRANS
+ if (CoProc == 10 || CoProc == 11)
+ {
+ if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
+ {
+ /* VMOV r to s */
+ /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
+ VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value);
+ return ARMul_DONE;
+ }
+
+ if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
+ {
+ VMRS(state, CRn, Rt, value);
+ return ARMul_DONE;
+ }
}
DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
@@ -72,8 +81,7 @@ VFPMRC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
return ARMul_CANT;
}
-unsigned
-VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
+unsigned VFPMCR(ARMul_State* state, unsigned type, u32 instr, u32 value)
{
/* MCR<c> <coproc>,<opc1>,<Rt>,<CRn>,<CRm>{,<opc2>} */
int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -86,10 +94,33 @@ VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
/* TODO check access permission */
/* CRn/opc1 CRm/opc2 */
- if (CoProc == 10 || CoProc == 11) {
-#define VFP_MCR_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_MCR_TRANS
+ if (CoProc == 10 || CoProc == 11)
+ {
+ if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
+ {
+ /* VMOV s to r */
+ /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
+ VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value);
+ return ARMul_DONE;
+ }
+
+ if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
+ {
+ VMSR(state, CRn, Rt);
+ return ARMul_DONE;
+ }
+
+ if ((OPC_1 & 0x4) == 0 && CoProc == 11 && CRm == 0)
+ {
+ VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
+ return ARMul_DONE;
+ }
+
+ if (CoProc == 11 && CRm == 0)
+ {
+ VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
+ return ARMul_DONE;
+ }
}
DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, CRn %x, CRm %x, OPC_2 %x\n",
instr, CoProc, OPC_1, Rt, CRn, CRm, OPC_2);
@@ -97,8 +128,7 @@ VFPMCR (ARMul_State * state, unsigned type, u32 instr, u32 value)
return ARMul_CANT;
}
-unsigned
-VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * value2)
+unsigned VFPMRRC(ARMul_State* state, unsigned type, u32 instr, u32* value1, u32* value2)
{
/* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -107,10 +137,20 @@ VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * valu
int Rt2 = BITS (16, 19);
int CRm = BITS (0, 3);
- if (CoProc == 10 || CoProc == 11) {
-#define VFP_MRRC_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_MRRC_TRANS
+ if (CoProc == 10 || CoProc == 11)
+ {
+ if (CoProc == 10 && (OPC_1 & 0xD) == 1)
+ {
+ VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
+ return ARMul_DONE;
+ }
+
+ if (CoProc == 11 && (OPC_1 & 0xD) == 1)
+ {
+ /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
+ VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2);
+ return ARMul_DONE;
+ }
}
DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
instr, CoProc, OPC_1, Rt, Rt2, CRm);
@@ -118,8 +158,7 @@ VFPMRRC (ARMul_State * state, unsigned type, u32 instr, u32 * value1, u32 * valu
return ARMul_CANT;
}
-unsigned
-VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
+unsigned VFPMCRR(ARMul_State* state, unsigned type, u32 instr, u32 value1, u32 value2)
{
/* MCRR<c> <coproc>,<opc1>,<Rt>,<Rt2>,<CRm> */
int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -132,10 +171,20 @@ VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
/* CRn/opc1 CRm/opc2 */
- if (CoProc == 11 || CoProc == 10) {
-#define VFP_MCRR_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_MCRR_TRANS
+ if (CoProc == 11 || CoProc == 10)
+ {
+ if (CoProc == 10 && (OPC_1 & 0xD) == 1)
+ {
+ VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
+ return ARMul_DONE;
+ }
+
+ if (CoProc == 11 && (OPC_1 & 0xD) == 1)
+ {
+ /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
+ VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2);
+ return ARMul_DONE;
+ }
}
DEBUG("Can't identify %x, CoProc %x, OPC_1 %x, Rt %x, Rt2 %x, CRm %x\n",
instr, CoProc, OPC_1, Rt, Rt2, CRm);
@@ -143,8 +192,7 @@ VFPMCRR (ARMul_State * state, unsigned type, u32 instr, u32 value1, u32 value2)
return ARMul_CANT;
}
-unsigned
-VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
+unsigned VFPSTC(ARMul_State* state, unsigned type, u32 instr, u32 * value)
{
/* STC{L}<c> <coproc>,<CRd>,[<Rn>],<option> */
int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -175,9 +223,17 @@ VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
}
#endif
-#define VFP_STC_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_STC_TRANS
+ if (P == 1 && W == 0)
+ {
+ return VSTR(state, type, instr, value);
+ }
+
+ if (P == 1 && U == 0 && W == 1 && Rn == 0xD)
+ {
+ return VPUSH(state, type, instr, value);
+ }
+
+ return VSTM(state, type, instr, value);
}
DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
instr, CoProc, CRd, Rn, imm8, P, U, D, W);
@@ -185,8 +241,7 @@ VFPSTC (ARMul_State * state, unsigned type, u32 instr, u32 * value)
return ARMul_CANT;
}
-unsigned
-VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
+unsigned VFPLDC(ARMul_State* state, unsigned type, u32 instr, u32 value)
{
/* LDC{L}<c> <coproc>,<CRd>,[<Rn>] */
int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -204,10 +259,19 @@ VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
DEBUG("In %s, UNDEFINED\n", __FUNCTION__);
exit(-1);
}
- if (CoProc == 10 || CoProc == 11) {
-#define VFP_LDC_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_LDC_TRANS
+ if (CoProc == 10 || CoProc == 11)
+ {
+ if (P == 1 && W == 0)
+ {
+ return VLDR(state, type, instr, value);
+ }
+
+ if (P == 0 && U == 1 && W == 1 && Rn == 0xD)
+ {
+ return VPOP(state, type, instr, value);
+ }
+
+ return VLDM(state, type, instr, value);
}
DEBUG("Can't identify %x, CoProc %x, CRd %x, Rn %x, imm8 %x, P %x, U %x, D %x, W %x\n",
instr, CoProc, CRd, Rn, imm8, P, U, D, W);
@@ -215,8 +279,7 @@ VFPLDC (ARMul_State * state, unsigned type, u32 instr, u32 value)
return ARMul_CANT;
}
-unsigned
-VFPCDP (ARMul_State * state, unsigned type, u32 instr)
+unsigned VFPCDP(ARMul_State* state, unsigned type, u32 instr)
{
/* CDP<c> <coproc>,<opc1>,<CRd>,<CRn>,<CRm>,<opc2> */
int CoProc = BITS (8, 11); /* 10 or 11 */
@@ -275,10 +338,83 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
/* CRn/opc1 CRm/opc2 */
- if (CoProc == 10 || CoProc == 11) {
-#define VFP_CDP_TRANS
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_CDP_TRANS
+ if (CoProc == 10 || CoProc == 11)
+ {
+ if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0)
+ DBG("VMLA :\n");
+
+ if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2)
+ DBG("VMLS :\n");
+
+ if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2)
+ DBG("VNMLA :\n");
+
+ if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0)
+ DBG("VNMLS :\n");
+
+ if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2)
+ DBG("VNMUL :\n");
+
+ if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0)
+ DBG("VMUL :\n");
+
+ if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0)
+ DBG("VADD :\n");
+
+ if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 2)
+ DBG("VSUB :\n");
+
+ if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0)
+ DBG("VDIV :\n");
+
+ if ((OPC_1 & 0xB) == 0xB && BITS(4, 7) == 0)
+ {
+ unsigned int single = BIT(8) == 0;
+ unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
+ unsigned int imm;
+ instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */
+
+ if (single)
+ imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19;
+ else
+ imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16;
+
+ VMOVI(state, single, d, imm);
+ return ARMul_DONE;
+ }
+
+ if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x6) == 0x2)
+ {
+ unsigned int single = BIT(8) == 0;
+ unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
+ unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);;
+ VMOVR(state, single, d, m);
+ return ARMul_DONE;
+ }
+
+ if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6)
+ DBG("VABS :\n");
+
+ if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2)
+ DBG("VNEG :\n");
+
+ if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6)
+ DBG("VSQRT :\n");
+
+ if ((OPC_1 & 0xB) == 0xB && CRn == 4 && (OPC_2 & 0x2) == 2)
+ DBG("VCMP(1) :\n");
+
+ if ((OPC_1 & 0xB) == 0xB && CRn == 5 && (OPC_2 & 0x2) == 2 && CRm == 0)
+ DBG("VCMP(2) :\n");
+
+ if ((OPC_1 & 0xB) == 0xB && CRn == 7 && (OPC_2 & 0x6) == 6)
+ DBG("VCVT(BDS) :\n");
+
+ if ((OPC_1 & 0xB) == 0xB && CRn >= 0xA && (OPC_2 & 0x2) == 2)
+ DBG("VCVT(BFF) :\n");
+
+ if ((OPC_1 & 0xB) == 0xB && CRn > 7 && (OPC_2 & 0x2) == 2)
+ DBG("VCVT(BFI) :\n");
int exceptions = 0;
if (CoProc == 10)
@@ -296,23 +432,93 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
/* ----------- MRC ------------ */
-#define VFP_MRC_IMPL
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_MRC_IMPL
-
-#define VFP_MRRC_IMPL
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_MRRC_IMPL
-
+void VMOVBRS(ARMul_State* state, ARMword to_arm, ARMword t, ARMword n, ARMword* value)
+{
+ DBG("VMOV(BRS) :\n");
+ if (to_arm)
+ {
+ DBG("\tr%d <= s%d=[%x]\n", t, n, state->ExtReg[n]);
+ *value = state->ExtReg[n];
+ }
+ else
+ {
+ DBG("\ts%d <= r%d=[%x]\n", n, t, *value);
+ state->ExtReg[n] = *value;
+ }
+}
+void VMRS(ARMul_State* state, ARMword reg, ARMword Rt, ARMword* value)
+{
+ DBG("VMRS :");
+ if (reg == 1)
+ {
+ if (Rt != 15)
+ {
+ *value = state->VFP[VFP_OFFSET(VFP_FPSCR)];
+ DBG("\tr%d <= fpscr[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ }
+ else
+ {
+ *value = state->VFP[VFP_OFFSET(VFP_FPSCR)] ;
+ DBG("\tflags <= fpscr[%1xxxxxxxx]\n", state->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
+ }
+ }
+ else
+ {
+ switch (reg)
+ {
+ case 0:
+ *value = state->VFP[VFP_OFFSET(VFP_FPSID)];
+ DBG("\tr%d <= fpsid[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSID)]);
+ break;
+ case 6:
+ /* MVFR1, VFPv3 only ? */
+ DBG("\tr%d <= MVFR1 unimplemented\n", Rt);
+ break;
+ case 7:
+ /* MVFR0, VFPv3 only? */
+ DBG("\tr%d <= MVFR0 unimplemented\n", Rt);
+ break;
+ case 8:
+ *value = state->VFP[VFP_OFFSET(VFP_FPEXC)];
+ DBG("\tr%d <= fpexc[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPEXC)]);
+ break;
+ default:
+ DBG("\tSUBARCHITECTURE DEFINED\n");
+ break;
+ }
+ }
+}
+void VMOVBRRD(ARMul_State* state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword* value1, ARMword* value2)
+{
+ DBG("VMOV(BRRD) :\n");
+ if (to_arm)
+ {
+ DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n*2+1, n*2, state->ExtReg[n*2+1], state->ExtReg[n*2]);
+ *value2 = state->ExtReg[n*2+1];
+ *value1 = state->ExtReg[n*2];
+ }
+ else
+ {
+ DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n*2+1, n*2, t2, t, *value2, *value1);
+ state->ExtReg[n*2+1] = *value2;
+ state->ExtReg[n*2] = *value1;
+ }
+}
/* ----------- MCR ------------ */
-#define VFP_MCR_IMPL
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_MCR_IMPL
-
-#define VFP_MCRR_IMPL
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_MCRR_IMPL
+void VMSR(ARMul_State* state, ARMword reg, ARMword Rt)
+{
+ if (reg == 1)
+ {
+ DBG("VMSR :\tfpscr <= r%d=[%x]\n", Rt, state->Reg[Rt]);
+ state->VFP[VFP_OFFSET(VFP_FPSCR)] = state->Reg[Rt];
+ }
+ else if (reg == 8)
+ {
+ DBG("VMSR :\tfpexc <= r%d=[%x]\n", Rt, state->Reg[Rt]);
+ state->VFP[VFP_OFFSET(VFP_FPEXC)] = state->Reg[Rt];
+ }
+}
/* Memory operation are not inlined, as old Interpreter and Fast interpreter
don't have the same memory operation interface.
@@ -322,21 +528,342 @@ VFPCDP (ARMul_State * state, unsigned type, u32 instr)
of vfp instructions in old interpreter and fast interpreter are separate. */
/* ----------- STC ------------ */
-#define VFP_STC_IMPL
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_STC_IMPL
+int VSTR(ARMul_State* state, int type, ARMword instr, ARMword* value)
+{
+ static int i = 0;
+ static int single_reg, add, d, n, imm32, regs;
+ if (type == ARMul_FIRST)
+ {
+ single_reg = BIT(8) == 0; /* Double precision */
+ add = BIT(23); /* */
+ imm32 = BITS(0,7)<<2; /* may not be used */
+ d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
+ n = BITS(16, 19); /* destination register */
+ DBG("VSTR :\n");
+
+ i = 0;
+ regs = 1;
+
+ return ARMul_DONE;
+ }
+ else if (type == ARMul_DATA)
+ {
+ if (single_reg)
+ {
+ *value = state->ExtReg[d+i];
+ DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d+i]);
+ i++;
+ if (i < regs)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ else
+ {
+ /* FIXME Careful of endianness, may need to rework this */
+ *value = state->ExtReg[d*2+i];
+ DBG("\taddr[?] <= s[%d]=[%x]\n", d*2+i, state->ExtReg[d*2+i]);
+ i++;
+ if (i < regs*2)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ }
+
+ return -1;
+}
+int VPUSH(ARMul_State* state, int type, ARMword instr, ARMword* value)
+{
+ static int i = 0;
+ static int single_regs, add, wback, d, n, imm32, regs;
+ if (type == ARMul_FIRST)
+ {
+ single_regs = BIT(8) == 0; /* Single precision */
+ d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
+ imm32 = BITS(0,7)<<2; /* may not be used */
+ regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */
+
+ DBG("VPUSH :\n");
+ DBG("\tsp[%x]", state->Reg[R13]);
+ state->Reg[R13] = state->Reg[R13] - imm32;
+ DBG("=>[%x]\n", state->Reg[R13]);
+
+ i = 0;
+
+ return ARMul_DONE;
+ }
+ else if (type == ARMul_DATA)
+ {
+ if (single_regs)
+ {
+ *value = state->ExtReg[d + i];
+ DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
+ i++;
+ if (i < regs)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ else
+ {
+ /* FIXME Careful of endianness, may need to rework this */
+ *value = state->ExtReg[d*2 + i];
+ DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
+ i++;
+ if (i < regs*2)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ }
+
+ return -1;
+}
+int VSTM(ARMul_State* state, int type, ARMword instr, ARMword* value)
+{
+ static int i = 0;
+ static int single_regs, add, wback, d, n, imm32, regs;
+ if (type == ARMul_FIRST)
+ {
+ single_regs = BIT(8) == 0; /* Single precision */
+ add = BIT(23); /* */
+ wback = BIT(21); /* write-back */
+ d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
+ n = BITS(16, 19); /* destination register */
+ imm32 = BITS(0,7) * 4; /* may not be used */
+ regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */
+
+ DBG("VSTM :\n");
+
+ if (wback) {
+ state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
+ DBG("\twback r%d[%x]\n", n, state->Reg[n]);
+ }
+
+ i = 0;
+
+ return ARMul_DONE;
+ }
+ else if (type == ARMul_DATA)
+ {
+ if (single_regs)
+ {
+ *value = state->ExtReg[d + i];
+ DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
+ i++;
+ if (i < regs)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ else
+ {
+ /* FIXME Careful of endianness, may need to rework this */
+ *value = state->ExtReg[d*2 + i];
+ DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
+ i++;
+ if (i < regs*2)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ }
+
+ return -1;
+}
/* ----------- LDC ------------ */
-#define VFP_LDC_IMPL
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_LDC_IMPL
+int VPOP(ARMul_State* state, int type, ARMword instr, ARMword value)
+{
+ static int i = 0;
+ static int single_regs, add, wback, d, n, imm32, regs;
+ if (type == ARMul_FIRST)
+ {
+ single_regs = BIT(8) == 0; /* Single precision */
+ d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
+ imm32 = BITS(0,7)<<2; /* may not be used */
+ regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */
+ DBG("VPOP :\n");
+ DBG("\tsp[%x]", state->Reg[R13]);
+ state->Reg[R13] = state->Reg[R13] + imm32;
+ DBG("=>[%x]\n", state->Reg[R13]);
+
+ i = 0;
+
+ return ARMul_DONE;
+ }
+ else if (type == ARMul_TRANSFER)
+ {
+ return ARMul_DONE;
+ }
+ else if (type == ARMul_DATA)
+ {
+ if (single_regs)
+ {
+ state->ExtReg[d + i] = value;
+ DBG("\ts%d <= [%x]\n", d + i, value);
+ i++;
+ if (i < regs)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ else
+ {
+ /* FIXME Careful of endianness, may need to rework this */
+ state->ExtReg[d*2 + i] = value;
+ DBG("\ts%d <= [%x]\n", d*2 + i, value);
+ i++;
+ if (i < regs*2)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ }
+
+ return -1;
+}
+int VLDR(ARMul_State* state, int type, ARMword instr, ARMword value)
+{
+ static int i = 0;
+ static int single_reg, add, d, n, imm32, regs;
+ if (type == ARMul_FIRST)
+ {
+ single_reg = BIT(8) == 0; /* Double precision */
+ add = BIT(23); /* */
+ imm32 = BITS(0,7)<<2; /* may not be used */
+ d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
+ n = BITS(16, 19); /* destination register */
+
+ DBG("VLDR :\n");
+
+ i = 0;
+ regs = 1;
+
+ return ARMul_DONE;
+ }
+ else if (type == ARMul_TRANSFER)
+ {
+ return ARMul_DONE;
+ }
+ else if (type == ARMul_DATA)
+ {
+ if (single_reg)
+ {
+ state->ExtReg[d+i] = value;
+ DBG("\ts%d <= [%x]\n", d+i, value);
+ i++;
+ if (i < regs)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ else
+ {
+ /* FIXME Careful of endianness, may need to rework this */
+ state->ExtReg[d*2+i] = value;
+ DBG("\ts[%d] <= [%x]\n", d*2+i, value);
+ i++;
+ if (i < regs*2)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ }
+
+ return -1;
+}
+int VLDM(ARMul_State* state, int type, ARMword instr, ARMword value)
+{
+ static int i = 0;
+ static int single_regs, add, wback, d, n, imm32, regs;
+ if (type == ARMul_FIRST)
+ {
+ single_regs = BIT(8) == 0; /* Single precision */
+ add = BIT(23); /* */
+ wback = BIT(21); /* write-back */
+ d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
+ n = BITS(16, 19); /* destination register */
+ imm32 = BITS(0,7) * 4; /* may not be used */
+ regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */
+
+ DBG("VLDM :\n");
+
+ if (wback) {
+ state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
+ DBG("\twback r%d[%x]\n", n, state->Reg[n]);
+ }
+
+ i = 0;
+
+ return ARMul_DONE;
+ }
+ else if (type == ARMul_DATA)
+ {
+ if (single_regs)
+ {
+ state->ExtReg[d + i] = value;
+ DBG("\ts%d <= [%x] addr[?]\n", d+i, state->ExtReg[d + i]);
+ i++;
+ if (i < regs)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ else
+ {
+ /* FIXME Careful of endianness, may need to rework this */
+ state->ExtReg[d*2 + i] = value;
+ DBG("\ts[%d] <= [%x] addr[?]\n", d*2 + i, state->ExtReg[d*2 + i]);
+ i++;
+ if (i < regs*2)
+ return ARMul_INC;
+ else
+ return ARMul_DONE;
+ }
+ }
+
+ return -1;
+}
/* ----------- CDP ------------ */
-#define VFP_CDP_IMPL
-#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
-#undef VFP_CDP_IMPL
+void VMOVI(ARMul_State* state, ARMword single, ARMword d, ARMword imm)
+{
+ DBG("VMOV(I) :\n");
+
+ if (single)
+ {
+ DBG("\ts%d <= [%x]\n", d, imm);
+ state->ExtReg[d] = imm;
+ }
+ else
+ {
+ /* Check endian please */
+ DBG("\ts[%d-%d] <= [%x-%x]\n", d*2+1, d*2, imm, 0);
+ state->ExtReg[d*2+1] = imm;
+ state->ExtReg[d*2] = 0;
+ }
+}
+void VMOVR(ARMul_State* state, ARMword single, ARMword d, ARMword m)
+{
+ DBG("VMOV(R) :\n");
+
+ if (single)
+ {
+ DBG("\ts%d <= s%d[%x]\n", d, m, state->ExtReg[m]);
+ state->ExtReg[d] = state->ExtReg[m];
+ }
+ else
+ {
+ /* Check endian please */
+ DBG("\ts[%d-%d] <= s[%d-%d][%x-%x]\n", d*2+1, d*2, m*2+1, m*2, state->ExtReg[m*2+1], state->ExtReg[m*2]);
+ state->ExtReg[d*2+1] = state->ExtReg[m*2+1];
+ state->ExtReg[d*2] = state->ExtReg[m*2];
+ }
+}
/* Miscellaneous functions */
int32_t vfp_get_float(arm_core_t* state, unsigned int reg)
@@ -366,8 +893,6 @@ void vfp_put_double(arm_core_t* state, uint64_t val, unsigned int reg)
state->ExtReg[reg*2+1] = (uint32_t) (val>>32);
}
-
-
/*
* Process bitmask of exception conditions. (from vfpmodule.c)
*/
diff --git a/src/core/arm/skyeye_common/vfp/vfp.h b/src/core/arm/skyeye_common/vfp/vfp.h
index 7256701f3..f9e8d521d 100644
--- a/src/core/arm/skyeye_common/vfp/vfp.h
+++ b/src/core/arm/skyeye_common/vfp/vfp.h
@@ -27,6 +27,12 @@
#include "core/arm/skyeye_common/vfp/vfp_helper.h" /* for references to cdp SoftFloat functions */
+#define VFP_DEBUG_TRANSLATE DBG("in func %s, %x\n", __FUNCTION__, inst);
+#define VFP_DEBUG_UNIMPLEMENTED(x) printf("in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1);
+#define VFP_DEBUG_UNTESTED(x) printf("in func %s, " #x " untested\n", __FUNCTION__);
+#define CHECK_VFP_ENABLED
+#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); //if (ret == -1) {printf("VFP CDP FAILURE %x\n", inst_cream->instr); exit(-1);}
+
unsigned VFPInit (ARMul_State *state);
unsigned VFPMRC (ARMul_State * state, unsigned type, ARMword instr, ARMword * value);
unsigned VFPMCR (ARMul_State * state, unsigned type, ARMword instr, ARMword value);
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index 45208fb13..2320449b6 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -28,34 +28,19 @@
/* ----------------------------------------------------------------------- */
/* VMLA */
/* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */
-#define vfpinstr vmla
-#define vfpinstr_inst vmla_inst
-#define VFPLABEL_INST VMLA_INST
-#ifdef VFP_DECODE
-{"vmla", 4, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmla", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmla_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vmla_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmla)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmla_inst));
+ vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -69,7 +54,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMLA_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -77,7 +62,7 @@ VFPLABEL_INST:
DBG("VMLA :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
int ret;
@@ -89,22 +74,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmla_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 0)
-{
- DBG("VMLA :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmla),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -114,7 +94,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int m;
@@ -168,41 +148,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VNMLS */
/* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */
-#define vfpinstr vmls
-#define vfpinstr_inst vmls_inst
-#define VFPLABEL_INST VMLS_INST
-#ifdef VFP_DECODE
-{"vmls", 7, ARMVFP2, 28 , 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmls", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmls_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vmls_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmls)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmls_inst));
+ vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -216,7 +178,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMLS_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -224,7 +186,7 @@ VFPLABEL_INST:
DBG("VMLS :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
int ret;
@@ -236,22 +198,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmls_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0 && (OPC_2 & 0x2) == 2)
-{
- DBG("VMLS :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmls),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -261,7 +218,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int m;
@@ -315,47 +272,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VNMLA */
/* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */
-#define vfpinstr vnmla
-#define vfpinstr_inst vnmla_inst
-#define VFPLABEL_INST VNMLA_INST
-#ifdef VFP_DECODE
-//{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
-{"vnmla", 4, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0},
-{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
-//{"vnmla", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vnmla", 0, ARMVFP2, 0},
-{"vnmla", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vnmla_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vnmla_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vnmla)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmla_inst));
+ vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -369,7 +302,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VNMLA_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -377,7 +310,7 @@ VFPLABEL_INST:
DBG("VNMLA :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
int ret;
@@ -389,23 +322,18 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vnmla_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 2)
-{
- DBG("VNMLA :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vnmla),
+DYNCOM_FILL_ACTION(vnmla),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vnmla)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -415,7 +343,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int m;
@@ -469,41 +397,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VNMLS */
/* cond 1110 0D01 Vn-- Vd-- 101X N0M0 Vm-- */
-#define vfpinstr vnmls
-#define vfpinstr_inst vnmls_inst
-#define VFPLABEL_INST VNMLS_INST
-#ifdef VFP_DECODE
-{"vnmls", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x1, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vnmls", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
+
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vnmls_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vnmls_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vnmls)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst));
+ vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -517,7 +428,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VNMLS_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -525,7 +436,7 @@ VFPLABEL_INST:
DBG("VNMLS :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
int ret;
@@ -537,22 +448,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vnmls_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 1 && (OPC_2 & 0x2) == 0)
-{
- DBG("VNMLS :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vnmls),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vnmls)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -562,7 +468,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int m;
@@ -616,41 +522,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VNMUL */
/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
-#define vfpinstr vnmul
-#define vfpinstr_inst vnmul_inst
-#define VFPLABEL_INST VNMUL_INST
-#ifdef VFP_DECODE
-{"vnmul", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vnmul", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vnmul_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vnmul_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vnmul)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst));
+ vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -664,7 +552,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VNMUL_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -672,7 +560,7 @@ VFPLABEL_INST:
DBG("VNMUL :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
int ret;
@@ -684,22 +572,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vnmul_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 2)
-{
- DBG("VNMUL :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vnmul),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vnmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -709,7 +592,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int m;
@@ -753,41 +636,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
+
/* ----------------------------------------------------------------------- */
/* VMUL */
/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
-#define vfpinstr vmul
-#define vfpinstr_inst vmul_inst
-#define VFPLABEL_INST VMUL_INST
-#ifdef VFP_DECODE
-{"vmul", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x2, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmul", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmul_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vmul_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmul)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst));
+ vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -801,7 +667,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMUL_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -809,7 +675,7 @@ VFPLABEL_INST:
DBG("VMUL :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
int ret;
@@ -821,22 +687,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmul_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 2 && (OPC_2 & 0x2) == 0)
-{
- DBG("VMUL :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmul),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmul)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -846,7 +707,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//printf("\n\n\t\tin %s instruction is executed out.\n\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
@@ -904,41 +765,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VADD */
/* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */
-#define vfpinstr vadd
-#define vfpinstr_inst vadd_inst
-#define VFPLABEL_INST VADD_INST
-#ifdef VFP_DECODE
-{"vadd", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vadd", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vadd_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vadd_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vadd)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst));
+ vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -952,7 +795,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VADD_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -960,7 +803,7 @@ VFPLABEL_INST:
DBG("VADD :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
int ret;
@@ -972,22 +815,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vadd_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 0)
-{
- DBG("VADD :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vadd),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vadd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -997,7 +835,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int m;
@@ -1049,41 +887,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VSUB */
/* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */
-#define vfpinstr vsub
-#define vfpinstr_inst vsub_inst
-#define VFPLABEL_INST VSUB_INST
-#ifdef VFP_DECODE
-{"vsub", 5, ARMVFP2, 23, 27, 0x1c, 20, 21, 0x3, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vsub", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vsub_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vsub_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vsub)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsub_inst));
+ vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -1097,7 +917,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VSUB_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1105,7 +925,7 @@ VFPLABEL_INST:
DBG("VSUB :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
int ret;
@@ -1117,22 +937,16 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vsub_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 3 && (OPC_2 & 0x2) == 2)
-{
- DBG("VSUB :\n");
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vsub),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vsub)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -1141,7 +955,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr);
//arch_arm_undef(cpu, bb, instr);
int m;
@@ -1193,41 +1007,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VDIV */
/* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */
-#define vfpinstr vdiv
-#define vfpinstr_inst vdiv_inst
-#define VFPLABEL_INST VDIV_INST
-#ifdef VFP_DECODE
-{"vdiv", 5, ARMVFP2, 23, 27, 0x1d, 20, 21, 0x0, 9, 11, 0x5, 6, 6, 0, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vdiv", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vdiv_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vdiv_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vdiv)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vdiv_inst));
+ vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -1241,7 +1037,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VDIV_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1249,7 +1045,7 @@ VFPLABEL_INST:
DBG("VDIV :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
int ret;
@@ -1261,22 +1057,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vdiv_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xA && (OPC_2 & 0x2) == 0)
-{
- DBG("VDIV :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vdiv),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vdiv)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1286,7 +1077,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int m;
@@ -1338,43 +1129,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VMOVI move immediate */
/* cond 1110 1D11 im4H Vd-- 101X 0000 im4L */
/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
-#define vfpinstr vmovi
-#define vfpinstr_inst vmovi_inst
-#define VFPLABEL_INST VMOVI_INST
-#ifdef VFP_DECODE
-{"vmov(i)", 4, ARMVFP3, 23, 27, 0x1d, 20, 21, 0x3, 9, 11, 0x5, 4, 7, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmov(i)", 0, ARMVFP3, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovi_inst {
unsigned int single;
unsigned int d;
unsigned int imm;
-} vfpinstr_inst;
+} vmovi_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmovi)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovi_inst));
+ vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -1392,62 +1165,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMOVI_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmovi_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ( (OPC_1 & 0xb) == 0xb && BITS(4, 7) == 0)
-{
- unsigned int single = BIT(8) == 0;
- unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
- unsigned int imm;
- instr = BITS(16, 19) << 4 | BITS(0, 3); /* FIXME dirty workaround to get a correct imm */
- if (single) {
- imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0x1f : 0)<<25 | BITS(0, 5)<<19;
- } else {
- imm = BIT(7)<<31 | (BIT(6)==0)<<30 | (BIT(6) ? 0xff : 0)<<22 | BITS(0, 5)<<16;
- }
- VMOVI(state, single, d, imm);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_CDP_IMPL
-void VMOVI(ARMul_State * state, ARMword single, ARMword d, ARMword imm)
-{
- DBG("VMOV(I) :\n");
-
- if (single)
- {
- DBG("\ts%d <= [%x]\n", d, imm);
- state->ExtReg[d] = imm;
- }
- else
- {
- /* Check endian please */
- DBG("\ts[%d-%d] <= [%x-%x]\n", d*2+1, d*2, imm, 0);
- state->ExtReg[d*2+1] = imm;
- state->ExtReg[d*2] = 0;
- }
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmovi),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmovi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1456,7 +1195,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int single = (BIT(8) == 0);
@@ -1482,44 +1221,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VMOVR move register */
/* cond 1110 1D11 0000 Vd-- 101X 01M0 Vm-- */
/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
-#define vfpinstr vmovr
-#define vfpinstr_inst vmovr_inst
-#define VFPLABEL_INST VMOVR_INST
-#ifdef VFP_DECODE
-{"vmov(r)", 5, ARMVFP3, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmov(r)", 0, ARMVFP3, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovr_inst {
unsigned int single;
unsigned int d;
unsigned int m;
-} vfpinstr_inst;
+} vmovr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmovr)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
VFP_DEBUG_UNTESTED(VMOVR);
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovr_inst));
+ vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -1533,56 +1254,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMOVR_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmovr_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ( (OPC_1 & 0xb) == 0xb && CRn == 0 && (OPC_2 & 0x6) == 0x2 )
-{
- unsigned int single = BIT(8) == 0;
- unsigned int d = (single ? BITS(12,15)<<1 | BIT(22) : BITS(12,15) | BIT(22)<<4);
- unsigned int m = (single ? BITS( 0, 3)<<1 | BIT( 5) : BITS( 0, 3) | BIT( 5)<<4);;
- VMOVR(state, single, d, m);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_CDP_IMPL
-void VMOVR(ARMul_State * state, ARMword single, ARMword d, ARMword m)
-{
- DBG("VMOV(R) :\n");
-
- if (single)
- {
- DBG("\ts%d <= s%d[%x]\n", d, m, state->ExtReg[m]);
- state->ExtReg[d] = state->ExtReg[m];
- }
- else
- {
- /* Check endian please */
- DBG("\ts[%d-%d] <= s[%d-%d][%x-%x]\n", d*2+1, d*2, m*2+1, m*2, state->ExtReg[m*2+1], state->ExtReg[m*2]);
- state->ExtReg[d*2+1] = state->ExtReg[m*2+1];
- state->ExtReg[d*2] = state->ExtReg[m*2];
- }
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmovr),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmovr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -1594,7 +1287,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s VMOV \n", __FUNCTION__);
int single = BIT(8) == 0;
int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
@@ -1613,41 +1306,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VABS */
/* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */
-#define vfpinstr vabs
-#define vfpinstr_inst vabs_inst
-#define VFPLABEL_INST VABS_INST
-#ifdef VFP_DECODE
-{"vabs", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vabs", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vabs_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vabs_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vabs)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VABS);
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vabs_inst));
+ vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -1661,7 +1336,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VABS_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1669,7 +1344,7 @@ VFPLABEL_INST:
DBG("VABS :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
int ret;
@@ -1681,22 +1356,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vabs_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xB && CRn == 0 && (OPC_2 & 0x7) == 6)
-{
- DBG("VABS :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vabs),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vabs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1706,7 +1376,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int single = BIT(8) == 0;
@@ -1744,42 +1414,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VNEG */
/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
-#define vfpinstr vneg
-#define vfpinstr_inst vneg_inst
-#define VFPLABEL_INST VNEG_INST
-#ifdef VFP_DECODE
-//{"vneg", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x30, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
-{"vneg", 5, ARMVFP2, 23, 27, 0x1d, 17, 21, 0x18, 9, 11, 0x5, 6, 7, 1, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vneg", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
+
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vneg_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vneg_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vneg)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VNEG);
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vneg_inst));
+ vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -1793,7 +1445,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VNEG_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1801,7 +1453,7 @@ VFPLABEL_INST:
DBG("VNEG :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
int ret;
@@ -1813,22 +1465,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vneg_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 2)
-{
- DBG("VNEG :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vneg),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vneg)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1838,7 +1485,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int single = BIT(8) == 0;
@@ -1876,41 +1523,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VSQRT */
/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
-#define vfpinstr vsqrt
-#define vfpinstr_inst vsqrt_inst
-#define VFPLABEL_INST VSQRT_INST
-#ifdef VFP_DECODE
-{"vsqrt", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x31, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vsqrt", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vsqrt_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vsqrt_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vsqrt)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vsqrt_inst));
+ vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -1924,7 +1553,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VSQRT_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -1932,7 +1561,7 @@ VFPLABEL_INST:
DBG("VSQRT :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
int ret;
@@ -1944,22 +1573,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vsqrt_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xB && CRn == 1 && (OPC_2 & 0x7) == 6)
-{
- DBG("VSQRT :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vsqrt),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vsqrt)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -1969,7 +1593,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int dp_op = (BIT(8) == 1);
@@ -1995,41 +1619,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VCMP VCMPE */
/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */
-#define vfpinstr vcmp
-#define vfpinstr_inst vcmp_inst
-#define VFPLABEL_INST VCMP_INST
-#ifdef VFP_DECODE
-{"vcmp", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x34, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vcmp", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcmp_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vcmp_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp_inst));
+ vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -2043,7 +1649,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VCMP_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2051,7 +1657,7 @@ VFPLABEL_INST:
DBG("VCMP(1) :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
int ret;
@@ -2063,22 +1669,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vcmp_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xB && CRn == 4 && (OPC_2 & 0x2) == 2)
-{
- DBG("VCMP(1) :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vcmp),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vcmp)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2087,7 +1688,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int dp_op = (BIT(8) == 1);
@@ -2141,41 +1742,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VCMP VCMPE */
/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */
-#define vfpinstr vcmp2
-#define vfpinstr_inst vcmp2_inst
-#define VFPLABEL_INST VCMP2_INST
-#ifdef VFP_DECODE
-{"vcmp2", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x35, 9, 11, 0x5, 0, 6, 0x40},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vcmp2", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcmp2_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vcmp2_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vcmp2)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcmp2_inst));
+ vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -2189,7 +1772,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VCMP2_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2197,7 +1780,7 @@ VFPLABEL_INST:
DBG("VCMP(2) :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
int ret;
@@ -2209,22 +1792,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vcmp2_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xB && CRn == 5 && (OPC_2 & 0x2) == 2 && CRm == 0)
-{
- DBG("VCMP(2) :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vcmp2),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vcmp2)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2233,7 +1811,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int dp_op = (BIT(8) == 1);
@@ -2287,41 +1865,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VCVTBDS between double and single */
/* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */
-#define vfpinstr vcvtbds
-#define vfpinstr_inst vcvtbds_inst
-#define VFPLABEL_INST VCVTBDS_INST
-#ifdef VFP_DECODE
-{"vcvt(bds)", 5, ARMVFP2, 23, 27, 0x1d, 16, 21, 0x37, 9, 11, 0x5, 6, 7, 3, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vcvt(bds)", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcvtbds_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vcvtbds_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbds)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbds_inst));
+ vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -2335,7 +1895,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VCVTBDS_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2343,7 +1903,7 @@ VFPLABEL_INST:
DBG("VCVT(BDS) :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
int ret;
@@ -2355,22 +1915,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vcvtbds_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xB && CRn == 7 && (OPC_2 & 0x6) == 6)
-{
- DBG("VCVT(BDS) :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vcvtbds),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vcvtbds)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
@@ -2379,7 +1934,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int dp_op = (BIT(8) == 1);
@@ -2407,41 +1962,23 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VCVTBFF between floating point and fixed point */
/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
-#define vfpinstr vcvtbff
-#define vfpinstr_inst vcvtbff_inst
-#define VFPLABEL_INST VCVTBFF_INST
-#ifdef VFP_DECODE
-{"vcvt(bff)", 6, ARMVFP3, 23, 27, 0x1d, 19, 21, 0x7, 17, 17, 0x1, 9, 11, 0x5, 6, 6, 1},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vcvt(bff)", 0, ARMVFP3, 4, 4, 1},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcvtbff_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vcvtbff_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbff)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF);
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbff_inst));
+ vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -2455,7 +1992,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VCVTBFF_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2463,7 +2000,7 @@ VFPLABEL_INST:
DBG("VCVT(BFF) :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
int ret;
@@ -2475,22 +2012,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vcvtbff_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xB && CRn >= 0xA && (OPC_2 & 0x2) == 2)
-{
- DBG("VCVT(BFF) :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vcvtbff),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vcvtbff)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2499,47 +2031,29 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
arch_arm_undef(cpu, bb, instr);
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VCVTBFI between floating point and integer */
/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
-#define vfpinstr vcvtbfi
-#define vfpinstr_inst vcvtbfi_inst
-#define VFPLABEL_INST VCVTBFI_INST
-#ifdef VFP_DECODE
-{"vcvt(bfi)", 5, ARMVFP2, 23, 27, 0x1d, 19, 21, 0x7, 9, 11, 0x5, 6, 6, 1, 4, 4, 0},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vcvt(bfi)", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcvtbfi_inst {
unsigned int instr;
unsigned int dp_operation;
-} vfpinstr_inst;
+} vcvtbfi_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vcvtbfi)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vcvtbfi_inst));
+ vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -2554,7 +2068,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VCVTBFI_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2562,7 +2076,7 @@ VFPLABEL_INST:
DBG("VCVT(BFI) :\n");
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
int ret;
@@ -2574,22 +2088,17 @@ VFPLABEL_INST:
CHECK_VFP_CDP_RET;
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vcvtbfi_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_CDP_TRANS
-if ((OPC_1 & 0xB) == 0xB && CRn > 7 && (OPC_2 & 0x2) == 2)
-{
- DBG("VCVT(BFI) :\n");
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vcvtbfi),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vcvtbfi)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2600,7 +2109,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
unsigned int opc2 = BITS(16,18);
@@ -2694,9 +2203,6 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
return 0;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* MRC / MCR instructions */
@@ -2707,35 +2213,20 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
/* VMOVBRS between register and single precision */
/* cond 1110 000o Vn-- Rt-- 1010 N001 0000 */
/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
-#define vfpinstr vmovbrs
-#define vfpinstr_inst vmovbrs_inst
-#define VFPLABEL_INST VMOVBRS_INST
-#ifdef VFP_DECODE
-{"vmovbrs", 3, ARMVFP2, 21, 27, 0x70, 8, 11, 0xA, 0, 6, 0x10},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmovbrs", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbrs_inst {
unsigned int to_arm;
unsigned int t;
unsigned int n;
-} vfpinstr_inst;
+} vmovbrs_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrs)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrs_inst));
+ vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -2750,61 +2241,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMOVBRS_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
-
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+
+ vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
VMOVBRS(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->n, &(cpu->Reg[inst_cream->t]));
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmovbrs_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_MRC_TRANS
-if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
-{
- /* VMOV r to s */
- /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
- VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, value);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_MCR_TRANS
-if (OPC_1 == 0x0 && CRm == 0 && (OPC_2 & 0x3) == 0)
-{
- /* VMOV s to r */
- /* Transfering Rt is not mandatory, as the value of interest is pointed by value */
- VMOVBRS(state, BIT(20), Rt, BIT(7)|CRn<<1, &value);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_MRC_IMPL
-void VMOVBRS(ARMul_State * state, ARMword to_arm, ARMword t, ARMword n, ARMword *value)
-{
- DBG("VMOV(BRS) :\n");
- if (to_arm)
- {
- DBG("\tr%d <= s%d=[%x]\n", t, n, state->ExtReg[n]);
- *value = state->ExtReg[n];
- }
- else
- {
- DBG("\ts%d <= r%d=[%x]\n", n, t, *value);
- state->ExtReg[n] = *value;
- }
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmovbrs),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmovbrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2813,7 +2271,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("VMOV(BRS) :\n");
int to_arm = BIT(20) == 1;
int t = BITS(12, 15);
@@ -2832,42 +2290,24 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VMSR */
/* cond 1110 1110 reg- Rt-- 1010 0001 0000 */
/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
-#define vfpinstr vmsr
-#define vfpinstr_inst vmsr_inst
-#define VFPLABEL_INST VMSR_INST
-#ifdef VFP_DECODE
-{"vmsr", 2, ARMVFP2, 20, 27, 0xEE, 0, 11, 0xA10},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmsr", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmsr_inst {
unsigned int reg;
unsigned int Rd;
-} vfpinstr_inst;
+} vmsr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmsr)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmsr_inst));
+ vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -2881,7 +2321,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMSR_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -2890,43 +2330,22 @@ VFPLABEL_INST:
/* Exceptions must be checked, according to v7 ref manual */
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
VMSR(cpu, inst_cream->reg, inst_cream->Rd);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmsr_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_MCR_TRANS
-if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
-{
- VMSR(state, CRn, Rt);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_MCR_IMPL
-void VMSR(ARMul_State * state, ARMword reg, ARMword Rt)
-{
- if (reg == 1)
- {
- DBG("VMSR :\tfpscr <= r%d=[%x]\n", Rt, state->Reg[Rt]);
- state->VFP[VFP_OFFSET(VFP_FPSCR)] = state->Reg[Rt];
- }
- else if (reg == 8)
- {
- DBG("VMSR :\tfpexc <= r%d=[%x]\n", Rt, state->Reg[Rt]);
- state->VFP[VFP_OFFSET(VFP_FPEXC)] = state->Reg[Rt];
- }
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmsr),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmsr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -2936,7 +2355,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
DBG("VMSR :");
@@ -2969,44 +2388,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VMOVBRC register to scalar */
/* cond 1110 0XX0 Vd-- Rt-- 1011 DXX1 0000 */
/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
-#define vfpinstr vmovbrc
-#define vfpinstr_inst vmovbrc_inst
-#define VFPLABEL_INST VMOVBRC_INST
-#ifdef VFP_DECODE
-{"vmovbrc", 4, ARMVFP2, 23, 27, 0x1C, 20, 20, 0x0, 8,11,0xB, 0,4,0x10},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmovbrc", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbrc_inst {
unsigned int esize;
unsigned int index;
unsigned int d;
unsigned int t;
-} vfpinstr_inst;
+} vmovbrc_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrc)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrc_inst));
+ vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -3023,34 +2424,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMOVBRC_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmovbrc_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_MCR_TRANS
-if ((OPC_1 & 0x4) == 0 && CoProc == 11 && CRm == 0)
-{
- VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
- return ARMul_DONE;
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmovbrc),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmovbrc)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3059,48 +2454,30 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
arch_arm_undef(cpu, bb, instr);
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VMRS */
/* cond 1110 1111 CRn- Rt-- 1010 0001 0000 */
/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
-#define vfpinstr vmrs
-#define vfpinstr_inst vmrs_inst
-#define VFPLABEL_INST VMRS_INST
-#ifdef VFP_DECODE
-{"vmrs", 2, ARMVFP2, 20, 27, 0xEF, 0, 11, 0xa10},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmrs", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmrs_inst {
unsigned int reg;
unsigned int Rt;
-} vfpinstr_inst;
+} vmrs_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmrs)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmrs_inst));
+ vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -3109,12 +2486,12 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
inst_cream->reg = BITS(inst, 16, 19);
inst_cream->Rt = BITS(inst, 12, 15);
-
+
return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMRS_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -3123,7 +2500,7 @@ VFPLABEL_INST:
/* Exceptions must be checked, according to v7 ref manual */
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
DBG("VMRS :");
@@ -3170,67 +2547,17 @@ VFPLABEL_INST:
}
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmrs_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_MRC_TRANS
-if (OPC_1 == 0x7 && CRm == 0 && OPC_2 == 0)
-{
- VMRS(state, CRn, Rt, value);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_MRC_IMPL
-void VMRS(ARMul_State * state, ARMword reg, ARMword Rt, ARMword * value)
-{
- DBG("VMRS :");
- if (reg == 1)
- {
- if (Rt != 15)
- {
- *value = state->VFP[VFP_OFFSET(VFP_FPSCR)];
- DBG("\tr%d <= fpscr[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSCR)]);
- }
- else
- {
- *value = state->VFP[VFP_OFFSET(VFP_FPSCR)] ;
- DBG("\tflags <= fpscr[%1xxxxxxxx]\n", state->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
- }
- }
- else
- {
- switch (reg)
- {
- case 0:
- *value = state->VFP[VFP_OFFSET(VFP_FPSID)];
- DBG("\tr%d <= fpsid[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPSID)]);
- break;
- case 6:
- /* MVFR1, VFPv3 only ? */
- DBG("\tr%d <= MVFR1 unimplemented\n", Rt);
- break;
- case 7:
- /* MVFR0, VFPv3 only? */
- DBG("\tr%d <= MVFR0 unimplemented\n", Rt);
- break;
- case 8:
- *value = state->VFP[VFP_OFFSET(VFP_FPEXC)];
- DBG("\tr%d <= fpexc[%08x]\n", Rt, state->VFP[VFP_OFFSET(VFP_FPEXC)]);
- break;
- default:
- DBG("\tSUBARCHITECTURE DEFINED\n");
- break;
- }
- }
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmrs),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmrs)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3241,7 +2568,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
@@ -3292,44 +2619,26 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VMOVBCR scalar to register */
/* cond 1110 XXX1 Vd-- Rt-- 1011 NXX1 0000 */
/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */
-#define vfpinstr vmovbcr
-#define vfpinstr_inst vmovbcr_inst
-#define VFPLABEL_INST VMOVBCR_INST
-#ifdef VFP_DECODE
-{"vmovbcr", 4, ARMVFP2, 24, 27, 0xE, 20, 20, 1, 8, 11,0xB, 0,4, 0x10},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmovbcr", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbcr_inst {
unsigned int esize;
unsigned int index;
unsigned int d;
unsigned int t;
-} vfpinstr_inst;
+} vmovbcr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbcr)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbcr_inst));
+ vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -3346,34 +2655,28 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMOVBCR_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmovbcr_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_MCR_TRANS
-if (CoProc == 11 && CRm == 0)
-{
- VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
- return ARMul_DONE;
-}
-#endif
+
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmovbcr),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmovbcr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3382,15 +2685,12 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
arch_arm_undef(cpu, bb, instr);
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* MRRC / MCRR instructions */
@@ -3401,36 +2701,21 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
/* VMOVBRRSS between 2 registers to 2 singles */
/* cond 1100 010X Rt2- Rt-- 1010 00X1 Vm-- */
/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
-#define vfpinstr vmovbrrss
-#define vfpinstr_inst vmovbrrss_inst
-#define VFPLABEL_INST VMOVBRRSS_INST
-#ifdef VFP_DECODE
-{"vmovbrrss", 3, ARMVFP2, 21, 27, 0x62, 8, 11, 0xA, 4, 4, 1},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmovbrrss", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbrrss_inst {
unsigned int to_arm;
unsigned int t;
unsigned int t2;
unsigned int m;
-} vfpinstr_inst;
+} vmovbrrss_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrss)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrss_inst));
+ vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -3446,41 +2731,27 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMOVBRRSS_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmovbrrss_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_MCRR_TRANS
-if (CoProc == 10 && (OPC_1 & 0xD) == 1)
-{
- VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_MRRC_TRANS
-if (CoProc == 10 && (OPC_1 & 0xD) == 1)
-{
- VFP_DEBUG_UNIMPLEMENTED(VMOVBRRSS);
- return ARMul_DONE;
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmovbrrss),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmovbrrss)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3489,50 +2760,32 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
arch_arm_undef(cpu, bb, instr);
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VMOVBRRD between 2 registers and 1 double */
/* cond 1100 010X Rt2- Rt-- 1011 00X1 Vm-- */
/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
-#define vfpinstr vmovbrrd
-#define vfpinstr_inst vmovbrrd_inst
-#define VFPLABEL_INST VMOVBRRD_INST
-#ifdef VFP_DECODE
-{"vmovbrrd", 3, ARMVFP2, 21, 27, 0x62, 6, 11, 0x2c, 4, 4, 1},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vmovbrrd", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbrrd_inst {
unsigned int to_arm;
unsigned int t;
unsigned int t2;
unsigned int m;
-} vfpinstr_inst;
+} vmovbrrd_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vmovbrrd)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst));
+ vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -3548,63 +2801,29 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VMOVBRRD_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
VMOVBRRD(cpu, inst_cream->to_arm, inst_cream->t, inst_cream->t2, inst_cream->m,
&(cpu->Reg[inst_cream->t]), &(cpu->Reg[inst_cream->t2]));
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vmovbrrd_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_MCRR_TRANS
-if (CoProc == 11 && (OPC_1 & 0xD) == 1)
-{
- /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
- VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, &value1, &value2);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_MRRC_TRANS
-if (CoProc == 11 && (OPC_1 & 0xD) == 1)
-{
- /* Transfering Rt and Rt2 is not mandatory, as the value of interest is pointed by value1 and value2 */
- VMOVBRRD(state, BIT(20), Rt, Rt2, BIT(5)<<4|CRm, value1, value2);
- return ARMul_DONE;
-}
-#endif
-#ifdef VFP_MRRC_IMPL
-void VMOVBRRD(ARMul_State * state, ARMword to_arm, ARMword t, ARMword t2, ARMword n, ARMword *value1, ARMword *value2)
-{
- DBG("VMOV(BRRD) :\n");
- if (to_arm)
- {
- DBG("\tr[%d-%d] <= s[%d-%d]=[%x-%x]\n", t2, t, n*2+1, n*2, state->ExtReg[n*2+1], state->ExtReg[n*2]);
- *value2 = state->ExtReg[n*2+1];
- *value1 = state->ExtReg[n*2];
- }
- else
- {
- DBG("\ts[%d-%d] <= r[%d-%d]=[%x-%x]\n", n*2+1, n*2, t2, t, *value2, *value1);
- state->ExtReg[n*2+1] = *value2;
- state->ExtReg[n*2] = *value1;
- }
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vmovbrrd),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vmovbrrd)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -3615,7 +2834,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int to_arm = BIT(20) == 1;
@@ -3633,9 +2852,6 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* LDC/STC between 2 registers and 1 double */
@@ -3645,21 +2861,6 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
/* ----------------------------------------------------------------------- */
/* VSTR */
/* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */
-#define vfpinstr vstr
-#define vfpinstr_inst vstr_inst
-#define VFPLABEL_INST VSTR_INST
-#ifdef VFP_DECODE
-{"vstr", 3, ARMVFP2, 24, 27, 0xd, 20, 21, 0, 9, 11, 0x5},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vstr", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vstr_inst {
unsigned int single;
@@ -3667,15 +2868,15 @@ typedef struct _vstr_inst {
unsigned int d;
unsigned int imm32;
unsigned int add;
-} vfpinstr_inst;
+} vstr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vstr)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstr_inst));
+ vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -3692,13 +2893,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VSTR_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
@@ -3736,65 +2937,12 @@ VFPLABEL_INST:
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_STC_TRANS
-if (P == 1 && W == 0)
-{
- return VSTR(state, type, instr, value);
-}
-#endif
-#ifdef VFP_STC_IMPL
-int VSTR(ARMul_State * state, int type, ARMword instr, ARMword * value)
-{
- static int i = 0;
- static int single_reg, add, d, n, imm32, regs;
- if (type == ARMul_FIRST)
- {
- single_reg = BIT(8) == 0; /* Double precision */
- add = BIT(23); /* */
- imm32 = BITS(0,7)<<2; /* may not be used */
- d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
- n = BITS(16, 19); /* destination register */
-
- DBG("VSTR :\n");
-
- i = 0;
- regs = 1;
-
- return ARMul_DONE;
- }
- else if (type == ARMul_DATA)
- {
- if (single_reg)
- {
- *value = state->ExtReg[d+i];
- DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d+i]);
- i++;
- if (i < regs)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- else
- {
- /* FIXME Careful of endianness, may need to rework this */
- *value = state->ExtReg[d*2+i];
- DBG("\taddr[?] <= s[%d]=[%x]\n", d*2+i, state->ExtReg[d*2+i]);
- i++;
- if (i < regs*2)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- }
- return -1;
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vstr),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -3807,7 +2955,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
int single = BIT(8) == 0;
int add = BIT(23);
int imm32 = BITS(0,7) << 2;
@@ -3853,43 +3001,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VPUSH */
/* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */
-#define vfpinstr vpush
-#define vfpinstr_inst vpush_inst
-#define VFPLABEL_INST VPUSH_INST
-#ifdef VFP_DECODE
-{"vpush", 3, ARMVFP2, 23, 27, 0x1a, 16, 21, 0x2d, 9, 11, 0x5},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vpush", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vpush_inst {
unsigned int single;
unsigned int d;
unsigned int imm32;
unsigned int regs;
-} vfpinstr_inst;
+} vpush_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vpush)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst));
+ vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -3905,7 +3035,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VPUSH_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -3913,7 +3043,7 @@ VFPLABEL_INST:
int i;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
DBG("VPUSH :\n");
@@ -3958,66 +3088,11 @@ VFPLABEL_INST:
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_STC_TRANS
-if (P == 1 && U == 0 && W == 1 && Rn == 0xD)
-{
- return VPUSH(state, type, instr, value);
-}
-#endif
-#ifdef VFP_STC_IMPL
-int VPUSH(ARMul_State * state, int type, ARMword instr, ARMword * value)
-{
- static int i = 0;
- static int single_regs, add, wback, d, n, imm32, regs;
- if (type == ARMul_FIRST)
- {
- single_regs = BIT(8) == 0; /* Single precision */
- d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
- imm32 = BITS(0,7)<<2; /* may not be used */
- regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FSTMX if regs is odd */
-
- DBG("VPUSH :\n");
- DBG("\tsp[%x]", state->Reg[R13]);
- state->Reg[R13] = state->Reg[R13] - imm32;
- DBG("=>[%x]\n", state->Reg[R13]);
-
- i = 0;
-
- return ARMul_DONE;
- }
- else if (type == ARMul_DATA)
- {
- if (single_regs)
- {
- *value = state->ExtReg[d + i];
- DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
- i++;
- if (i < regs)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- else
- {
- /* FIXME Careful of endianness, may need to rework this */
- *value = state->ExtReg[d*2 + i];
- DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
- i++;
- if (i < regs*2)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- }
-
- return -1;
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vpush),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vpush)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
@@ -4030,7 +3105,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
int single = BIT(8) == 0;
int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
int imm32 = BITS(0, 7)<<2;
@@ -4087,28 +3162,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VSTM */
/* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */
-#define vfpinstr vstm
-#define vfpinstr_inst vstm_inst
-#define VFPLABEL_INST VSTM_INST
-#ifdef VFP_DECODE
-{"vstm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 0, 9, 11, 0x5},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vstm", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vstm_inst {
unsigned int single;
@@ -4118,15 +3175,15 @@ typedef struct _vstm_inst {
unsigned int n;
unsigned int imm32;
unsigned int regs;
-} vfpinstr_inst;
+} vstm_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vstm)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vstm_inst));
+ vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -4145,7 +3202,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST: /* encoding 1 */
+VSTM_INST: /* encoding 1 */
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -4153,7 +3210,7 @@ VFPLABEL_INST: /* encoding 1 */
int i;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
DBG("VSTM : addr[%x]\n", addr);
@@ -4203,69 +3260,12 @@ VFPLABEL_INST: /* encoding 1 */
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_STC_TRANS
-/* Should be the last operation of STC */
-return VSTM(state, type, instr, value);
-#endif
-#ifdef VFP_STC_IMPL
-int VSTM(ARMul_State * state, int type, ARMword instr, ARMword * value)
-{
- static int i = 0;
- static int single_regs, add, wback, d, n, imm32, regs;
- if (type == ARMul_FIRST)
- {
- single_regs = BIT(8) == 0; /* Single precision */
- add = BIT(23); /* */
- wback = BIT(21); /* write-back */
- d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
- n = BITS(16, 19); /* destination register */
- imm32 = BITS(0,7) * 4; /* may not be used */
- regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FSTMX if regs is odd */
-
- DBG("VSTM :\n");
-
- if (wback) {
- state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
- DBG("\twback r%d[%x]\n", n, state->Reg[n]);
- }
-
- i = 0;
-
- return ARMul_DONE;
- }
- else if (type == ARMul_DATA)
- {
- if (single_regs)
- {
- *value = state->ExtReg[d + i];
- DBG("\taddr[?] <= s%d=[%x]\n", d+i, state->ExtReg[d + i]);
- i++;
- if (i < regs)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- else
- {
- /* FIXME Careful of endianness, may need to rework this */
- *value = state->ExtReg[d*2 + i];
- DBG("\taddr[?] <= s[%d]=[%x]\n", d*2 + i, state->ExtReg[d*2 + i]);
- i++;
- if (i < regs*2)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- }
- return -1;
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vstm),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vstm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4280,7 +3280,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
//arch_arm_undef(cpu, bb, instr);
int single = BIT(8) == 0;
int add = BIT(23);
@@ -4356,43 +3356,25 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VPOP */
/* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */
-#define vfpinstr vpop
-#define vfpinstr_inst vpop_inst
-#define VFPLABEL_INST VPOP_INST
-#ifdef VFP_DECODE
-{"vpop", 3, ARMVFP2, 23, 27, 0x19, 16, 21, 0x3d, 9, 11, 0x5},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vpop", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vpop_inst {
unsigned int single;
unsigned int d;
unsigned int imm32;
unsigned int regs;
-} vfpinstr_inst;
+} vpop_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vpop)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpop_inst));
+ vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -4408,7 +3390,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VPOP_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -4417,7 +3399,7 @@ VFPLABEL_INST:
int i;
unsigned int value1, value2;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
DBG("VPOP :\n");
@@ -4468,70 +3450,12 @@ VFPLABEL_INST:
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_LDC_TRANS
-if (P == 0 && U == 1 && W == 1 && Rn == 0xD)
-{
- return VPOP(state, type, instr, value);
-}
-#endif
-#ifdef VFP_LDC_IMPL
-int VPOP(ARMul_State * state, int type, ARMword instr, ARMword value)
-{
- static int i = 0;
- static int single_regs, add, wback, d, n, imm32, regs;
- if (type == ARMul_FIRST)
- {
- single_regs = BIT(8) == 0; /* Single precision */
- d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
- imm32 = BITS(0,7)<<2; /* may not be used */
- regs = single_regs ? BITS(0, 7) : BITS(1, 7); /* FLDMX if regs is odd */
- DBG("VPOP :\n");
- DBG("\tsp[%x]", state->Reg[R13]);
- state->Reg[R13] = state->Reg[R13] + imm32;
- DBG("=>[%x]\n", state->Reg[R13]);
-
- i = 0;
-
- return ARMul_DONE;
- }
- else if (type == ARMul_TRANSFER)
- {
- return ARMul_DONE;
- }
- else if (type == ARMul_DATA)
- {
- if (single_regs)
- {
- state->ExtReg[d + i] = value;
- DBG("\ts%d <= [%x]\n", d + i, value);
- i++;
- if (i < regs)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- else
- {
- /* FIXME Careful of endianness, may need to rework this */
- state->ExtReg[d*2 + i] = value;
- DBG("\ts%d <= [%x]\n", d*2 + i, value);
- i++;
- if (i < regs*2)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- }
-
- return -1;
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vpop),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vpop)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4547,7 +3471,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
DBG("\t\tin %s instruction .\n", __FUNCTION__);
//arch_arm_undef(cpu, bb, instr);
int single = BIT(8) == 0;
@@ -4611,28 +3535,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VLDR */
/* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */
-#define vfpinstr vldr
-#define vfpinstr_inst vldr_inst
-#define VFPLABEL_INST VLDR_INST
-#ifdef VFP_DECODE
-{"vldr", 3, ARMVFP2, 24, 27, 0xd, 20, 21, 0x1, 9, 11, 0x5},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vldr", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vldr_inst {
unsigned int single;
@@ -4640,15 +3546,15 @@ typedef struct _vldr_inst {
unsigned int d;
unsigned int imm32;
unsigned int add;
-} vfpinstr_inst;
+} vldr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vldr)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldr_inst));
+ vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -4665,13 +3571,13 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VLDR_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
CHECK_VFP_ENABLED;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
unsigned int base = (inst_cream->n == 15 ? (cpu->Reg[inst_cream->n] & 0xFFFFFFFC) + 8 : cpu->Reg[inst_cream->n]);
addr = (inst_cream->add ? base + inst_cream->imm32 : base - inst_cream->imm32);
@@ -4710,69 +3616,12 @@ VFPLABEL_INST:
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_LDC_TRANS
-if (P == 1 && W == 0)
-{
- return VLDR(state, type, instr, value);
-}
-#endif
-#ifdef VFP_LDC_IMPL
-int VLDR(ARMul_State * state, int type, ARMword instr, ARMword value)
-{
- static int i = 0;
- static int single_reg, add, d, n, imm32, regs;
- if (type == ARMul_FIRST)
- {
- single_reg = BIT(8) == 0; /* Double precision */
- add = BIT(23); /* */
- imm32 = BITS(0,7)<<2; /* may not be used */
- d = single_reg ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
- n = BITS(16, 19); /* destination register */
-
- DBG("VLDR :\n");
-
- i = 0;
- regs = 1;
-
- return ARMul_DONE;
- }
- else if (type == ARMul_TRANSFER)
- {
- return ARMul_DONE;
- }
- else if (type == ARMul_DATA)
- {
- if (single_reg)
- {
- state->ExtReg[d+i] = value;
- DBG("\ts%d <= [%x]\n", d+i, value);
- i++;
- if (i < regs)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- else
- {
- /* FIXME Careful of endianness, may need to rework this */
- state->ExtReg[d*2+i] = value;
- DBG("\ts[%d] <= [%x]\n", d*2+i, value);
- i++;
- if (i < regs*2)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- }
- return -1;
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vldr),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vldr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -4788,7 +3637,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
int single = BIT(8) == 0;
int add = BIT(23);
int wback = BIT(21);
@@ -4846,28 +3695,10 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
/* ----------------------------------------------------------------------- */
/* VLDM */
/* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */
-#define vfpinstr vldm
-#define vfpinstr_inst vldm_inst
-#define VFPLABEL_INST VLDM_INST
-#ifdef VFP_DECODE
-{"vldm", 3, ARMVFP2, 25, 27, 0x6, 20, 20, 1, 9, 11, 0x5},
-#endif
-#ifdef VFP_DECODE_EXCLUSION
-{"vldm", 0, ARMVFP2, 0},
-#endif
-#ifdef VFP_INTERPRETER_TABLE
-INTERPRETER_TRANSLATE(vfpinstr),
-#endif
-#ifdef VFP_INTERPRETER_LABEL
-&&VFPLABEL_INST,
-#endif
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vldm_inst {
unsigned int single;
@@ -4877,15 +3708,15 @@ typedef struct _vldm_inst {
unsigned int n;
unsigned int imm32;
unsigned int regs;
-} vfpinstr_inst;
+} vldm_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
-ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(vldm)(unsigned int inst, int index)
{
VFP_DEBUG_TRANSLATE;
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vfpinstr_inst));
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vldm_inst));
+ vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
@@ -4904,7 +3735,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(vfpinstr)(unsigned int inst, int index)
}
#endif
#ifdef VFP_INTERPRETER_IMPL
-VFPLABEL_INST:
+VLDM_INST:
{
INC_ICOUNTER;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -4912,7 +3743,7 @@ VFPLABEL_INST:
int i;
- vfpinstr_inst *inst_cream = (vfpinstr_inst *)inst_base->component;
+ vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
addr = (inst_cream->add ? cpu->Reg[inst_cream->n] : cpu->Reg[inst_cream->n] - inst_cream->imm32);
DBG("VLDM : addr[%x]\n", addr);
@@ -4952,74 +3783,17 @@ VFPLABEL_INST:
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vfpinstr_inst));
+ INC_PC(sizeof(vldm_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
#endif
-#ifdef VFP_LDC_TRANS
-/* Should be the last operation of LDC */
-return VLDM(state, type, instr, value);
-#endif
-#ifdef VFP_LDC_IMPL
-int VLDM(ARMul_State * state, int type, ARMword instr, ARMword value)
-{
- static int i = 0;
- static int single_regs, add, wback, d, n, imm32, regs;
- if (type == ARMul_FIRST)
- {
- single_regs = BIT(8) == 0; /* Single precision */
- add = BIT(23); /* */
- wback = BIT(21); /* write-back */
- d = single_regs ? BITS(12, 15)<<1|BIT(22) : BIT(22)<<4|BITS(12, 15); /* Base register */
- n = BITS(16, 19); /* destination register */
- imm32 = BITS(0,7) * 4; /* may not be used */
- regs = single_regs ? BITS(0, 7) : BITS(0, 7)>>1; /* FLDMX if regs is odd */
-
- DBG("VLDM :\n");
-
- if (wback) {
- state->Reg[n] = (add ? state->Reg[n] + imm32 : state->Reg[n] - imm32);
- DBG("\twback r%d[%x]\n", n, state->Reg[n]);
- }
-
- i = 0;
-
- return ARMul_DONE;
- }
- else if (type == ARMul_DATA)
- {
- if (single_regs)
- {
- state->ExtReg[d + i] = value;
- DBG("\ts%d <= [%x] addr[?]\n", d+i, state->ExtReg[d + i]);
- i++;
- if (i < regs)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- else
- {
- /* FIXME Careful of endianness, may need to rework this */
- state->ExtReg[d*2 + i] = value;
- DBG("\ts[%d] <= [%x] addr[?]\n", d*2 + i, state->ExtReg[d*2 + i]);
- i++;
- if (i < regs*2)
- return ARMul_INC;
- else
- return ARMul_DONE;
- }
- }
- return -1;
-}
-#endif
#ifdef VFP_DYNCOM_TABLE
-DYNCOM_FILL_ACTION(vfpinstr),
+DYNCOM_FILL_ACTION(vldm),
#endif
#ifdef VFP_DYNCOM_TAG
-int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
+int DYNCOM_TAG(vldm)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr_t *new_pc, addr_t *next_pc)
{
int instr_size = INSTR_SIZE;
//DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
@@ -5034,7 +3808,7 @@ int DYNCOM_TAG(vfpinstr)(cpu_t *cpu, addr_t pc, uint32_t instr, tag_t *tag, addr
}
#endif
#ifdef VFP_DYNCOM_TRANS
-int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
+int DYNCOM_TRANS(vldm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
int single = BIT(8) == 0;
int add = BIT(23);
int wback = BIT(21);
@@ -5110,14 +3884,3 @@ int DYNCOM_TRANS(vfpinstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
return No_exp;
}
#endif
-#undef vfpinstr
-#undef vfpinstr_inst
-#undef VFPLABEL_INST
-
-#define VFP_DEBUG_TRANSLATE DBG("in func %s, %x\n", __FUNCTION__, inst);
-#define VFP_DEBUG_UNIMPLEMENTED(x) printf("in func %s, " #x " unimplemented\n", __FUNCTION__); exit(-1);
-#define VFP_DEBUG_UNTESTED(x) printf("in func %s, " #x " untested\n", __FUNCTION__);
-
-#define CHECK_VFP_ENABLED
-
-#define CHECK_VFP_CDP_RET vfp_raise_exceptions(cpu, ret, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]); //if (ret == -1) {printf("VFP CDP FAILURE %x\n", inst_cream->instr); exit(-1);}
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 77491900a..38705e3cd 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -20,8 +20,8 @@ public:
std::string GetTypeName() const override { return "Arbiter"; }
std::string GetName() const override { return name; }
- static Kernel::HandleType GetStaticHandleType() { return HandleType::AddressArbiter; }
- Kernel::HandleType GetHandleType() const override { return HandleType::AddressArbiter; }
+ static const HandleType HANDLE_TYPE = HandleType::AddressArbiter;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
std::string name; ///< Name of address arbiter object (optional)
};
@@ -62,7 +62,8 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
/// Create an address arbiter
AddressArbiter* CreateAddressArbiter(Handle& handle, const std::string& name) {
AddressArbiter* address_arbiter = new AddressArbiter;
- handle = Kernel::g_object_pool.Create(address_arbiter);
+ // TOOD(yuriks): Fix error reporting
+ handle = Kernel::g_handle_table.Create(address_arbiter).ValueOr(INVALID_HANDLE);
address_arbiter->name = name;
return address_arbiter;
}
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 4de3fab3c..e43c3ee4e 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -19,8 +19,8 @@ public:
std::string GetTypeName() const override { return "Event"; }
std::string GetName() const override { return name; }
- static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Event; }
- Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Event; }
+ static const HandleType HANDLE_TYPE = HandleType::Event;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
ResetType intitial_reset_type; ///< ResetType specified at Event initialization
ResetType reset_type; ///< Current ResetType
@@ -53,7 +53,7 @@ public:
* @return Result of operation, 0 on success, otherwise error code
*/
ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) {
- Event* evt = g_object_pool.Get<Event>(handle);
+ Event* evt = g_handle_table.Get<Event>(handle);
if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
evt->permanent_locked = permanent_locked;
@@ -67,7 +67,7 @@ ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) {
* @return Result of operation, 0 on success, otherwise error code
*/
ResultCode SetEventLocked(const Handle handle, const bool locked) {
- Event* evt = g_object_pool.Get<Event>(handle);
+ Event* evt = g_handle_table.Get<Event>(handle);
if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
if (!evt->permanent_locked) {
@@ -82,7 +82,7 @@ ResultCode SetEventLocked(const Handle handle, const bool locked) {
* @return Result of operation, 0 on success, otherwise error code
*/
ResultCode SignalEvent(const Handle handle) {
- Event* evt = g_object_pool.Get<Event>(handle);
+ Event* evt = g_handle_table.Get<Event>(handle);
if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
// Resume threads waiting for event to signal
@@ -110,7 +110,7 @@ ResultCode SignalEvent(const Handle handle) {
* @return Result of operation, 0 on success, otherwise error code
*/
ResultCode ClearEvent(Handle handle) {
- Event* evt = g_object_pool.Get<Event>(handle);
+ Event* evt = g_handle_table.Get<Event>(handle);
if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
if (!evt->permanent_locked) {
@@ -129,7 +129,8 @@ ResultCode ClearEvent(Handle handle) {
Event* CreateEvent(Handle& handle, const ResetType reset_type, const std::string& name) {
Event* evt = new Event;
- handle = Kernel::g_object_pool.Create(evt);
+ // TOOD(yuriks): Fix error reporting
+ handle = Kernel::g_handle_table.Create(evt).ValueOr(INVALID_HANDLE);
evt->locked = true;
evt->permanent_locked = false;
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 5fd06046e..e59ed1b57 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -13,77 +13,93 @@
namespace Kernel {
Handle g_main_thread = 0;
-ObjectPool g_object_pool;
+HandleTable g_handle_table;
u64 g_program_id = 0;
-ObjectPool::ObjectPool() {
- next_id = INITIAL_NEXT_ID;
+HandleTable::HandleTable() {
+ next_generation = 1;
+ Clear();
}
-Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) {
- if (range_top > MAX_COUNT) {
- range_top = MAX_COUNT;
- }
- if (next_id >= range_bottom && next_id < range_top) {
- range_bottom = next_id++;
- }
- for (int i = range_bottom; i < range_top; i++) {
- if (!occupied[i]) {
- occupied[i] = true;
- pool[i] = obj;
- pool[i]->handle = i + HANDLE_OFFSET;
- return i + HANDLE_OFFSET;
- }
+ResultVal<Handle> HandleTable::Create(Object* obj) {
+ _dbg_assert_(Kernel, obj != nullptr);
+
+ u16 slot = next_free_slot;
+ if (slot >= generations.size()) {
+ LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use.");
+ return ERR_OUT_OF_HANDLES;
}
- LOG_ERROR(Kernel, "Unable to allocate kernel object, too many objects slots in use.");
- return 0;
-}
+ next_free_slot = generations[slot];
-bool ObjectPool::IsValid(Handle handle) const {
- int index = handle - HANDLE_OFFSET;
- if (index < 0)
- return false;
- if (index >= MAX_COUNT)
- return false;
+ u16 generation = next_generation++;
- return occupied[index];
+ // Overflow count so it fits in the 15 bits dedicated to the generation in the handle.
+ // CTR-OS doesn't use generation 0, so skip straight to 1.
+ if (next_generation >= (1 << 15)) next_generation = 1;
+
+ generations[slot] = generation;
+ intrusive_ptr_add_ref(obj);
+ objects[slot] = obj;
+
+ Handle handle = generation | (slot << 15);
+ obj->handle = handle;
+ return MakeResult<Handle>(handle);
}
-void ObjectPool::Clear() {
- for (int i = 0; i < MAX_COUNT; i++) {
- //brutally clear everything, no validation
- if (occupied[i])
- delete pool[i];
- occupied[i] = false;
+ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
+ Object* object = GetGeneric(handle);
+ if (object == nullptr) {
+ LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle);
+ return ERR_INVALID_HANDLE;
}
- pool.fill(nullptr);
- next_id = INITIAL_NEXT_ID;
+ return Create(object);
}
-Object* &ObjectPool::operator [](Handle handle)
-{
- _dbg_assert_msg_(Kernel, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ");
- return pool[handle - HANDLE_OFFSET];
+ResultCode HandleTable::Close(Handle handle) {
+ if (!IsValid(handle))
+ return ERR_INVALID_HANDLE;
+
+ size_t slot = GetSlot(handle);
+ u16 generation = GetGeneration(handle);
+
+ intrusive_ptr_release(objects[slot]);
+ objects[slot] = nullptr;
+
+ generations[generation] = next_free_slot;
+ next_free_slot = slot;
+ return RESULT_SUCCESS;
}
-void ObjectPool::List() {
- for (int i = 0; i < MAX_COUNT; i++) {
- if (occupied[i]) {
- if (pool[i]) {
- LOG_DEBUG(Kernel, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName().c_str(),
- pool[i]->GetName().c_str());
- }
- }
- }
+bool HandleTable::IsValid(Handle handle) const {
+ size_t slot = GetSlot(handle);
+ u16 generation = GetGeneration(handle);
+
+ return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;
}
-int ObjectPool::GetCount() const {
- return std::count(occupied.begin(), occupied.end(), true);
+Object* HandleTable::GetGeneric(Handle handle) const {
+ if (handle == CurrentThread) {
+ // TODO(yuriks) Directly return the pointer once this is possible.
+ handle = GetCurrentThreadHandle();
+ } else if (handle == CurrentProcess) {
+ LOG_ERROR(Kernel, "Current process (%08X) pseudo-handle not supported", CurrentProcess);
+ return nullptr;
+ }
+
+ if (!IsValid(handle)) {
+ return nullptr;
+ }
+ return objects[GetSlot(handle)];
}
-Object* ObjectPool::CreateByIDType(int type) {
- LOG_ERROR(Kernel, "Unimplemented: %d.", type);
- return nullptr;
+void HandleTable::Clear() {
+ for (size_t i = 0; i < MAX_COUNT; ++i) {
+ generations[i] = i + 1;
+ if (objects[i] != nullptr)
+ intrusive_ptr_release(objects[i]);
+ objects[i] = nullptr;
+ }
+ next_free_slot = 0;
}
/// Initialize the kernel
@@ -95,7 +111,7 @@ void Init() {
void Shutdown() {
Kernel::ThreadingShutdown();
- g_object_pool.Clear(); // Free all kernel objects
+ g_handle_table.Clear(); // Free all kernel objects
}
/**
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 32258d5a0..7f86fd07d 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -12,13 +12,17 @@
typedef u32 Handle;
typedef s32 Result;
+const Handle INVALID_HANDLE = 0;
+
namespace Kernel {
-// From kernel.h. Declarations duplicated here to avoid a circular header dependency.
-class Thread;
-Thread* GetCurrentThread();
+// TODO: Verify code
+const ResultCode ERR_OUT_OF_HANDLES(ErrorDescription::OutOfMemory, ErrorModule::Kernel,
+ ErrorSummary::OutOfResource, ErrorLevel::Temporary);
+// TOOD: Verify code
+const ResultCode ERR_INVALID_HANDLE = InvalidHandle(ErrorModule::Kernel);
-enum KernelHandle {
+enum KernelHandle : Handle {
CurrentThread = 0xFFFF8000,
CurrentProcess = 0xFFFF8001,
};
@@ -41,10 +45,10 @@ enum {
DEFAULT_STACK_SIZE = 0x4000,
};
-class ObjectPool;
+class HandleTable;
class Object : NonCopyable {
- friend class ObjectPool;
+ friend class HandleTable;
u32 handle;
public:
virtual ~Object() {}
@@ -61,106 +65,130 @@ public:
LOG_ERROR(Kernel, "(UNIMPLEMENTED)");
return UnimplementedFunction(ErrorModule::Kernel);
}
-};
-class ObjectPool : NonCopyable {
-public:
- ObjectPool();
- ~ObjectPool() {}
+private:
+ friend void intrusive_ptr_add_ref(Object*);
+ friend void intrusive_ptr_release(Object*);
- // Allocates a handle within the range and inserts the object into the map.
- Handle Create(Object* obj, int range_bottom=INITIAL_NEXT_ID, int range_top=0x7FFFFFFF);
+ unsigned int ref_count = 0;
+};
- static Object* CreateByIDType(int type);
+// Special functions that will later be used by boost::instrusive_ptr to do automatic ref-counting
+inline void intrusive_ptr_add_ref(Object* object) {
+ ++object->ref_count;
+}
- template <class T>
- void Destroy(Handle handle) {
- if (Get<T>(handle)) {
- occupied[handle - HANDLE_OFFSET] = false;
- delete pool[handle - HANDLE_OFFSET];
- }
+inline void intrusive_ptr_release(Object* object) {
+ if (--object->ref_count == 0) {
+ delete object;
}
+}
- bool IsValid(Handle handle) const;
+/**
+ * This class allows the creation of Handles, which are references to objects that can be tested
+ * for validity and looked up. Here they are used to pass references to kernel objects to/from the
+ * emulated process. it has been designed so that it follows the same handle format and has
+ * approximately the same restrictions as the handle manager in the CTR-OS.
+ *
+ * Handles contain two sub-fields: a slot index (bits 31:15) and a generation value (bits 14:0).
+ * The slot index is used to index into the arrays in this class to access the data corresponding
+ * to the Handle.
+ *
+ * To prevent accidental use of a freed Handle whose slot has already been reused, a global counter
+ * is kept and incremented every time a Handle is created. This is the Handle's "generation". The
+ * value of the counter is stored into the Handle as well as in the handle table (in the
+ * "generations" array). When looking up a handle, the Handle's generation must match with the
+ * value stored on the class, otherwise the Handle is considered invalid.
+ *
+ * To find free slots when allocating a Handle without needing to scan the entire object array, the
+ * generations field of unallocated slots is re-purposed as a linked list of indices to free slots.
+ * When a Handle is created, an index is popped off the list and used for the new Handle. When it
+ * is destroyed, it is again pushed onto the list to be re-used by the next allocation. It is
+ * likely that this allocation strategy differs from the one used in CTR-OS, but this hasn't been
+ * verified and isn't likely to cause any problems.
+ */
+class HandleTable final : NonCopyable {
+public:
+ HandleTable();
- template <class T>
- T* Get(Handle handle) {
- if (handle == CurrentThread) {
- return reinterpret_cast<T*>(GetCurrentThread());
- }
+ /**
+ * Allocates a handle for the given object.
+ * @return The created Handle or one of the following errors:
+ * - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded.
+ */
+ ResultVal<Handle> Create(Object* obj);
- if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) {
- if (handle != 0) {
- LOG_ERROR(Kernel, "Bad object handle %08x", handle);
- }
- return nullptr;
- } else {
- Object* t = pool[handle - HANDLE_OFFSET];
- if (t->GetHandleType() != T::GetStaticHandleType()) {
- LOG_ERROR(Kernel, "Wrong object type for %08x", handle);
- return nullptr;
- }
- return static_cast<T*>(t);
- }
- }
+ /**
+ * Returns a new handle that points to the same object as the passed in handle.
+ * @return The duplicated Handle or one of the following errors:
+ * - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
+ * - Any errors returned by `Create()`.
+ */
+ ResultVal<Handle> Duplicate(Handle handle);
- // ONLY use this when you know the handle is valid.
- template <class T>
- T *GetFast(Handle handle) {
- if (handle == CurrentThread) {
- return reinterpret_cast<T*>(GetCurrentThread());
- }
+ /**
+ * Closes a handle, removing it from the table and decreasing the object's ref-count.
+ * @return `RESULT_SUCCESS` or one of the following errors:
+ * - `ERR_INVALID_HANDLE`: an invalid handle was passed in.
+ */
+ ResultCode Close(Handle handle);
- const Handle realHandle = handle - HANDLE_OFFSET;
- _dbg_assert_(Kernel, realHandle >= 0 && realHandle < MAX_COUNT && occupied[realHandle]);
- return static_cast<T*>(pool[realHandle]);
- }
+ /// Checks if a handle is valid and points to an existing object.
+ bool IsValid(Handle handle) const;
- template <class T, typename ArgT>
- void Iterate(bool func(T*, ArgT), ArgT arg) {
- int type = T::GetStaticIDType();
- for (int i = 0; i < MAX_COUNT; i++)
- {
- if (!occupied[i])
- continue;
- T* t = static_cast<T*>(pool[i]);
- if (t->GetIDType() == type) {
- if (!func(t, arg))
- break;
- }
- }
- }
+ /**
+ * Looks up a handle.
+ * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid.
+ */
+ Object* GetGeneric(Handle handle) const;
- bool GetIDType(Handle handle, HandleType* type) const {
- if ((handle < HANDLE_OFFSET) || (handle >= HANDLE_OFFSET + MAX_COUNT) ||
- !occupied[handle - HANDLE_OFFSET]) {
- LOG_ERROR(Kernel, "Bad object handle %08X", handle);
- return false;
+ /**
+ * Looks up a handle while verifying its type.
+ * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid or its
+ * type differs from the handle type `T::HANDLE_TYPE`.
+ */
+ template <class T>
+ T* Get(Handle handle) const {
+ Object* object = GetGeneric(handle);
+ if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
+ return static_cast<T*>(object);
}
- Object* t = pool[handle - HANDLE_OFFSET];
- *type = t->GetHandleType();
- return true;
+ return nullptr;
}
- Object* &operator [](Handle handle);
- void List();
+ /// Closes all handles held in this table.
void Clear();
- int GetCount() const;
private:
+ /**
+ * This is the maximum limit of handles allowed per process in CTR-OS. It can be further
+ * reduced by ExHeader values, but this is not emulated here.
+ */
+ static const size_t MAX_COUNT = 4096;
+
+ static size_t GetSlot(Handle handle) { return handle >> 15; }
+ static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; }
+
+ /// Stores the Object referenced by the handle or null if the slot is empty.
+ std::array<Object*, MAX_COUNT> objects;
- enum {
- MAX_COUNT = 0x1000,
- HANDLE_OFFSET = 0x100,
- INITIAL_NEXT_ID = 0x10,
- };
+ /**
+ * The value of `next_generation` when the handle was created, used to check for validity. For
+ * empty slots, contains the index of the next free slot in the list.
+ */
+ std::array<u16, MAX_COUNT> generations;
+
+ /**
+ * Global counter of the number of created handles. Stored in `generations` when a handle is
+ * created, and wraps around to 1 when it hits 0x8000.
+ */
+ u16 next_generation;
- std::array<Object*, MAX_COUNT> pool;
- std::array<bool, MAX_COUNT> occupied;
- int next_id;
+ /// Head of the free slots linked list.
+ u16 next_free_slot;
};
-extern ObjectPool g_object_pool;
+extern HandleTable g_handle_table;
extern Handle g_main_thread;
/// The ID code of the currently running game
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 5a18af114..558068c79 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -18,8 +18,8 @@ public:
std::string GetTypeName() const override { return "Mutex"; }
std::string GetName() const override { return name; }
- static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Mutex; }
- Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Mutex; }
+ static const HandleType HANDLE_TYPE = HandleType::Mutex;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
bool initial_locked; ///< Initial lock state when mutex was created
bool locked; ///< Current locked state
@@ -87,7 +87,7 @@ void ReleaseThreadMutexes(Handle thread) {
// Release every mutex that the thread holds, and resume execution on the waiting threads
for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) {
- Mutex* mutex = g_object_pool.GetFast<Mutex>(iter->second);
+ Mutex* mutex = g_handle_table.Get<Mutex>(iter->second);
ResumeWaitingThread(mutex);
}
@@ -115,7 +115,7 @@ bool ReleaseMutex(Mutex* mutex) {
* @param handle Handle to mutex to release
*/
ResultCode ReleaseMutex(Handle handle) {
- Mutex* mutex = Kernel::g_object_pool.Get<Mutex>(handle);
+ Mutex* mutex = Kernel::g_handle_table.Get<Mutex>(handle);
if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel);
if (!ReleaseMutex(mutex)) {
@@ -136,7 +136,8 @@ ResultCode ReleaseMutex(Handle handle) {
*/
Mutex* CreateMutex(Handle& handle, bool initial_locked, const std::string& name) {
Mutex* mutex = new Mutex;
- handle = Kernel::g_object_pool.Create(mutex);
+ // TODO(yuriks): Fix error reporting
+ handle = Kernel::g_handle_table.Create(mutex).ValueOr(INVALID_HANDLE);
mutex->locked = mutex->initial_locked = initial_locked;
mutex->name = name;
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
index b81d0b26a..6bc8066a6 100644
--- a/src/core/hle/kernel/semaphore.cpp
+++ b/src/core/hle/kernel/semaphore.cpp
@@ -17,8 +17,8 @@ public:
std::string GetTypeName() const override { return "Semaphore"; }
std::string GetName() const override { return name; }
- static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Semaphore; }
- Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Semaphore; }
+ static const HandleType HANDLE_TYPE = HandleType::Semaphore;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
s32 max_count; ///< Maximum number of simultaneous holders the semaphore can have
s32 available_count; ///< Number of free slots left in the semaphore
@@ -57,7 +57,8 @@ ResultCode CreateSemaphore(Handle* handle, s32 initial_count,
ErrorSummary::WrongArgument, ErrorLevel::Permanent);
Semaphore* semaphore = new Semaphore;
- *handle = g_object_pool.Create(semaphore);
+ // TOOD(yuriks): Fix error reporting
+ *handle = g_handle_table.Create(semaphore).ValueOr(INVALID_HANDLE);
// When the semaphore is created, some slots are reserved for other threads,
// and the rest is reserved for the caller thread
@@ -69,7 +70,7 @@ ResultCode CreateSemaphore(Handle* handle, s32 initial_count,
}
ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
- Semaphore* semaphore = g_object_pool.Get<Semaphore>(handle);
+ Semaphore* semaphore = g_handle_table.Get<Semaphore>(handle);
if (semaphore == nullptr)
return InvalidHandle(ErrorModule::Kernel);
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h
index 6760f346e..91f3ffc2c 100644
--- a/src/core/hle/kernel/session.h
+++ b/src/core/hle/kernel/session.h
@@ -45,8 +45,8 @@ class Session : public Object {
public:
std::string GetTypeName() const override { return "Session"; }
- static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Session; }
- Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Session; }
+ static const HandleType HANDLE_TYPE = HandleType::Session;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
/**
* Handles a synchronous call to this session using HLE emulation. Emulated <-> emulated calls
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index 2840f13bb..cea1f6fa1 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -13,8 +13,8 @@ class SharedMemory : public Object {
public:
std::string GetTypeName() const override { return "SharedMemory"; }
- static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::SharedMemory; }
- Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::SharedMemory; }
+ static const HandleType HANDLE_TYPE = HandleType::SharedMemory;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
u32 base_address; ///< Address of shared memory block in RAM
MemoryPermission permissions; ///< Permissions of shared memory block (SVC field)
@@ -32,7 +32,8 @@ public:
*/
SharedMemory* CreateSharedMemory(Handle& handle, const std::string& name) {
SharedMemory* shared_memory = new SharedMemory;
- handle = Kernel::g_object_pool.Create(shared_memory);
+ // TOOD(yuriks): Fix error reporting
+ handle = Kernel::g_handle_table.Create(shared_memory).ValueOr(INVALID_HANDLE);
shared_memory->name = name;
return shared_memory;
}
@@ -60,7 +61,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions
return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
}
- SharedMemory* shared_memory = Kernel::g_object_pool.Get<SharedMemory>(handle);
+ SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel);
shared_memory->base_address = address;
@@ -71,7 +72,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions
}
ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) {
- SharedMemory* shared_memory = Kernel::g_object_pool.Get<SharedMemory>(handle);
+ SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel);
if (0 != shared_memory->base_address)
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index c6a8dc7b9..872df2d14 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -26,8 +26,8 @@ public:
std::string GetName() const override { return name; }
std::string GetTypeName() const override { return "Thread"; }
- static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Thread; }
- Kernel::HandleType GetHandleType() const override { return Kernel::HandleType::Thread; }
+ static const HandleType HANDLE_TYPE = HandleType::Thread;
+ HandleType GetHandleType() const override { return HANDLE_TYPE; }
inline bool IsRunning() const { return (status & THREADSTATUS_RUNNING) != 0; }
inline bool IsStopped() const { return (status & THREADSTATUS_DORMANT) != 0; }
@@ -164,7 +164,7 @@ static bool CheckWaitType(const Thread* thread, WaitType type, Handle wait_handl
/// Stops the current thread
ResultCode StopThread(Handle handle, const char* reason) {
- Thread* thread = g_object_pool.Get<Thread>(handle);
+ Thread* thread = g_handle_table.Get<Thread>(handle);
if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel);
// Release all the mutexes that this thread holds
@@ -173,7 +173,7 @@ ResultCode StopThread(Handle handle, const char* reason) {
ChangeReadyState(thread, false);
thread->status = THREADSTATUS_DORMANT;
for (Handle waiting_handle : thread->waiting_threads) {
- Thread* waiting_thread = g_object_pool.Get<Thread>(waiting_handle);
+ Thread* waiting_thread = g_handle_table.Get<Thread>(waiting_handle);
if (CheckWaitType(waiting_thread, WAITTYPE_THREADEND, handle))
ResumeThreadFromWait(waiting_handle);
@@ -210,7 +210,7 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address) {
// Iterate through threads, find highest priority thread that is waiting to be arbitrated...
for (Handle handle : thread_queue) {
- Thread* thread = g_object_pool.Get<Thread>(handle);
+ Thread* thread = g_handle_table.Get<Thread>(handle);
if (!CheckWaitType(thread, WAITTYPE_ARB, arbiter, address))
continue;
@@ -235,7 +235,7 @@ void ArbitrateAllThreads(u32 arbiter, u32 address) {
// Iterate through threads, find highest priority thread that is waiting to be arbitrated...
for (Handle handle : thread_queue) {
- Thread* thread = g_object_pool.Get<Thread>(handle);
+ Thread* thread = g_handle_table.Get<Thread>(handle);
if (CheckWaitType(thread, WAITTYPE_ARB, arbiter, address))
ResumeThreadFromWait(handle);
@@ -288,7 +288,7 @@ Thread* NextThread() {
if (next == 0) {
return nullptr;
}
- return Kernel::g_object_pool.Get<Thread>(next);
+ return Kernel::g_handle_table.Get<Thread>(next);
}
void WaitCurrentThread(WaitType wait_type, Handle wait_handle) {
@@ -305,7 +305,7 @@ void WaitCurrentThread(WaitType wait_type, Handle wait_handle, VAddr wait_addres
/// Resumes a thread from waiting by marking it as "ready"
void ResumeThreadFromWait(Handle handle) {
- Thread* thread = Kernel::g_object_pool.Get<Thread>(handle);
+ Thread* thread = Kernel::g_handle_table.Get<Thread>(handle);
if (thread) {
thread->status &= ~THREADSTATUS_WAIT;
thread->wait_handle = 0;
@@ -341,7 +341,8 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio
Thread* thread = new Thread;
- handle = Kernel::g_object_pool.Create(thread);
+ // TOOD(yuriks): Fix error reporting
+ handle = Kernel::g_handle_table.Create(thread).ValueOr(INVALID_HANDLE);
thread_queue.push_back(handle);
thread_ready_queue.prepare(priority);
@@ -398,7 +399,7 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3
/// Get the priority of the thread specified by handle
ResultVal<u32> GetThreadPriority(const Handle handle) {
- Thread* thread = g_object_pool.Get<Thread>(handle);
+ Thread* thread = g_handle_table.Get<Thread>(handle);
if (thread == nullptr) return InvalidHandle(ErrorModule::Kernel);
return MakeResult<u32>(thread->current_priority);
@@ -410,7 +411,7 @@ ResultCode SetThreadPriority(Handle handle, s32 priority) {
if (!handle) {
thread = GetCurrentThread(); // TODO(bunnei): Is this correct behavior?
} else {
- thread = g_object_pool.Get<Thread>(handle);
+ thread = g_handle_table.Get<Thread>(handle);
if (thread == nullptr) {
return InvalidHandle(ErrorModule::Kernel);
}
@@ -481,7 +482,7 @@ void Reschedule() {
LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle());
for (Handle handle : thread_queue) {
- Thread* thread = g_object_pool.Get<Thread>(handle);
+ Thread* thread = g_handle_table.Get<Thread>(handle);
LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X",
thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, thread->wait_handle);
}
@@ -497,7 +498,7 @@ void Reschedule() {
}
ResultCode GetThreadId(u32* thread_id, Handle handle) {
- Thread* thread = g_object_pool.Get<Thread>(handle);
+ Thread* thread = g_handle_table.Get<Thread>(handle);
if (thread == nullptr)
return ResultCode(ErrorDescription::InvalidHandle, ErrorModule::OS,
ErrorSummary::WrongArgument, ErrorLevel::Permanent);
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 9396b6b26..0e1397cd9 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -77,9 +77,6 @@ Handle ArbitrateHighestPriorityThread(u32 arbiter, u32 address);
/// Arbitrate all threads currently waiting...
void ArbitrateAllThreads(u32 arbiter, u32 address);
-/// Gets the current thread
-Thread* GetCurrentThread();
-
/// Gets the current thread handle
Handle GetCurrentThreadHandle();
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 98db02f15..487bf3aa7 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -133,7 +133,7 @@ public:
case FileCommand::Close:
{
LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str());
- Kernel::g_object_pool.Destroy<File>(GetHandle());
+ backend->Close();
break;
}
@@ -189,7 +189,7 @@ public:
case DirectoryCommand::Close:
{
LOG_TRACE(Service_FS, "Close %s %s", GetTypeName().c_str(), GetName().c_str());
- Kernel::g_object_pool.Destroy<Directory>(GetHandle());
+ backend->Close();
break;
}
@@ -283,7 +283,8 @@ ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSy
}
auto file = Common::make_unique<File>(std::move(backend), path);
- Handle handle = Kernel::g_object_pool.Create(file.release());
+ // TOOD(yuriks): Fix error reporting
+ Handle handle = Kernel::g_handle_table.Create(file.release()).ValueOr(INVALID_HANDLE);
return MakeResult<Handle>(handle);
}
@@ -388,7 +389,8 @@ ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const F
}
auto directory = Common::make_unique<Directory>(std::move(backend), path);
- Handle handle = Kernel::g_object_pool.Create(directory.release());
+ // TOOD(yuriks): Fix error reporting
+ Handle handle = Kernel::g_handle_table.Create(directory.release()).ValueOr(INVALID_HANDLE);
return MakeResult<Handle>(handle);
}
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 44e4fbcb2..0f3cc2aa8 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -56,7 +56,8 @@ Manager::~Manager() {
/// Add a service to the manager (does not create it though)
void Manager::AddService(Interface* service) {
- m_port_map[service->GetPortName()] = Kernel::g_object_pool.Create(service);
+ // TOOD(yuriks): Fix error reporting
+ m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE);
m_services.push_back(service);
}
@@ -70,7 +71,7 @@ void Manager::DeleteService(const std::string& port_name) {
/// Get a Service Interface from its Handle
Interface* Manager::FetchFromHandle(Handle handle) {
- return Kernel::g_object_pool.Get<Interface>(handle);
+ return Kernel::g_handle_table.Get<Interface>(handle);
}
/// Get a Service Interface from its port
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 0616822fa..28b4ccd17 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -54,7 +54,8 @@ public:
/// Allocates a new handle for the service
Handle CreateHandle(Kernel::Object *obj) {
- Handle handle = Kernel::g_object_pool.Create(obj);
+ // TODO(yuriks): Fix error reporting
+ Handle handle = Kernel::g_handle_table.Create(obj).ValueOr(INVALID_HANDLE);
m_handles.push_back(handle);
return handle;
}
@@ -62,7 +63,7 @@ public:
/// Frees a handle from the service
template <class T>
void DeleteHandle(const Handle handle) {
- Kernel::g_object_pool.Destroy<T>(handle);
+ Kernel::g_handle_table.Close(handle);
m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end());
}
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index c98168e51..25944fc68 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -92,7 +92,7 @@ static Result ConnectToPort(Handle* out, const char* port_name) {
/// Synchronize to an OS service
static Result SendSyncRequest(Handle handle) {
- Kernel::Session* session = Kernel::g_object_pool.Get<Kernel::Session>(handle);
+ Kernel::Session* session = Kernel::g_handle_table.Get<Kernel::Session>(handle);
if (session == nullptr) {
return InvalidHandle(ErrorModule::Kernel).raw;
}
@@ -119,11 +119,9 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
// TODO(bunnei): Do something with nano_seconds, currently ignoring this
bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated
- if (!Kernel::g_object_pool.IsValid(handle)) {
+ Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handle);
+ if (object == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw;
- }
- Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handle);
- _dbg_assert_(Kernel, object != nullptr);
LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, object->GetTypeName().c_str(),
object->GetName().c_str(), nano_seconds);
@@ -150,10 +148,9 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
// Iterate through each handle, synchronize kernel object
for (s32 i = 0; i < handle_count; i++) {
- if (!Kernel::g_object_pool.IsValid(handles[i])) {
+ Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handles[i]);
+ if (object == nullptr)
return InvalidHandle(ErrorModule::Kernel).raw;
- }
- Kernel::Object* object = Kernel::g_object_pool.GetFast<Kernel::Object>(handles[i]);
LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], object->GetTypeName().c_str(),
object->GetName().c_str());
@@ -321,19 +318,12 @@ static Result CreateEvent(Handle* evt, u32 reset_type) {
/// Duplicates a kernel handle
static Result DuplicateHandle(Handle* out, Handle handle) {
- LOG_WARNING(Kernel_SVC, "(STUBBED) called handle=0x%08X", handle);
-
- // Translate kernel handles -> real handles
- if (handle == Kernel::CurrentThread) {
- handle = Kernel::GetCurrentThreadHandle();
+ ResultVal<Handle> out_h = Kernel::g_handle_table.Duplicate(handle);
+ if (out_h.Succeeded()) {
+ *out = *out_h;
+ LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out);
}
- _assert_msg_(KERNEL, (handle != Kernel::CurrentProcess),
- "(UNIMPLEMENTED) process handle duplication!");
-
- // TODO(bunnei): FixMe - This is a hack to return the handle that we were asked to duplicate.
- *out = handle;
-
- return 0;
+ return out_h.Code().raw;
}
/// Signals an event