mirror of
https://github.com/Lime3DS/Lime3DS
synced 2024-11-01 12:47:52 +00:00
Make arm_dyncom_trans* into a fully fledged compilation unit
This commit is contained in:
parent
54b5178f6c
commit
ca20b1f87d
4 changed files with 73 additions and 53 deletions
|
@ -5,6 +5,7 @@ set(SRCS
|
||||||
arm/dyncom/arm_dyncom_dec.cpp
|
arm/dyncom/arm_dyncom_dec.cpp
|
||||||
arm/dyncom/arm_dyncom_interpreter.cpp
|
arm/dyncom/arm_dyncom_interpreter.cpp
|
||||||
arm/dyncom/arm_dyncom_thumb.cpp
|
arm/dyncom/arm_dyncom_thumb.cpp
|
||||||
|
arm/dyncom/arm_dyncom_trans.cpp
|
||||||
arm/skyeye_common/armstate.cpp
|
arm/skyeye_common/armstate.cpp
|
||||||
arm/skyeye_common/armsupp.cpp
|
arm/skyeye_common/armsupp.cpp
|
||||||
arm/skyeye_common/vfp/vfp.cpp
|
arm/skyeye_common/vfp/vfp.cpp
|
||||||
|
@ -140,6 +141,7 @@ set(HEADERS
|
||||||
arm/dyncom/arm_dyncom_interpreter.h
|
arm/dyncom/arm_dyncom_interpreter.h
|
||||||
arm/dyncom/arm_dyncom_run.h
|
arm/dyncom/arm_dyncom_run.h
|
||||||
arm/dyncom/arm_dyncom_thumb.h
|
arm/dyncom/arm_dyncom_thumb.h
|
||||||
|
arm/dyncom/arm_dyncom_trans.h
|
||||||
arm/skyeye_common/arm_regformat.h
|
arm/skyeye_common/arm_regformat.h
|
||||||
arm/skyeye_common/armstate.h
|
arm/skyeye_common/armstate.h
|
||||||
arm/skyeye_common/armsupp.h
|
arm/skyeye_common/armsupp.h
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
|
@ -18,6 +17,7 @@
|
||||||
#include "core/arm/dyncom/arm_dyncom_dec.h"
|
#include "core/arm/dyncom/arm_dyncom_dec.h"
|
||||||
#include "core/arm/dyncom/arm_dyncom_interpreter.h"
|
#include "core/arm/dyncom/arm_dyncom_interpreter.h"
|
||||||
#include "core/arm/dyncom/arm_dyncom_thumb.h"
|
#include "core/arm/dyncom/arm_dyncom_thumb.h"
|
||||||
|
#include "core/arm/dyncom/arm_dyncom_trans.h"
|
||||||
#include "core/arm/dyncom/arm_dyncom_run.h"
|
#include "core/arm/dyncom/arm_dyncom_run.h"
|
||||||
#include "core/arm/skyeye_common/armstate.h"
|
#include "core/arm/skyeye_common/armstate.h"
|
||||||
#include "core/arm/skyeye_common/armsupp.h"
|
#include "core/arm/skyeye_common/armsupp.h"
|
||||||
|
@ -25,18 +25,6 @@
|
||||||
|
|
||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
|
|
||||||
enum class TransExtData {
|
|
||||||
COND = (1 << 0),
|
|
||||||
NON_BRANCH = (1 << 1),
|
|
||||||
DIRECT_BRANCH = (1 << 2),
|
|
||||||
INDIRECT_BRANCH = (1 << 3),
|
|
||||||
CALL = (1 << 4),
|
|
||||||
RET = (1 << 5),
|
|
||||||
END_OF_PAGE = (1 << 6),
|
|
||||||
THUMB = (1 << 7),
|
|
||||||
SINGLE_STEP = (1 << 8)
|
|
||||||
};
|
|
||||||
|
|
||||||
#define RM BITS(sht_oper, 0, 3)
|
#define RM BITS(sht_oper, 0, 3)
|
||||||
#define RS BITS(sht_oper, 8, 11)
|
#define RS BITS(sht_oper, 8, 11)
|
||||||
|
|
||||||
|
@ -47,8 +35,6 @@ enum class TransExtData {
|
||||||
#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
|
#define ROTATE_RIGHT_32(n, i) ROTATE_RIGHT(n, i, 32)
|
||||||
#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
|
#define ROTATE_LEFT_32(n, i) ROTATE_LEFT(n, i, 32)
|
||||||
|
|
||||||
typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
|
|
||||||
|
|
||||||
static bool CondPassed(const ARMul_State* cpu, unsigned int cond) {
|
static bool CondPassed(const ARMul_State* cpu, unsigned int cond) {
|
||||||
const bool n_flag = cpu->NFlag != 0;
|
const bool n_flag = cpu->NFlag != 0;
|
||||||
const bool z_flag = cpu->ZFlag != 0;
|
const bool z_flag = cpu->ZFlag != 0;
|
||||||
|
@ -246,12 +232,6 @@ static unsigned int DPO(RotateRightByRegister)(ARMul_State* cpu, unsigned int sh
|
||||||
return shifter_operand;
|
return shifter_operand;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef void (*get_addr_fp_t)(ARMul_State *cpu, unsigned int inst, unsigned int &virt_addr);
|
|
||||||
|
|
||||||
struct ldst_inst {
|
|
||||||
unsigned int inst;
|
|
||||||
get_addr_fp_t get_addr;
|
|
||||||
};
|
|
||||||
#define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0)
|
#define DEBUG_MSG LOG_DEBUG(Core_ARM11, "inst is %x", inst); CITRA_IGNORE_EXIT(0)
|
||||||
|
|
||||||
#define LnSWoUB(s) glue(LnSWoUB, s)
|
#define LnSWoUB(s) glue(LnSWoUB, s)
|
||||||
|
@ -669,23 +649,7 @@ static void LnSWoUB(ScaledRegisterOffset)(ARMul_State* cpu, unsigned int inst, u
|
||||||
virt_addr = addr;
|
virt_addr = addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "arm_dyncom_trans_struct.inc"
|
shtop_fp_t GetShifterOp(unsigned int inst) {
|
||||||
|
|
||||||
typedef arm_inst * ARM_INST_PTR;
|
|
||||||
|
|
||||||
#define TRANS_CACHE_SIZE (64 * 1024 * 2000)
|
|
||||||
static char trans_cache_buf[TRANS_CACHE_SIZE];
|
|
||||||
static size_t trans_cache_buf_top = 0;
|
|
||||||
|
|
||||||
static void* AllocBuffer(size_t size) {
|
|
||||||
size_t start = trans_cache_buf_top;
|
|
||||||
trans_cache_buf_top += size;
|
|
||||||
ASSERT_MSG(trans_cache_buf_top <= TRANS_CACHE_SIZE, "Translation cache is full!");
|
|
||||||
return static_cast<void*>(&trans_cache_buf[start]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static shtop_fp_t GetShifterOp(unsigned int inst) {
|
|
||||||
if (BIT(inst, 25)) {
|
if (BIT(inst, 25)) {
|
||||||
return DPO(Immediate);
|
return DPO(Immediate);
|
||||||
} else if (BITS(inst, 4, 11) == 0) {
|
} else if (BITS(inst, 4, 11) == 0) {
|
||||||
|
@ -710,7 +674,7 @@ static shtop_fp_t GetShifterOp(unsigned int inst) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static get_addr_fp_t GetAddressingOp(unsigned int inst) {
|
get_addr_fp_t GetAddressingOp(unsigned int inst) {
|
||||||
if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
|
if (BITS(inst, 24, 27) == 5 && BIT(inst, 21) == 0) {
|
||||||
return LnSWoUB(ImmediateOffset);
|
return LnSWoUB(ImmediateOffset);
|
||||||
} else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
|
} else if (BITS(inst, 24, 27) == 7 && BIT(inst, 21) == 0 && BITS(inst, 4, 11) == 0) {
|
||||||
|
@ -768,10 +732,6 @@ get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
|
|
||||||
|
|
||||||
#include "arm_dyncom_trans.inc"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FETCH_SUCCESS,
|
FETCH_SUCCESS,
|
||||||
FETCH_FAILURE
|
FETCH_FAILURE
|
||||||
|
@ -782,7 +742,7 @@ static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_ins
|
||||||
ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
|
ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
|
||||||
if (ret == ThumbDecodeStatus::BRANCH) {
|
if (ret == ThumbDecodeStatus::BRANCH) {
|
||||||
int inst_index;
|
int inst_index;
|
||||||
int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
|
int table_length = arm_instruction_trans_len;
|
||||||
u32 tinstr = GetThumbInstruction(inst, addr);
|
u32 tinstr = GetThumbInstruction(inst, addr);
|
||||||
|
|
||||||
switch ((tinstr & 0xF800) >> 11) {
|
switch ((tinstr & 0xF800) >> 11) {
|
||||||
|
|
|
@ -1,5 +1,31 @@
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
#include "core/arm/dyncom/arm_dyncom_interpreter.h"
|
||||||
|
#include "core/arm/dyncom/arm_dyncom_trans.h"
|
||||||
|
#include "core/arm/skyeye_common/armstate.h"
|
||||||
|
#include "core/arm/skyeye_common/armsupp.h"
|
||||||
|
#include "core/arm/skyeye_common/vfp/vfp.h"
|
||||||
|
|
||||||
|
char trans_cache_buf[TRANS_CACHE_SIZE];
|
||||||
|
size_t trans_cache_buf_top = 0;
|
||||||
|
|
||||||
|
static void* AllocBuffer(size_t size) {
|
||||||
|
size_t start = trans_cache_buf_top;
|
||||||
|
trans_cache_buf_top += size;
|
||||||
|
ASSERT_MSG(trans_cache_buf_top <= TRANS_CACHE_SIZE, "Translation cache is full!");
|
||||||
|
return static_cast<void*>(&trans_cache_buf[start]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define glue(x, y) x ## y
|
||||||
#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
|
#define INTERPRETER_TRANSLATE(s) glue(InterpreterTranslate_, s)
|
||||||
|
|
||||||
|
shtop_fp_t GetShifterOp(unsigned int inst);
|
||||||
|
get_addr_fp_t GetAddressingOp(unsigned int inst);
|
||||||
|
get_addr_fp_t GetAddressingOpLoadStoreT(unsigned int inst);
|
||||||
|
|
||||||
static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
|
static ARM_INST_PTR INTERPRETER_TRANSLATE(adc)(unsigned int inst, int index)
|
||||||
{
|
{
|
||||||
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
|
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(adc_inst));
|
||||||
|
@ -1937,7 +1963,6 @@ static ARM_INST_PTR INTERPRETER_TRANSLATE(yield)(unsigned int inst, int index)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Floating point VFPv3 instructions
|
// Floating point VFPv3 instructions
|
||||||
|
|
||||||
#define VFP_INTERPRETER_TRANS
|
#define VFP_INTERPRETER_TRANS
|
||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||||
#undef VFP_INTERPRETER_TRANS
|
#undef VFP_INTERPRETER_TRANS
|
||||||
|
@ -2149,3 +2174,5 @@ const transop_fp_t arm_instruction_trans[] = {
|
||||||
INTERPRETER_TRANSLATE(bl_2_thumb),
|
INTERPRETER_TRANSLATE(bl_2_thumb),
|
||||||
INTERPRETER_TRANSLATE(blx_1_thumb)
|
INTERPRETER_TRANSLATE(blx_1_thumb)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const size_t arm_instruction_trans_len = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
|
|
@ -1,3 +1,18 @@
|
||||||
|
struct ARMul_State;
|
||||||
|
typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
|
||||||
|
|
||||||
|
enum class TransExtData {
|
||||||
|
COND = (1 << 0),
|
||||||
|
NON_BRANCH = (1 << 1),
|
||||||
|
DIRECT_BRANCH = (1 << 2),
|
||||||
|
INDIRECT_BRANCH = (1 << 3),
|
||||||
|
CALL = (1 << 4),
|
||||||
|
RET = (1 << 5),
|
||||||
|
END_OF_PAGE = (1 << 6),
|
||||||
|
THUMB = (1 << 7),
|
||||||
|
SINGLE_STEP = (1 << 8)
|
||||||
|
};
|
||||||
|
|
||||||
struct arm_inst {
|
struct arm_inst {
|
||||||
unsigned int idx;
|
unsigned int idx;
|
||||||
unsigned int cond;
|
unsigned int cond;
|
||||||
|
@ -456,7 +471,23 @@ struct pkh_inst {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Floating point VFPv3 structures
|
// Floating point VFPv3 structures
|
||||||
|
|
||||||
#define VFP_INTERPRETER_STRUCT
|
#define VFP_INTERPRETER_STRUCT
|
||||||
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
#include "core/arm/skyeye_common/vfp/vfpinstr.cpp"
|
||||||
#undef VFP_INTERPRETER_STRUCT
|
#undef VFP_INTERPRETER_STRUCT
|
||||||
|
|
||||||
|
typedef void (*get_addr_fp_t)(ARMul_State *cpu, unsigned int inst, unsigned int &virt_addr);
|
||||||
|
|
||||||
|
struct ldst_inst {
|
||||||
|
unsigned int inst;
|
||||||
|
get_addr_fp_t get_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef arm_inst* ARM_INST_PTR;
|
||||||
|
typedef ARM_INST_PTR (*transop_fp_t)(unsigned int, int);
|
||||||
|
|
||||||
|
extern const transop_fp_t arm_instruction_trans[];
|
||||||
|
extern const size_t arm_instruction_trans_len;
|
||||||
|
|
||||||
|
#define TRANS_CACHE_SIZE (64 * 1024 * 2000)
|
||||||
|
extern char trans_cache_buf[TRANS_CACHE_SIZE];
|
||||||
|
extern size_t trans_cache_buf_top;
|
Loading…
Reference in a new issue