summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt16
-rw-r--r--src/core/arm/arm_interface.h6
-rw-r--r--src/core/arm/dyncom/arm_dyncom.cpp49
-rw-r--r--src/core/arm/dyncom/arm_dyncom.h14
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp74
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp458
-rw-r--r--src/core/arm/interpreter/arm_interpreter.cpp51
-rw-r--r--src/core/arm/interpreter/arm_interpreter.h6
-rw-r--r--src/core/arm/interpreter/armemu.cpp704
-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/hle.cpp8
-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/ac_u.cpp3
-rw-r--r--src/core/hle/service/ac_u.h6
-rw-r--r--src/core/hle/service/act_u.cpp24
-rw-r--r--src/core/hle/service/act_u.h23
-rw-r--r--src/core/hle/service/am_app.h4
-rw-r--r--src/core/hle/service/am_net.cpp3
-rw-r--r--src/core/hle/service/am_net.h6
-rw-r--r--src/core/hle/service/apt_a.cpp34
-rw-r--r--src/core/hle/service/apt_a.h23
-rw-r--r--src/core/hle/service/apt_u.cpp3
-rw-r--r--src/core/hle/service/apt_u.h7
-rw-r--r--src/core/hle/service/boss_u.cpp19
-rw-r--r--src/core/hle/service/boss_u.h20
-rw-r--r--src/core/hle/service/cecd_u.h4
-rw-r--r--src/core/hle/service/cfg/cfg_i.cpp69
-rw-r--r--src/core/hle/service/cfg/cfg_i.h6
-rw-r--r--src/core/hle/service/cfg/cfg_u.cpp4
-rw-r--r--src/core/hle/service/cfg/cfg_u.h6
-rw-r--r--src/core/hle/service/csnd_snd.cpp3
-rw-r--r--src/core/hle/service/csnd_snd.h6
-rw-r--r--src/core/hle/service/dsp_dsp.cpp3
-rw-r--r--src/core/hle/service/dsp_dsp.h6
-rw-r--r--src/core/hle/service/err_f.cpp18
-rw-r--r--src/core/hle/service/err_f.h20
-rw-r--r--src/core/hle/service/frd_u.cpp34
-rw-r--r--src/core/hle/service/frd_u.h20
-rw-r--r--src/core/hle/service/fs/archive.cpp10
-rw-r--r--src/core/hle/service/fs/fs_user.cpp3
-rw-r--r--src/core/hle/service/fs/fs_user.h7
-rw-r--r--src/core/hle/service/gsp_gpu.cpp3
-rw-r--r--src/core/hle/service/gsp_gpu.h8
-rw-r--r--src/core/hle/service/hid_user.cpp4
-rw-r--r--src/core/hle/service/hid_user.h8
-rw-r--r--src/core/hle/service/http_c.cpp64
-rw-r--r--src/core/hle/service/http_c.h23
-rw-r--r--src/core/hle/service/ir_rst.cpp3
-rw-r--r--src/core/hle/service/ir_rst.h6
-rw-r--r--src/core/hle/service/ir_u.cpp3
-rw-r--r--src/core/hle/service/ir_u.h6
-rw-r--r--src/core/hle/service/ldr_ro.cpp1
-rw-r--r--src/core/hle/service/ldr_ro.h4
-rw-r--r--src/core/hle/service/mic_u.cpp3
-rw-r--r--src/core/hle/service/mic_u.h6
-rw-r--r--src/core/hle/service/ndm_u.cpp3
-rw-r--r--src/core/hle/service/ndm_u.h8
-rw-r--r--src/core/hle/service/news_u.cpp25
-rw-r--r--src/core/hle/service/news_u.h23
-rw-r--r--src/core/hle/service/nim_aoc.h4
-rw-r--r--src/core/hle/service/nwm_uds.cpp3
-rw-r--r--src/core/hle/service/nwm_uds.h6
-rw-r--r--src/core/hle/service/pm_app.cpp3
-rw-r--r--src/core/hle/service/pm_app.h6
-rw-r--r--src/core/hle/service/ptm_u.cpp3
-rw-r--r--src/core/hle/service/ptm_u.h6
-rw-r--r--src/core/hle/service/service.cpp17
-rw-r--r--src/core/hle/service/service.h5
-rw-r--r--src/core/hle/service/soc_u.cpp3
-rw-r--r--src/core/hle/service/soc_u.h6
-rw-r--r--src/core/hle/service/srv.cpp3
-rw-r--r--src/core/hle/service/srv.h9
-rw-r--r--src/core/hle/service/ssl_c.cpp3
-rw-r--r--src/core/hle/service/ssl_c.h8
-rw-r--r--src/core/hle/svc.cpp30
-rw-r--r--src/core/hw/gpu.cpp71
-rw-r--r--src/core/hw/gpu.h1
-rw-r--r--src/core/settings.h1
91 files changed, 2572 insertions, 2654 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index c00fc3493..fdd97c184 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -32,8 +32,10 @@ set(SRCS
hle/kernel/shared_memory.cpp
hle/kernel/thread.cpp
hle/service/ac_u.cpp
+ hle/service/act_u.cpp
hle/service/am_app.cpp
hle/service/am_net.cpp
+ hle/service/apt_a.cpp
hle/service/apt_u.cpp
hle/service/boss_u.cpp
hle/service/cecd_u.cpp
@@ -43,17 +45,19 @@ set(SRCS
hle/service/csnd_snd.cpp
hle/service/dsp_dsp.cpp
hle/service/err_f.cpp
+ hle/service/frd_u.cpp
hle/service/fs/archive.cpp
hle/service/fs/fs_user.cpp
- hle/service/frd_u.cpp
hle/service/gsp_gpu.cpp
hle/service/hid_user.cpp
+ hle/service/http_c.cpp
hle/service/ir_rst.cpp
hle/service/ir_u.cpp
hle/service/ldr_ro.cpp
hle/service/mic_u.cpp
- hle/service/nim_aoc.cpp
hle/service/ndm_u.cpp
+ hle/service/news_u.cpp
+ hle/service/nim_aoc.cpp
hle/service/nwm_uds.cpp
hle/service/pm_app.cpp
hle/service/ptm_u.cpp
@@ -118,8 +122,10 @@ set(HEADERS
hle/kernel/shared_memory.h
hle/kernel/thread.h
hle/service/ac_u.h
+ hle/service/act_u.h
hle/service/am_app.h
hle/service/am_net.h
+ hle/service/apt_a.h
hle/service/apt_u.h
hle/service/boss_u.h
hle/service/cecd_u.h
@@ -129,17 +135,19 @@ set(HEADERS
hle/service/csnd_snd.h
hle/service/dsp_dsp.h
hle/service/err_f.h
+ hle/service/frd_u.h
hle/service/fs/archive.h
hle/service/fs/fs_user.h
- hle/service/frd_u.h
hle/service/gsp_gpu.h
hle/service/hid_user.h
+ hle/service/http_c.h
hle/service/ir_rst.h
hle/service/ir_u.h
hle/service/ldr_ro.h
hle/service/mic_u.h
- hle/service/nim_aoc.h
hle/service/ndm_u.h
+ hle/service/news_u.h
+ hle/service/nim_aoc.h
hle/service/nwm_uds.h
hle/service/pm_app.h
hle/service/ptm_u.h
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index c59355339..3b7209418 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -78,6 +78,12 @@ public:
virtual u64 GetTicks() const = 0;
/**
+ * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
+ * @param ticks Number of ticks to advance the CPU core
+ */
+ virtual void AddTicks(u64 ticks) = 0;
+
+ /**
* Saves the current CPU context
* @param ctx Thread context to save
*/
diff --git a/src/core/arm/dyncom/arm_dyncom.cpp b/src/core/arm/dyncom/arm_dyncom.cpp
index 6d4fb1b48..a838fd25a 100644
--- a/src/core/arm/dyncom/arm_dyncom.cpp
+++ b/src/core/arm/dyncom/arm_dyncom.cpp
@@ -47,68 +47,38 @@ ARM_DynCom::ARM_DynCom() : ticks(0) {
ARM_DynCom::~ARM_DynCom() {
}
-/**
- * Set the Program Counter to an address
- * @param addr Address to set PC to
- */
void ARM_DynCom::SetPC(u32 pc) {
state->pc = state->Reg[15] = pc;
}
-/*
- * Get the current Program Counter
- * @return Returns current PC
- */
u32 ARM_DynCom::GetPC() const {
return state->Reg[15];
}
-/**
- * Get an ARM register
- * @param index Register index (0-15)
- * @return Returns the value in the register
- */
u32 ARM_DynCom::GetReg(int index) const {
return state->Reg[index];
}
-/**
- * Set an ARM register
- * @param index Register index (0-15)
- * @param value Value to set register to
- */
void ARM_DynCom::SetReg(int index, u32 value) {
state->Reg[index] = value;
}
-/**
- * Get the current CPSR register
- * @return Returns the value of the CPSR register
- */
u32 ARM_DynCom::GetCPSR() const {
return state->Cpsr;
}
-/**
- * Set the current CPSR register
- * @param cpsr Value to set CPSR to
- */
void ARM_DynCom::SetCPSR(u32 cpsr) {
state->Cpsr = cpsr;
}
-/**
- * Returns the number of clock ticks since the last reset
- * @return Returns number of clock ticks
- */
u64 ARM_DynCom::GetTicks() const {
return ticks;
}
-/**
- * Executes the given number of instructions
- * @param num_instructions Number of instructions to executes
- */
+void ARM_DynCom::AddTicks(u64 ticks) {
+ this->ticks += ticks;
+}
+
void ARM_DynCom::ExecuteInstructions(int num_instructions) {
state->NumInstrsToExecute = num_instructions;
@@ -118,11 +88,6 @@ void ARM_DynCom::ExecuteInstructions(int num_instructions) {
ticks += InterpreterMainLoop(state.get());
}
-/**
- * Saves the current CPU context
- * @param ctx Thread context to save
- * @todo Do we need to save Reg[15] and NextInstr?
- */
void ARM_DynCom::SaveContext(ThreadContext& ctx) {
memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
@@ -139,11 +104,6 @@ void ARM_DynCom::SaveContext(ThreadContext& ctx) {
ctx.mode = state->NextInstr;
}
-/**
- * Loads a CPU context
- * @param ctx Thread context to load
- * @param Do we need to load Reg[15] and NextInstr?
- */
void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
@@ -160,7 +120,6 @@ void ARM_DynCom::LoadContext(const ThreadContext& ctx) {
state->NextInstr = ctx.mode;
}
-/// Prepare core for thread reschedule (if needed to correctly handle state)
void ARM_DynCom::PrepareReschedule() {
state->NumInstrsToExecute = 0;
}
diff --git a/src/core/arm/dyncom/arm_dyncom.h b/src/core/arm/dyncom/arm_dyncom.h
index 6fa2a0ba7..7284dcd07 100644
--- a/src/core/arm/dyncom/arm_dyncom.h
+++ b/src/core/arm/dyncom/arm_dyncom.h
@@ -27,14 +27,14 @@ public:
* Get the current Program Counter
* @return Returns current PC
*/
- u32 GetPC() const;
+ u32 GetPC() const override;
/**
* Get an ARM register
* @param index Register index (0-15)
* @return Returns the value in the register
*/
- u32 GetReg(int index) const;
+ u32 GetReg(int index) const override;
/**
* Set an ARM register
@@ -47,7 +47,7 @@ public:
* Get the current CPSR register
* @return Returns the value of the CPSR register
*/
- u32 GetCPSR() const;
+ u32 GetCPSR() const override;
/**
* Set the current CPSR register
@@ -59,7 +59,13 @@ public:
* Returns the number of clock ticks since the last reset
* @return Returns number of clock ticks
*/
- u64 GetTicks() const;
+ u64 GetTicks() const override;
+
+ /**
+ * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
+ * @param ticks Number of ticks to advance the CPU core
+ */
+ void AddTicks(u64 ticks) override;
/**
* Saves the current CPU context
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..45e7b441f 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,23 +3278,93 @@ 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"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(usub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUB8"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(usubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("USUBADDX"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UXTAB16"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("UXTB16"); }
+ARM_INST_PTR INTERPRETER_TRANSLATE(uxtab16)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(uxtab_inst));
+ uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_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->rotate = BITS(inst, 10, 11);
+
+ return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(uxtb16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(uxtab16)(inst, index);
+}
/* Floating point VFPv3 structures and instructions */
@@ -3250,9 +3381,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 +4255,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 +4294,7 @@ unsigned InterpreterMainLoop(ARMul_State* state)
DISPATCH:
{
if (!cpu->NirqSig) {
- if (!(cpu->Cpsr & 0x80)) {
+ if (!(cpu->Cpsr & 0x80)) {
goto END;
}
}
@@ -5575,8 +5739,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 +6812,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,21 +7034,143 @@ 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:
USUB8_INST:
USUBADDX_INST:
+
UXTAB16_INST:
UXTB16_INST:
+ {
+ INC_ICOUNTER;
+
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ uxtab_inst* const inst_cream = (uxtab_inst*)inst_base->component;
+
+ const u8 rn_idx = inst_cream->Rn;
+ const u32 rm_val = RM;
+ const u32 rotation = inst_cream->rotate * 8;
+ const u32 rotated_rm = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
+
+ // UXTB16, otherwise UXTAB16
+ if (rn_idx == 15) {
+ RD = rotated_rm & 0x00FF00FF;
+ }
+ else {
+ const u32 rn_val = RN;
+
+ const u8 lo_rotated = (rotated_rm & 0xFF);
+ const u16 lo_result = (rn_val & 0xFFFF) + (u16)lo_rotated;
+
+ const u8 hi_rotated = (rotated_rm >> 16) & 0xFF;
+ const u16 hi_result = (rn_val >> 16) + (u16)hi_rotated;
+
+ RD = ((hi_result << 16) | (lo_result & 0xFFFF));
+ }
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(uxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
#define VFP_INTERPRETER_IMPL
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
#undef VFP_INTERPRETER_IMPL
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index be04fc1a1..80ebc359e 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -38,78 +38,43 @@ ARM_Interpreter::~ARM_Interpreter() {
delete state;
}
-/**
- * Set the Program Counter to an address
- * @param addr Address to set PC to
- */
void ARM_Interpreter::SetPC(u32 pc) {
state->pc = state->Reg[15] = pc;
}
-/*
- * Get the current Program Counter
- * @return Returns current PC
- */
u32 ARM_Interpreter::GetPC() const {
return state->pc;
}
-/**
- * Get an ARM register
- * @param index Register index (0-15)
- * @return Returns the value in the register
- */
u32 ARM_Interpreter::GetReg(int index) const {
return state->Reg[index];
}
-/**
- * Set an ARM register
- * @param index Register index (0-15)
- * @param value Value to set register to
- */
void ARM_Interpreter::SetReg(int index, u32 value) {
state->Reg[index] = value;
}
-/**
- * Get the current CPSR register
- * @return Returns the value of the CPSR register
- */
u32 ARM_Interpreter::GetCPSR() const {
return state->Cpsr;
}
-/**
- * Set the current CPSR register
- * @param cpsr Value to set CPSR to
- */
void ARM_Interpreter::SetCPSR(u32 cpsr) {
state->Cpsr = cpsr;
}
-/**
- * Returns the number of clock ticks since the last reset
- * @return Returns number of clock ticks
- */
u64 ARM_Interpreter::GetTicks() const {
- return ARMul_Time(state);
+ return state->NumInstrs;
+}
+
+void ARM_Interpreter::AddTicks(u64 ticks) {
+ state->NumInstrs += ticks;
}
-/**
- * Executes the given number of instructions
- * @param num_instructions Number of instructions to executes
- */
void ARM_Interpreter::ExecuteInstructions(int num_instructions) {
state->NumInstrsToExecute = num_instructions - 1;
ARMul_Emulate32(state);
}
-/**
- * Saves the current CPU context
- * @param ctx Thread context to save
- * @todo Do we need to save Reg[15] and NextInstr?
- */
void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
@@ -126,11 +91,6 @@ void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
ctx.mode = state->NextInstr;
}
-/**
- * Loads a CPU context
- * @param ctx Thread context to load
- * @param Do we need to load Reg[15] and NextInstr?
- */
void ARM_Interpreter::LoadContext(const ThreadContext& ctx) {
memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
@@ -147,7 +107,6 @@ void ARM_Interpreter::LoadContext(const ThreadContext& ctx) {
state->NextInstr = ctx.mode;
}
-/// Prepare core for thread reschedule (if needed to correctly handle state)
void ARM_Interpreter::PrepareReschedule() {
state->NumInstrsToExecute = 0;
}
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index b685215a0..019dad5df 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -61,6 +61,12 @@ public:
u64 GetTicks() const override;
/**
+ * Advance the CPU core by the specified number of ticks (e.g. to simulate CPU execution time)
+ * @param ticks Number of ticks to advance the CPU core
+ */
+ void AddTicks(u64 ticks) override;
+
+ /**
* Saves the current CPU context
* @param ctx Thread context to save
*/
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index b2f671f94..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
@@ -5863,22 +5855,21 @@ L_stm_s_takeabort:
state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
if (lo_result >= 0) {
- state->Cpsr |= (1 << 16);
- state->Cpsr |= (1 << 17);
+ state->GEFlag |= (1 << 16);
+ state->GEFlag |= (1 << 17);
} else {
- state->Cpsr &= ~(1 << 16);
- state->Cpsr &= ~(1 << 17);
+ state->GEFlag &= ~(1 << 16);
+ state->GEFlag &= ~(1 << 17);
}
if (hi_result >= 0) {
- state->Cpsr |= (1 << 18);
- state->Cpsr |= (1 << 19);
+ state->GEFlag |= (1 << 18);
+ state->GEFlag |= (1 << 19);
} else {
- state->Cpsr &= ~(1 << 18);
- state->Cpsr &= ~(1 << 19);
+ state->GEFlag &= ~(1 << 18);
+ state->GEFlag &= ~(1 << 19);
}
- ARMul_CPSRAltered(state);
return 1;
}
// SADD8/SSUB8
@@ -5903,24 +5894,24 @@ L_stm_s_takeabort:
hi_val2 = (u8)(((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF));
if (lo_val1 & 0x80)
- state->Cpsr |= (1 << 16);
+ state->GEFlag |= (1 << 16);
else
- state->Cpsr &= ~(1 << 16);
+ state->GEFlag &= ~(1 << 16);
if (lo_val2 & 0x80)
- state->Cpsr |= (1 << 17);
+ state->GEFlag |= (1 << 17);
else
- state->Cpsr &= ~(1 << 17);
+ state->GEFlag &= ~(1 << 17);
if (hi_val1 & 0x80)
- state->Cpsr |= (1 << 18);
+ state->GEFlag |= (1 << 18);
else
- state->Cpsr &= ~(1 << 18);
+ state->GEFlag &= ~(1 << 18);
if (hi_val2 & 0x80)
- state->Cpsr |= (1 << 19);
+ state->GEFlag |= (1 << 19);
else
- state->Cpsr &= ~(1 << 19);
+ state->GEFlag &= ~(1 << 19);
}
// SSUB8
else {
@@ -5930,27 +5921,26 @@ L_stm_s_takeabort:
hi_val2 = (u8)(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF));
if (!(lo_val1 & 0x80))
- state->Cpsr |= (1 << 16);
+ state->GEFlag |= (1 << 16);
else
- state->Cpsr &= ~(1 << 16);
+ state->GEFlag &= ~(1 << 16);
if (!(lo_val2 & 0x80))
- state->Cpsr |= (1 << 17);
+ state->GEFlag |= (1 << 17);
else
- state->Cpsr &= ~(1 << 17);
+ state->GEFlag &= ~(1 << 17);
if (!(hi_val1 & 0x80))
- state->Cpsr |= (1 << 18);
+ state->GEFlag |= (1 << 18);
else
- state->Cpsr &= ~(1 << 18);
+ state->GEFlag &= ~(1 << 18);
if (!(hi_val2 & 0x80))
- state->Cpsr |= (1 << 19);
+ state->GEFlag |= (1 << 19);
else
- state->Cpsr &= ~(1 << 19);
+ state->GEFlag &= ~(1 << 19);
}
- ARMul_CPSRAltered(state);
state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24);
return 1;
}
@@ -6029,31 +6019,30 @@ L_stm_s_takeabort:
h2 = ((u16)(from >> 16) - (u16)(to >> 16));
if (!(h1 & 0xffff0000))
- state->Cpsr |= (3 << 16);
+ state->GEFlag |= (3 << 16);
else
- state->Cpsr &= ~(3 << 16);
+ state->GEFlag &= ~(3 << 16);
if (!(h2 & 0xffff0000))
- state->Cpsr |= (3 << 18);
+ state->GEFlag |= (3 << 18);
else
- state->Cpsr &= ~(3 << 18);
+ state->GEFlag &= ~(3 << 18);
}
else { // UADD16
h1 = ((u16)from + (u16)to);
h2 = ((u16)(from >> 16) + (u16)(to >> 16));
if (h1 & 0xffff0000)
- state->Cpsr |= (3 << 16);
+ state->GEFlag |= (3 << 16);
else
- state->Cpsr &= ~(3 << 16);
+ state->GEFlag &= ~(3 << 16);
if (h2 & 0xffff0000)
- state->Cpsr |= (3 << 18);
+ state->GEFlag |= (3 << 18);
else
- state->Cpsr &= ~(3 << 18);
+ state->GEFlag &= ~(3 << 18);
}
- ARMul_CPSRAltered(state);
state->Reg[rd] = (u32)((h1 & 0xffff) | ((h2 & 0xffff) << 16));
return 1;
}
@@ -6068,24 +6057,24 @@ L_stm_s_takeabort:
b4 = ((u8)(from >> 24) - (u8)(to >> 24));
if (!(b1 & 0xffffff00))
- state->Cpsr |= (1 << 16);
+ state->GEFlag |= (1 << 16);
else
- state->Cpsr &= ~(1 << 16);
+ state->GEFlag &= ~(1 << 16);
if (!(b2 & 0xffffff00))
- state->Cpsr |= (1 << 17);
+ state->GEFlag |= (1 << 17);
else
- state->Cpsr &= ~(1 << 17);
+ state->GEFlag &= ~(1 << 17);
if (!(b3 & 0xffffff00))
- state->Cpsr |= (1 << 18);
+ state->GEFlag |= (1 << 18);
else
- state->Cpsr &= ~(1 << 18);
+ state->GEFlag &= ~(1 << 18);
if (!(b4 & 0xffffff00))
- state->Cpsr |= (1 << 19);
+ state->GEFlag |= (1 << 19);
else
- state->Cpsr &= ~(1 << 19);
+ state->GEFlag &= ~(1 << 19);
}
else { // UADD8
b1 = ((u8)from + (u8)to);
@@ -6094,57 +6083,156 @@ L_stm_s_takeabort:
b4 = ((u8)(from >> 24) + (u8)(to >> 24));
if (b1 & 0xffffff00)
- state->Cpsr |= (1 << 16);
+ state->GEFlag |= (1 << 16);
else
- state->Cpsr &= ~(1 << 16);
+ state->GEFlag &= ~(1 << 16);
if (b2 & 0xffffff00)
- state->Cpsr |= (1 << 17);
+ state->GEFlag |= (1 << 17);
else
- state->Cpsr &= ~(1 << 17);
+ state->GEFlag &= ~(1 << 17);
if (b3 & 0xffffff00)
- state->Cpsr |= (1 << 18);
+ state->GEFlag |= (1 << 18);
else
- state->Cpsr &= ~(1 << 18);
+ state->GEFlag &= ~(1 << 18);
if (b4 & 0xffffff00)
- state->Cpsr |= (1 << 19);
+ state->GEFlag |= (1 << 19);
else
- state->Cpsr &= ~(1 << 19);
+ state->GEFlag &= ~(1 << 19);
}
- ARMul_CPSRAltered(state);
state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
return 1;
}
}
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:
{
@@ -6176,130 +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;
- state->Cpsr |= (1 << 27);
- } else if (rn_lo < min) {
- rn_lo = min;
- state->Cpsr |= (1 << 27);
- }
-
- if (rn_hi > max) {
- rn_hi = max;
- state->Cpsr |= (1 << 27);
- } else if (rn_hi < min) {
- rn_hi = min;
- state->Cpsr |= (1 << 27);
- }
-
- ARMul_CPSRAltered(state);
- 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);
@@ -6327,133 +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;
- state->Cpsr |= (1 << 27);
- } else if (rn_lo < 0) {
- rn_lo = 0;
- state->Cpsr |= (1 << 27);
- }
-
- if (max < rn_hi) {
- rn_hi = max;
- state->Cpsr |= (1 << 27);
- } else if (rn_hi < 0) {
- rn_hi = 0;
- state->Cpsr |= (1 << 27);
- }
-
- ARMul_CPSRAltered(state);
- 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;
}
- break;
+
+ 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;
}
-
- 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;
-
- return 1;
- }
+ state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + rm;
- 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
@@ -6503,11 +6506,70 @@ L_stm_s_takeabort:
return 1;
}
break;
- case 0x74:
- printf ("Unhandled v6 insn: smlald/smlsld\n");
+ case 0x74: // SMLALD and SMLSLD
+ {
+ const u8 rm_idx = BITS(8, 11);
+ const u8 rn_idx = BITS(0, 3);
+ const u8 rdlo_idx = BITS(12, 15);
+ const u8 rdhi_idx = BITS(16, 19);
+ const bool do_swap = (BIT(5) == 1);
+
+ const u32 rdlo_val = state->Reg[rdlo_idx];
+ const u32 rdhi_val = state->Reg[rdhi_idx];
+ const u32 rn_val = state->Reg[rn_idx];
+ u32 rm_val = state->Reg[rm_idx];
+
+ if (do_swap)
+ rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
+
+ const s32 product1 = (s16)(rn_val & 0xFFFF) * (s16)(rm_val & 0xFFFF);
+ const s32 product2 = (s16)((rn_val >> 16) & 0xFFFF) * (s16)((rm_val >> 16) & 0xFFFF);
+ s64 result;
+
+ // SMLALD
+ if (BIT(6) == 0) {
+ result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
+ }
+ // SMLSLD
+ else {
+ result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
+ }
+
+ state->Reg[rdlo_idx] = (result & 0xFFFFFFFF);
+ state->Reg[rdhi_idx] = ((result >> 32) & 0xFFFFFFFF);
+ return 1;
+ }
break;
- case 0x75:
- printf ("Unhandled v6 insn: smmla/smmls/smmul\n");
+ case 0x75: // SMMLA, SMMUL, and SMMLS
+ {
+ const u8 rm_idx = BITS(8, 11);
+ const u8 rn_idx = BITS(0, 3);
+ const u8 ra_idx = BITS(12, 15);
+ const u8 rd_idx = BITS(16, 19);
+ const bool do_round = (BIT(5) == 1);
+
+ const u32 rm_val = state->Reg[rm_idx];
+ const u32 rn_val = state->Reg[rn_idx];
+
+ // Assume SMMUL by default.
+ s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
+
+ if (ra_idx != 15) {
+ const u32 ra_val = state->Reg[ra_idx];
+
+ // SMMLA, otherwise SMMLS
+ if (BIT(6) == 0)
+ result += ((s64)ra_val << 32);
+ else
+ result = ((s64)ra_val << 32) - result;
+ }
+
+ if (do_round)
+ result += 0x80000000;
+
+ state->Reg[rd_idx] = ((result >> 32) & 0xFFFFFFFF);
+ return 1;
+ }
break;
case 0x78:
if (BITS(20, 24) == 0x18)
@@ -6519,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/hle.cpp b/src/core/hle/hle.cpp
index 2d314a4cf..33ac12507 100644
--- a/src/core/hle/hle.cpp
+++ b/src/core/hle/hle.cpp
@@ -43,7 +43,15 @@ void CallSVC(u32 opcode) {
void Reschedule(const char *reason) {
_dbg_assert_msg_(Kernel, reason != 0 && strlen(reason) < 256, "Reschedule: Invalid or too long reason.");
+
+ // TODO(bunnei): It seems that games depend on some CPU execution time elapsing during HLE
+ // routines. This simulates that time by artificially advancing the number of CPU "ticks".
+ // The value was chosen empirically, it seems to work well enough for everything tested, but
+ // is likely not ideal. We should find a more accurate way to simulate timing with HLE.
+ Core::g_app_core->AddTicks(4000);
+
Core::g_app_core->PrepareReschedule();
+
g_reschedule = true;
}
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/ac_u.cpp b/src/core/hle/service/ac_u.cpp
index d180bb4ec..20a3fa2e5 100644
--- a/src/core/hle/service/ac_u.cpp
+++ b/src/core/hle/service/ac_u.cpp
@@ -56,7 +56,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/ac_u.h b/src/core/hle/service/ac_u.h
index 097b18c4e..f1d26ebe8 100644
--- a/src/core/hle/service/ac_u.h
+++ b/src/core/hle/service/ac_u.h
@@ -16,11 +16,7 @@ namespace AC_U {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "ac:u";
}
diff --git a/src/core/hle/service/act_u.cpp b/src/core/hle/service/act_u.cpp
new file mode 100644
index 000000000..10870f14b
--- /dev/null
+++ b/src/core/hle/service/act_u.cpp
@@ -0,0 +1,24 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/log.h"
+#include "core/hle/hle.h"
+#include "core/hle/service/act_u.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace ACT_U
+
+namespace ACT_U {
+
+// Empty arrays are illegal -- commented out until an entry is added.
+//const Interface::FunctionInfo FunctionTable[] = { };
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+ //Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+} // namespace
diff --git a/src/core/hle/service/act_u.h b/src/core/hle/service/act_u.h
new file mode 100644
index 000000000..be41454a4
--- /dev/null
+++ b/src/core/hle/service/act_u.h
@@ -0,0 +1,23 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace ACT_U
+
+namespace ACT_U {
+
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "act:u";
+ }
+};
+
+} // namespace
diff --git a/src/core/hle/service/am_app.h b/src/core/hle/service/am_app.h
index 30a0be4c5..50dc2f5a2 100644
--- a/src/core/hle/service/am_app.h
+++ b/src/core/hle/service/am_app.h
@@ -15,10 +15,6 @@ class Interface : public Service::Interface {
public:
Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "am:app";
}
diff --git a/src/core/hle/service/am_net.cpp b/src/core/hle/service/am_net.cpp
index 943205e9e..112844e5b 100644
--- a/src/core/hle/service/am_net.cpp
+++ b/src/core/hle/service/am_net.cpp
@@ -41,7 +41,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/am_net.h b/src/core/hle/service/am_net.h
index c0dbfb444..616c33ee8 100644
--- a/src/core/hle/service/am_net.h
+++ b/src/core/hle/service/am_net.h
@@ -14,11 +14,7 @@ namespace AM_NET {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "am:net";
}
diff --git a/src/core/hle/service/apt_a.cpp b/src/core/hle/service/apt_a.cpp
new file mode 100644
index 000000000..dcf5ec4fe
--- /dev/null
+++ b/src/core/hle/service/apt_a.cpp
@@ -0,0 +1,34 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/log.h"
+#include "core/hle/hle.h"
+#include "core/hle/service/apt_a.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace APT_A
+
+namespace APT_A {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010040, nullptr, "GetLockHandle?"},
+ {0x00020080, nullptr, "Initialize?"},
+ {0x00030040, nullptr, "Enable?"},
+ {0x00040040, nullptr, "Finalize?"},
+ {0x00050040, nullptr, "GetAppletManInfo?"},
+ {0x00060040, nullptr, "GetAppletInfo?"},
+ {0x003B0040, nullptr, "CancelLibraryApplet?"},
+ {0x00430040, nullptr, "NotifyToWait?"},
+ {0x004B00C2, nullptr, "AppletUtility?"},
+ {0x00550040, nullptr, "WriteInputToNsState?"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+} // namespace
diff --git a/src/core/hle/service/apt_a.h b/src/core/hle/service/apt_a.h
new file mode 100644
index 000000000..6cbf1288f
--- /dev/null
+++ b/src/core/hle/service/apt_a.h
@@ -0,0 +1,23 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace APT_A
+
+namespace APT_A {
+
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "APT:A";
+ }
+};
+
+} // namespace
diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp
index fecc6e6f9..d8b261ba7 100644
--- a/src/core/hle/service/apt_u.cpp
+++ b/src/core/hle/service/apt_u.cpp
@@ -330,7 +330,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/apt_u.h b/src/core/hle/service/apt_u.h
index 3807cbecc..aad918cfc 100644
--- a/src/core/hle/service/apt_u.h
+++ b/src/core/hle/service/apt_u.h
@@ -20,15 +20,8 @@ namespace APT_U {
/// Interface to "APT:U" service
class Interface : public Service::Interface {
public:
-
Interface();
- ~Interface();
-
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "APT:U";
}
diff --git a/src/core/hle/service/boss_u.cpp b/src/core/hle/service/boss_u.cpp
index 24cd413da..1820ea7ad 100644
--- a/src/core/hle/service/boss_u.cpp
+++ b/src/core/hle/service/boss_u.cpp
@@ -11,18 +11,15 @@
namespace BOSS_U {
- const Interface::FunctionInfo FunctionTable[] = {
- {0x00020100, nullptr, "GetStorageInfo"},
- };
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00020100, nullptr, "GetStorageInfo"},
+};
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // Interface class
-
- Interface::Interface() {
- Register(FunctionTable, ARRAY_SIZE(FunctionTable));
- }
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
- Interface::~Interface() {
- }
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
} // namespace
diff --git a/src/core/hle/service/boss_u.h b/src/core/hle/service/boss_u.h
index 31e4d0c3a..2668f2dfd 100644
--- a/src/core/hle/service/boss_u.h
+++ b/src/core/hle/service/boss_u.h
@@ -11,17 +11,13 @@
namespace BOSS_U {
- class Interface : public Service::Interface {
- public:
- Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
- std::string GetPortName() const {
- return "boss:U";
- }
- };
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "boss:U";
+ }
+};
} // namespace
diff --git a/src/core/hle/service/cecd_u.h b/src/core/hle/service/cecd_u.h
index 0c9968bfe..e67564135 100644
--- a/src/core/hle/service/cecd_u.h
+++ b/src/core/hle/service/cecd_u.h
@@ -15,10 +15,6 @@ class Interface : public Service::Interface {
public:
Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "cecd:u";
}
diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp
index 3254cc10e..7c1ee8ac3 100644
--- a/src/core/hle/service/cfg/cfg_i.cpp
+++ b/src/core/hle/service/cfg/cfg_i.cpp
@@ -66,40 +66,40 @@ static void FormatConfig(Service::Interface* self) {
}
const Interface::FunctionInfo FunctionTable[] = {
- {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"},
- {0x04020082, nullptr, "SetConfigInfoBlk4"},
- {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
- {0x04040042, nullptr, "GetLocalFriendCodeSeedData"},
- {0x04050000, nullptr, "GetLocalFriendCodeSeed"},
- {0x04060000, nullptr, "SecureInfoGetRegion"},
- {0x04070000, nullptr, "SecureInfoGetByte101"},
- {0x04080042, nullptr, "SecureInfoGetSerialNo"},
- {0x04090000, nullptr, "UpdateConfigBlk00040003"},
- {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"},
- {0x08020082, nullptr, "SetConfigInfoBlk4"},
- {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
- {0x080400C2, nullptr, "CreateConfigInfoBlk"},
- {0x08050000, nullptr, "DeleteConfigNANDSavefile"},
- {0x08060000, FormatConfig, "FormatConfig"},
- {0x08070000, nullptr, "Unknown"},
- {0x08080000, nullptr, "UpdateConfigBlk1"},
- {0x08090000, nullptr, "UpdateConfigBlk2"},
- {0x080A0000, nullptr, "UpdateConfigBlk3"},
- {0x080B0082, nullptr, "SetGetLocalFriendCodeSeedData"},
- {0x080C0042, nullptr, "SetLocalFriendCodeSeedSignature"},
- {0x080D0000, nullptr, "DeleteCreateNANDLocalFriendCodeSeed"},
- {0x080E0000, nullptr, "VerifySigLocalFriendCodeSeed"},
- {0x080F0042, nullptr, "GetLocalFriendCodeSeedData"},
- {0x08100000, nullptr, "GetLocalFriendCodeSeed"},
- {0x08110084, nullptr, "SetSecureInfo"},
- {0x08120000, nullptr, "DeleteCreateNANDSecureInfo"},
- {0x08130000, nullptr, "VerifySigSecureInfo"},
- {0x08140042, nullptr, "SecureInfoGetData"},
- {0x08150042, nullptr, "SecureInfoGetSignature"},
- {0x08160000, nullptr, "SecureInfoGetRegion"},
- {0x08170000, nullptr, "SecureInfoGetByte101"},
- {0x08180042, nullptr, "SecureInfoGetSerialNo"},
+ {0x04010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"},
+ {0x04020082, nullptr, "SetConfigInfoBlk4"},
+ {0x04030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
+ {0x04040042, nullptr, "GetLocalFriendCodeSeedData"},
+ {0x04050000, nullptr, "GetLocalFriendCodeSeed"},
+ {0x04060000, nullptr, "SecureInfoGetRegion"},
+ {0x04070000, nullptr, "SecureInfoGetByte101"},
+ {0x04080042, nullptr, "SecureInfoGetSerialNo"},
+ {0x04090000, nullptr, "UpdateConfigBlk00040003"},
+ {0x08010082, GetConfigInfoBlk8, "GetConfigInfoBlk8"},
+ {0x08020082, nullptr, "SetConfigInfoBlk4"},
+ {0x08030000, UpdateConfigNANDSavegame, "UpdateConfigNANDSavegame"},
+ {0x080400C2, nullptr, "CreateConfigInfoBlk"},
+ {0x08050000, nullptr, "DeleteConfigNANDSavefile"},
+ {0x08060000, FormatConfig, "FormatConfig"},
+ {0x08080000, nullptr, "UpdateConfigBlk1"},
+ {0x08090000, nullptr, "UpdateConfigBlk2"},
+ {0x080A0000, nullptr, "UpdateConfigBlk3"},
+ {0x080B0082, nullptr, "SetGetLocalFriendCodeSeedData"},
+ {0x080C0042, nullptr, "SetLocalFriendCodeSeedSignature"},
+ {0x080D0000, nullptr, "DeleteCreateNANDLocalFriendCodeSeed"},
+ {0x080E0000, nullptr, "VerifySigLocalFriendCodeSeed"},
+ {0x080F0042, nullptr, "GetLocalFriendCodeSeedData"},
+ {0x08100000, nullptr, "GetLocalFriendCodeSeed"},
+ {0x08110084, nullptr, "SetSecureInfo"},
+ {0x08120000, nullptr, "DeleteCreateNANDSecureInfo"},
+ {0x08130000, nullptr, "VerifySigSecureInfo"},
+ {0x08140042, nullptr, "SecureInfoGetData"},
+ {0x08150042, nullptr, "SecureInfoGetSignature"},
+ {0x08160000, nullptr, "SecureInfoGetRegion"},
+ {0x08170000, nullptr, "SecureInfoGetByte101"},
+ {0x08180042, nullptr, "SecureInfoGetSerialNo"},
};
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interface class
@@ -107,7 +107,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/cfg/cfg_i.h b/src/core/hle/service/cfg/cfg_i.h
index 577aad236..a498dd589 100644
--- a/src/core/hle/service/cfg/cfg_i.h
+++ b/src/core/hle/service/cfg/cfg_i.h
@@ -14,11 +14,7 @@ namespace CFG_I {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "cfg:i";
}
diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp
index 59934ea46..03c01cf90 100644
--- a/src/core/hle/service/cfg/cfg_u.cpp
+++ b/src/core/hle/service/cfg/cfg_u.cpp
@@ -181,6 +181,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00090040, GetCountryCodeString, "GetCountryCodeString"},
{0x000A0040, GetCountryCodeID, "GetCountryCodeID"},
};
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interface class
@@ -188,7 +189,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/cfg/cfg_u.h b/src/core/hle/service/cfg/cfg_u.h
index 0136bff53..9ad73f355 100644
--- a/src/core/hle/service/cfg/cfg_u.h
+++ b/src/core/hle/service/cfg/cfg_u.h
@@ -14,11 +14,7 @@ namespace CFG_U {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "cfg:u";
}
diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp
index 3f62c7e9c..aef8cfbca 100644
--- a/src/core/hle/service/csnd_snd.cpp
+++ b/src/core/hle/service/csnd_snd.cpp
@@ -33,7 +33,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/csnd_snd.h b/src/core/hle/service/csnd_snd.h
index 85aab1dd3..a84752473 100644
--- a/src/core/hle/service/csnd_snd.h
+++ b/src/core/hle/service/csnd_snd.h
@@ -14,11 +14,7 @@ namespace CSND_SND {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "csnd:SND";
}
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 4c1c5b70b..2cf4d118f 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -190,7 +190,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index 7bf27fe0f..0b8b64600 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -14,11 +14,7 @@ namespace DSP_DSP {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "dsp::DSP";
}
diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp
index 5c7cce841..8c900eabc 100644
--- a/src/core/hle/service/err_f.cpp
+++ b/src/core/hle/service/err_f.cpp
@@ -11,17 +11,15 @@
namespace ERR_F {
- const Interface::FunctionInfo FunctionTable[] = {
- {0x00010800, nullptr, "ThrowFatalError"}
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // Interface class
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010800, nullptr, "ThrowFatalError"}
+};
- Interface::Interface() {
- Register(FunctionTable, ARRAY_SIZE(FunctionTable));
- }
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
- Interface::~Interface() {
- }
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
} // namespace
diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h
index 2c61c3651..892d8af9b 100644
--- a/src/core/hle/service/err_f.h
+++ b/src/core/hle/service/err_f.h
@@ -11,17 +11,13 @@
namespace ERR_F {
- class Interface : public Service::Interface {
- public:
- Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
- std::string GetPortName() const override {
- return "err:f";
- }
- };
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "err:f";
+ }
+};
} // namespace
diff --git a/src/core/hle/service/frd_u.cpp b/src/core/hle/service/frd_u.cpp
index c2ecef5bb..021186e57 100644
--- a/src/core/hle/service/frd_u.cpp
+++ b/src/core/hle/service/frd_u.cpp
@@ -11,25 +11,23 @@
namespace FRD_U {
- const Interface::FunctionInfo FunctionTable[] = {
- {0x00050000, nullptr, "GetFriendKey"},
- {0x00080000, nullptr, "GetMyPresence"},
- {0x00100040, nullptr, "GetPassword"},
- {0x00190042, nullptr, "GetFriendFavoriteGame"},
- {0x001A00C4, nullptr, "GetFriendInfo"},
- {0x001B0080, nullptr, "IsOnFriendList"},
- {0x001C0042, nullptr, "DecodeLocalFriendCode"},
- {0x001D0002, nullptr, "SetCurrentlyPlayingText"},
- {0x00320042, nullptr, "SetClientSdkVersion"}
- };
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- // Interface class
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00050000, nullptr, "GetFriendKey"},
+ {0x00080000, nullptr, "GetMyPresence"},
+ {0x00100040, nullptr, "GetPassword"},
+ {0x00190042, nullptr, "GetFriendFavoriteGame"},
+ {0x001A00C4, nullptr, "GetFriendInfo"},
+ {0x001B0080, nullptr, "IsOnFriendList"},
+ {0x001C0042, nullptr, "DecodeLocalFriendCode"},
+ {0x001D0002, nullptr, "SetCurrentlyPlayingText"},
+ {0x00320042, nullptr, "SetClientSdkVersion"}
+};
- Interface::Interface() {
- Register(FunctionTable, ARRAY_SIZE(FunctionTable));
- }
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
- Interface::~Interface() {
- }
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
} // namespace
diff --git a/src/core/hle/service/frd_u.h b/src/core/hle/service/frd_u.h
index e030f8b3b..ab8897d5b 100644
--- a/src/core/hle/service/frd_u.h
+++ b/src/core/hle/service/frd_u.h
@@ -11,17 +11,13 @@
namespace FRD_U {
- class Interface : public Service::Interface {
- public:
- Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
- std::string GetPortName() const override {
- return "frd:u";
- }
- };
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "frd:u";
+ }
+};
} // namespace
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/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index 957185f8f..b1a465274 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -597,8 +597,5 @@ FSUserInterface::FSUserInterface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-FSUserInterface::~FSUserInterface() {
-}
-
} // namespace FS
} // namespace Service
diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h
index af4da269b..2d896dd5f 100644
--- a/src/core/hle/service/fs/fs_user.h
+++ b/src/core/hle/service/fs/fs_user.h
@@ -15,15 +15,8 @@ namespace FS {
/// Interface to "fs:USER" service
class FSUserInterface : public Service::Interface {
public:
-
FSUserInterface();
- ~FSUserInterface();
-
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "fs:USER";
}
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index 1f841078a..0127d4ee5 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -396,7 +396,4 @@ Interface::Interface() {
g_thread_id = 1;
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/gsp_gpu.h b/src/core/hle/service/gsp_gpu.h
index 56b5a16c9..932b6170f 100644
--- a/src/core/hle/service/gsp_gpu.h
+++ b/src/core/hle/service/gsp_gpu.h
@@ -158,19 +158,11 @@ static_assert(sizeof(CommandBuffer) == 0x200, "CommandBuffer struct has incorrec
/// Interface to "srv:" service
class Interface : public Service::Interface {
public:
-
Interface();
- ~Interface();
-
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "gsp::Gpu";
}
-
};
/**
diff --git a/src/core/hle/service/hid_user.cpp b/src/core/hle/service/hid_user.cpp
index cec9b1bfb..99b0ea5a0 100644
--- a/src/core/hle/service/hid_user.cpp
+++ b/src/core/hle/service/hid_user.cpp
@@ -179,7 +179,6 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00170000, nullptr, "GetSoundVolume"},
};
-
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interface class
@@ -196,7 +195,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/hid_user.h b/src/core/hle/service/hid_user.h
index 2164ad896..5b96dda60 100644
--- a/src/core/hle/service/hid_user.h
+++ b/src/core/hle/service/hid_user.h
@@ -102,19 +102,11 @@ void PadUpdateComplete();
*/
class Interface : public Service::Interface {
public:
-
Interface();
- ~Interface();
-
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "hid:USER";
}
-
};
} // namespace
diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp
new file mode 100644
index 000000000..d0bff552f
--- /dev/null
+++ b/src/core/hle/service/http_c.cpp
@@ -0,0 +1,64 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/log.h"
+#include "core/hle/hle.h"
+#include "core/hle/service/http_c.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace HTTP_C
+
+namespace HTTP_C {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010044, nullptr, "Initialize"},
+ {0x00020082, nullptr, "CreateContext"},
+ {0x00030040, nullptr, "CloseContext"},
+ {0x00040040, nullptr, "CancelConnection"},
+ {0x00050040, nullptr, "GetRequestState"},
+ {0x00060040, nullptr, "GetDownloadSizeState"},
+ {0x00070040, nullptr, "GetRequestError"},
+ {0x00080042, nullptr, "InitializeConnectionSession"},
+ {0x00090040, nullptr, "BeginRequest"},
+ {0x000A0040, nullptr, "BeginRequestAsync"},
+ {0x000B0082, nullptr, "ReceiveData"},
+ {0x000C0102, nullptr, "ReceiveDataTimeout"},
+ {0x000D0146, nullptr, "SetProxy"},
+ {0x000E0040, nullptr, "SetProxyDefault"},
+ {0x000F00C4, nullptr, "SetBasicAuthorization"},
+ {0x00100080, nullptr, "SetSocketBufferSize"},
+ {0x001100C4, nullptr, "AddRequestHeader"},
+ {0x001200C4, nullptr, "AddPostDataAscii"},
+ {0x001300C4, nullptr, "AddPostDataBinary"},
+ {0x00140082, nullptr, "AddPostDataRaw"},
+ {0x00150080, nullptr, "SetPostDataType"},
+ {0x001600C4, nullptr, "SendPostDataAscii"},
+ {0x00170144, nullptr, "SendPostDataAsciiTimeout"},
+ {0x001800C4, nullptr, "SendPostDataBinary"},
+ {0x00190144, nullptr, "SendPostDataBinaryTimeout"},
+ {0x001A0082, nullptr, "SendPostDataRaw"},
+ {0x001B0102, nullptr, "SendPOSTDataRawTimeout"},
+ {0x001C0080, nullptr, "SetPostDataEncoding"},
+ {0x001D0040, nullptr, "NotifyFinishSendPostData"},
+ {0x001E00C4, nullptr, "GetResponseHeader"},
+ {0x001F0144, nullptr, "GetResponseHeaderTimeout"},
+ {0x00200082, nullptr, "GetResponseData"},
+ {0x00210102, nullptr, "GetResponseDataTimeout"},
+ {0x00220040, nullptr, "GetResponseStatusCode"},
+ {0x002300C0, nullptr, "GetResponseStatusCodeTimeout"},
+ {0x00240082, nullptr, "AddTrustedRootCA"},
+ {0x00350186, nullptr, "SetDefaultProxy"},
+ {0x00360000, nullptr, "ClearDNSCache"},
+ {0x00370080, nullptr, "SetKeepAlive"},
+ {0x003800C0, nullptr, "Finalize"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+} // namespace
diff --git a/src/core/hle/service/http_c.h b/src/core/hle/service/http_c.h
new file mode 100644
index 000000000..5ea3d1df3
--- /dev/null
+++ b/src/core/hle/service/http_c.h
@@ -0,0 +1,23 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace HTTP_C
+
+namespace HTTP_C {
+
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "http:C";
+ }
+};
+
+} // namespace
diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp
index 6145b8b2c..b388afb15 100644
--- a/src/core/hle/service/ir_rst.cpp
+++ b/src/core/hle/service/ir_rst.cpp
@@ -30,7 +30,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/ir_rst.h b/src/core/hle/service/ir_rst.h
index 2fdab9f02..deef701c5 100644
--- a/src/core/hle/service/ir_rst.h
+++ b/src/core/hle/service/ir_rst.h
@@ -14,11 +14,7 @@ namespace IR_RST {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "ir:rst";
}
diff --git a/src/core/hle/service/ir_u.cpp b/src/core/hle/service/ir_u.cpp
index db62a9c98..da6f38e41 100644
--- a/src/core/hle/service/ir_u.cpp
+++ b/src/core/hle/service/ir_u.cpp
@@ -39,7 +39,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/ir_u.h b/src/core/hle/service/ir_u.h
index cf1c73f52..ec47a1524 100644
--- a/src/core/hle/service/ir_u.h
+++ b/src/core/hle/service/ir_u.h
@@ -14,11 +14,7 @@ namespace IR_U {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "ir:u";
}
diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp
index c08313f9a..9c9e90a40 100644
--- a/src/core/hle/service/ldr_ro.cpp
+++ b/src/core/hle/service/ldr_ro.cpp
@@ -18,6 +18,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x000402C2, nullptr, "CRO_LoadAndFix"},
{0x000500C2, nullptr, "CRO_ApplyRelocationPatchesAndLink"}
};
+
////////////////////////////////////////////////////////////////////////////////////////////////////
// Interface class
diff --git a/src/core/hle/service/ldr_ro.h b/src/core/hle/service/ldr_ro.h
index 7716ae74e..331637cde 100644
--- a/src/core/hle/service/ldr_ro.h
+++ b/src/core/hle/service/ldr_ro.h
@@ -15,10 +15,6 @@ class Interface : public Service::Interface {
public:
Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "ldr:ro";
}
diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp
index 399548d4d..82bce9180 100644
--- a/src/core/hle/service/mic_u.cpp
+++ b/src/core/hle/service/mic_u.cpp
@@ -37,7 +37,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/mic_u.h b/src/core/hle/service/mic_u.h
index 26842e5f1..dc795d14c 100644
--- a/src/core/hle/service/mic_u.h
+++ b/src/core/hle/service/mic_u.h
@@ -16,11 +16,7 @@ namespace MIC_U {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "mic:u";
}
diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm_u.cpp
index 141c311fd..233b14f6d 100644
--- a/src/core/hle/service/ndm_u.cpp
+++ b/src/core/hle/service/ndm_u.cpp
@@ -24,7 +24,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/ndm_u.h b/src/core/hle/service/ndm_u.h
index 62ed901c2..51c4b3902 100644
--- a/src/core/hle/service/ndm_u.h
+++ b/src/core/hle/service/ndm_u.h
@@ -15,19 +15,11 @@ namespace NDM_U {
class Interface : public Service::Interface {
public:
-
Interface();
- ~Interface();
-
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "ndm:u";
}
-
};
} // namespace
diff --git a/src/core/hle/service/news_u.cpp b/src/core/hle/service/news_u.cpp
new file mode 100644
index 000000000..b5adad4c6
--- /dev/null
+++ b/src/core/hle/service/news_u.cpp
@@ -0,0 +1,25 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/log.h"
+#include "core/hle/hle.h"
+#include "core/hle/service/news_u.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace NEWS_U
+
+namespace NEWS_U {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x000100C8, nullptr, "AddNotification"},
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+} // namespace
diff --git a/src/core/hle/service/news_u.h b/src/core/hle/service/news_u.h
new file mode 100644
index 000000000..0473cd19c
--- /dev/null
+++ b/src/core/hle/service/news_u.h
@@ -0,0 +1,23 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace NEWS_U
+
+namespace NEWS_U {
+
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "news:u";
+ }
+};
+
+} // namespace
diff --git a/src/core/hle/service/nim_aoc.h b/src/core/hle/service/nim_aoc.h
index 33aa25c91..aeb71eed2 100644
--- a/src/core/hle/service/nim_aoc.h
+++ b/src/core/hle/service/nim_aoc.h
@@ -15,10 +15,6 @@ class Interface : public Service::Interface {
public:
Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "nim:aoc";
}
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp
index 2491d14d6..ce456a966 100644
--- a/src/core/hle/service/nwm_uds.cpp
+++ b/src/core/hle/service/nwm_uds.cpp
@@ -29,7 +29,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/nwm_uds.h b/src/core/hle/service/nwm_uds.h
index cd27f78fc..9043f5aa7 100644
--- a/src/core/hle/service/nwm_uds.h
+++ b/src/core/hle/service/nwm_uds.h
@@ -16,11 +16,7 @@ namespace NWM_UDS {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "nwm:UDS";
}
diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp
index 729255348..529dccafb 100644
--- a/src/core/hle/service/pm_app.cpp
+++ b/src/core/hle/service/pm_app.cpp
@@ -29,7 +29,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/pm_app.h b/src/core/hle/service/pm_app.h
index 7ed617e5e..c1fb1f9da 100644
--- a/src/core/hle/service/pm_app.h
+++ b/src/core/hle/service/pm_app.h
@@ -14,11 +14,7 @@ namespace PM_APP {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "pm:app";
}
diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp
index da48729da..d1498f05c 100644
--- a/src/core/hle/service/ptm_u.cpp
+++ b/src/core/hle/service/ptm_u.cpp
@@ -122,7 +122,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/ptm_u.h b/src/core/hle/service/ptm_u.h
index c9e0c519f..a44624fd5 100644
--- a/src/core/hle/service/ptm_u.h
+++ b/src/core/hle/service/ptm_u.h
@@ -16,11 +16,7 @@ namespace PTM_U {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "ptm:u";
}
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 664f914d6..0f3cc2aa8 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -7,8 +7,10 @@
#include "core/hle/service/service.h"
#include "core/hle/service/ac_u.h"
+#include "core/hle/service/act_u.h"
#include "core/hle/service/am_app.h"
#include "core/hle/service/am_net.h"
+#include "core/hle/service/apt_a.h"
#include "core/hle/service/apt_u.h"
#include "core/hle/service/boss_u.h"
#include "core/hle/service/cecd_u.h"
@@ -21,12 +23,14 @@
#include "core/hle/service/frd_u.h"
#include "core/hle/service/gsp_gpu.h"
#include "core/hle/service/hid_user.h"
+#include "core/hle/service/http_c.h"
#include "core/hle/service/ir_rst.h"
#include "core/hle/service/ir_u.h"
#include "core/hle/service/ldr_ro.h"
#include "core/hle/service/mic_u.h"
-#include "core/hle/service/nim_aoc.h"
#include "core/hle/service/ndm_u.h"
+#include "core/hle/service/news_u.h"
+#include "core/hle/service/nim_aoc.h"
#include "core/hle/service/nwm_uds.h"
#include "core/hle/service/pm_app.h"
#include "core/hle/service/ptm_u.h"
@@ -52,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);
}
@@ -66,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
@@ -88,8 +93,10 @@ void Init() {
g_manager->AddService(new SRV::Interface);
g_manager->AddService(new AC_U::Interface);
+ g_manager->AddService(new ACT_U::Interface);
g_manager->AddService(new AM_APP::Interface);
g_manager->AddService(new AM_NET::Interface);
+ g_manager->AddService(new APT_A::Interface);
g_manager->AddService(new APT_U::Interface);
g_manager->AddService(new BOSS_U::Interface);
g_manager->AddService(new CECD_U::Interface);
@@ -102,12 +109,14 @@ void Init() {
g_manager->AddService(new FS::FSUserInterface);
g_manager->AddService(new GSP_GPU::Interface);
g_manager->AddService(new HID_User::Interface);
+ g_manager->AddService(new HTTP_C::Interface);
g_manager->AddService(new IR_RST::Interface);
g_manager->AddService(new IR_U::Interface);
g_manager->AddService(new LDR_RO::Interface);
g_manager->AddService(new MIC_U::Interface);
- g_manager->AddService(new NIM_AOC::Interface);
g_manager->AddService(new NDM_U::Interface);
+ g_manager->AddService(new NEWS_U::Interface);
+ g_manager->AddService(new NIM_AOC::Interface);
g_manager->AddService(new NWM_UDS::Interface);
g_manager->AddService(new PM_APP::Interface);
g_manager->AddService(new PTM_U::Interface);
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/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 03deabe43..ef4f9829d 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -52,7 +52,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/soc_u.h b/src/core/hle/service/soc_u.h
index 5c9623730..2edf3b482 100644
--- a/src/core/hle/service/soc_u.h
+++ b/src/core/hle/service/soc_u.h
@@ -14,11 +14,7 @@ namespace SOC_U {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
+
std::string GetPortName() const override {
return "soc:U";
}
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 05ff1846b..25fab1a4f 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -68,7 +68,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/srv.h b/src/core/hle/service/srv.h
index 4f3e01aca..653aba5cb 100644
--- a/src/core/hle/service/srv.h
+++ b/src/core/hle/service/srv.h
@@ -11,21 +11,12 @@ namespace SRV {
/// Interface to "srv:" service
class Interface : public Service::Interface {
-
public:
-
Interface();
- ~Interface();
-
- /**
- * Gets the string name used by CTROS for the service
- * @return Port name of service
- */
std::string GetPortName() const override {
return "srv:";
}
-
};
} // namespace
diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp
index d5b0c4b06..360516cdf 100644
--- a/src/core/hle/service/ssl_c.cpp
+++ b/src/core/hle/service/ssl_c.cpp
@@ -25,7 +25,4 @@ Interface::Interface() {
Register(FunctionTable, ARRAY_SIZE(FunctionTable));
}
-Interface::~Interface() {
-}
-
} // namespace
diff --git a/src/core/hle/service/ssl_c.h b/src/core/hle/service/ssl_c.h
index 6281503a5..58e87c1cb 100644
--- a/src/core/hle/service/ssl_c.h
+++ b/src/core/hle/service/ssl_c.h
@@ -14,12 +14,8 @@ namespace SSL_C {
class Interface : public Service::Interface {
public:
Interface();
- ~Interface();
- /**
- * Gets the string port name used by CTROS for the service
- * @return Port name of service
- */
- std::string GetPortName() const {
+
+ std::string GetPortName() const override {
return "ssl:C";
}
};
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
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 67a8bc324..dd619cb16 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -21,12 +21,14 @@ namespace GPU {
Regs g_regs;
-u32 g_cur_line = 0; ///< Current vertical screen line
-u64 g_last_line_ticks = 0; ///< CPU tick count from last vertical screen line
-u64 g_last_frame_ticks = 0; ///< CPU tick count from last frame
+bool g_skip_frame = false; ///< True if the current frame was skipped
-static u32 kFrameCycles = 0; ///< 268MHz / 60 frames per second
-static u32 kFrameTicks = 0; ///< Approximate number of instructions/frame
+static u64 frame_ticks = 0; ///< 268MHz / gpu_refresh_rate frames per second
+static u64 line_ticks = 0; ///< Number of ticks for a screen line
+static u32 cur_line = 0; ///< Current screen line
+static u64 last_update_tick = 0; ///< CPU ticl count from last GPU update
+static u64 frame_count = 0; ///< Number of frames drawn
+static bool last_skip_frame = false; ///< True if the last frame was skipped
template <typename T>
inline void Read(T &var, const u32 raw_addr) {
@@ -34,7 +36,7 @@ inline void Read(T &var, const u32 raw_addr) {
u32 index = addr / 4;
// Reads other than u32 are untested, so I'd rather have them abort than silently fail
- if (index >= Regs::NumIds() || !std::is_same<T,u32>::value) {
+ if (index >= Regs::NumIds() || !std::is_same<T, u32>::value) {
LOG_ERROR(HW_GPU, "unknown Read%lu @ 0x%08X", sizeof(var) * 8, addr);
return;
}
@@ -48,7 +50,7 @@ inline void Write(u32 addr, const T data) {
u32 index = addr / 4;
// Writes other than u32 are untested, so I'd rather have them abort than silently fail
- if (index >= Regs::NumIds() || !std::is_same<T,u32>::value) {
+ if (index >= Regs::NumIds() || !std::is_same<T, u32>::value) {
LOG_ERROR(HW_GPU, "unknown Write%lu 0x%08X @ 0x%08X", sizeof(data) * 8, (u32)data, addr);
return;
}
@@ -179,37 +181,41 @@ template void Write<u8>(u32 addr, const u8 data);
/// Update hardware
void Update() {
auto& framebuffer_top = g_regs.framebuffer_config[0];
- u64 current_ticks = Core::g_app_core->GetTicks();
-
- // Update the frame after a certain number of CPU ticks have elapsed. This assumes that the
- // active frame in memory is always complete to render. There also may be issues with this
- // becoming out-of-synch with GSP synchrinization code (as follows). At this time, this seems to
- // be the most effective solution for both homebrew and retail applications. With retail, this
- // could be moved below (and probably would guarantee more accurate synchronization). However,
- // primitive homebrew relies on a vertical blank interrupt to happen inevitably (regardless of a
- // threading reschedule).
-
- if ((current_ticks - g_last_frame_ticks) > GPU::kFrameTicks) {
- VideoCore::g_renderer->SwapBuffers();
- g_last_frame_ticks = current_ticks;
- }
// Synchronize GPU on a thread reschedule: Because we cannot accurately predict a vertical
// blank, we need to simulate it. Based on testing, it seems that retail applications work more
// accurately when this is signalled between thread switches.
if (HLE::g_reschedule) {
+ u64 current_ticks = Core::g_app_core->GetTicks();
+ u32 num_lines = static_cast<u32>((current_ticks - last_update_tick) / line_ticks);
// Synchronize line...
- if ((current_ticks - g_last_line_ticks) >= GPU::kFrameTicks / framebuffer_top.height) {
+ if (num_lines > 0) {
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC0);
- g_cur_line++;
- g_last_line_ticks = current_ticks;
+ cur_line += num_lines;
+ last_update_tick += (num_lines * line_ticks);
}
// Synchronize frame...
- if (g_cur_line >= framebuffer_top.height) {
- g_cur_line = 0;
+ if (cur_line >= framebuffer_top.height) {
+ cur_line = 0;
+ frame_count++;
+ last_skip_frame = g_skip_frame;
+ g_skip_frame = (frame_count & Settings::values.frame_skip) != 0;
+
+ // Swap buffers based on the frameskip mode, which is a little bit tricky. When
+ // a frame is being skipped, nothing is being rendered to the internal framebuffer(s).
+ // So, we should only swap frames if the last frame was rendered. The rules are:
+ // - If frameskip == 0 (disabled), always swap buffers
+ // - If frameskip == 1, swap buffers every other frame (starting from the first frame)
+ // - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame)
+
+ if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) ||
+ Settings::values.frame_skip == 0) {
+ VideoCore::g_renderer->SwapBuffers();
+ }
+
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1);
}
}
@@ -217,12 +223,6 @@ void Update() {
/// Initialize hardware
void Init() {
- kFrameCycles = 268123480 / Settings::values.gpu_refresh_rate;
- kFrameTicks = kFrameCycles / 3;
-
- g_cur_line = 0;
- g_last_frame_ticks = g_last_line_ticks = Core::g_app_core->GetTicks();
-
auto& framebuffer_top = g_regs.framebuffer_config[0];
auto& framebuffer_sub = g_regs.framebuffer_config[1];
@@ -251,6 +251,13 @@ void Init() {
framebuffer_sub.color_format = Regs::PixelFormat::RGB8;
framebuffer_sub.active_fb = 0;
+ frame_ticks = 268123480 / Settings::values.gpu_refresh_rate;
+ line_ticks = (GPU::frame_ticks / framebuffer_top.height);
+ cur_line = 0;
+ last_update_tick = Core::g_app_core->GetTicks();
+ last_skip_frame = false;
+ g_skip_frame = false;
+
LOG_DEBUG(HW_GPU, "initialized OK");
}
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index 68f11bfcb..292f496c1 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -241,6 +241,7 @@ ASSERT_REG_POSITION(command_processor_config, 0x00638);
static_assert(sizeof(Regs) == 0x1000 * sizeof(u32), "Invalid total size of register set");
extern Regs g_regs;
+extern bool g_skip_frame;
template <typename T>
void Read(T &var, const u32 addr);
diff --git a/src/core/settings.h b/src/core/settings.h
index 4808872ae..4b8928847 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -31,6 +31,7 @@ struct Values {
// Core
int cpu_core;
int gpu_refresh_rate;
+ int frame_skip;
// Data Storage
bool use_virtual_sd;