aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt10
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp11
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h216
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp1197
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.h12
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h8
-rw-r--r--src/core/arm/interpreter/armemu.cpp92
-rw-r--r--src/core/arm/interpreter/armsupp.cpp28
-rw-r--r--src/core/arm/skyeye_common/armdefs.h7
-rw-r--r--src/core/arm/skyeye_common/armemu.h7
-rw-r--r--src/core/arm/skyeye_common/skyeye_types.h30
-rw-r--r--src/core/arm/skyeye_common/vfp/vfpinstr.cpp5063
-rw-r--r--src/core/core.cpp4
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/file_sys/archive_backend.h3
-rw-r--r--src/core/file_sys/archive_romfs.cpp47
-rw-r--r--src/core/file_sys/archive_romfs.h76
-rw-r--r--src/core/file_sys/archive_savedatacheck.cpp41
-rw-r--r--src/core/file_sys/archive_savedatacheck.h31
-rw-r--r--src/core/file_sys/directory_romfs.cpp32
-rw-r--r--src/core/file_sys/directory_romfs.h43
-rw-r--r--src/core/file_sys/disk_archive.cpp11
-rw-r--r--src/core/file_sys/disk_archive.h6
-rw-r--r--src/core/file_sys/file_romfs.cpp43
-rw-r--r--src/core/file_sys/file_romfs.h73
-rw-r--r--src/core/file_sys/ivfc_archive.cpp88
-rw-r--r--src/core/file_sys/ivfc_archive.h66
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp11
-rw-r--r--src/core/hle/kernel/mutex.cpp4
-rw-r--r--src/core/hle/service/dsp_dsp.cpp22
-rw-r--r--src/core/hle/service/dsp_dsp.h3
-rw-r--r--src/core/hle/service/fs/archive.cpp44
-rw-r--r--src/core/hle/service/fs/archive.h3
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/soc_u.cpp2
-rw-r--r--src/core/hle/service/y2r_u.cpp45
-rw-r--r--src/core/hle/service/y2r_u.h23
-rw-r--r--src/core/hw/gpu.cpp14
-rw-r--r--src/core/hw/gpu.h3
-rw-r--r--src/core/loader/elf.cpp2
-rw-r--r--src/core/loader/loader.cpp2
41 files changed, 3948 insertions, 3479 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 89ea70d2..b67226d8 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -20,11 +20,11 @@ set(SRCS
file_sys/archive_extsavedata.cpp
file_sys/archive_romfs.cpp
file_sys/archive_savedata.cpp
+ file_sys/archive_savedatacheck.cpp
file_sys/archive_sdmc.cpp
file_sys/archive_systemsavedata.cpp
file_sys/disk_archive.cpp
- file_sys/file_romfs.cpp
- file_sys/directory_romfs.cpp
+ file_sys/ivfc_archive.cpp
hle/kernel/address_arbiter.cpp
hle/kernel/event.cpp
hle/kernel/kernel.cpp
@@ -66,6 +66,7 @@ set(SRCS
hle/service/soc_u.cpp
hle/service/srv.cpp
hle/service/ssl_c.cpp
+ hle/service/y2r_u.cpp
hle/config_mem.cpp
hle/hle.cpp
hle/svc.cpp
@@ -108,13 +109,13 @@ set(HEADERS
file_sys/archive_extsavedata.h
file_sys/archive_romfs.h
file_sys/archive_savedata.h
+ file_sys/archive_savedatacheck.h
file_sys/archive_sdmc.h
file_sys/archive_systemsavedata.h
file_sys/disk_archive.h
file_sys/file_backend.h
- file_sys/file_romfs.h
+ file_sys/ivfc_archive.h
file_sys/directory_backend.h
- file_sys/directory_romfs.h
hle/kernel/address_arbiter.h
hle/kernel/event.h
hle/kernel/kernel.h
@@ -157,6 +158,7 @@ set(HEADERS
hle/service/soc_u.h
hle/service/srv.h
hle/service/ssl_c.h
+ hle/service/y2r_u.h
hle/config_mem.h
hle/result.h
hle/function_wrappers.h
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 333b40f5..0927eece 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -136,7 +136,6 @@ const ISEITEM arm_instruction[] = {
{ "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 },
{ "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 },
{ "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 },
- // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009},
{ "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 },
{ "mcrr", 1, 6, 20, 27, 0x000000c4 },
{ "mrrc", 1, 6, 20, 27, 0x000000c5 },
@@ -194,6 +193,10 @@ const ISEITEM arm_instruction[] = {
{ "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 },
{ "swi", 1, 0, 24, 27, 0x0000000f },
{ "bbl", 1, 0, 25, 27, 0x00000005 },
+ { "ldrexd", 2, ARMV6K, 20, 27, 0x0000001B, 4, 7, 0x00000009 },
+ { "strexd", 2, ARMV6K, 20, 27, 0x0000001A, 4, 7, 0x00000009 },
+ { "ldrexh", 2, ARMV6K, 20, 27, 0x0000001F, 4, 7, 0x00000009 },
+ { "strexh", 2, ARMV6K, 20, 27, 0x0000001E, 4, 7, 0x00000009 },
};
const ISEITEM arm_exclusion_code[] = {
@@ -383,6 +386,11 @@ const ISEITEM arm_exclusion_code[] = {
{ "ldc", 0, 0, 0 },
{ "swi", 0, 0, 0 },
{ "bbl", 0, 0, 0 },
+ { "ldrexd", 0, ARMV6K, 0 },
+ { "strexd", 0, ARMV6K, 0 },
+ { "ldrexh", 0, ARMV6K, 0 },
+ { "strexh", 0, ARMV6K, 0 },
+
{ "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4]
{ "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3]
{ "blx_1_thumb", 0, INVALID, 0 }, // Should be located at table[-2]
@@ -395,6 +403,7 @@ int decode_arm_instr(uint32_t instr, int32_t *idx) {
int ret = DECODE_FAILURE;
int i = 0;
int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM);
+
for (i = 0; i < instr_slots; i++) {
n = arm_instruction[i].attribute_value;
base = 0;
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
index 70eb96e9..58784aee 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.h
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -1,153 +1,117 @@
-/* Copyright (C)
-* 2012 - Michael.Kang blackfin.kang@gmail.com
-* This program is free software; you can redistribute it and/or
-* modify it under the terms of the GNU General Public License
-* as published by the Free Software Foundation; either version 2
-* of the License, or (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*
-*/
-
-/**
-* @file arm_dyncom_dec.h
-* @brief Some common utility for arm instruction decoder
-* @author Michael.Kang blackfin.kang@gmail.com
-* @version 7849
-* @date 2012-03-15
-*/
-
-#ifndef __ARM_DYNCOM_DEC__
-#define __ARM_DYNCOM_DEC__
-
-#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
-#define BIT(n) ((instr >> (n)) & 1)
-#define BAD do{printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); /*exit(0);*/}while(0);
-#define ptr_N cpu->ptr_N
-#define ptr_Z cpu->ptr_Z
-#define ptr_C cpu->ptr_C
-#define ptr_V cpu->ptr_V
-#define ptr_I cpu->ptr_I
-#define ptr_T cpu->ptr_T
-#define ptr_CPSR cpu->ptr_gpr[16]
-
-/* for MUL instructions */
-/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
-#define RDHi ((instr >> 16) & 0xF)
-/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
-#define RDLo ((instr >> 12) & 0xF)
-/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
-#define MUL_RD ((instr >> 16) & 0xF)
-/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
-#define MUL_RN ((instr >> 12) & 0xF)
-/*xxxx xxxx xxxx xxxx xxxx 1111 xxxx xxxx */
-#define RS ((instr >> 8) & 0xF)
-
-/*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */
-#define RD ((instr >> 12) & 0xF)
-/*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */
-#define RN ((instr >> 16) & 0xF)
-/*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */
-#define RM (instr & 0xF)
-
-/* CP15 registers */
-#define OPCODE_1 BITS(21, 23)
-#define CRn BITS(16, 19)
-#define CRm BITS(0, 3)
-#define OPCODE_2 BITS(5, 7)
-
-/*xxxx xx1x xxxx xxxx xxxx xxxx xxxx xxxx */
-#define I BIT(25)
-/*xxxx xxxx xxx1 xxxx xxxx xxxx xxxx xxxx */
-#define S BIT(20)
-
-#define SHIFT BITS(5,6)
-#define SHIFT_IMM BITS(7,11)
-#define IMMH BITS(8,11)
-#define IMML BITS(0,3)
-
-#define LSPBIT BIT(24)
-#define LSUBIT BIT(23)
-#define LSBBIT BIT(22)
-#define LSWBIT BIT(21)
-#define LSLBIT BIT(20)
-#define LSSHBITS BITS(5,6)
-#define OFFSET12 BITS(0,11)
-#define SBIT BIT(20)
-#define DESTReg (BITS (12, 15))
-
-/* they are in unused state, give a corrent value when using */
+// Copyright 2012 Michael Kang, 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1))
+#define BIT(n) ((instr >> (n)) & 1)
+#define BAD do { printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); } while(0);
+#define ptr_N cpu->ptr_N
+#define ptr_Z cpu->ptr_Z
+#define ptr_C cpu->ptr_C
+#define ptr_V cpu->ptr_V
+#define ptr_I cpu->ptr_I
+#define ptr_T cpu->ptr_T
+#define ptr_CPSR cpu->ptr_gpr[16]
+
+// For MUL instructions
+#define RDHi ((instr >> 16) & 0xF)
+#define RDLo ((instr >> 12) & 0xF)
+#define MUL_RD ((instr >> 16) & 0xF)
+#define MUL_RN ((instr >> 12) & 0xF)
+#define RS ((instr >> 8) & 0xF)
+#define RD ((instr >> 12) & 0xF)
+#define RN ((instr >> 16) & 0xF)
+#define RM (instr & 0xF)
+
+// CP15 registers
+#define OPCODE_1 BITS(21, 23)
+#define CRn BITS(16, 19)
+#define CRm BITS(0, 3)
+#define OPCODE_2 BITS(5, 7)
+
+#define I BIT(25)
+#define S BIT(20)
+
+#define SHIFT BITS(5,6)
+#define SHIFT_IMM BITS(7,11)
+#define IMMH BITS(8,11)
+#define IMML BITS(0,3)
+
+#define LSPBIT BIT(24)
+#define LSUBIT BIT(23)
+#define LSBBIT BIT(22)
+#define LSWBIT BIT(21)
+#define LSLBIT BIT(20)
+#define LSSHBITS BITS(5,6)
+#define OFFSET12 BITS(0,11)
+#define SBIT BIT(20)
+#define DESTReg (BITS (12, 15))
+
+// They are in unused state, give a corrent value when using
#define IS_V5E 0
#define IS_V5 0
#define IS_V6 0
#define LHSReg 0
-/* temp define the using the pc reg need implement a flow */
-#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2))
+// Temp define the using the pc reg need implement a flow
+#define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2))
-#define OPERAND operand(cpu,instr,bb,NULL)
-#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco)
-#define BOPERAND boperand(instr)
+#define OPERAND operand(cpu,instr,bb,NULL)
+#define SCO_OPERAND(sco) operand(cpu,instr,bb,sco)
+#define BOPERAND boperand(instr)
-#define CHECK_RN_PC (RN==15? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)):R(RN))
-#define CHECK_RN_PC_WA (RN==15? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)):R(RN))
+#define CHECK_RN_PC (RN == 15 ? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)) : R(RN))
+#define CHECK_RN_PC_WA (RN == 15 ? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)) : R(RN))
-#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE))))
+#define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE))))
int decode_arm_instr(uint32_t instr, int32_t *idx);
enum DECODE_STATUS {
- DECODE_SUCCESS,
- DECODE_FAILURE
+ DECODE_SUCCESS,
+ DECODE_FAILURE
};
struct instruction_set_encoding_item {
- const char *name;
- int attribute_value;
- int version;
- u32 content[21];
+ const char *name;
+ int attribute_value;
+ int version;
+ u32 content[21];
};
typedef struct instruction_set_encoding_item ISEITEM;
-#define RECORD_WB(value, flag) {cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag;}
+#define RECORD_WB(value, flag) { cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag; }
#define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag)
-#define EXECUTE_WB(base_reg) {if(cpu->dyncom_engine->wb_flag) \
- LET(base_reg, cpu->dyncom_engine->wb_value);}
-inline int get_reg_count(uint32_t instr){
- int i = BITS(0,15);
- int count = 0;
- while(i){
- if(i & 1)
- count ++;
- i = i >> 1;
- }
- return count;
+#define EXECUTE_WB(base_reg) { if(cpu->dyncom_engine->wb_flag) LET(base_reg, cpu->dyncom_engine->wb_value); }
+
+inline int get_reg_count(uint32_t instr) {
+ int i = BITS(0, 15);
+ int count = 0;
+ while (i) {
+ if (i & 1)
+ count++;
+ i = i >> 1;
+ }
+ return count;
}
enum ARMVER {
- INVALID = 0,
- ARMALL,
- ARMV4,
- ARMV4T,
- ARMV5T,
- ARMV5TE,
- ARMV5TEJ,
- ARMV6,
- ARM1176JZF_S,
- ARMVFP2,
- ARMVFP3
+ INVALID = 0,
+ ARMALL,
+ ARMV4,
+ ARMV4T,
+ ARMV5T,
+ ARMV5TE,
+ ARMV5TEJ,
+ ARMV6,
+ ARM1176JZF_S,
+ ARMVFP2,
+ ARMVFP3,
+ ARMV6K,
};
-//extern const INSTRACT arm_instruction_action[];
extern const ISEITEM arm_instruction[];
-
-#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index c61ae005..593e0eab 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -622,9 +622,7 @@ void LdnStM(DecrementAfter)(arm_processor *cpu, unsigned int inst, unsigned int
}
unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn);
unsigned int start_addr = rn - count * 4 + 4;
- unsigned int end_addr = rn;
- virt_addr = end_addr;
virt_addr = start_addr;
if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) {
@@ -873,6 +871,8 @@ typedef struct _mvn_inst {
typedef struct _rev_inst {
unsigned int Rd;
unsigned int Rm;
+ unsigned int op1;
+ unsigned int op2;
} rev_inst;
typedef struct _rsb_inst {
@@ -930,6 +930,8 @@ typedef struct _smlad_inst {
unsigned int Rd;
unsigned int Ra;
unsigned int Rn;
+ unsigned int op1;
+ unsigned int op2;
} smlad_inst;
typedef struct _smla_inst {
@@ -972,6 +974,16 @@ typedef struct _smlal_inst {
unsigned int RdLo;
} smlal_inst;
+typedef struct smlald_inst {
+ unsigned int RdLo;
+ unsigned int RdHi;
+ unsigned int Rm;
+ unsigned int Rn;
+ unsigned int swap;
+ unsigned int op1;
+ unsigned int op2;
+} smlald_inst;
+
typedef struct _mla_inst {
unsigned int S;
unsigned int Rn;
@@ -1067,7 +1079,7 @@ typedef struct _cdp_inst {
unsigned int cp_num;
unsigned int opcode_2;
unsigned int CRm;
- uint32 inst;
+ unsigned int inst;
}cdp_inst;
typedef struct _uxtb_inst {
@@ -1102,10 +1114,10 @@ typedef struct _blx_1_thumb {
}blx_1_thumb;
typedef struct _pkh_inst {
- u32 Rm;
- u32 Rn;
- u32 Rd;
- u8 imm;
+ unsigned int Rm;
+ unsigned int Rn;
+ unsigned int Rd;
+ unsigned char imm;
} pkh_inst;
typedef arm_inst * ARM_INST_PTR;
@@ -1407,15 +1419,19 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
bx_inst *inst_cream = (bx_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = INDIRECT_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rm = BITS(inst, 0, 3);
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); }
+ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(bx)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
@@ -1738,40 +1754,31 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index)
return inst_base;
}
-
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->idx = index;
+ inst_base->br = (BITS(inst, 12, 15) == 15) ? INDIRECT_BRANCH : NON_BRANCH; // Branch if dest is R15
- inst_cream->inst = inst;
- //inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ return INTERPRETER_TRANSLATE(ldrex)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(ldrex)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(ldrex)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index)
{
@@ -2050,7 +2057,37 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); }
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->op1 = BITS(inst, 21, 22);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
{
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
@@ -2077,9 +2114,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
{
return INTERPRETER_TRANSLATE(qadd8)(inst, index);
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
{
return INTERPRETER_TRANSLATE(qadd8)(inst, index);
@@ -2092,36 +2126,33 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qsubaddx)(unsigned int inst, int index)
{
return INTERPRETER_TRANSLATE(qadd8)(inst, index);
}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(rev)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
- rev_inst *inst_cream = (rev_inst *)inst_base->component;
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
+ rev_inst* const inst_cream = (rev_inst*)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_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->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(rev_inst));
- rev_inst *inst_cream = (rev_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->Rd = BITS(inst, 12, 15);
-
- return inst_base;
+ARM_INST_PTR INTERPRETER_TRANSLATE(rev16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(rev)(inst, index);
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("REVSH"); }
+ARM_INST_PTR INTERPRETER_TRANSLATE(revsh)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(rev)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(rfe)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("RFE"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(rsb)(unsigned int inst, int index)
{
@@ -2171,29 +2202,45 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(rsc)(unsigned int inst, int index)
}
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SADD8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(sadd16)(unsigned int inst, int index)
+ARM_INST_PTR INTERPRETER_TRANSLATE(sadd8)(unsigned int inst, int index)
{
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
-
+
inst_base->cond = BITS(inst, 28, 31);
inst_base->idx = index;
inst_base->br = NON_BRANCH;
inst_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(sadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
ARM_INST_PTR INTERPRETER_TRANSLATE(saddsubx)(unsigned int inst, int index)
{
- return INTERPRETER_TRANSLATE(sadd16)(inst, index);
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sadd8)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(sbc)(unsigned int inst, int index)
{
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sbc_inst));
@@ -2236,13 +2283,48 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sel)(unsigned int inst, int index)
return inst_base;
}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(setend)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SETEND"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(shadd16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD16"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADD8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHADDSUBX"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB16"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUB8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SHSUBADDX"); }
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(shadd8)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_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(shadd16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shaddsubx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shsub8)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shsub16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(shsubaddx)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(shadd8)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
{
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smla_inst));
@@ -2262,25 +2344,40 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smla)(unsigned int inst, int index)
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index){
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
- smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlad)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
inst_base->load_r15 = 0;
- inst_cream->m = BIT(inst, 4);
- inst_cream->Rn = BITS(inst, 0, 3);
- inst_cream->Rm = BITS(inst, 8, 11);
- inst_cream->Rd = BITS(inst, 16, 19);
- inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->m = BIT(inst, 5);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
- if (CHECK_RM )
- inst_base->load_r15 = 1;
return inst_base;
}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smlad)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smlad)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smlad)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
{
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(umlal_inst));
@@ -2301,15 +2398,82 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
inst_base->load_r15 = 1;
return inst_base;
}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALD"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLAW"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smlsd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSD"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLSLD"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLA"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMLS"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMMUL"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smuad)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUAD"); }
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->m = BIT(inst, 6);
+
+ return inst_base;
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlald_inst));
+ smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->RdLo = BITS(inst, 12, 15);
+ inst_cream->RdHi = BITS(inst, 16, 19);
+ inst_cream->swap = BIT(inst, 5);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlsld)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smlald)(inst, index);
+}
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(smmla)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->m = BIT(inst, 5);
+ inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->op1 = BITS(inst, 20, 22);
+ inst_cream->op2 = BITS(inst, 5, 7);
+
+ return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smmls)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smmla)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(smmul)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(smmla)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(smul)(unsigned int inst, int index)
{
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(smul_inst));
@@ -2372,7 +2536,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smulw)(unsigned int inst, int index)
inst_base->load_r15 = 1;
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(smusd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMUSD"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(srs)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SRS"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(ssat)(unsigned int inst, int index)
{
@@ -2408,15 +2571,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ssat16)(unsigned int inst, int index)
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(ssub8)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SSUB8"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(ssub16)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(sadd16)(inst, index);
-}
-ARM_INST_PTR INTERPRETER_TRANSLATE(ssubaddx)(unsigned int inst, int index)
-{
- return INTERPRETER_TRANSLATE(sadd16)(inst, index);
-}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(stc)(unsigned int inst, int index)
{
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(stc_inst));
@@ -2566,37 +2721,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component;
inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 0, 3);
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
return inst_base;
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index)
{
- arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst));
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
-
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
-
- inst_cream->inst = inst;
- inst_cream->get_addr = get_calc_addr_op(inst);
-
- if (BITS(inst, 12, 15) == 15) {
- inst_base->br = INDIRECT_BRANCH;
- }
- return inst_base;
+ return INTERPRETER_TRANSLATE(strex)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(strex)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(strex)(inst, index);
}
ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index)
{
@@ -2723,7 +2871,29 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab)(unsigned int inst, int index){
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTAB16"); }
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(sxtab16)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(sxtab_inst));
+ sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_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(sxtb16)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(sxtab16)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
LOG_WARNING(Core_ARM11, "SXTAH untested");
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(sxtah_inst));
@@ -2741,7 +2911,7 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(sxtah)(unsigned int inst, int index){
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(sxtb16)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SXTB16"); }
+
ARM_INST_PTR INTERPRETER_TRANSLATE(teq)(unsigned int inst, int index)
{
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(teq_inst));
@@ -3276,6 +3446,11 @@ const transop_fp_t arm_instruction_trans[] = {
INTERPRETER_TRANSLATE(ldc),
INTERPRETER_TRANSLATE(swi),
INTERPRETER_TRANSLATE(bbl),
+ INTERPRETER_TRANSLATE(ldrexd),
+ INTERPRETER_TRANSLATE(strexd),
+ INTERPRETER_TRANSLATE(ldrexh),
+ INTERPRETER_TRANSLATE(strexh),
+
// All the thumb instructions should be placed the end of table
INTERPRETER_TRANSLATE(b_2_thumb),
INTERPRETER_TRANSLATE(b_cond_thumb),
@@ -3314,7 +3489,7 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr
tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size);
if(ret == t_branch){
// TODO: FIXME, endian should be judged
- uint32 tinstr;
+ u32 tinstr;
if((addr & 0x3) != 0)
tinstr = inst >> 16;
else
@@ -3327,7 +3502,7 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr
case 26:
case 27:
if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
- uint32 cond = (tinstr & 0x0F00) >> 8;
+ u32 cond = (tinstr & 0x0F00) >> 8;
inst_index = table_length - 4;
*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
} else {
@@ -3364,8 +3539,6 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr
return ret;
}
-unsigned int *InstLength;
-
enum {
KEEP_GOING,
FETCH_EXCEPTION
@@ -3450,28 +3623,6 @@ translated:
#define LOG_IN_CLR skyeye_printf_in_color
-int cmp(const void *x, const void *y) {
- return *(unsigned long long int*)x - *(unsigned long long int *)y;
-}
-
-void InterpreterInitInstLength(unsigned long long int *ptr, size_t size) {
- int array_size = size / sizeof(void *);
- unsigned long long int *InstLabel = new unsigned long long int[array_size];
- memcpy(InstLabel, ptr, size);
- qsort(InstLabel, array_size, sizeof(void *), cmp);
- InstLength = new unsigned int[array_size - 4];
- for (int i = 0; i < array_size - 4; i++) {
- for (int j = 0; j < array_size; j++) {
- if (ptr[i] == InstLabel[j]) {
- InstLength[i] = InstLabel[j + 1] - InstLabel[j];
- break;
- }
- }
- }
- for (int i = 0; i < array_size - 4; i++)
- LOG_DEBUG(Core_ARM11, "[%d]:%d", i, InstLength[i]);
-}
-
int clz(unsigned int x) {
int n;
if (x == 0) return (32);
@@ -3496,6 +3647,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
#define CRm inst_cream->crm
#define CP15_REG(n) cpu->CP15[CP15(n)]
#define RD cpu->Reg[inst_cream->Rd]
+ #define RD2 cpu->Reg[inst_cream->Rd + 1]
#define RN cpu->Reg[inst_cream->Rn]
#define RM cpu->Reg[inst_cream->Rm]
#define RS cpu->Reg[inst_cream->Rs]
@@ -3707,14 +3859,18 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
case 182: goto LDC_INST; \
case 183: goto SWI_INST; \
case 184: goto BBL_INST; \
- case 185: goto B_2_THUMB ; \
- case 186: goto B_COND_THUMB ; \
- case 187: goto BL_1_THUMB ; \
- case 188: goto BL_2_THUMB ; \
- case 189: goto BLX_1_THUMB ; \
- case 190: goto DISPATCH; \
- case 191: goto INIT_INST_LENGTH; \
- case 192: goto END; \
+ case 185: goto LDREXD_INST; \
+ case 186: goto STREXD_INST; \
+ case 187: goto LDREXH_INST; \
+ case 188: goto STREXH_INST; \
+ case 189: goto B_2_THUMB ; \
+ case 190: goto B_COND_THUMB ; \
+ case 191: goto BL_1_THUMB ; \
+ case 192: goto BL_2_THUMB ; \
+ case 193: goto BLX_1_THUMB ; \
+ case 194: goto DISPATCH; \
+ case 195: goto INIT_INST_LENGTH; \
+ case 196: goto END; \
}
#endif
@@ -3775,8 +3931,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
&&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST,
&&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST,
&&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST,
- &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&B_2_THUMB, &&B_COND_THUMB,
- &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END
+ &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&LDREXD_INST,
+ &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST,&&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,
+ &&INIT_INST_LENGTH,&&END
};
#endif
arm_inst * inst_base;
@@ -3976,22 +4133,35 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
INC_PC(sizeof(blx_inst));
goto DISPATCH;
}
+
BX_INST:
+ BXJ_INST:
{
- bx_inst *inst_cream = (bx_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ // Note that only the 'fail' case of BXJ is emulated. This is because
+ // the facilities for Jazelle emulation are not implemented.
+ //
+ // According to the ARM documentation on BXJ, if setting the J bit in the APSR
+ // fails, then BXJ functions identically like a regular BX instruction.
+ //
+ // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
+
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ bx_inst* const inst_cream = (bx_inst*)inst_base->component;
+
if (inst_cream->Rm == 15)
LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]);
+
cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
INC_PC(sizeof(bx_inst));
goto DISPATCH;
}
+
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(bx_inst));
goto DISPATCH;
}
- BXJ_INST:
+
CDP_INST:
{
cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
@@ -4377,45 +4547,84 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
LDREX_INST:
{
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+ unsigned int read_addr = RN;
- unsigned int value = Memory::Read32(addr);
-
- add_exclusive_addr(cpu, addr);
+ add_exclusive_addr(cpu, read_addr);
cpu->exclusive_state = 1;
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
+ RD = Memory::Read32(read_addr);
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(generic_arm_inst));
goto DISPATCH;
}
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
+ INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
LDREXB_INST:
{
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
+ unsigned int read_addr = RN;
- unsigned int value = Memory::Read8(addr);
+ add_exclusive_addr(cpu, read_addr);
+ cpu->exclusive_state = 1;
+
+ RD = Memory::Read8(read_addr);
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(generic_arm_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDREXH_INST:
+ {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int read_addr = RN;
- add_exclusive_addr(cpu, addr);
+ add_exclusive_addr(cpu, read_addr);
cpu->exclusive_state = 1;
- cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value;
- if (BITS(inst_cream->inst, 12, 15) == 15) {
- INC_PC(sizeof(ldst_inst));
+ RD = Memory::Read16(read_addr);
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(generic_arm_inst));
goto DISPATCH;
}
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ LDREXD_INST:
+ {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int read_addr = RN;
+
+ add_exclusive_addr(cpu, read_addr);
+ cpu->exclusive_state = 1;
+ // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive?
+
+ RD = Memory::Read32(read_addr);
+ RD2 = Memory::Read32(read_addr + 4);
+
+ if (inst_cream->Rd == 15) {
+ INC_PC(sizeof(generic_arm_inst));
+ goto DISPATCH;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
@@ -4877,6 +5086,78 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
}
QADD_INST:
+ QDADD_INST:
+ QDSUB_INST:
+ QSUB_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ const u8 op1 = inst_cream->op1;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ u32 result = 0;
+
+ // QADD
+ if (op1 == 0x00) {
+ result = rm_val + rn_val;
+
+ if (AddOverflow(rm_val, rn_val, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+ // QSUB
+ else if (op1 == 0x01) {
+ result = rm_val - rn_val;
+
+ if (SubOverflow(rm_val, rn_val, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+ // QDADD
+ else if (op1 == 0x02) {
+ u32 mul = (rn_val * 2);
+
+ if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
+ mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+
+ result = mul + rm_val;
+
+ if (AddOverflow(rm_val, mul, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+ // QDSUB
+ else if (op1 == 0x03) {
+ u32 mul = (rn_val * 2);
+
+ if (AddOverflow(rn_val, rn_val, mul)) {
+ mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+
+ result = rm_val - mul;
+
+ if (SubOverflow(rm_val, mul, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+
+ RD = result;
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
QADD8_INST:
QADD16_INST:
QADDSUBX_INST:
@@ -4939,42 +5220,39 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
GOTO_NEXT_INST;
}
- QDADD_INST:
- QDSUB_INST:
- QSUB_INST:
REV_INST:
- {
- rev_inst *inst_cream = (rev_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- RD = ((RM & 0xff) << 24) |
- (((RM >> 8) & 0xff) << 16) |
- (((RM >> 16) & 0xff) << 8) |
- ((RM >> 24) & 0xff);
- if (inst_cream->Rm == 15) {
- LOG_ERROR(Core_ARM11, "invalid operand for REV");
- CITRA_IGNORE_EXIT(-1);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(rev_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
- }
REV16_INST:
+ REVSH_INST:
{
- rev_inst *inst_cream = (rev_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- RD = (BITS(RM, 0, 7) << 8) |
- BITS(RM, 8, 15) |
- (BITS(RM, 16, 23) << 24) |
- (BITS(RM, 24, 31) << 16);
+
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ rev_inst* const inst_cream = (rev_inst*)inst_base->component;
+
+ const u8 op1 = inst_cream->op1;
+ const u8 op2 = inst_cream->op2;
+
+ // REV
+ if (op1 == 0x03 && op2 == 0x01) {
+ RD = ((RM & 0xFF) << 24) | (((RM >> 8) & 0xFF) << 16) | (((RM >> 16) & 0xFF) << 8) | ((RM >> 24) & 0xFF);
+ }
+ // REV16
+ else if (op1 == 0x03 && op2 == 0x05) {
+ RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8) | ((RM & 0xFF0000) << 8) | ((RM & 0xFF000000) >> 8);
+ }
+ // REVSH
+ else if (op1 == 0x07 && op2 == 0x05) {
+ RD = ((RM & 0xFF) << 8) | ((RM & 0xFF00) >> 8);
+ if (RD & 0x8000)
+ RD |= 0xffff0000;
+ }
}
+
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(rev_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
- REVSH_INST:
+
RFE_INST:
RSB_INST:
{
@@ -5039,6 +5317,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
}
SADD8_INST:
+ SSUB8_INST:
SADD16_INST:
SADDSUBX_INST:
SSUBADDX_INST:
@@ -5046,52 +5325,96 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
{
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 s16 rn_lo = (RN & 0xFFFF);
- const s16 rn_hi = ((RN >> 16) & 0xFFFF);
- const s16 rm_lo = (RM & 0xFFFF);
- const s16 rm_hi = ((RM >> 16) & 0xFFFF);
+ if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
+ const s16 rn_lo = (RN & 0xFFFF);
+ const s16 rn_hi = ((RN >> 16) & 0xFFFF);
+ const s16 rm_lo = (RM & 0xFFFF);
+ const s16 rm_hi = ((RM >> 16) & 0xFFFF);
- s32 lo_result = 0;
- s32 hi_result = 0;
+ s32 lo_result = 0;
+ s32 hi_result = 0;
- // SADD16
- if (inst_cream->op2 == 0x00) {
- lo_result = (rn_lo + rm_lo);
- hi_result = (rn_hi + rm_hi);
- }
- // SASX
- else if (inst_cream->op2 == 0x01) {
- lo_result = (rn_lo - rm_hi);
- hi_result = (rn_hi + rm_lo);
- }
- // SSAX
- else if (inst_cream->op2 == 0x02) {
- lo_result = (rn_lo + rm_hi);
- hi_result = (rn_hi - rm_lo);
- }
- // SSUB16
- else if (inst_cream->op2 == 0x03) {
- lo_result = (rn_lo - rm_lo);
- hi_result = (rn_hi - rm_hi);
- }
+ // SADD16
+ if (inst_cream->op2 == 0x00) {
+ lo_result = (rn_lo + rm_lo);
+ hi_result = (rn_hi + rm_hi);
+ }
+ // SASX
+ else if (op2 == 0x01) {
+ lo_result = (rn_lo - rm_hi);
+ hi_result = (rn_hi + rm_lo);
+ }
+ // SSAX
+ else if (op2 == 0x02) {
+ lo_result = (rn_lo + rm_hi);
+ hi_result = (rn_hi - rm_lo);
+ }
+ // SSUB16
+ else if (op2 == 0x03) {
+ lo_result = (rn_lo - rm_lo);
+ hi_result = (rn_hi - rm_hi);
+ }
- RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
+ RD = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
- if (lo_result >= 0) {
- cpu->Cpsr |= (1 << 16);
- cpu->Cpsr |= (1 << 17);
- } else {
- cpu->Cpsr &= ~(1 << 16);
- cpu->Cpsr &= ~(1 << 17);
+ if (lo_result >= 0) {
+ cpu->Cpsr |= (1 << 16);
+ cpu->Cpsr |= (1 << 17);
+ } else {
+ cpu->Cpsr &= ~(1 << 16);
+ cpu->Cpsr &= ~(1 << 17);
+ }
+
+ if (hi_result >= 0) {
+ cpu->Cpsr |= (1 << 18);
+ cpu->Cpsr |= (1 << 19);
+ } else {
+ cpu->Cpsr &= ~(1 << 18);
+ cpu->Cpsr &= ~(1 << 19);
+ }
}
+ else if (op2 == 0x04 || op2 == 0x07) {
+ s32 lo_val1, lo_val2;
+ s32 hi_val1, hi_val2;
- if (hi_result >= 0) {
- cpu->Cpsr |= (1 << 18);
- cpu->Cpsr |= (1 << 19);
- } else {
- cpu->Cpsr &= ~(1 << 18);
- cpu->Cpsr &= ~(1 << 19);
+ // SADD8
+ if (op2 == 0x04) {
+ lo_val1 = (s32)(s8)(RN & 0xFF) + (s32)(s8)(RM & 0xFF);
+ lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) + (s32)(s8)((RM >> 8) & 0xFF);
+ hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) + (s32)(s8)((RM >> 16) & 0xFF);
+ hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) + (s32)(s8)((RM >> 24) & 0xFF);
+ }
+ // SSUB8
+ else {
+ lo_val1 = (s32)(s8)(RN & 0xFF) - (s32)(s8)(RM & 0xFF);
+ lo_val2 = (s32)(s8)((RN >> 8) & 0xFF) - (s32)(s8)((RM >> 8) & 0xFF);
+ hi_val1 = (s32)(s8)((RN >> 16) & 0xFF) - (s32)(s8)((RM >> 16) & 0xFF);
+ hi_val2 = (s32)(s8)((RN >> 24) & 0xFF) - (s32)(s8)((RM >> 24) & 0xFF);
+ }
+
+ RD = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24));
+
+ if (lo_val1 >= 0)
+ cpu->Cpsr |= (1 << 16);
+ else
+ cpu->Cpsr &= ~(1 << 16);
+
+ if (lo_val2 >= 0)
+ cpu->Cpsr |= (1 << 17);
+ else
+ cpu->Cpsr &= ~(1 << 17);
+
+ if (hi_val1 >= 0)
+ cpu->Cpsr |= (1 << 18);
+ else
+ cpu->Cpsr &= ~(1 << 18);
+
+ if (hi_val2 >= 0)
+ cpu->Cpsr |= (1 << 19);
+ else
+ cpu->Cpsr &= ~(1 << 19);
}
}
@@ -5176,12 +5499,79 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
}
SETEND_INST:
- SHADD16_INST:
+
SHADD8_INST:
+ SHADD16_INST:
SHADDSUBX_INST:
- SHSUB16_INST:
SHSUB8_INST:
+ SHSUB16_INST:
SHSUBADDX_INST:
+ {
+ 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;
+
+ if (op2 == 0x00 || op2 == 0x01 || op2 == 0x02 || op2 == 0x03) {
+ s32 lo_result = 0;
+ s32 hi_result = 0;
+
+ // SHADD16
+ if (op2 == 0x00) {
+ lo_result = ((s16)(rn_val & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
+ hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
+ }
+ // SHASX
+ else if (op2 == 0x01) {
+ lo_result = ((s16)(rn_val & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
+ hi_result = ((s16)((rn_val >> 16) & 0xFFFF) + (s16)(rm_val & 0xFFFF)) >> 1;
+ }
+ // SHSAX
+ else if (op2 == 0x02) {
+ lo_result = ((s16)(rn_val & 0xFFFF) + (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
+ hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
+ }
+ // SHSUB16
+ else if (op2 == 0x03) {
+ lo_result = ((s16)(rn_val & 0xFFFF) - (s16)(rm_val & 0xFFFF)) >> 1;
+ hi_result = ((s16)((rn_val >> 16) & 0xFFFF) - (s16)((rm_val >> 16) & 0xFFFF)) >> 1;
+ }
+
+ RD = ((lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16));
+ }
+ else if (op2 == 0x04 || op2 == 0x07) {
+ s16 lo_val1, lo_val2;
+ s16 hi_val1, hi_val2;
+
+ // SHADD8
+ if (op2 == 0x04) {
+ lo_val1 = ((s8)(rn_val & 0xFF) + (s8)(rm_val & 0xFF)) >> 1;
+ lo_val2 = ((s8)((rn_val >> 8) & 0xFF) + (s8)((rm_val >> 8) & 0xFF)) >> 1;
+
+ hi_val1 = ((s8)((rn_val >> 16) & 0xFF) + (s8)((rm_val >> 16) & 0xFF)) >> 1;
+ hi_val2 = ((s8)((rn_val >> 24) & 0xFF) + (s8)((rm_val >> 24) & 0xFF)) >> 1;
+ }
+ // SHSUB8
+ else {
+ lo_val1 = ((s8)(rn_val & 0xFF) - (s8)(rm_val & 0xFF)) >> 1;
+ lo_val2 = ((s8)((rn_val >> 8) & 0xFF) - (s8)((rm_val >> 8) & 0xFF)) >> 1;
+
+ hi_val1 = ((s8)((rn_val >> 16) & 0xFF) - (s8)((rm_val >> 16) & 0xFF)) >> 1;
+ hi_val2 = ((s8)((rn_val >> 24) & 0xFF) - (s8)((rm_val >> 24) & 0xFF)) >> 1;
+ }
+
+ RD = (lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24);
+ }
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
SMLA_INST:
{
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -5198,51 +5588,67 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
RD = operand1 * operand2 + RN;
- // TODO: FIXME: UPDATE Q FLAGS
+ if (AddOverflow(operand1 * operand2, RN, RD))
+ cpu->Cpsr |= (1 << 27);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(smla_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
+
SMLAD_INST:
+ SMLSD_INST:
+ SMUAD_INST:
+ SMUSD_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- smlad_inst *inst_cream = (smlad_inst *)inst_base->component;
- long long int rm = cpu->Reg[inst_cream->Rm];
- long long int rn = cpu->Reg[inst_cream->Rn];
- long long int ra = cpu->Reg[inst_cream->Ra];
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+ const u8 op2 = inst_cream->op2;
- // See SMUAD
- if(inst_cream->Ra == 15)
- CITRA_IGNORE_EXIT(-1);
- int operand2 = (inst_cream->m)? ROTATE_RIGHT_32(rm, 16):rm;
- int half_rn, half_operand2;
+ u32 rm_val = cpu->Reg[inst_cream->Rm];
+ const u32 rn_val = cpu->Reg[inst_cream->Rn];
- half_rn = rn & 0xFFFF;
- half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
+ if (inst_cream->m)
+ rm_val = (((rm_val & 0xFFFF) << 16) | (rm_val >> 16));
- half_operand2 = operand2 & 0xFFFF;
- half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
+ const s16 rm_lo = (rm_val & 0xFFFF);
+ const s16 rm_hi = ((rm_val >> 16) & 0xFFFF);
+ const s16 rn_lo = (rn_val & 0xFFFF);
+ const s16 rn_hi = ((rn_val >> 16) & 0xFFFF);
- long long int product1 = half_rn * half_operand2;
+ const u32 product1 = (rn_lo * rm_lo);
+ const u32 product2 = (rn_hi * rm_hi);
- half_rn = (rn & 0xFFFF0000) >> 16;
- half_rn = (half_rn & 0x8000)? (0xFFFF0000|half_rn) : half_rn;
+ // SMUAD and SMLAD
+ if (BIT(op2, 1) == 0) {
+ RD = (product1 + product2);
- half_operand2 = (operand2 & 0xFFFF0000) >> 16;
- half_operand2 = (half_operand2 & 0x8000)? (0xFFFF0000|half_operand2) : half_operand2;
+ if (inst_cream->Ra != 15) {
+ RD += cpu->Reg[inst_cream->Ra];
- long long int product2 = half_rn * half_operand2;
+ if (ARMul_AddOverflowQ(product1 + product2, cpu->Reg[inst_cream->Ra]))
+ cpu->Cpsr |= (1 << 27);
+ }
- long long int signed_ra = (ra & 0x80000000)? (0xFFFFFFFF00000000LL) | ra : ra;
- long long int result = product1 + product2 + signed_ra;
- cpu->Reg[inst_cream->Rd] = result & 0xFFFFFFFF;
+ if (ARMul_AddOverflowQ(product1, product2))
+ cpu->Cpsr |= (1 << 27);
+ }
+ // SMUSD and SMLSD
+ else {
+ RD = (product1 - product2);
+
+ if (inst_cream->Ra != 15) {
+ RD += cpu->Reg[inst_cream->Ra];
- // TODO: FIXME should check Signed overflow
+ if (ARMul_AddOverflowQ(product1 - product2, cpu->Reg[inst_cream->Ra]))
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
}
+
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(umlal_inst));
+ INC_PC(sizeof(smlad_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
@@ -5275,15 +5681,108 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
FETCH_INST;
GOTO_NEXT_INST;
}
+
SMLALXY_INST:
- SMLALD_INST:
+
SMLAW_INST:
- SMLSD_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+ const u32 ra_val = cpu->Reg[inst_cream->Ra];
+ const bool high = (inst_cream->m == 1);
+
+ const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
+ const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
+
+ RD = (result & (0xFFFFFFFFFFFFFFFFLL >> 15)) >> 16;
+
+ if ((result >> 16) != (s32)RD)
+ cpu->Cpsr |= (1 << 27);
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(smlad_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
+ SMLALD_INST:
SMLSLD_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ smlald_inst* const inst_cream = (smlald_inst*)inst_base->component;
+
+ const bool do_swap = (inst_cream->swap == 1);
+ const u32 rdlo_val = RDLO;
+ const u32 rdhi_val = RDHI;
+ const u32 rn_val = RN;
+ u32 rm_val = RM;
+
+ 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(inst_cream->op2, 1) == 0) {
+ result = (product1 + product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
+ }
+ // SMLSLD
+ else {
+ result = (product1 - product2) + (s64)(rdlo_val | ((s64)rdhi_val << 32));
+ }
+
+ RDLO = (result & 0xFFFFFFFF);
+ RDHI = ((result >> 32) & 0xFFFFFFFF);
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(smlald_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
SMMLA_INST:
SMMLS_INST:
SMMUL_INST:
- SMUAD_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+ const bool do_round = (inst_cream->m == 1);
+
+ // Assume SMMUL by default.
+ s64 result = (s64)(s32)rn_val * (s64)(s32)rm_val;
+
+ if (inst_cream->Ra != 15) {
+ const u32 ra_val = cpu->Reg[inst_cream->Ra];
+
+ // SMMLA, otherwise SMMLS
+ if (BIT(inst_cream->op2, 1) == 0)
+ result += ((s64)ra_val << 32);
+ else
+ result = ((s64)ra_val << 32) - result;
+ }
+
+ if (do_round)
+ result += 0x80000000;
+
+ RD = ((result >> 32) & 0xFFFFFFFF);
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(smlad_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
SMUL_INST:
{
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -5351,8 +5850,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
GOTO_NEXT_INST;
}
- SMUSD_INST:
SRS_INST:
+
SSAT_INST:
{
if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
@@ -5407,7 +5906,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
FETCH_INST;
GOTO_NEXT_INST;
}
- SSUB8_INST:
+
STC_INST:
{
// Instruction not implemented
@@ -5580,46 +6079,96 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
}
STREX_INST:
{
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)];
+ unsigned int write_addr = cpu->Reg[inst_cream->Rn];
- int dest_reg = BITS(inst_cream->inst, 12, 15);
- if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){
- remove_exclusive(cpu, addr);
- cpu->Reg[dest_reg] = 0;
+ if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
+ remove_exclusive(cpu, write_addr);
cpu->exclusive_state = 0;
- Memory::Write32(addr, value);
+ Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]);
+ RD = 0;
} else {
// Failed to write due to mutex access
- cpu->Reg[dest_reg] = 1;
+ RD = 1;
}
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
+ INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
STREXB_INST:
{
- ldst_inst *inst_cream = (ldst_inst *)inst_base->component;
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)];
- unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff;
- int dest_reg = BITS(inst_cream->inst, 12, 15);
- if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){
- remove_exclusive(cpu, addr);
- cpu->Reg[dest_reg] = 0;
+ unsigned int write_addr = cpu->Reg[inst_cream->Rn];
+
+ if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
+ remove_exclusive(cpu, write_addr);
cpu->exclusive_state = 0;
- Memory::Write8(addr, value);
+
+ Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]);
+ RD = 0;
} else {
- cpu->Reg[dest_reg] = 1;
+ // Failed to write due to mutex access
+ RD = 1;
}
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(ldst_inst));
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STREXD_INST:
+ {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int write_addr = cpu->Reg[inst_cream->Rn];
+
+ if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
+ remove_exclusive(cpu, write_addr);
+ cpu->exclusive_state = 0;
+ // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD
+
+ Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]);
+ Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]);
+ RD = 0;
+ }
+ else {
+ // Failed to write due to mutex access
+ RD = 1;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+ STREXH_INST:
+ {
+ generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
+
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ unsigned int write_addr = cpu->Reg[inst_cream->Rn];
+
+ if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
+ remove_exclusive(cpu, write_addr);
+ cpu->exclusive_state = 0;
+
+ Memory::Write16(write_addr, cpu->Reg[inst_cream->Rm]);
+ RD = 0;
+ } else {
+ // Failed to write due to mutex access
+ RD = 1;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
FETCH_INST;
GOTO_NEXT_INST;
}
@@ -5741,7 +6290,40 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
FETCH_INST;
GOTO_NEXT_INST;
}
+
SXTAB16_INST:
+ SXTB16_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ sxtab_inst* const inst_cream = (sxtab_inst*)inst_base->component;
+
+ const u8 rotation = inst_cream->rotate * 8;
+ u32 rm_val = RM;
+ u32 rn_val = RN;
+
+ if (rotation)
+ rm_val = ((rm_val << (32 - rotation)) | (rm_val >> rotation));
+
+ // SXTB16
+ if (inst_cream->Rn == 15) {
+ u32 lo = (u32)(s8)rm_val;
+ u32 hi = (u32)(s8)(rm_val >> 16);
+ RD = (lo | (hi << 16));
+ }
+ // SXTAB16
+ else {
+ u32 lo = (rn_val & 0xFFFF) + (u32)(s8)(rm_val & 0xFF);
+ u32 hi = ((rn_val >> 16) & 0xFFFF) + (u32)(s8)((rm_val >> 16) & 0xFF);
+ RD = (lo | (hi << 16));
+ }
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(sxtab_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
SXTAH_INST:
{
sxtah_inst *inst_cream = (sxtah_inst *)inst_base->component;
@@ -5760,7 +6342,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
FETCH_INST;
GOTO_NEXT_INST;
}
- SXTB16_INST:
+
TEQ_INST:
{
if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
@@ -6156,7 +6738,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
BLX_1_THUMB:
{
// BLX 1 for armv5t and above
- uint32 tmp = cpu->Reg[15];
+ u32 tmp = cpu->Reg[15];
blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
cpu->Reg[14] = ((tmp + 2) | 1);
@@ -6354,9 +6936,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
}
INIT_INST_LENGTH:
{
-#if defined __GNUC__ || defined __clang__
- InterpreterInitInstLength((unsigned long long int *)InstLabel, sizeof(InstLabel));
-#endif
cpu->NumInstrsToExecute = 0;
return num_instrs;
}
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
index aeabeac1..c7052227 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.h
+++ b/src/core/arm/dyncom/arm_dyncom_run.h
@@ -24,8 +24,8 @@
void switch_mode(arm_core_t *core, uint32_t mode);
/* FIXME, we temporarily think thumb instruction is always 16 bit */
-static inline uint32 GET_INST_SIZE(arm_core_t* core){
- return core->TFlag? 2 : 4;
+static inline u32 GET_INST_SIZE(arm_core_t* core) {
+ return core->TFlag? 2 : 4;
}
/**
@@ -36,8 +36,8 @@ static inline uint32 GET_INST_SIZE(arm_core_t* core){
*
* @return
*/
-static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){
- return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
+static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn) {
+ return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
}
/**
@@ -48,8 +48,8 @@ static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){
*
* @return
*/
-static inline uint32 CHECK_READ_REG15(arm_core_t* core, int Rn){
- return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
+static inline u32 CHECK_READ_REG15(arm_core_t* core, int Rn) {
+ return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
}
#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
index 5541de9d..bf69b2fd 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -37,10 +37,10 @@ enum tdstate {
t_uninitialized,
};
-tdstate
-thumb_translate(addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size);
-static inline uint32 get_thumb_instr(uint32 instr, addr_t pc){
- uint32 tinstr;
+tdstate thumb_translate(addr_t addr, u32 instr, u32* ainstr, u32* inst_size);
+
+static inline u32 get_thumb_instr(u32 instr, addr_t pc) {
+ u32 tinstr;
if ((pc & 0x3) != 0)
tinstr = instr >> 16;
else
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index b9c2aa6c..12166bf7 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -5881,67 +5881,45 @@ L_stm_s_takeabort:
const u32 rm_val = state->Reg[rm_idx];
const u32 rn_val = state->Reg[rn_idx];
- u8 lo_val1;
- u8 lo_val2;
- u8 hi_val1;
- u8 hi_val2;
+ s32 lo_val1, lo_val2;
+ s32 hi_val1, hi_val2;
// SADD8
if ((instr & 0xFF0) == 0xf90) {
- lo_val1 = (u8)((rn_val & 0xFF) + (rm_val & 0xFF));
- lo_val2 = (u8)(((rn_val >> 8) & 0xFF) + ((rm_val >> 8) & 0xFF));
- hi_val1 = (u8)(((rn_val >> 16) & 0xFF) + ((rm_val >> 16) & 0xFF));
- hi_val2 = (u8)(((rn_val >> 24) & 0xFF) + ((rm_val >> 24) & 0xFF));
-
- if (lo_val1 & 0x80)
- state->GEFlag |= (1 << 16);
- else
- state->GEFlag &= ~(1 << 16);
-
- if (lo_val2 & 0x80)
- state->GEFlag |= (1 << 17);
- else
- state->GEFlag &= ~(1 << 17);
-
- if (hi_val1 & 0x80)
- state->GEFlag |= (1 << 18);
- else
- state->GEFlag &= ~(1 << 18);
-
- if (hi_val2 & 0x80)
- state->GEFlag |= (1 << 19);
- else
- state->GEFlag &= ~(1 << 19);
+ lo_val1 = (s32)(s8)(rn_val & 0xFF) + (s32)(s8)(rm_val & 0xFF);
+ lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) + (s32)(s8)((rm_val >> 8) & 0xFF);
+ hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) + (s32)(s8)((rm_val >> 16) & 0xFF);
+ hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) + (s32)(s8)((rm_val >> 24) & 0xFF);
}
// SSUB8
else {
- lo_val1 = (u8)((rn_val & 0xFF) - (rm_val & 0xFF));
- lo_val2 = (u8)(((rn_val >> 8) & 0xFF) - ((rm_val >> 8) & 0xFF));
- hi_val1 = (u8)(((rn_val >> 16) & 0xFF) - ((rm_val >> 16) & 0xFF));
- hi_val2 = (u8)(((rn_val >> 24) & 0xFF) - ((rm_val >> 24) & 0xFF));
+ lo_val1 = (s32)(s8)(rn_val & 0xFF) - (s32)(s8)(rm_val & 0xFF);
+ lo_val2 = (s32)(s8)((rn_val >> 8) & 0xFF) - (s32)(s8)((rm_val >> 8) & 0xFF);
+ hi_val1 = (s32)(s8)((rn_val >> 16) & 0xFF) - (s32)(s8)((rm_val >> 16) & 0xFF);
+ hi_val2 = (s32)(s8)((rn_val >> 24) & 0xFF) - (s32)(s8)((rm_val >> 24) & 0xFF);
+ }
- if (!(lo_val1 & 0x80))
- state->GEFlag |= (1 << 16);
- else
- state->GEFlag &= ~(1 << 16);
+ if (lo_val1 >= 0)
+ state->GEFlag |= (1 << 16);
+ else
+ state->GEFlag &= ~(1 << 16);
- if (!(lo_val2 & 0x80))
- state->GEFlag |= (1 << 17);
- else
- state->GEFlag &= ~(1 << 17);
+ if (lo_val2 >= 0)
+ state->GEFlag |= (1 << 17);
+ else
+ state->GEFlag &= ~(1 << 17);
- if (!(hi_val1 & 0x80))
- state->GEFlag |= (1 << 18);
- else
- state->GEFlag &= ~(1 << 18);
+ if (hi_val1 >= 0)
+ state->GEFlag |= (1 << 18);
+ else
+ state->GEFlag &= ~(1 << 18);
- if (!(hi_val2 & 0x80))
- state->GEFlag |= (1 << 19);
- else
- state->GEFlag &= ~(1 << 19);
- }
+ if (hi_val2 >= 0)
+ state->GEFlag |= (1 << 19);
+ else
+ state->GEFlag &= ~(1 << 19);
- state->Reg[rd_idx] = (lo_val1 | lo_val2 << 8 | hi_val1 << 16 | hi_val2 << 24);
+ state->Reg[rd_idx] = ((lo_val1 & 0xFF) | ((lo_val2 & 0xFF) << 8) | ((hi_val1 & 0xFF) << 16) | ((hi_val2 & 0xFF) << 24));
return 1;
}
else {
@@ -6492,17 +6470,23 @@ L_stm_s_takeabort:
if (BITS(12, 15) != 15) {
state->Reg[rd_idx] += state->Reg[ra_idx];
- ARMul_AddOverflowQ(state, product1 + product2, state->Reg[ra_idx]);
+ if (ARMul_AddOverflowQ(product1 + product2, state->Reg[ra_idx]))
+ SETQ;
}
- ARMul_AddOverflowQ(state, product1, product2);
+ if (ARMul_AddOverflowQ(product1, product2))
+ SETQ;
}
// SMUSD and SMLSD
else {
state->Reg[rd_idx] = product1 - product2;
-
- if (BITS(12, 15) != 15)
+
+ if (BITS(12, 15) != 15) {
state->Reg[rd_idx] += state->Reg[ra_idx];
+
+ if (ARMul_AddOverflowQ(product1 - product2, state->Reg[ra_idx]))
+ SETQ;
+ }
}
return 1;
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index 426b6783..68ac2a0c 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -418,22 +418,18 @@ ARMul_NegZero (ARMul_State * state, ARMword result)
}
}
-/* Compute whether an addition of A and B, giving RESULT, overflowed. */
-
-int
-AddOverflow (ARMword a, ARMword b, ARMword result)
+// Compute whether an addition of A and B, giving RESULT, overflowed.
+bool AddOverflow(ARMword a, ARMword b, ARMword result)
{
- return ((NEG (a) && NEG (b) && POS (result))
- || (POS (a) && POS (b) && NEG (result)));
+ return ((NEG(a) && NEG(b) && POS(result)) ||
+ (POS(a) && POS(b) && NEG(result)));
}
-/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */
-
-int
-SubOverflow (ARMword a, ARMword b, ARMword result)
+// Compute whether a subtraction of A and B, giving RESULT, overflowed.
+bool SubOverflow(ARMword a, ARMword b, ARMword result)
{
- return ((NEG (a) && POS (b) && POS (result))
- || (POS (a) && NEG (b) && NEG (result)));
+ return ((NEG(a) && POS(b) && POS(result)) ||
+ (POS(a) && NEG(b) && NEG(result)));
}
/* Assigns the C flag after an addition of a and b to give result. */
@@ -453,12 +449,14 @@ ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
ASSIGNV (AddOverflow (a, b, result));
}
-/* Assigns the Q flag if the given result is considered an overflow from the addition of a and b */
-void ARMul_AddOverflowQ(ARMul_State* state, ARMword a, ARMword b)
+// Returns true if the Q flag should be set as a result of overflow.
+bool ARMul_AddOverflowQ(ARMword a, ARMword b)
{
u32 result = a + b;
if (((result ^ a) & (u32)0x80000000) && ((a ^ b) & (u32)0x80000000) == 0)
- SETQ;
+ return true;
+
+ return false;
}
/* Assigns the C flag after an subtraction of a and b to give result. */
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 8611d739..3100d7ad 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -70,6 +70,9 @@
#define DATACACHE 1
#define INSTCACHE 2
+#define POS(i) ( (~(i)) >> 31 )
+#define NEG(i) ( (i) >> 31 )
+
#ifndef __STDC__
typedef char *VoidStar;
#endif
@@ -783,6 +786,8 @@ RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\
//#define PXA250 0x69052903
// 0x69052903; //PXA250 B1 from intel 278522-001.pdf
+extern bool AddOverflow(ARMword, ARMword, ARMword);
+extern bool SubOverflow(ARMword, ARMword, ARMword);
extern void ARMul_UndefInstr(ARMul_State*, ARMword);
extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword);
@@ -790,6 +795,8 @@ extern void ARMul_FixSPSR(ARMul_State*, ARMword, ARMword);
extern void ARMul_ConsolePrint(ARMul_State*, const char*, ...);
extern void ARMul_SelectProcessor(ARMul_State*, unsigned);
+extern bool ARMul_AddOverflowQ(ARMword, ARMword);
+
extern u8 ARMul_SignedSaturatedAdd8(u8, u8);
extern u8 ARMul_SignedSaturatedSub8(u8, u8);
extern u16 ARMul_SignedSaturatedAdd16(u16, u16);
diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h
index 3ea14b5a..1dfcc635 100644
--- a/src/core/arm/skyeye_common/armemu.h
+++ b/src/core/arm/skyeye_common/armemu.h
@@ -42,9 +42,6 @@
#define R15FBIT (1L << 26)
#define R15IFBITS (3L << 26)
-#define POS(i) ( (~(i)) >> 31 )
-#define NEG(i) ( (i) >> 31 )
-
#ifdef MODET /* Thumb support. */
/* ??? This bit is actually in the low order bit of the PC in the hardware.
It isn't clear if the simulator needs to model that or not. */
@@ -561,8 +558,7 @@ tdstate;
/* Prototypes for exported functions. */
extern unsigned ARMul_NthReg (ARMword, unsigned);
-extern int AddOverflow (ARMword, ARMword, ARMword);
-extern int SubOverflow (ARMword, ARMword, ARMword);
+
/* Prototypes for exported functions. */
#ifdef __cplusplus
extern "C" {
@@ -602,7 +598,6 @@ extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword);
extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword);
extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword);
-extern void ARMul_AddOverflowQ(ARMul_State*, ARMword, ARMword);
extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword);
extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword);
extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *);
diff --git a/src/core/arm/skyeye_common/skyeye_types.h b/src/core/arm/skyeye_common/skyeye_types.h
index e7f022f1..fc7d8d92 100644
--- a/src/core/arm/skyeye_common/skyeye_types.h
+++ b/src/core/arm/skyeye_common/skyeye_types.h
@@ -22,34 +22,10 @@
* 12/16/2006 Michael.Kang <blackfin.kang@gmail.com>
*/
-#ifndef __SKYEYE_TYPES_H
-#define __SKYEYE_TYPES_H
+#pragma once
-#include <stdint.h>
-
-/*default machine word length */
-
-#ifndef __BEOS__
-/* To avoid the type conflict with the qemu */
-#ifndef QEMU
-typedef uint8_t uint8;
-typedef uint16_t uint16;
-typedef uint32_t uint32;
-typedef uint64_t uint64;
-
-typedef int8_t sint8;
-typedef int16_t sint16;
-typedef int32_t sint32;
-typedef int64_t sint64;
-#endif
+#include <cstdint>
typedef uint32_t address_t;
-typedef uint32_t uinteger_t;
-typedef int32_t integer_t;
-
typedef uint32_t physical_address_t;
-typedef uint32_t generic_address_t;
-
-#endif
-
-#endif
+typedef uint32_t generic_address_t;
diff --git a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
index b5fcbac8..2c1218c3 100644
--- a/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
+++ b/src/core/arm/skyeye_common/vfp/vfpinstr.cpp
@@ -1,22 +1,6 @@
-/*
- vfp/vfpinstr.c - ARM VFPv3 emulation unit - Individual instructions data
- Copyright (C) 2003 Skyeye Develop Group
- for help please send mail to <skyeye-developer@lists.gro.clinux.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-*/
+// Copyright 2012 Michael Kang, 2015 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
/* Notice: this file should not be compiled as is, and is meant to be
included in other files only. */
@@ -30,52 +14,52 @@
/* cond 1110 0D00 Vn-- Vd-- 101X N0M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmla_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vmla_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmla_inst));
- vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMLA_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VMLA :\n");
-
- vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VMLA :\n");
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ vmla_inst *inst_cream = (vmla_inst *)inst_base->component;
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ int ret;
+
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vmla_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -85,66 +69,66 @@ DYNCOM_FILL_ACTION(vmla),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int n;
- int d ;
- int add = (BIT(6) == 0);
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPMUL(nn,mm);
- if(!add)
- tmp = FPNEG32(tmp);
- mm = FR32(d);
- tmp = FPADD(mm,tmp);
- //LETS(d,tmp);
- LETFPS(d,tmp);
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- //mm = SITOFP(32,RSPR(m));
- //LETS(d,tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * m)));
- nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
- tmp = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(tmp);
- tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
- nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
- nn = OR(SHL(nn,CONST64(32)),tmp);
- nn = FPBITCAST64(nn);
- tmp = FPMUL(nn,mm);
- if(!add)
- tmp = FPNEG64(tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * d)));
- nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
- mm = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(mm);
- tmp = FPADD(mm,tmp);
- mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
- nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
- LETFPS(2*d ,FPBITCAST32(nn));
- LETFPS(d*2 + 1 , FPBITCAST32(mm));
- }
- return No_exp;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int m;
+ int n;
+ int d ;
+ int add = (BIT(6) == 0);
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPMUL(nn,mm);
+ if(!add)
+ tmp = FPNEG32(tmp);
+ mm = FR32(d);
+ tmp = FPADD(mm,tmp);
+ //LETS(d,tmp);
+ LETFPS(d,tmp);
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ //mm = SITOFP(32,RSPR(m));
+ //LETS(d,tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * m)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
+ tmp = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(tmp);
+ tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
+ nn = OR(SHL(nn,CONST64(32)),tmp);
+ nn = FPBITCAST64(nn);
+ tmp = FPMUL(nn,mm);
+ if(!add)
+ tmp = FPNEG64(tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * d)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
+ mm = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(mm);
+ tmp = FPADD(mm,tmp);
+ mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
+ nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
+ LETFPS(2*d ,FPBITCAST32(nn));
+ LETFPS(d*2 + 1 , FPBITCAST32(mm));
+ }
+ return No_exp;
}
#endif
@@ -153,52 +137,52 @@ int DYNCOM_TRANS(vmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 0D00 Vn-- Vd-- 101X N1M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmls_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vmls_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmls_inst));
- vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMLS_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VMLS :\n");
-
- vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ DBG("VMLS :\n");
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmls_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ vmls_inst *inst_cream = (vmls_inst *)inst_base->component;
+
+ int ret;
+
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vmls_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -208,66 +192,66 @@ DYNCOM_FILL_ACTION(vmls),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int n;
- int d ;
- int add = (BIT(6) == 0);
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPMUL(nn,mm);
- if(!add)
- tmp = FPNEG32(tmp);
- mm = FR32(d);
- tmp = FPADD(mm,tmp);
- //LETS(d,tmp);
- LETFPS(d,tmp);
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- //mm = SITOFP(32,RSPR(m));
- //LETS(d,tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * m)));
- nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
- tmp = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(tmp);
- tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
- nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
- nn = OR(SHL(nn,CONST64(32)),tmp);
- nn = FPBITCAST64(nn);
- tmp = FPMUL(nn,mm);
- if(!add)
- tmp = FPNEG64(tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * d)));
- nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
- mm = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(mm);
- tmp = FPADD(mm,tmp);
- mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
- nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
- LETFPS(2*d ,FPBITCAST32(nn));
- LETFPS(d*2 + 1 , FPBITCAST32(mm));
- }
- return No_exp;
+ DBG("\t\tin %s VMLS instruction is executed out of here.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int m;
+ int n;
+ int d ;
+ int add = (BIT(6) == 0);
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPMUL(nn,mm);
+ if(!add)
+ tmp = FPNEG32(tmp);
+ mm = FR32(d);
+ tmp = FPADD(mm,tmp);
+ //LETS(d,tmp);
+ LETFPS(d,tmp);
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ //mm = SITOFP(32,RSPR(m));
+ //LETS(d,tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * m)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
+ tmp = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(tmp);
+ tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
+ nn = OR(SHL(nn,CONST64(32)),tmp);
+ nn = FPBITCAST64(nn);
+ tmp = FPMUL(nn,mm);
+ if(!add)
+ tmp = FPNEG64(tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * d)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
+ mm = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(mm);
+ tmp = FPADD(mm,tmp);
+ mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
+ nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
+ LETFPS(2*d ,FPBITCAST32(nn));
+ LETFPS(d*2 + 1 , FPBITCAST32(mm));
+ }
+ return No_exp;
}
#endif
@@ -276,52 +260,52 @@ int DYNCOM_TRANS(vmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 0D01 Vn-- Vd-- 101X N1M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vnmla_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vnmla_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vnmla_inst));
- vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VNMLA_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VNMLA :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VNMLA :\n");
+
+ vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
- vnmla_inst *inst_cream = (vnmla_inst *)inst_base->component;
+ int ret;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vnmla_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vnmla_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -332,66 +316,66 @@ DYNCOM_FILL_ACTION(vnmla),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int n;
- int d ;
- int add = (BIT(6) == 0);
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPMUL(nn,mm);
- if(!add)
- tmp = FPNEG32(tmp);
- mm = FR32(d);
- tmp = FPADD(FPNEG32(mm),tmp);
- //LETS(d,tmp);
- LETFPS(d,tmp);
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- //mm = SITOFP(32,RSPR(m));
- //LETS(d,tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * m)));
- nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
- tmp = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(tmp);
- tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
- nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
- nn = OR(SHL(nn,CONST64(32)),tmp);
- nn = FPBITCAST64(nn);
- tmp = FPMUL(nn,mm);
- if(!add)
- tmp = FPNEG64(tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * d)));
- nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
- mm = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(mm);
- tmp = FPADD(FPNEG64(mm),tmp);
- mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
- nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
- LETFPS(2*d ,FPBITCAST32(nn));
- LETFPS(d*2 + 1 , FPBITCAST32(mm));
- }
- return No_exp;
+ DBG("\t\tin %s VNMLA instruction is executed out of here.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int m;
+ int n;
+ int d ;
+ int add = (BIT(6) == 0);
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPMUL(nn,mm);
+ if(!add)
+ tmp = FPNEG32(tmp);
+ mm = FR32(d);
+ tmp = FPADD(FPNEG32(mm),tmp);
+ //LETS(d,tmp);
+ LETFPS(d,tmp);
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ //mm = SITOFP(32,RSPR(m));
+ //LETS(d,tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * m)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
+ tmp = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(tmp);
+ tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
+ nn = OR(SHL(nn,CONST64(32)),tmp);
+ nn = FPBITCAST64(nn);
+ tmp = FPMUL(nn,mm);
+ if(!add)
+ tmp = FPNEG64(tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * d)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
+ mm = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(mm);
+ tmp = FPADD(FPNEG64(mm),tmp);
+ mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
+ nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
+ LETFPS(2*d ,FPBITCAST32(nn));
+ LETFPS(d*2 + 1 , FPBITCAST32(mm));
+ }
+ return No_exp;
}
#endif
@@ -401,52 +385,52 @@ int DYNCOM_TRANS(vnmla)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vnmls_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vnmls_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vnmls_inst));
- vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmls_inst));
+ vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VNMLS_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VNMLS :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VNMLS :\n");
+
+ vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
- vnmls_inst *inst_cream = (vnmls_inst *)inst_base->component;
+ int ret;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vnmls_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vnmls_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -456,66 +440,66 @@ DYNCOM_FILL_ACTION(vnmls),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int n;
- int d ;
- int add = (BIT(6) == 0);
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPMUL(nn,mm);
- if(!add)
- tmp = FPNEG32(tmp);
- mm = FR32(d);
- tmp = FPADD(FPNEG32(mm),tmp);
- //LETS(d,tmp);
- LETFPS(d,tmp);
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- //mm = SITOFP(32,RSPR(m));
- //LETS(d,tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * m)));
- nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
- tmp = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(tmp);
- tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
- nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
- nn = OR(SHL(nn,CONST64(32)),tmp);
- nn = FPBITCAST64(nn);
- tmp = FPMUL(nn,mm);
- if(!add)
- tmp = FPNEG64(tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * d)));
- nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
- mm = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(mm);
- tmp = FPADD(FPNEG64(mm),tmp);
- mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
- nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
- LETFPS(2*d ,FPBITCAST32(nn));
- LETFPS(d*2 + 1 , FPBITCAST32(mm));
- }
- return No_exp;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int m;
+ int n;
+ int d ;
+ int add = (BIT(6) == 0);
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPMUL(nn,mm);
+ if(!add)
+ tmp = FPNEG32(tmp);
+ mm = FR32(d);
+ tmp = FPADD(FPNEG32(mm),tmp);
+ //LETS(d,tmp);
+ LETFPS(d,tmp);
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ //mm = SITOFP(32,RSPR(m));
+ //LETS(d,tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * m)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
+ tmp = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(tmp);
+ tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
+ nn = OR(SHL(nn,CONST64(32)),tmp);
+ nn = FPBITCAST64(nn);
+ tmp = FPMUL(nn,mm);
+ if(!add)
+ tmp = FPNEG64(tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * d)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * d + 1)));
+ mm = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(mm);
+ tmp = FPADD(FPNEG64(mm),tmp);
+ mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
+ nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
+ LETFPS(2*d ,FPBITCAST32(nn));
+ LETFPS(d*2 + 1 , FPBITCAST32(mm));
+ }
+ return No_exp;
}
#endif
@@ -524,52 +508,52 @@ int DYNCOM_TRANS(vnmls)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vnmul_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vnmul_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vnmul_inst));
- vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vnmul_inst));
+ vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VNMUL_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VNMUL :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VNMUL :\n");
+
+ vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
- vnmul_inst *inst_cream = (vnmul_inst *)inst_base->component;
+ int ret;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vnmul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vnmul_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -579,56 +563,56 @@ DYNCOM_FILL_ACTION(vnmul),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
-}
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
+}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int n;
- int d ;
- int add = (BIT(6) == 0);
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPMUL(nn,mm);
- //LETS(d,tmp);
- LETFPS(d,FPNEG32(tmp));
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- //mm = SITOFP(32,RSPR(m));
- //LETS(d,tmp);
- mm = ZEXT64(IBITCAST32(FR32(2 * m)));
- nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
- tmp = OR(SHL(nn,CONST64(32)),mm);
- mm = FPBITCAST64(tmp);
- tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
- nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
- nn = OR(SHL(nn,CONST64(32)),tmp);
- nn = FPBITCAST64(nn);
- tmp = FPMUL(nn,mm);
- tmp = FPNEG64(tmp);
- mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
- nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
- LETFPS(2*d ,FPBITCAST32(nn));
- LETFPS(d*2 + 1 , FPBITCAST32(mm));
- }
- return No_exp;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int m;
+ int n;
+ int d ;
+ int add = (BIT(6) == 0);
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPMUL(nn,mm);
+ //LETS(d,tmp);
+ LETFPS(d,FPNEG32(tmp));
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ //mm = SITOFP(32,RSPR(m));
+ //LETS(d,tmp);
+ mm = ZEXT64(IBITCAST32(FR32(2 * m)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * m + 1)));
+ tmp = OR(SHL(nn,CONST64(32)),mm);
+ mm = FPBITCAST64(tmp);
+ tmp = ZEXT64(IBITCAST32(FR32(2 * n)));
+ nn = ZEXT64(IBITCAST32(FR32(2 * n + 1)));
+ nn = OR(SHL(nn,CONST64(32)),tmp);
+ nn = FPBITCAST64(nn);
+ tmp = FPMUL(nn,mm);
+ tmp = FPNEG64(tmp);
+ mm = TRUNC32(LSHR(IBITCAST64(tmp),CONST64(32)));
+ nn = TRUNC32(AND(IBITCAST64(tmp),CONST64(0xffffffff)));
+ LETFPS(2*d ,FPBITCAST32(nn));
+ LETFPS(d*2 + 1 , FPBITCAST32(mm));
+ }
+ return No_exp;
}
#endif
@@ -638,52 +622,52 @@ int DYNCOM_TRANS(vnmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 0D10 Vn-- Vd-- 101X N0M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmul_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vmul_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmul_inst));
- vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmul_inst));
+ vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMUL_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VMUL :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VMUL :\n");
+
+ vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
- vmul_inst *inst_cream = (vmul_inst *)inst_base->component;
+ int ret;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmul_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vmul_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -693,70 +677,70 @@ DYNCOM_FILL_ACTION(vmul),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int m;
- int n;
- int d ;
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- //mm = SITOFP(32,FR(m));
- //nn = SITOFP(32,FRn));
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPMUL(nn,mm);
- //LETS(d,tmp);
- LETFPS(d,tmp);
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- //mm = SITOFP(32,RSPR(m));
- //LETS(d,tmp);
- Value *lo = FR32(2 * m);
- Value *hi = FR32(2 * m + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- Value *hi64 = ZEXT64(hi);
- Value* lo64 = ZEXT64(lo);
- Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
- Value* m0 = FPBITCAST64(v64);
- lo = FR32(2 * n);
- hi = FR32(2 * n + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- hi64 = ZEXT64(hi);
- lo64 = ZEXT64(lo);
- v64 = OR(SHL(hi64,CONST64(32)),lo64);
- Value *n0 = FPBITCAST64(v64);
- tmp = FPMUL(n0,m0);
- Value *val64 = IBITCAST64(tmp);
- hi = LSHR(val64,CONST64(32));
- lo = AND(val64,CONST64(0xffffffff));
- hi = TRUNC32(hi);
- lo = TRUNC32(lo);
- hi = FPBITCAST32(hi);
- lo = FPBITCAST32(lo);
- LETFPS(2*d ,lo);
- LETFPS(d*2 + 1 , hi);
- }
- return No_exp;
+ 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);
+ int m;
+ int n;
+ int d ;
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ //mm = SITOFP(32,FR(m));
+ //nn = SITOFP(32,FRn));
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPMUL(nn,mm);
+ //LETS(d,tmp);
+ LETFPS(d,tmp);
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ //mm = SITOFP(32,RSPR(m));
+ //LETS(d,tmp);
+ Value *lo = FR32(2 * m);
+ Value *hi = FR32(2 * m + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ Value *hi64 = ZEXT64(hi);
+ Value* lo64 = ZEXT64(lo);
+ Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ Value* m0 = FPBITCAST64(v64);
+ lo = FR32(2 * n);
+ hi = FR32(2 * n + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ hi64 = ZEXT64(hi);
+ lo64 = ZEXT64(lo);
+ v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ Value *n0 = FPBITCAST64(v64);
+ tmp = FPMUL(n0,m0);
+ Value *val64 = IBITCAST64(tmp);
+ hi = LSHR(val64,CONST64(32));
+ lo = AND(val64,CONST64(0xffffffff));
+ hi = TRUNC32(hi);
+ lo = TRUNC32(lo);
+ hi = FPBITCAST32(hi);
+ lo = FPBITCAST32(lo);
+ LETFPS(2*d ,lo);
+ LETFPS(d*2 + 1 , hi);
+ }
+ return No_exp;
}
#endif
@@ -765,52 +749,52 @@ int DYNCOM_TRANS(vmul)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 0D11 Vn-- Vd-- 101X N0M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vadd_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vadd_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vadd_inst));
- vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vadd_inst));
+ vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VADD_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VADD :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VADD :\n");
- vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
+ vadd_inst *inst_cream = (vadd_inst *)inst_base->component;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ int ret;
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vadd_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vadd_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -820,64 +804,64 @@ DYNCOM_FILL_ACTION(vadd),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int n;
- int d ;
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPADD(nn,mm);
- LETFPS(d,tmp);
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- Value *lo = FR32(2 * m);
- Value *hi = FR32(2 * m + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- Value *hi64 = ZEXT64(hi);
- Value* lo64 = ZEXT64(lo);
- Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
- Value* m0 = FPBITCAST64(v64);
- lo = FR32(2 * n);
- hi = FR32(2 * n + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- hi64 = ZEXT64(hi);
- lo64 = ZEXT64(lo);
- v64 = OR(SHL(hi64,CONST64(32)),lo64);
- Value *n0 = FPBITCAST64(v64);
- tmp = FPADD(n0,m0);
- Value *val64 = IBITCAST64(tmp);
- hi = LSHR(val64,CONST64(32));
- lo = AND(val64,CONST64(0xffffffff));
- hi = TRUNC32(hi);
- lo = TRUNC32(lo);
- hi = FPBITCAST32(hi);
- lo = FPBITCAST32(lo);
- LETFPS(2*d ,lo);
- LETFPS(d*2 + 1 , hi);
- }
- return No_exp;
+ DBG("\t\tin %s instruction will implement out of JIT.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int m;
+ int n;
+ int d ;
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPADD(nn,mm);
+ LETFPS(d,tmp);
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ Value *lo = FR32(2 * m);
+ Value *hi = FR32(2 * m + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ Value *hi64 = ZEXT64(hi);
+ Value* lo64 = ZEXT64(lo);
+ Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ Value* m0 = FPBITCAST64(v64);
+ lo = FR32(2 * n);
+ hi = FR32(2 * n + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ hi64 = ZEXT64(hi);
+ lo64 = ZEXT64(lo);
+ v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ Value *n0 = FPBITCAST64(v64);
+ tmp = FPADD(n0,m0);
+ Value *val64 = IBITCAST64(tmp);
+ hi = LSHR(val64,CONST64(32));
+ lo = AND(val64,CONST64(0xffffffff));
+ hi = TRUNC32(hi);
+ lo = TRUNC32(lo);
+ hi = FPBITCAST32(hi);
+ lo = FPBITCAST32(lo);
+ LETFPS(2*d ,lo);
+ LETFPS(d*2 + 1 , hi);
+ }
+ return No_exp;
}
#endif
@@ -886,52 +870,52 @@ int DYNCOM_TRANS(vadd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 0D11 Vn-- Vd-- 101X N1M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vsub_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vsub_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vsub_inst));
- vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VSUB_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VSUB :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VSUB :\n");
- vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
+ vsub_inst *inst_cream = (vsub_inst *)inst_base->component;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ int ret;
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vsub_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vsub_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
#ifdef VFP_DYNCOM_TABLE
@@ -940,63 +924,63 @@ DYNCOM_FILL_ACTION(vsub),
#ifdef VFP_DYNCOM_TAG
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);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int n;
- int d ;
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPSUB(nn,mm);
- LETFPS(d,tmp);
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- Value *lo = FR32(2 * m);
- Value *hi = FR32(2 * m + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- Value *hi64 = ZEXT64(hi);
- Value* lo64 = ZEXT64(lo);
- Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
- Value* m0 = FPBITCAST64(v64);
- lo = FR32(2 * n);
- hi = FR32(2 * n + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- hi64 = ZEXT64(hi);
- lo64 = ZEXT64(lo);
- v64 = OR(SHL(hi64,CONST64(32)),lo64);
- Value *n0 = FPBITCAST64(v64);
- tmp = FPSUB(n0,m0);
- Value *val64 = IBITCAST64(tmp);
- hi = LSHR(val64,CONST64(32));
- lo = AND(val64,CONST64(0xffffffff));
- hi = TRUNC32(hi);
- lo = TRUNC32(lo);
- hi = FPBITCAST32(hi);
- lo = FPBITCAST32(lo);
- LETFPS(2*d ,lo);
- LETFPS(d*2 + 1 , hi);
- }
- return No_exp;
+ DBG("\t\tin %s instr=0x%x, instruction is executed out of JIT.\n", __FUNCTION__, instr);
+ //arch_arm_undef(cpu, bb, instr);
+ int m;
+ int n;
+ int d ;
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPSUB(nn,mm);
+ LETFPS(d,tmp);
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ Value *lo = FR32(2 * m);
+ Value *hi = FR32(2 * m + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ Value *hi64 = ZEXT64(hi);
+ Value* lo64 = ZEXT64(lo);
+ Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ Value* m0 = FPBITCAST64(v64);
+ lo = FR32(2 * n);
+ hi = FR32(2 * n + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ hi64 = ZEXT64(hi);
+ lo64 = ZEXT64(lo);
+ v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ Value *n0 = FPBITCAST64(v64);
+ tmp = FPSUB(n0,m0);
+ Value *val64 = IBITCAST64(tmp);
+ hi = LSHR(val64,CONST64(32));
+ lo = AND(val64,CONST64(0xffffffff));
+ hi = TRUNC32(hi);
+ lo = TRUNC32(lo);
+ hi = FPBITCAST32(hi);
+ lo = FPBITCAST32(lo);
+ LETFPS(2*d ,lo);
+ LETFPS(d*2 + 1 , hi);
+ }
+ return No_exp;
}
#endif
@@ -1005,52 +989,52 @@ int DYNCOM_TRANS(vsub)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 1D00 Vn-- Vd-- 101X N0M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vdiv_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vdiv_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vdiv_inst));
- vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VDIV_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VDIV :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VDIV :\n");
- vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
+ vdiv_inst *inst_cream = (vdiv_inst *)inst_base->component;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ int ret;
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vdiv_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vdiv_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1060,64 +1044,64 @@ DYNCOM_FILL_ACTION(vdiv),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int n;
- int d ;
- int s = BIT(8) == 0;
- Value *mm;
- Value *nn;
- Value *tmp;
- if(s){
- m = BIT(5) | BITS(0,3) << 1;
- n = BIT(7) | BITS(16,19) << 1;
- d = BIT(22) | BITS(12,15) << 1;
- mm = FR32(m);
- nn = FR32(n);
- tmp = FPDIV(nn,mm);
- LETFPS(d,tmp);
- }else {
- m = BITS(0,3) | BIT(5) << 4;
- n = BITS(16,19) | BIT(7) << 4;
- d = BIT(22) << 4 | BITS(12,15);
- Value *lo = FR32(2 * m);
- Value *hi = FR32(2 * m + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- Value *hi64 = ZEXT64(hi);
- Value* lo64 = ZEXT64(lo);
- Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
- Value* m0 = FPBITCAST64(v64);
- lo = FR32(2 * n);
- hi = FR32(2 * n + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- hi64 = ZEXT64(hi);
- lo64 = ZEXT64(lo);
- v64 = OR(SHL(hi64,CONST64(32)),lo64);
- Value *n0 = FPBITCAST64(v64);
- tmp = FPDIV(n0,m0);
- Value *val64 = IBITCAST64(tmp);
- hi = LSHR(val64,CONST64(32));
- lo = AND(val64,CONST64(0xffffffff));
- hi = TRUNC32(hi);
- lo = TRUNC32(lo);
- hi = FPBITCAST32(hi);
- lo = FPBITCAST32(lo);
- LETFPS(2*d ,lo);
- LETFPS(d*2 + 1 , hi);
- }
- return No_exp;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int m;
+ int n;
+ int d ;
+ int s = BIT(8) == 0;
+ Value *mm;
+ Value *nn;
+ Value *tmp;
+ if(s){
+ m = BIT(5) | BITS(0,3) << 1;
+ n = BIT(7) | BITS(16,19) << 1;
+ d = BIT(22) | BITS(12,15) << 1;
+ mm = FR32(m);
+ nn = FR32(n);
+ tmp = FPDIV(nn,mm);
+ LETFPS(d,tmp);
+ }else {
+ m = BITS(0,3) | BIT(5) << 4;
+ n = BITS(16,19) | BIT(7) << 4;
+ d = BIT(22) << 4 | BITS(12,15);
+ Value *lo = FR32(2 * m);
+ Value *hi = FR32(2 * m + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ Value *hi64 = ZEXT64(hi);
+ Value* lo64 = ZEXT64(lo);
+ Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ Value* m0 = FPBITCAST64(v64);
+ lo = FR32(2 * n);
+ hi = FR32(2 * n + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ hi64 = ZEXT64(hi);
+ lo64 = ZEXT64(lo);
+ v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ Value *n0 = FPBITCAST64(v64);
+ tmp = FPDIV(n0,m0);
+ Value *val64 = IBITCAST64(tmp);
+ hi = LSHR(val64,CONST64(32));
+ lo = AND(val64,CONST64(0xffffffff));
+ hi = TRUNC32(hi);
+ lo = TRUNC32(lo);
+ hi = FPBITCAST32(hi);
+ lo = FPBITCAST32(lo);
+ LETFPS(2*d ,lo);
+ LETFPS(d*2 + 1 , hi);
+ }
+ return No_exp;
}
#endif
@@ -1127,48 +1111,48 @@ int DYNCOM_TRANS(vdiv)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovi_inst {
- unsigned int single;
- unsigned int d;
- unsigned int imm;
+ unsigned int single;
+ unsigned int d;
+ unsigned int imm;
} vmovi_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmovi_inst));
- vmovi_inst *inst_cream = (vmovi_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->single = BIT(inst, 8) == 0;
- inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
- unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3);
- if (inst_cream->single)
- inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19;
- else
- inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16;
- return inst_base;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->single = BIT(inst, 8) == 0;
+ inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
+ unsigned int imm8 = BITS(inst, 16, 19) << 4 | BITS(inst, 0, 3);
+ if (inst_cream->single)
+ inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0x1f : 0)<<25 | BITS(imm8, 0, 5)<<19;
+ else
+ inst_cream->imm = BIT(imm8, 7)<<31 | (BIT(imm8, 6)==0)<<30 | (BIT(imm8, 6) ? 0xff : 0)<<22 | BITS(imm8, 0, 5)<<16;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMOVI_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- vmovi_inst *inst_cream = (vmovi_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
- VMOVI(cpu, inst_cream->single, inst_cream->d, inst_cream->imm);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmovi_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ 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(vmovi_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1178,37 +1162,37 @@ DYNCOM_FILL_ACTION(vmovi),
#ifdef VFP_DYNCOM_TAG
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__);
- arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int d;
- int imm32;
- Value *v;
- Value *tmp;
- v = CONST32(BITS(0,3) | BITS(16,19) << 4);
- //v = CONST64(0x3ff0000000000000);
- if(single){
- d = BIT(22) | BITS(12,15) << 1;
- }else {
- d = BITS(12,15) | BIT(22) << 4;
- }
- if(single){
- LETFPS(d,FPBITCAST32(v));
- }else {
- //v = UITOFP(64,v);
- //tmp = IBITCAST64(v);
- LETFPS(d*2 ,FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff)))));
- LETFPS(d * 2 + 1,FPBITCAST32(TRUNC32(LSHR(v,CONST64(32)))));
- }
- return No_exp;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int single = (BIT(8) == 0);
+ int d;
+ int imm32;
+ Value *v;
+ Value *tmp;
+ v = CONST32(BITS(0,3) | BITS(16,19) << 4);
+ //v = CONST64(0x3ff0000000000000);
+ if(single){
+ d = BIT(22) | BITS(12,15) << 1;
+ }else {
+ d = BITS(12,15) | BIT(22) << 4;
+ }
+ if(single){
+ LETFPS(d,FPBITCAST32(v));
+ }else {
+ //v = UITOFP(64,v);
+ //tmp = IBITCAST64(v);
+ LETFPS(d*2 ,FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff)))));
+ LETFPS(d * 2 + 1,FPBITCAST32(TRUNC32(LSHR(v,CONST64(32)))));
+ }
+ return No_exp;
}
#endif
@@ -1218,45 +1202,44 @@ int DYNCOM_TRANS(vmovi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 opc1 CRn- CRd- copr op20 CRm- CDP */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovr_inst {
- unsigned int single;
- unsigned int d;
- unsigned int m;
+ unsigned int single;
+ unsigned int d;
+ unsigned int m;
} vmovr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmovr_inst));
- vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->single = BIT(inst, 8) == 0;
- inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
- inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4);
- return inst_base;
+ inst_cream->single = BIT(inst, 8) == 0;
+ inst_cream->d = (inst_cream->single ? BITS(inst,12,15)<<1 | BIT(inst,22) : BITS(inst,12,15) | BIT(inst,22)<<4);
+ inst_cream->m = (inst_cream->single ? BITS(inst, 0, 3)<<1 | BIT(inst, 5) : BITS(inst, 0, 3) | BIT(inst, 5)<<4);
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMOVR_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- vmovr_inst *inst_cream = (vmovr_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
- VMOVR(cpu, inst_cream->single, inst_cream->d, inst_cream->m);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmovr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ 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(vmovr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1266,33 +1249,33 @@ DYNCOM_FILL_ACTION(vmovr),
#ifdef VFP_DYNCOM_TAG
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);
- DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
- if(instr >> 28 != 0xe)
- *tag |= TAG_CONDITIONAL;
+ int instr_size = INSTR_SIZE;
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
+ if(instr >> 28 != 0xe)
+ *tag |= TAG_CONDITIONAL;
- return instr_size;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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));
- int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
+ 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));
+ int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
- if (single)
- {
- LETFPS(d, FR32(m));
- }
- else
- {
- /* Check endian please */
- LETFPS((d*2 + 1), FR32(m*2 + 1));
- LETFPS((d * 2), FR32(m * 2));
- }
- return No_exp;
+ if (single)
+ {
+ LETFPS(d, FR32(m));
+ }
+ else
+ {
+ /* Check endian please */
+ LETFPS((d*2 + 1), FR32(m*2 + 1));
+ LETFPS((d * 2), FR32(m * 2));
+ }
+ return No_exp;
}
#endif
@@ -1301,52 +1284,50 @@ int DYNCOM_TRANS(vmovr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 1D11 0000 Vd-- 101X 11M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vabs_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vabs_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vabs_inst));
- vabs_inst *inst_cream = (vabs_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;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VABS_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VABS :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VABS :\n");
+
+ vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
- vabs_inst *inst_cream = (vabs_inst *)inst_base->component;
+ int ret;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vabs_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vabs_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1356,50 +1337,50 @@ DYNCOM_FILL_ACTION(vabs),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
- int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
- Value* m0;
- if (single)
- {
- m0 = FR32(m);
- m0 = SELECT(FPCMP_OLT(m0,FPCONST32(0.0)),FPNEG32(m0),m0);
- LETFPS(d,m0);
- }
- else
- {
- /* Check endian please */
- Value *lo = FR32(2 * m);
- Value *hi = FR32(2 * m + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- Value *hi64 = ZEXT64(hi);
- Value* lo64 = ZEXT64(lo);
- Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
- m0 = FPBITCAST64(v64);
- m0 = SELECT(FPCMP_OLT(m0,FPCONST64(0.0)),FPNEG64(m0),m0);
- Value *val64 = IBITCAST64(m0);
- hi = LSHR(val64,CONST64(32));
- lo = AND(val64,CONST64(0xffffffff));
- hi = TRUNC32(hi);
- lo = TRUNC32(lo);
- hi = FPBITCAST32(hi);
- lo = FPBITCAST32(lo);
- LETFPS(2*d ,lo);
- LETFPS(d*2 + 1 , hi);
- }
- return No_exp;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int single = BIT(8) == 0;
+ int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
+ int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
+ Value* m0;
+ if (single)
+ {
+ m0 = FR32(m);
+ m0 = SELECT(FPCMP_OLT(m0,FPCONST32(0.0)),FPNEG32(m0),m0);
+ LETFPS(d,m0);
+ }
+ else
+ {
+ /* Check endian please */
+ Value *lo = FR32(2 * m);
+ Value *hi = FR32(2 * m + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ Value *hi64 = ZEXT64(hi);
+ Value* lo64 = ZEXT64(lo);
+ Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ m0 = FPBITCAST64(v64);
+ m0 = SELECT(FPCMP_OLT(m0,FPCONST64(0.0)),FPNEG64(m0),m0);
+ Value *val64 = IBITCAST64(m0);
+ hi = LSHR(val64,CONST64(32));
+ lo = AND(val64,CONST64(0xffffffff));
+ hi = TRUNC32(hi);
+ lo = TRUNC32(lo);
+ hi = FPBITCAST32(hi);
+ lo = FPBITCAST32(lo);
+ LETFPS(2*d ,lo);
+ LETFPS(d*2 + 1 , hi);
+ }
+ return No_exp;
}
#endif
@@ -1409,52 +1390,50 @@ int DYNCOM_TRANS(vabs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vneg_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vneg_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vneg_inst));
- vneg_inst *inst_cream = (vneg_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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VNEG_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VNEG :\n");
- DBG("VNEG :\n");
+ vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
- vneg_inst *inst_cream = (vneg_inst *)inst_base->component;
+ int ret;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vneg_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vneg_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1464,50 +1443,50 @@ DYNCOM_FILL_ACTION(vneg),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
- int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
- Value* m0;
- if (single)
- {
- m0 = FR32(m);
- m0 = FPNEG32(m0);
- LETFPS(d,m0);
- }
- else
- {
- /* Check endian please */
- Value *lo = FR32(2 * m);
- Value *hi = FR32(2 * m + 1);
- hi = IBITCAST32(hi);
- lo = IBITCAST32(lo);
- Value *hi64 = ZEXT64(hi);
- Value* lo64 = ZEXT64(lo);
- Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
- m0 = FPBITCAST64(v64);
- m0 = FPNEG64(m0);
- Value *val64 = IBITCAST64(m0);
- hi = LSHR(val64,CONST64(32));
- lo = AND(val64,CONST64(0xffffffff));
- hi = TRUNC32(hi);
- lo = TRUNC32(lo);
- hi = FPBITCAST32(hi);
- lo = FPBITCAST32(lo);
- LETFPS(2*d ,lo);
- LETFPS(d*2 + 1 , hi);
- }
- return No_exp;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int single = BIT(8) == 0;
+ int d = (single ? BITS(12,15)<<1 | BIT(22) : BIT(22) << 4 | BITS(12,15));
+ int m = (single ? BITS(0, 3)<<1 | BIT(5) : BITS(0, 3) | BIT(5)<<4);
+ Value* m0;
+ if (single)
+ {
+ m0 = FR32(m);
+ m0 = FPNEG32(m0);
+ LETFPS(d,m0);
+ }
+ else
+ {
+ /* Check endian please */
+ Value *lo = FR32(2 * m);
+ Value *hi = FR32(2 * m + 1);
+ hi = IBITCAST32(hi);
+ lo = IBITCAST32(lo);
+ Value *hi64 = ZEXT64(hi);
+ Value* lo64 = ZEXT64(lo);
+ Value* v64 = OR(SHL(hi64,CONST64(32)),lo64);
+ m0 = FPBITCAST64(v64);
+ m0 = FPNEG64(m0);
+ Value *val64 = IBITCAST64(m0);
+ hi = LSHR(val64,CONST64(32));
+ lo = AND(val64,CONST64(0xffffffff));
+ hi = TRUNC32(hi);
+ lo = TRUNC32(lo);
+ hi = FPBITCAST32(hi);
+ lo = FPBITCAST32(lo);
+ LETFPS(2*d ,lo);
+ LETFPS(d*2 + 1 , hi);
+ }
+ return No_exp;
}
#endif
@@ -1516,52 +1495,52 @@ int DYNCOM_TRANS(vneg)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 1D11 0001 Vd-- 101X 11M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vsqrt_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vsqrt_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vsqrt_inst));
- vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VSQRT_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VSQRT :\n");
-
- vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ DBG("VSQRT :\n");
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vsqrt_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ vsqrt_inst *inst_cream = (vsqrt_inst *)inst_base->component;
+
+ int ret;
+
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vsqrt_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1571,38 +1550,38 @@ DYNCOM_FILL_ACTION(vsqrt),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
- int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
- Value* v;
- Value* tmp;
- if(dp_op){
- v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
- tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
- v = OR(v,tmp);
- v = FPSQRT(FPBITCAST64(v));
- tmp = TRUNC32(LSHR(IBITCAST64(v),CONST64(32)));
- v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff)));
- LETFPS(2 * d , FPBITCAST32(v));
- LETFPS(2 * d + 1, FPBITCAST32(tmp));
- }else {
- v = FR32(m);
- v = FPSQRT(FPEXT(64,v));
- v = FPTRUNC(32,v);
- LETFPS(d,v);
- }
- return No_exp;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int dp_op = (BIT(8) == 1);
+ int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
+ int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
+ Value* v;
+ Value* tmp;
+ if(dp_op){
+ v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
+ tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
+ v = OR(v,tmp);
+ v = FPSQRT(FPBITCAST64(v));
+ tmp = TRUNC32(LSHR(IBITCAST64(v),CONST64(32)));
+ v = TRUNC32(AND(IBITCAST64(v),CONST64( 0xffffffff)));
+ LETFPS(2 * d , FPBITCAST32(v));
+ LETFPS(2 * d + 1, FPBITCAST32(tmp));
+ }else {
+ v = FR32(m);
+ v = FPSQRT(FPEXT(64,v));
+ v = FPTRUNC(32,v);
+ LETFPS(d,v);
+ }
+ return No_exp;
}
#endif
@@ -1611,52 +1590,52 @@ int DYNCOM_TRANS(vsqrt)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 1 */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcmp_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vcmp_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vcmp_inst));
- vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VCMP_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VCMP(1) :\n");
- DBG("VCMP(1) :\n");
+ vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
- vcmp_inst *inst_cream = (vcmp_inst *)inst_base->component;
+ int ret;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vcmp_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vcmp_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1666,65 +1645,65 @@ DYNCOM_FILL_ACTION(vcmp),
#ifdef VFP_DYNCOM_TAG
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);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
- int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
- Value* v;
- Value* tmp;
- Value* n;
- Value* z;
- Value* c;
- Value* vt;
- Value* v1;
- Value* nzcv;
- if(dp_op){
- v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
- tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
- v1 = OR(v,tmp);
- v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32));
- tmp = ZEXT64(IBITCAST32(FR32(2 * d)));
- v = OR(v,tmp);
- z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1));
- n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1));
- c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1));
- tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1));
- v1 = tmp;
- c = OR(c,tmp);
- n = SHL(ZEXT32(n),CONST32(31));
- z = SHL(ZEXT32(z),CONST32(30));
- c = SHL(ZEXT32(c),CONST32(29));
- v1 = SHL(ZEXT32(v1),CONST(28));
- nzcv = OR(OR(OR(n,z),c),v1);
- v = R(VFP_FPSCR);
- tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
- LET(VFP_FPSCR,tmp);
- }else {
- z = FPCMP_OEQ(FR32(d),FR32(m));
- n = FPCMP_OLT(FR32(d),FR32(m));
- c = FPCMP_OGE(FR32(d),FR32(m));
- tmp = FPCMP_UNO(FR32(d),FR32(m));
- c = OR(c,tmp);
- v1 = tmp;
- n = SHL(ZEXT32(n),CONST32(31));
- z = SHL(ZEXT32(z),CONST32(30));
- c = SHL(ZEXT32(c),CONST32(29));
- v1 = SHL(ZEXT32(v1),CONST(28));
- nzcv = OR(OR(OR(n,z),c),v1);
- v = R(VFP_FPSCR);
- tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
- LET(VFP_FPSCR,tmp);
- }
- return No_exp;
+ DBG("\t\tin %s instruction is executed out of JIT.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int dp_op = (BIT(8) == 1);
+ int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
+ int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
+ Value* v;
+ Value* tmp;
+ Value* n;
+ Value* z;
+ Value* c;
+ Value* vt;
+ Value* v1;
+ Value* nzcv;
+ if(dp_op){
+ v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
+ tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
+ v1 = OR(v,tmp);
+ v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32));
+ tmp = ZEXT64(IBITCAST32(FR32(2 * d)));
+ v = OR(v,tmp);
+ z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1));
+ n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1));
+ c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1));
+ tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1));
+ v1 = tmp;
+ c = OR(c,tmp);
+ n = SHL(ZEXT32(n),CONST32(31));
+ z = SHL(ZEXT32(z),CONST32(30));
+ c = SHL(ZEXT32(c),CONST32(29));
+ v1 = SHL(ZEXT32(v1),CONST(28));
+ nzcv = OR(OR(OR(n,z),c),v1);
+ v = R(VFP_FPSCR);
+ tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
+ LET(VFP_FPSCR,tmp);
+ }else {
+ z = FPCMP_OEQ(FR32(d),FR32(m));
+ n = FPCMP_OLT(FR32(d),FR32(m));
+ c = FPCMP_OGE(FR32(d),FR32(m));
+ tmp = FPCMP_UNO(FR32(d),FR32(m));
+ c = OR(c,tmp);
+ v1 = tmp;
+ n = SHL(ZEXT32(n),CONST32(31));
+ z = SHL(ZEXT32(z),CONST32(30));
+ c = SHL(ZEXT32(c),CONST32(29));
+ v1 = SHL(ZEXT32(v1),CONST(28));
+ nzcv = OR(OR(OR(n,z),c),v1);
+ v = R(VFP_FPSCR);
+ tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
+ LET(VFP_FPSCR,tmp);
+ }
+ return No_exp;
}
#endif
@@ -1733,52 +1712,52 @@ int DYNCOM_TRANS(vcmp)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 1D11 0100 Vd-- 101X E1M0 Vm-- Encoding 2 */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcmp2_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vcmp2_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vcmp2_inst));
- vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VCMP2_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VCMP(2) :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VCMP(2) :\n");
- vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
+ vcmp2_inst *inst_cream = (vcmp2_inst *)inst_base->component;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ int ret;
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vcmp2_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vcmp2_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1788,65 +1767,65 @@ DYNCOM_FILL_ACTION(vcmp2),
#ifdef VFP_DYNCOM_TAG
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);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
- //int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
- Value* v;
- Value* tmp;
- Value* n;
- Value* z;
- Value* c;
- Value* vt;
- Value* v1;
- Value* nzcv;
- if(dp_op){
- v1 = CONST64(0);
- v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32));
- tmp = ZEXT64(IBITCAST32(FR32(2 * d)));
- v = OR(v,tmp);
- z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1));
- n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1));
- c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1));
- tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1));
- v1 = tmp;
- c = OR(c,tmp);
- n = SHL(ZEXT32(n),CONST32(31));
- z = SHL(ZEXT32(z),CONST32(30));
- c = SHL(ZEXT32(c),CONST32(29));
- v1 = SHL(ZEXT32(v1),CONST(28));
- nzcv = OR(OR(OR(n,z),c),v1);
- v = R(VFP_FPSCR);
- tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
- LET(VFP_FPSCR,tmp);
- }else {
- v1 = CONST(0);
- v1 = FPBITCAST32(v1);
- z = FPCMP_OEQ(FR32(d),v1);
- n = FPCMP_OLT(FR32(d),v1);
- c = FPCMP_OGE(FR32(d),v1);
- tmp = FPCMP_UNO(FR32(d),v1);
- c = OR(c,tmp);
- v1 = tmp;
- n = SHL(ZEXT32(n),CONST32(31));
- z = SHL(ZEXT32(z),CONST32(30));
- c = SHL(ZEXT32(c),CONST32(29));
- v1 = SHL(ZEXT32(v1),CONST(28));
- nzcv = OR(OR(OR(n,z),c),v1);
- v = R(VFP_FPSCR);
- tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
- LET(VFP_FPSCR,tmp);
- }
- return No_exp;
+ DBG("\t\tin %s instruction will executed out of JIT.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int dp_op = (BIT(8) == 1);
+ int d = dp_op ? BITS(12,15) | BIT(22) << 4 : BIT(22) | BITS(12,15) << 1;
+ //int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
+ Value* v;
+ Value* tmp;
+ Value* n;
+ Value* z;
+ Value* c;
+ Value* vt;
+ Value* v1;
+ Value* nzcv;
+ if(dp_op){
+ v1 = CONST64(0);
+ v = SHL(ZEXT64(IBITCAST32(FR32(2 * d + 1))),CONST64(32));
+ tmp = ZEXT64(IBITCAST32(FR32(2 * d)));
+ v = OR(v,tmp);
+ z = FPCMP_OEQ(FPBITCAST64(v),FPBITCAST64(v1));
+ n = FPCMP_OLT(FPBITCAST64(v),FPBITCAST64(v1));
+ c = FPCMP_OGE(FPBITCAST64(v),FPBITCAST64(v1));
+ tmp = FPCMP_UNO(FPBITCAST64(v),FPBITCAST64(v1));
+ v1 = tmp;
+ c = OR(c,tmp);
+ n = SHL(ZEXT32(n),CONST32(31));
+ z = SHL(ZEXT32(z),CONST32(30));
+ c = SHL(ZEXT32(c),CONST32(29));
+ v1 = SHL(ZEXT32(v1),CONST(28));
+ nzcv = OR(OR(OR(n,z),c),v1);
+ v = R(VFP_FPSCR);
+ tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
+ LET(VFP_FPSCR,tmp);
+ }else {
+ v1 = CONST(0);
+ v1 = FPBITCAST32(v1);
+ z = FPCMP_OEQ(FR32(d),v1);
+ n = FPCMP_OLT(FR32(d),v1);
+ c = FPCMP_OGE(FR32(d),v1);
+ tmp = FPCMP_UNO(FR32(d),v1);
+ c = OR(c,tmp);
+ v1 = tmp;
+ n = SHL(ZEXT32(n),CONST32(31));
+ z = SHL(ZEXT32(z),CONST32(30));
+ c = SHL(ZEXT32(c),CONST32(29));
+ v1 = SHL(ZEXT32(v1),CONST(28));
+ nzcv = OR(OR(OR(n,z),c),v1);
+ v = R(VFP_FPSCR);
+ tmp = OR(nzcv,AND(v,CONST32(0x0fffffff)));
+ LET(VFP_FPSCR,tmp);
+ }
+ return No_exp;
}
#endif
@@ -1855,52 +1834,52 @@ int DYNCOM_TRANS(vcmp2)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 1D11 0111 Vd-- 101X 11M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcvtbds_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vcvtbds_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vcvtbds_inst));
- vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VCVTBDS_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VCVT(BDS) :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VCVT(BDS) :\n");
- vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
+ vcvtbds_inst *inst_cream = (vcvtbds_inst *)inst_base->component;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ int ret;
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vcvtbds_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vcvtbds_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -1910,39 +1889,39 @@ DYNCOM_FILL_ACTION(vcvtbds),
#ifdef VFP_DYNCOM_TAG
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);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int d = dp_op ? BITS(12,15) << 1 | BIT(22) : BIT(22) << 4 | BITS(12,15);
- int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
- int d2s = dp_op;
- Value* v;
- Value* tmp;
- Value* v1;
- if(d2s){
- v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
- tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
- v1 = OR(v,tmp);
- tmp = FPTRUNC(32,FPBITCAST64(v1));
- LETFPS(d,tmp);
- }else {
- v = FR32(m);
- tmp = FPEXT(64,v);
- v = IBITCAST64(tmp);
- tmp = TRUNC32(AND(v,CONST64(0xffffffff)));
- v1 = TRUNC32(LSHR(v,CONST64(32)));
- LETFPS(2 * d, FPBITCAST32(tmp) );
- LETFPS(2 * d + 1, FPBITCAST32(v1));
- }
- return No_exp;
+ DBG("\t\tin %s instruction is executed out.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int dp_op = (BIT(8) == 1);
+ int d = dp_op ? BITS(12,15) << 1 | BIT(22) : BIT(22) << 4 | BITS(12,15);
+ int m = dp_op ? BITS(0,3) | BIT(5) << 4 : BIT(5) | BITS(0,3) << 1;
+ int d2s = dp_op;
+ Value* v;
+ Value* tmp;
+ Value* v1;
+ if(d2s){
+ v = SHL(ZEXT64(IBITCAST32(FR32(2 * m + 1))),CONST64(32));
+ tmp = ZEXT64(IBITCAST32(FR32(2 * m)));
+ v1 = OR(v,tmp);
+ tmp = FPTRUNC(32,FPBITCAST64(v1));
+ LETFPS(d,tmp);
+ }else {
+ v = FR32(m);
+ tmp = FPEXT(64,v);
+ v = IBITCAST64(tmp);
+ tmp = TRUNC32(AND(v,CONST64(0xffffffff)));
+ v1 = TRUNC32(LSHR(v,CONST64(32)));
+ LETFPS(2 * d, FPBITCAST32(tmp) );
+ LETFPS(2 * d + 1, FPBITCAST32(v1));
+ }
+ return No_exp;
}
#endif
@@ -1951,52 +1930,52 @@ int DYNCOM_TRANS(vcvtbds)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcvtbff_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vcvtbff_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vcvtbff_inst));
- vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;VFP_DEBUG_UNTESTED(VCVTBFF);
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
-
- return inst_base;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VCVTBFF_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VCVT(BFF) :\n");
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VCVT(BFF) :\n");
- vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
+ vcvtbff_inst *inst_cream = (vcvtbff_inst *)inst_base->component;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ int ret;
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vcvtbff_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vcvtbff_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2006,17 +1985,17 @@ DYNCOM_FILL_ACTION(vcvtbff),
#ifdef VFP_DYNCOM_TAG
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__);
- arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arch_arm_undef(cpu, bb, instr);
+ return No_exp;
}
#endif
@@ -2025,53 +2004,53 @@ int DYNCOM_TRANS(vcvtbff)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
/* cond 1110 1D11 1op2 Vd-- 101X X1M0 Vm-- */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vcvtbfi_inst {
- unsigned int instr;
- unsigned int dp_operation;
+ unsigned int instr;
+ unsigned int dp_operation;
} vcvtbfi_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vcvtbfi_inst));
- vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->dp_operation = BIT(inst, 8);
- inst_cream->instr = inst;
+ inst_cream->dp_operation = BIT(inst, 8);
+ inst_cream->instr = inst;
-
- return inst_base;
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VCVTBFI_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- DBG("VCVT(BFI) :\n");
-
- vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ DBG("VCVT(BFI) :\n");
+
+ vcvtbfi_inst *inst_cream = (vcvtbfi_inst *)inst_base->component;
- int ret;
-
- if (inst_cream->dp_operation)
- ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ int ret;
- CHECK_VFP_CDP_RET;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vcvtbfi_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if (inst_cream->dp_operation)
+ ret = vfp_double_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, inst_cream->instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+
+ CHECK_VFP_CDP_RET;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vcvtbfi_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2081,87 +2060,87 @@ DYNCOM_FILL_ACTION(vcvtbfi),
#ifdef VFP_DYNCOM_TAG
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__);
- DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ DBG("\t\tin %s, instruction will be executed out of JIT.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int to_integer = ((opc2 >> 2) == 1);
- int dp_op = (BIT(8) == 1);
- unsigned int op = BIT(7);
- int m,d;
- Value* v;
- Value* hi;
- Value* lo;
- Value* v64;
- if(to_integer){
- d = BIT(22) | (BITS(12,15) << 1);
- if(dp_op)
- m = BITS(0,3) | BIT(5) << 4;
- else
- m = BIT(5) | BITS(0,3) << 1;
- }else {
- m = BIT(5) | BITS(0,3) << 1;
- if(dp_op)
- d = BITS(12,15) | BIT(22) << 4;
- else
- d = BIT(22) | BITS(12,15) << 1;
- }
- if(to_integer){
- if(dp_op){
- lo = FR32(m * 2);
- hi = FR32(m * 2 + 1);
- hi = ZEXT64(IBITCAST32(hi));
- lo = ZEXT64(IBITCAST32(lo));
- v64 = OR(SHL(hi,CONST64(32)),lo);
- if(BIT(16)){
- v = FPTOSI(32,FPBITCAST64(v64));
- }
- else
- v = FPTOUI(32,FPBITCAST64(v64));
-
- v = FPBITCAST32(v);
- LETFPS(d,v);
- }else {
- v = FR32(m);
- if(BIT(16)){
-
- v = FPTOSI(32,v);
- }
- else
- v = FPTOUI(32,v);
- LETFPS(d,FPBITCAST32(v));
- }
- }else {
- if(dp_op){
- v = IBITCAST32(FR32(m));
- if(BIT(7))
- v64 = SITOFP(64,v);
- else
- v64 = UITOFP(64,v);
- v = IBITCAST64(v64);
- hi = FPBITCAST32(TRUNC32(LSHR(v,CONST64(32))));
- lo = FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff))));
- LETFPS(2 * d , lo);
- LETFPS(2 * d + 1, hi);
- }else {
- v = IBITCAST32(FR32(m));
- if(BIT(7))
- v = SITOFP(32,v);
- else
- v = UITOFP(32,v);
- LETFPS(d,v);
- }
- }
- return No_exp;
+ 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);
+ int to_integer = ((opc2 >> 2) == 1);
+ int dp_op = (BIT(8) == 1);
+ unsigned int op = BIT(7);
+ int m,d;
+ Value* v;
+ Value* hi;
+ Value* lo;
+ Value* v64;
+ if(to_integer){
+ d = BIT(22) | (BITS(12,15) << 1);
+ if(dp_op)
+ m = BITS(0,3) | BIT(5) << 4;
+ else
+ m = BIT(5) | BITS(0,3) << 1;
+ }else {
+ m = BIT(5) | BITS(0,3) << 1;
+ if(dp_op)
+ d = BITS(12,15) | BIT(22) << 4;
+ else
+ d = BIT(22) | BITS(12,15) << 1;
+ }
+ if(to_integer){
+ if(dp_op){
+ lo = FR32(m * 2);
+ hi = FR32(m * 2 + 1);
+ hi = ZEXT64(IBITCAST32(hi));
+ lo = ZEXT64(IBITCAST32(lo));
+ v64 = OR(SHL(hi,CONST64(32)),lo);
+ if(BIT(16)){
+ v = FPTOSI(32,FPBITCAST64(v64));
+ }
+ else
+ v = FPTOUI(32,FPBITCAST64(v64));
+
+ v = FPBITCAST32(v);
+ LETFPS(d,v);
+ }else {
+ v = FR32(m);
+ if(BIT(16)){
+
+ v = FPTOSI(32,v);
+ }
+ else
+ v = FPTOUI(32,v);
+ LETFPS(d,FPBITCAST32(v));
+ }
+ }else {
+ if(dp_op){
+ v = IBITCAST32(FR32(m));
+ if(BIT(7))
+ v64 = SITOFP(64,v);
+ else
+ v64 = UITOFP(64,v);
+ v = IBITCAST64(v64);
+ hi = FPBITCAST32(TRUNC32(LSHR(v,CONST64(32))));
+ lo = FPBITCAST32(TRUNC32(AND(v,CONST64(0xffffffff))));
+ LETFPS(2 * d , lo);
+ LETFPS(2 * d + 1, hi);
+ }else {
+ v = IBITCAST32(FR32(m));
+ if(BIT(7))
+ v = SITOFP(32,v);
+ else
+ v = UITOFP(32,v);
+ LETFPS(d,v);
+ }
+ }
+ return No_exp;
}
/**
@@ -2173,15 +2152,15 @@ int DYNCOM_TRANS(vcvtbfi)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
* @return
*/
int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
- int dp_operation = BIT(8);
- int ret;
- if (dp_operation)
- ret = vfp_double_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- else
- ret = vfp_single_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ int dp_operation = BIT(8);
+ int ret;
+ if (dp_operation)
+ ret = vfp_double_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ else
+ ret = vfp_single_cpdo(cpu, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- vfp_raise_exceptions(cpu, ret, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- return 0;
+ vfp_raise_exceptions(cpu, ret, instr, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ return 0;
}
#endif
@@ -2196,45 +2175,45 @@ int vcvtbfi_instr_impl(arm_core_t* cpu, uint32 instr){
/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbrs_inst {
- unsigned int to_arm;
- unsigned int t;
- unsigned int n;
+ unsigned int to_arm;
+ unsigned int t;
+ unsigned int n;
} vmovbrs_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmovbrs_inst));
- vmovbrs_inst *inst_cream = (vmovbrs_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->to_arm = BIT(inst, 20) == 1;
- inst_cream->t = BITS(inst, 12, 15);
- inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1;
+ inst_cream->to_arm = BIT(inst, 20) == 1;
+ inst_cream->t = BITS(inst, 12, 15);
+ inst_cream->n = BIT(inst, 7) | BITS(inst, 16, 19)<<1;
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMOVBRS_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
- vmovbrs_inst *inst_cream = (vmovbrs_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(vmovbrs_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ 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(vmovbrs_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2244,30 +2223,30 @@ DYNCOM_FILL_ACTION(vmovbrs),
#ifdef VFP_DYNCOM_TAG
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__);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int n = BIT(7) | BITS(16, 19)<<1;
+ DBG("VMOV(BRS) :\n");
+ int to_arm = BIT(20) == 1;
+ int t = BITS(12, 15);
+ int n = BIT(7) | BITS(16, 19)<<1;
- if (to_arm)
- {
- DBG("\tr%d <= s%d\n", t, n);
- LET(t, IBITCAST32(FR32(n)));
- }
- else
- {
- DBG("\ts%d <= r%d\n", n, t);
- LETFPS(n, FPBITCAST32(R(t)));
- }
- return No_exp;
+ if (to_arm)
+ {
+ DBG("\tr%d <= s%d\n", t, n);
+ LET(t, IBITCAST32(FR32(n)));
+ }
+ else
+ {
+ DBG("\ts%d <= r%d\n", n, t);
+ LETFPS(n, FPBITCAST32(R(t)));
+ }
+ return No_exp;
}
#endif
@@ -2277,46 +2256,46 @@ int DYNCOM_TRANS(vmovbrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmsr_inst {
- unsigned int reg;
- unsigned int Rd;
+ unsigned int reg;
+ unsigned int Rd;
} vmsr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmsr_inst));
- vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_cream->reg = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
- inst_cream->reg = BITS(inst, 16, 19);
- inst_cream->Rd = BITS(inst, 12, 15);
-
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMSR_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled ,
- and in privilegied mode */
- /* Exceptions must be checked, according to v7 ref manual */
- CHECK_VFP_ENABLED;
-
- vmsr_inst *inst_cream = (vmsr_inst *)inst_base->component;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled ,
+ and in privilegied mode */
+ /* Exceptions must be checked, according to v7 ref manual */
+ CHECK_VFP_ENABLED;
- VMSR(cpu, inst_cream->reg, inst_cream->Rd);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmsr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ 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(vmsr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2326,45 +2305,45 @@ DYNCOM_FILL_ACTION(vmsr),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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 :");
- if(RD == 15) {
- printf("in %s is not implementation.\n", __FUNCTION__);
- exit(-1);
- }
-
- Value *data = NULL;
- int reg = RN;
- int Rt = RD;
- if (reg == 1)
- {
- LET(VFP_FPSCR, R(Rt));
- DBG("\tflags <= fpscr\n");
- }
- else
- {
- switch (reg)
- {
- case 8:
- LET(VFP_FPEXC, R(Rt));
- DBG("\tfpexc <= r%d \n", Rt);
- break;
- default:
- DBG("\tSUBARCHITECTURE DEFINED\n");
- break;
- }
- }
- return No_exp;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ DBG("VMSR :");
+ if(RD == 15) {
+ printf("in %s is not implementation.\n", __FUNCTION__);
+ exit(-1);
+ }
+
+ Value *data = NULL;
+ int reg = RN;
+ int Rt = RD;
+ if (reg == 1)
+ {
+ LET(VFP_FPSCR, R(Rt));
+ DBG("\tflags <= fpscr\n");
+ }
+ else
+ {
+ switch (reg)
+ {
+ case 8:
+ LET(VFP_FPEXC, R(Rt));
+ DBG("\tfpexc <= r%d \n", Rt);
+ break;
+ default:
+ DBG("\tSUBARCHITECTURE DEFINED\n");
+ break;
+ }
+ }
+ return No_exp;
}
#endif
@@ -2374,48 +2353,48 @@ int DYNCOM_TRANS(vmsr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 op10 CRn- Rt-- copr op21 CRm- MCR */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbrc_inst {
- unsigned int esize;
- unsigned int index;
- unsigned int d;
- unsigned int t;
+ unsigned int esize;
+ unsigned int index;
+ unsigned int d;
+ unsigned int t;
} vmovbrc_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmovbrc_inst));
- vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
- inst_cream->t = BITS(inst, 12, 15);
- /* VFP variant of instruction */
- inst_cream->esize = 32;
- inst_cream->index = BIT(inst, 21);
-
- return inst_base;
+ inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
+ inst_cream->t = BITS(inst, 12, 15);
+ /* VFP variant of instruction */
+ inst_cream->esize = 32;
+ inst_cream->index = BIT(inst, 21);
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMOVBRC_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
-
- VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmovbrc_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ vmovbrc_inst *inst_cream = (vmovbrc_inst *)inst_base->component;
+
+ VFP_DEBUG_UNIMPLEMENTED(VMOVBRC);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vmovbrc_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2425,17 +2404,17 @@ DYNCOM_FILL_ACTION(vmovbrc),
#ifdef VFP_DYNCOM_TAG
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__);
- arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arch_arm_undef(cpu, bb, instr);
+ return No_exp;
}
#endif
@@ -2445,88 +2424,88 @@ int DYNCOM_TRANS(vmovbrc)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MRC */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmrs_inst {
- unsigned int reg;
- unsigned int Rt;
+ unsigned int reg;
+ unsigned int Rt;
} vmrs_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmrs_inst));
- vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->reg = BITS(inst, 16, 19);
- inst_cream->Rt = BITS(inst, 12, 15);
+ inst_cream->reg = BITS(inst, 16, 19);
+ inst_cream->Rt = BITS(inst, 12, 15);
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMRS_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled,
- and in privilegied mode */
- /* Exceptions must be checked, according to v7 ref manual */
- CHECK_VFP_ENABLED;
-
- vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
-
- DBG("VMRS :");
-
- if (inst_cream->reg == 1) /* FPSCR */
- {
- if (inst_cream->Rt != 15)
- {
- cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSCR)];
- DBG("\tr%d <= fpscr[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
- }
- else
- {
- cpu->NFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 31) & 1;
- cpu->ZFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 30) & 1;
- cpu->CFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 29) & 1;
- cpu->VFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 28) & 1;
- DBG("\tflags <= fpscr[%1xxxxxxxx]\n", cpu->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
- }
- }
- else
- {
- switch (inst_cream->reg)
- {
- case 0:
- cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSID)];
- DBG("\tr%d <= fpsid[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSID)]);
- break;
- case 6:
- /* MVFR1, VFPv3 only ? */
- DBG("\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt);
- break;
- case 7:
- /* MVFR0, VFPv3 only? */
- DBG("\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt);
- break;
- case 8:
- cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPEXC)];
- DBG("\tr%d <= fpexc[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPEXC)]);
- break;
- default:
- DBG("\tSUBARCHITECTURE DEFINED\n");
- break;
- }
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmrs_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ /* FIXME: special case for access to FPSID and FPEXC, VFP must be disabled,
+ and in privilegied mode */
+ /* Exceptions must be checked, according to v7 ref manual */
+ CHECK_VFP_ENABLED;
+
+ vmrs_inst *inst_cream = (vmrs_inst *)inst_base->component;
+
+ DBG("VMRS :");
+
+ if (inst_cream->reg == 1) /* FPSCR */
+ {
+ if (inst_cream->Rt != 15)
+ {
+ cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSCR)];
+ DBG("\tr%d <= fpscr[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSCR)]);
+ }
+ else
+ {
+ cpu->NFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 31) & 1;
+ cpu->ZFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 30) & 1;
+ cpu->CFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 29) & 1;
+ cpu->VFlag = (cpu->VFP[VFP_OFFSET(VFP_FPSCR)] >> 28) & 1;
+ DBG("\tflags <= fpscr[%1xxxxxxxx]\n", cpu->VFP[VFP_OFFSET(VFP_FPSCR)]>>28);
+ }
+ }
+ else
+ {
+ switch (inst_cream->reg)
+ {
+ case 0:
+ cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPSID)];
+ DBG("\tr%d <= fpsid[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPSID)]);
+ break;
+ case 6:
+ /* MVFR1, VFPv3 only ? */
+ DBG("\tr%d <= MVFR1 unimplemented\n", inst_cream->Rt);
+ break;
+ case 7:
+ /* MVFR0, VFPv3 only? */
+ DBG("\tr%d <= MVFR0 unimplemented\n", inst_cream->Rt);
+ break;
+ case 8:
+ cpu->Reg[inst_cream->Rt] = cpu->VFP[VFP_OFFSET(VFP_FPEXC)];
+ DBG("\tr%d <= fpexc[%08x]\n", inst_cream->Rt, cpu->VFP[VFP_OFFSET(VFP_FPEXC)]);
+ break;
+ default:
+ DBG("\tSUBARCHITECTURE DEFINED\n");
+ break;
+ }
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vmrs_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2536,64 +2515,64 @@ DYNCOM_FILL_ACTION(vmrs),
#ifdef VFP_DYNCOM_TAG
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__);
- DBG("\t\tin %s .\n", __FUNCTION__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ DBG("\t\tin %s .\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
-
- Value *data = NULL;
- int reg = BITS(16, 19);;
- int Rt = BITS(12, 15);
- DBG("VMRS : reg=%d, Rt=%d\n", reg, Rt);
- if (reg == 1)
- {
- if (Rt != 15)
- {
- LET(Rt, R(VFP_FPSCR));
- DBG("\tr%d <= fpscr\n", Rt);
- }
- else
- {
- //LET(Rt, R(VFP_FPSCR));
- update_cond_from_fpscr(cpu, instr, bb, pc);
- DBG("In %s, \tflags <= fpscr\n", __FUNCTION__);
- }
- }
- else
- {
- switch (reg)
- {
- case 0:
- LET(Rt, R(VFP_FPSID));
- DBG("\tr%d <= fpsid\n", Rt);
- 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:
- LET(Rt, R(VFP_FPEXC));
- DBG("\tr%d <= fpexc\n", Rt);
- break;
- default:
- DBG("\tSUBARCHITECTURE DEFINED\n");
- break;
- }
- }
-
- return No_exp;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+
+ Value *data = NULL;
+ int reg = BITS(16, 19);;
+ int Rt = BITS(12, 15);
+ DBG("VMRS : reg=%d, Rt=%d\n", reg, Rt);
+ if (reg == 1)
+ {
+ if (Rt != 15)
+ {
+ LET(Rt, R(VFP_FPSCR));
+ DBG("\tr%d <= fpscr\n", Rt);
+ }
+ else
+ {
+ //LET(Rt, R(VFP_FPSCR));
+ update_cond_from_fpscr(cpu, instr, bb, pc);
+ DBG("In %s, \tflags <= fpscr\n", __FUNCTION__);
+ }
+ }
+ else
+ {
+ switch (reg)
+ {
+ case 0:
+ LET(Rt, R(VFP_FPSID));
+ DBG("\tr%d <= fpsid\n", Rt);
+ 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:
+ LET(Rt, R(VFP_FPEXC));
+ DBG("\tr%d <= fpexc\n", Rt);
+ break;
+ default:
+ DBG("\tSUBARCHITECTURE DEFINED\n");
+ break;
+ }
+ }
+
+ return No_exp;
}
#endif
@@ -2603,48 +2582,48 @@ int DYNCOM_TRANS(vmrs)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1110 op11 CRn- Rt-- copr op21 CRm- MCR */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbcr_inst {
- unsigned int esize;
- unsigned int index;
- unsigned int d;
- unsigned int t;
+ unsigned int esize;
+ unsigned int index;
+ unsigned int d;
+ unsigned int t;
} vmovbcr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmovbcr_inst));
- vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
+ inst_cream->t = BITS(inst, 12, 15);
+ /* VFP variant of instruction */
+ inst_cream->esize = 32;
+ inst_cream->index = BIT(inst, 21);
- inst_cream->d = BITS(inst, 16, 19)|BIT(inst, 7)<<4;
- inst_cream->t = BITS(inst, 12, 15);
- /* VFP variant of instruction */
- inst_cream->esize = 32;
- inst_cream->index = BIT(inst, 21);
-
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMOVBCR_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
-
- VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vmovbcr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ vmovbcr_inst *inst_cream = (vmovbcr_inst *)inst_base->component;
+
+ VFP_DEBUG_UNIMPLEMENTED(VMOVBCR);
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vmovbcr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2654,17 +2633,17 @@ DYNCOM_FILL_ACTION(vmovbcr),
#ifdef VFP_DYNCOM_TAG
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__);
- arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
+ DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arch_arm_undef(cpu, bb, instr);
+ return No_exp;
}
#endif
@@ -2679,48 +2658,48 @@ int DYNCOM_TRANS(vmovbcr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbrrss_inst {
- unsigned int to_arm;
- unsigned int t;
- unsigned int t2;
- unsigned int m;
+ unsigned int to_arm;
+ unsigned int t;
+ unsigned int t2;
+ unsigned int m;
} vmovbrrss_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmovbrrss_inst));
- vmovbrrss_inst *inst_cream = (vmovbrrss_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->to_arm = BIT(inst, 20) == 1;
- inst_cream->t = BITS(inst, 12, 15);
- inst_cream->t2 = BITS(inst, 16, 19);
- inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5);
+ inst_cream->to_arm = BIT(inst, 20) == 1;
+ inst_cream->t = BITS(inst, 12, 15);
+ inst_cream->t2 = BITS(inst, 16, 19);
+ inst_cream->m = BITS(inst, 0, 3)<<1|BIT(inst, 5);
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMOVBRRSS_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
- vmovbrrss_inst* const inst_cream = (vmovbrrss_inst*)inst_base->component;
+ vmovbrrss_inst* const inst_cream = (vmovbrrss_inst*)inst_base->component;
- VMOVBRRSS(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(vmovbrrss_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ VMOVBRRSS(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(vmovbrrss_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
#ifdef VFP_DYNCOM_TABLE
@@ -2729,31 +2708,31 @@ DYNCOM_FILL_ACTION(vmovbrrss),
#ifdef VFP_DYNCOM_TAG
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;
+ int instr_size = INSTR_SIZE;
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- if (instr >> 28 != 0xE)
- *tag |= TAG_CONDITIONAL;
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ if (instr >> 28 != 0xE)
+ *tag |= TAG_CONDITIONAL;
- return instr_size;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc)
{
- int to_arm = BIT(20) == 1;
- int t = BITS(12, 15);
- int t2 = BITS(16, 19);
- int n = BIT(5)<<4 | BITS(0, 3);
- if (to_arm) {
- LET(t, IBITCAST32(FR32(n + 0)));
- LET(t2, IBITCAST32(FR32(n + 1)));
- }
- else {
- LETFPS(n + 0, FPBITCAST32(R(t)));
- LETFPS(n + 1, FPBITCAST32(R(t2)));
- }
- return No_exp;
+ int to_arm = BIT(20) == 1;
+ int t = BITS(12, 15);
+ int t2 = BITS(16, 19);
+ int n = BIT(5)<<4 | BITS(0, 3);
+ if (to_arm) {
+ LET(t, IBITCAST32(FR32(n + 0)));
+ LET(t2, IBITCAST32(FR32(n + 1)));
+ }
+ else {
+ LETFPS(n + 0, FPBITCAST32(R(t)));
+ LETFPS(n + 1, FPBITCAST32(R(t2)));
+ }
+ return No_exp;
}
#endif
@@ -2763,48 +2742,48 @@ int DYNCOM_TRANS(vmovbrrss)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t p
/* cond 1100 0101 Rt2- Rt-- copr opc1 CRm- MRRC */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vmovbrrd_inst {
- unsigned int to_arm;
- unsigned int t;
- unsigned int t2;
- unsigned int m;
+ unsigned int to_arm;
+ unsigned int t;
+ unsigned int t2;
+ unsigned int m;
} vmovbrrd_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vmovbrrd_inst));
- vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vmovbrrd_inst));
+ vmovbrrd_inst *inst_cream = (vmovbrrd_inst *)inst_base->component;
- inst_cream->to_arm = BIT(inst, 20) == 1;
- inst_cream->t = BITS(inst, 12, 15);
- inst_cream->t2 = BITS(inst, 16, 19);
- inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3);
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- return inst_base;
+ inst_cream->to_arm = BIT(inst, 20) == 1;
+ inst_cream->t = BITS(inst, 12, 15);
+ inst_cream->t2 = BITS(inst, 16, 19);
+ inst_cream->m = BIT(inst, 5)<<4 | BITS(inst, 0, 3);
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VMOVBRRD_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- 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(vmovbrrd_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ 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(vmovbrrd_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2814,31 +2793,31 @@ DYNCOM_FILL_ACTION(vmovbrrd),
#ifdef VFP_DYNCOM_TAG
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__);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- if(instr >> 28 != 0xe)
- *tag |= TAG_CONDITIONAL;
- return instr_size;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ if(instr >> 28 != 0xe)
+ *tag |= TAG_CONDITIONAL;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int t = BITS(12, 15);
- int t2 = BITS(16, 19);
- int n = BIT(5)<<4 | BITS(0, 3);
- if(to_arm){
- LET(t, IBITCAST32(FR32(n * 2)));
- LET(t2, IBITCAST32(FR32(n * 2 + 1)));
- }
- else{
- LETFPS(n * 2, FPBITCAST32(R(t)));
- LETFPS(n * 2 + 1, FPBITCAST32(R(t2)));
- }
- return No_exp;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ int to_arm = BIT(20) == 1;
+ int t = BITS(12, 15);
+ int t2 = BITS(16, 19);
+ int n = BIT(5)<<4 | BITS(0, 3);
+ if(to_arm){
+ LET(t, IBITCAST32(FR32(n * 2)));
+ LET(t2, IBITCAST32(FR32(n * 2 + 1)));
+ }
+ else{
+ LETFPS(n * 2, FPBITCAST32(R(t)));
+ LETFPS(n * 2 + 1, FPBITCAST32(R(t2)));
+ }
+ return No_exp;
}
#endif
@@ -2852,60 +2831,60 @@ int DYNCOM_TRANS(vmovbrrd)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc
/* cond 1101 UD00 Rn-- Vd-- 101X imm8 imm8 */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vstr_inst {
- unsigned int single;
- unsigned int n;
- unsigned int d;
- unsigned int imm32;
- unsigned int add;
+ unsigned int single;
+ unsigned int n;
+ unsigned int d;
+ unsigned int imm32;
+ unsigned int add;
} vstr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vstr_inst));
- vstr_inst *inst_cream = (vstr_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->single = BIT(inst, 8) == 0;
- inst_cream->add = BIT(inst, 23);
- inst_cream->imm32 = BITS(inst, 0,7) << 2;
- inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
- inst_cream->n = BITS(inst, 16, 19);
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- return inst_base;
+ inst_cream->single = BIT(inst, 8) == 0;
+ inst_cream->add = BIT(inst, 23);
+ inst_cream->imm32 = BITS(inst, 0,7) << 2;
+ inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
+ inst_cream->n = BITS(inst, 16, 19);
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VSTR_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- 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);
-
- if (inst_cream->single)
- {
- Memory::Write32(addr, cpu->ExtReg[inst_cream->d]);
- }
- else
- {
- Memory::Write32(addr, cpu->ExtReg[inst_cream->d*2]);
- Memory::Write32(addr + 4, cpu->ExtReg[inst_cream->d*2+1]);
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vstr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ 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);
+
+ if (inst_cream->single)
+ {
+ Memory::Write32(addr, cpu->ExtReg[inst_cream->d]);
+ }
+ else
+ {
+ Memory::Write32(addr, cpu->ExtReg[inst_cream->d*2]);
+ Memory::Write32(addr + 4, cpu->ExtReg[inst_cream->d*2+1]);
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vstr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -2915,61 +2894,46 @@ DYNCOM_FILL_ACTION(vstr),
#ifdef VFP_DYNCOM_TAG
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);
- DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
- *tag |= TAG_NEW_BB;
- if(instr >> 28 != 0xe)
- *tag |= TAG_CONDITIONAL;
+ int instr_size = INSTR_SIZE;
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
+ *tag |= TAG_NEW_BB;
+ if(instr >> 28 != 0xe)
+ *tag |= TAG_CONDITIONAL;
- return instr_size;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
- int n = BITS(16, 19);
-
- Value* base = (n == 15) ? ADD(AND(R(n), CONST(0xFFFFFFFC)), CONST(8)): R(n);
- Value* Addr = add ? ADD(base, CONST(imm32)) : SUB(base, CONST(imm32));
- DBG("VSTR :\n");
- //if(single)
- // bb = arch_check_mm(cpu, bb, Addr, 4, 0, cpu->dyncom_engine->bb_trap);
- //else
- // bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap);
- //Value* phys_addr;
- if(single){
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR(d), 32);
- #endif
- //memory_write(cpu, bb, Addr, RSPR(d), 32);
- memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32);
- bb = cpu->dyncom_engine->bb;
- }
- else{
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2), 32);
- #endif
- //memory_write(cpu, bb, Addr, RSPR(d * 2), 32);
- memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32);
- bb = cpu->dyncom_engine->bb;
- #if 0
- phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR(d * 2 + 1), 32);
- #endif
- //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32);
- memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32);
- bb = cpu->dyncom_engine->bb;
- }
- return No_exp;
+ int single = BIT(8) == 0;
+ int add = BIT(23);
+ int imm32 = BITS(0,7) << 2;
+ int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
+ int n = BITS(16, 19);
+
+ Value* base = (n == 15) ? ADD(AND(R(n), CONST(0xFFFFFFFC)), CONST(8)): R(n);
+ Value* Addr = add ? ADD(base, CONST(imm32)) : SUB(base, CONST(imm32));
+ DBG("VSTR :\n");
+ //if(single)
+ // bb = arch_check_mm(cpu, bb, Addr, 4, 0, cpu->dyncom_engine->bb_trap);
+ //else
+ // bb = arch_check_mm(cpu, bb, Addr, 8, 0, cpu->dyncom_engine->bb_trap);
+ //Value* phys_addr;
+ if(single){
+ //memory_write(cpu, bb, Addr, RSPR(d), 32);
+ memory_write(cpu, bb, Addr, IBITCAST32(FR32(d)), 32);
+ bb = cpu->dyncom_engine->bb;
+ }
+ else{
+ //memory_write(cpu, bb, Addr, RSPR(d * 2), 32);
+ memory_write(cpu, bb, Addr, IBITCAST32(FR32(d * 2)), 32);
+ bb = cpu->dyncom_engine->bb;
+ //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR(d * 2 + 1), 32);
+ memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32(d * 2 + 1)), 32);
+ bb = cpu->dyncom_engine->bb;
+ }
+ return No_exp;
}
#endif
@@ -2978,64 +2942,64 @@ int DYNCOM_TRANS(vstr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1101 0D10 1101 Vd-- 101X imm8 imm8 */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vpush_inst {
- unsigned int single;
- unsigned int d;
- unsigned int imm32;
- unsigned int regs;
+ unsigned int single;
+ unsigned int d;
+ unsigned int imm32;
+ unsigned int regs;
} vpush_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vpush_inst));
- vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(vpush_inst));
+ vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
- inst_cream->single = BIT(inst, 8) == 0;
- inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
- inst_cream->imm32 = BITS(inst, 0, 7)<<2;
- inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- return inst_base;
+ inst_cream->single = BIT(inst, 8) == 0;
+ inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
+ inst_cream->imm32 = BITS(inst, 0, 7)<<2;
+ inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VPUSH_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
- int i;
-
- vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
-
- addr = cpu->Reg[R13] - inst_cream->imm32;
-
- for (i = 0; i < inst_cream->regs; i++)
- {
- if (inst_cream->single)
- {
- Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
- addr += 4;
- }
- else
- {
- Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
- Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
- addr += 8;
- }
- }
- cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vpush_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+ int i;
+
+ vpush_inst *inst_cream = (vpush_inst *)inst_base->component;
+
+ addr = cpu->Reg[R13] - inst_cream->imm32;
+
+ for (i = 0; i < inst_cream->regs; i++)
+ {
+ if (inst_cream->single)
+ {
+ Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
+ addr += 4;
+ }
+ else
+ {
+ Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
+ Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
+ addr += 8;
+ }
+ }
+ cpu->Reg[R13] = cpu->Reg[R13] - inst_cream->imm32;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vpush_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
#ifdef VFP_DYNCOM_TABLE
@@ -3044,72 +3008,57 @@ DYNCOM_FILL_ACTION(vpush),
#ifdef VFP_DYNCOM_TAG
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);
- DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
- *tag |= TAG_NEW_BB;
- if(instr >> 28 != 0xe)
- *tag |= TAG_CONDITIONAL;
+ int instr_size = INSTR_SIZE;
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
+ *tag |= TAG_NEW_BB;
+ if(instr >> 28 != 0xe)
+ *tag |= TAG_CONDITIONAL;
- return instr_size;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int regs = (single ? BITS(0, 7) : BITS(1, 7));
-
- DBG("\t\tin %s \n", __FUNCTION__);
- Value* Addr = SUB(R(13), CONST(imm32));
- //if(single)
- // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap);
- //else
- // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap);
- //Value* phys_addr;
- int i;
- for (i = 0; i < regs; i++)
- {
- if (single)
- {
- //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32);
- #endif
- //memory_write(cpu, bb, Addr, RSPR(d + i), 32);
- memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32);
- bb = cpu->dyncom_engine->bb;
- Addr = ADD(Addr, CONST(4));
- }
- else
- {
- /* Careful of endianness, little by default */
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32);
- #endif
- //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
- memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32);
- bb = cpu->dyncom_engine->bb;
- #if 0
- phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32);
- #endif
- //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
- memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
- bb = cpu->dyncom_engine->bb;
-
- Addr = ADD(Addr, CONST(8));
- }
- }
- LET(13, SUB(R(13), CONST(imm32)));
-
- return No_exp;
+ 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;
+ int regs = (single ? BITS(0, 7) : BITS(1, 7));
+
+ DBG("\t\tin %s \n", __FUNCTION__);
+ Value* Addr = SUB(R(13), CONST(imm32));
+ //if(single)
+ // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap);
+ //else
+ // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap);
+ //Value* phys_addr;
+ int i;
+ for (i = 0; i < regs; i++)
+ {
+ if (single)
+ {
+ //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
+ //memory_write(cpu, bb, Addr, RSPR(d + i), 32);
+ memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)), 32);
+ bb = cpu->dyncom_engine->bb;
+ Addr = ADD(Addr, CONST(4));
+ }
+ else
+ {
+ /* Careful of endianness, little by default */
+ //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
+ memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)), 32);
+ bb = cpu->dyncom_engine->bb;
+ //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
+ memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
+ bb = cpu->dyncom_engine->bb;
+
+ Addr = ADD(Addr, CONST(8));
+ }
+ }
+ LET(13, SUB(R(13), CONST(imm32)));
+
+ return No_exp;
}
#endif
@@ -3118,76 +3067,76 @@ int DYNCOM_TRANS(vpush)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 110P UDW0 Rn-- Vd-- 101X imm8 imm8 */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vstm_inst {
- unsigned int single;
- unsigned int add;
- unsigned int wback;
- unsigned int d;
- unsigned int n;
- unsigned int imm32;
- unsigned int regs;
+ unsigned int single;
+ unsigned int add;
+ unsigned int wback;
+ unsigned int d;
+ unsigned int n;
+ unsigned int imm32;
+ unsigned int regs;
} vstm_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vstm_inst));
- vstm_inst *inst_cream = (vstm_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->single = BIT(inst, 8) == 0;
- inst_cream->add = BIT(inst, 23);
- inst_cream->wback = BIT(inst, 21);
- inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
- inst_cream->n = BITS(inst, 16, 19);
- inst_cream->imm32 = BITS(inst, 0, 7)<<2;
- inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
+ inst_cream->single = BIT(inst, 8) == 0;
+ inst_cream->add = BIT(inst, 23);
+ inst_cream->wback = BIT(inst, 21);
+ inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
+ inst_cream->n = BITS(inst, 16, 19);
+ inst_cream->imm32 = BITS(inst, 0, 7)<<2;
+ inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VSTM_INST: /* encoding 1 */
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- int i;
-
- 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);
-
- for (i = 0; i < inst_cream->regs; i++)
- {
- if (inst_cream->single)
- {
- Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
- addr += 4;
- }
- else
- {
- Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
- Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
- addr += 8;
- }
- }
- if (inst_cream->wback){
- cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
- cpu->Reg[inst_cream->n] - inst_cream->imm32);
- }
-
- }
- cpu->Reg[15] += 4;
- INC_PC(sizeof(vstm_inst));
-
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ int i;
+
+ 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);
+
+ for (i = 0; i < inst_cream->regs; i++)
+ {
+ if (inst_cream->single)
+ {
+ Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
+ addr += 4;
+ }
+ else
+ {
+ Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
+ Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
+ addr += 8;
+ }
+ }
+ if (inst_cream->wback){
+ cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
+ cpu->Reg[inst_cream->n] - inst_cream->imm32);
+ }
+
+ }
+ cpu->Reg[15] += 4;
+ INC_PC(sizeof(vstm_inst));
+
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -3197,90 +3146,75 @@ DYNCOM_FILL_ACTION(vstm),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
- *tag |= TAG_NEW_BB;
- if(instr >> 28 != 0xe)
- *tag |= TAG_CONDITIONAL;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
+ *tag |= TAG_NEW_BB;
+ if(instr >> 28 != 0xe)
+ *tag |= TAG_CONDITIONAL;
- return instr_size;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int wback = BIT(21);
- int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4);
- int n = BITS(16, 19);
- int imm32 = BITS(0, 7)<<2;
- int regs = single ? BITS(0, 7) : BITS(1, 7);
-
- Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32)));
- DBG("VSTM \n");
- //if(single)
- // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap);
- //else
- // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap);
-
- int i;
- Value* phys_addr;
- for (i = 0; i < regs; i++)
- {
- if (single)
- {
-
- //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
- /* if R(i) is R15? */
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR(d + i), 32);
- #endif
- //memory_write(cpu, bb, Addr, RSPR(d + i), 32);
- memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32);
- bb = cpu->dyncom_engine->bb;
- //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
- Addr = ADD(Addr, CONST(4));
- }
- else
- {
-
- //Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2), 32);
- #endif
- //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
- memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32);
- bb = cpu->dyncom_engine->bb;
-
- //Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
- #if 0
- phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 0);
- bb = cpu->dyncom_engine->bb;
- arch_write_memory(cpu, bb, phys_addr, RSPR((d + i) * 2 + 1), 32);
- #endif
- //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
- memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
- bb = cpu->dyncom_engine->bb;
- //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
- //addr += 8;
- Addr = ADD(Addr, CONST(8));
- }
- }
- if (wback){
- //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
- // cpu->Reg[n] - imm32);
- LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
- DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
- }
- return No_exp;
+ //arch_arm_undef(cpu, bb, instr);
+ int single = BIT(8) == 0;
+ int add = BIT(23);
+ int wback = BIT(21);
+ int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4);
+ int n = BITS(16, 19);
+ int imm32 = BITS(0, 7)<<2;
+ int regs = single ? BITS(0, 7) : BITS(1, 7);
+
+ Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32)));
+ DBG("VSTM \n");
+ //if(single)
+ // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 0, cpu->dyncom_engine->bb_trap);
+ //else
+ // bb = arch_check_mm(cpu, bb, Addr, regs * 8, 0, cpu->dyncom_engine->bb_trap);
+
+ int i;
+ Value* phys_addr;
+ for (i = 0; i < regs; i++)
+ {
+ if (single)
+ {
+
+ //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
+ /* if R(i) is R15? */
+ //memory_write(cpu, bb, Addr, RSPR(d + i), 32);
+ memory_write(cpu, bb, Addr, IBITCAST32(FR32(d + i)),32);
+ bb = cpu->dyncom_engine->bb;
+ //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
+ Addr = ADD(Addr, CONST(4));
+ }
+ else
+ {
+
+ //Memory::Write32(addr, cpu->ExtReg[(inst_cream->d+i)*2]);
+ //memory_write(cpu, bb, Addr, RSPR((d + i) * 2), 32);
+ memory_write(cpu, bb, Addr, IBITCAST32(FR32((d + i) * 2)),32);
+ bb = cpu->dyncom_engine->bb;
+
+ //Memory::Write32(addr + 4, cpu->ExtReg[(inst_cream->d+i)*2 + 1]);
+ //memory_write(cpu, bb, ADD(Addr, CONST(4)), RSPR((d + i) * 2 + 1), 32);
+ memory_write(cpu, bb, ADD(Addr, CONST(4)), IBITCAST32(FR32((d + i) * 2 + 1)), 32);
+ bb = cpu->dyncom_engine->bb;
+ //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
+ //addr += 8;
+ Addr = ADD(Addr, CONST(8));
+ }
+ }
+ if (wback){
+ //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
+ // cpu->Reg[n] - imm32);
+ LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
+ DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
+ }
+ return No_exp;
}
#endif
@@ -3289,69 +3223,69 @@ int DYNCOM_TRANS(vstm)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1100 1D11 1101 Vd-- 101X imm8 imm8 */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vpop_inst {
- unsigned int single;
- unsigned int d;
- unsigned int imm32;
- unsigned int regs;
+ unsigned int single;
+ unsigned int d;
+ unsigned int imm32;
+ unsigned int regs;
} vpop_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vpop_inst));
- vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->single = BIT(inst, 8) == 0;
- inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4));
- inst_cream->imm32 = BITS(inst, 0, 7)<<2;
- inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
-
- return inst_base;
+ inst_cream->single = BIT(inst, 8) == 0;
+ inst_cream->d = (inst_cream->single ? (BITS(inst, 12, 15)<<1)|BIT(inst, 22) : BITS(inst, 12, 15)|(BIT(inst, 22)<<4));
+ inst_cream->imm32 = BITS(inst, 0, 7)<<2;
+ inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VPOP_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- int i;
- unsigned int value1, value2;
-
- vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
-
- addr = cpu->Reg[R13];
-
- for (i = 0; i < inst_cream->regs; i++)
- {
- if (inst_cream->single)
- {
- value1 = Memory::Read32(addr);
- cpu->ExtReg[inst_cream->d+i] = value1;
- addr += 4;
- }
- else
- {
- value1 = Memory::Read32(addr);
- value2 = Memory::Read32(addr + 4);
- cpu->ExtReg[(inst_cream->d+i)*2] = value1;
- cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2;
- addr += 8;
- }
- }
- cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32;
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vpop_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ int i;
+ unsigned int value1, value2;
+
+ vpop_inst *inst_cream = (vpop_inst *)inst_base->component;
+
+ addr = cpu->Reg[R13];
+
+ for (i = 0; i < inst_cream->regs; i++)
+ {
+ if (inst_cream->single)
+ {
+ value1 = Memory::Read32(addr);
+ cpu->ExtReg[inst_cream->d+i] = value1;
+ addr += 4;
+ }
+ else
+ {
+ value1 = Memory::Read32(addr);
+ value2 = Memory::Read32(addr + 4);
+ cpu->ExtReg[(inst_cream->d+i)*2] = value1;
+ cpu->ExtReg[(inst_cream->d+i)*2 + 1] = value2;
+ addr += 8;
+ }
+ }
+ cpu->Reg[R13] = cpu->Reg[R13] + inst_cream->imm32;
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vpop_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -3361,82 +3295,67 @@ DYNCOM_FILL_ACTION(vpop),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- /* Should check if PC is destination register */
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
- *tag |= TAG_NEW_BB;
- if(instr >> 28 != 0xe)
- *tag |= TAG_CONDITIONAL;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ /* Should check if PC is destination register */
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
+ *tag |= TAG_NEW_BB;
+ if(instr >> 28 != 0xe)
+ *tag |= TAG_CONDITIONAL;
- return instr_size;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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;
- int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
- int imm32 = BITS(0, 7)<<2;
- int regs = (single ? BITS(0, 7) : BITS(1, 7));
-
- int i;
- unsigned int value1, value2;
-
- DBG("VPOP :\n");
-
- Value* Addr = R(13);
- Value* val;
- //if(single)
- // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
- //else
- // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
- //Value* phys_addr;
- for (i = 0; i < regs; i++)
- {
- if (single)
- {
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, Addr, 0, 32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- LETFPS(d + i, FPBITCAST32(val));
- Addr = ADD(Addr, CONST(4));
- }
- else
- {
- /* Careful of endianness, little by default */
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, Addr, 0, 32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- LETFPS((d + i) * 2, FPBITCAST32(val));
- #if 0
- phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
-
- Addr = ADD(Addr, CONST(8));
- }
- }
- LET(13, ADD(R(13), CONST(imm32)));
- return No_exp;
+ DBG("\t\tin %s instruction .\n", __FUNCTION__);
+ //arch_arm_undef(cpu, bb, instr);
+ 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;
+ int regs = (single ? BITS(0, 7) : BITS(1, 7));
+
+ int i;
+ unsigned int value1, value2;
+
+ DBG("VPOP :\n");
+
+ Value* Addr = R(13);
+ Value* val;
+ //if(single)
+ // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
+ //else
+ // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
+ //Value* phys_addr;
+ for (i = 0; i < regs; i++)
+ {
+ if (single)
+ {
+ memory_read(cpu, bb, Addr, 0, 32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ LETFPS(d + i, FPBITCAST32(val));
+ Addr = ADD(Addr, CONST(4));
+ }
+ else
+ {
+ /* Careful of endianness, little by default */
+ memory_read(cpu, bb, Addr, 0, 32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ LETFPS((d + i) * 2, FPBITCAST32(val));
+ memory_read(cpu, bb, ADD(Addr, CONST(4)), 0, 32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
+
+ Addr = ADD(Addr, CONST(8));
+ }
+ }
+ LET(13, ADD(R(13), CONST(imm32)));
+ return No_exp;
}
#endif
@@ -3445,64 +3364,64 @@ int DYNCOM_TRANS(vpop)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 1101 UD01 Rn-- Vd-- 101X imm8 imm8 */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vldr_inst {
- unsigned int single;
- unsigned int n;
- unsigned int d;
- unsigned int imm32;
- unsigned int add;
+ unsigned int single;
+ unsigned int n;
+ unsigned int d;
+ unsigned int imm32;
+ unsigned int add;
} vldr_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vldr_inst));
- vldr_inst *inst_cream = (vldr_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
-
- inst_cream->single = BIT(inst, 8) == 0;
- inst_cream->add = BIT(inst, 23);
- inst_cream->imm32 = BITS(inst, 0,7) << 2;
- inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
- inst_cream->n = BITS(inst, 16, 19);
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- return inst_base;
+ inst_cream->single = BIT(inst, 8) == 0;
+ inst_cream->add = BIT(inst, 23);
+ inst_cream->imm32 = BITS(inst, 0,7) << 2;
+ inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
+ inst_cream->n = BITS(inst, 16, 19);
+
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VLDR_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- 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);
-
- if (inst_cream->single)
- {
- cpu->ExtReg[inst_cream->d] = Memory::Read32(addr);
- }
- else
- {
- unsigned int word1, word2;
- word1 = Memory::Read32(addr);
- word2 = Memory::Read32(addr + 4);
-
- cpu->ExtReg[inst_cream->d*2] = word1;
- cpu->ExtReg[inst_cream->d*2+1] = word2;
- }
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vldr_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ 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);
+
+ if (inst_cream->single)
+ {
+ cpu->ExtReg[inst_cream->d] = Memory::Read32(addr);
+ }
+ else
+ {
+ unsigned int word1, word2;
+ word1 = Memory::Read32(addr);
+ word2 = Memory::Read32(addr + 4);
+
+ cpu->ExtReg[inst_cream->d*2] = word1;
+ cpu->ExtReg[inst_cream->d*2+1] = word2;
+ }
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vldr_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -3512,76 +3431,61 @@ DYNCOM_FILL_ACTION(vldr),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- /* Should check if PC is destination register */
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
- *tag |= TAG_NEW_BB;
- if(instr >> 28 != 0xe)
- *tag |= TAG_CONDITIONAL;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ /* Should check if PC is destination register */
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
+ *tag |= TAG_NEW_BB;
+ if(instr >> 28 != 0xe)
+ *tag |= TAG_CONDITIONAL;
- return instr_size;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
- int n = BITS(16, 19);
- int imm32 = BITS(0, 7)<<2;
- int regs = (single ? BITS(0, 7) : BITS(1, 7));
- Value* base = R(n);
- DBG("\t\tin %s .\n", __FUNCTION__);
- if(n == 15){
- base = ADD(AND(base, CONST(0xFFFFFFFC)), CONST(8));
- }
- Value* Addr = add ? (ADD(base, CONST(imm32))) : (SUB(base, CONST(imm32)));
- //if(single)
- // bb = arch_check_mm(cpu, bb, Addr, 4, 1, cpu->dyncom_engine->bb_trap);
- //else
- // bb = arch_check_mm(cpu, bb, Addr, 8, 1, cpu->dyncom_engine->bb_trap);
- //Value* phys_addr;
- Value* val;
- if(single){
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, Addr, 0, 32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- //LETS(d, val);
- LETFPS(d,FPBITCAST32(val));
- }
- else{
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, Addr, 0, 32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- //LETS(d * 2, val);
- LETFPS(d * 2,FPBITCAST32(val));
- #if 0
- phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- //LETS(d * 2 + 1, val);
- LETFPS( d * 2 + 1,FPBITCAST32(val));
- }
-
- return No_exp;
+ int single = BIT(8) == 0;
+ int add = BIT(23);
+ int wback = BIT(21);
+ int d = (single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|(BIT(22)<<4));
+ int n = BITS(16, 19);
+ int imm32 = BITS(0, 7)<<2;
+ int regs = (single ? BITS(0, 7) : BITS(1, 7));
+ Value* base = R(n);
+ DBG("\t\tin %s .\n", __FUNCTION__);
+ if(n == 15){
+ base = ADD(AND(base, CONST(0xFFFFFFFC)), CONST(8));
+ }
+ Value* Addr = add ? (ADD(base, CONST(imm32))) : (SUB(base, CONST(imm32)));
+ //if(single)
+ // bb = arch_check_mm(cpu, bb, Addr, 4, 1, cpu->dyncom_engine->bb_trap);
+ //else
+ // bb = arch_check_mm(cpu, bb, Addr, 8, 1, cpu->dyncom_engine->bb_trap);
+ //Value* phys_addr;
+ Value* val;
+ if(single){
+ memory_read(cpu, bb, Addr, 0, 32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ //LETS(d, val);
+ LETFPS(d,FPBITCAST32(val));
+ }
+ else{
+ memory_read(cpu, bb, Addr, 0, 32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ //LETS(d * 2, val);
+ LETFPS(d * 2,FPBITCAST32(val));
+ memory_read(cpu, bb, ADD(Addr, CONST(4)), 0,32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ //LETS(d * 2 + 1, val);
+ LETFPS( d * 2 + 1,FPBITCAST32(val));
+ }
+
+ return No_exp;
}
#endif
@@ -3590,76 +3494,76 @@ int DYNCOM_TRANS(vldr)(cpu_t *cpu, uint32_t instr, BasicBlock *bb, addr_t pc){
/* cond 110P UDW1 Rn-- Vd-- 101X imm8 imm8 */
#ifdef VFP_INTERPRETER_STRUCT
typedef struct _vldm_inst {
- unsigned int single;
- unsigned int add;
- unsigned int wback;
- unsigned int d;
- unsigned int n;
- unsigned int imm32;
- unsigned int regs;
+ unsigned int single;
+ unsigned int add;
+ unsigned int wback;
+ unsigned int d;
+ unsigned int n;
+ unsigned int imm32;
+ unsigned int regs;
} vldm_inst;
#endif
#ifdef VFP_INTERPRETER_TRANS
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(vldm_inst));
- vldm_inst *inst_cream = (vldm_inst *)inst_base->component;
+ VFP_DEBUG_TRANSLATE;
+
+ 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;
- inst_base->br = NON_BRANCH;
- inst_base->load_r15 = 0;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
- inst_cream->single = BIT(inst, 8) == 0;
- inst_cream->add = BIT(inst, 23);
- inst_cream->wback = BIT(inst, 21);
- inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
- inst_cream->n = BITS(inst, 16, 19);
- inst_cream->imm32 = BITS(inst, 0, 7)<<2;
- inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
+ inst_cream->single = BIT(inst, 8) == 0;
+ inst_cream->add = BIT(inst, 23);
+ inst_cream->wback = BIT(inst, 21);
+ inst_cream->d = (inst_cream->single ? BITS(inst, 12, 15)<<1|BIT(inst, 22) : BITS(inst, 12, 15)|BIT(inst, 22)<<4);
+ inst_cream->n = BITS(inst, 16, 19);
+ inst_cream->imm32 = BITS(inst, 0, 7)<<2;
+ inst_cream->regs = (inst_cream->single ? BITS(inst, 0, 7) : BITS(inst, 1, 7));
- return inst_base;
+ return inst_base;
}
#endif
#ifdef VFP_INTERPRETER_IMPL
VLDM_INST:
{
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
- CHECK_VFP_ENABLED;
-
- int i;
-
- 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);
-
- for (i = 0; i < inst_cream->regs; i++)
- {
- if (inst_cream->single)
- {
- cpu->ExtReg[inst_cream->d+i] = Memory::Read32(addr);
- addr += 4;
- }
- else
- {
- cpu->ExtReg[(inst_cream->d+i)*2] = Memory::Read32(addr);
- cpu->ExtReg[(inst_cream->d+i)*2 + 1] = Memory::Read32(addr + 4);
- addr += 8;
- }
- }
- if (inst_cream->wback){
- cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
- cpu->Reg[inst_cream->n] - inst_cream->imm32);
- DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]);
- }
-
- }
- cpu->Reg[15] += GET_INST_SIZE(cpu);
- INC_PC(sizeof(vldm_inst));
- FETCH_INST;
- GOTO_NEXT_INST;
+ if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ CHECK_VFP_ENABLED;
+
+ int i;
+
+ 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);
+
+ for (i = 0; i < inst_cream->regs; i++)
+ {
+ if (inst_cream->single)
+ {
+ cpu->ExtReg[inst_cream->d+i] = Memory::Read32(addr);
+ addr += 4;
+ }
+ else
+ {
+ cpu->ExtReg[(inst_cream->d+i)*2] = Memory::Read32(addr);
+ cpu->ExtReg[(inst_cream->d+i)*2 + 1] = Memory::Read32(addr + 4);
+ addr += 8;
+ }
+ }
+ if (inst_cream->wback){
+ cpu->Reg[inst_cream->n] = (inst_cream->add ? cpu->Reg[inst_cream->n] + inst_cream->imm32 :
+ cpu->Reg[inst_cream->n] - inst_cream->imm32);
+ DBG("\twback r%d[%x]\n", inst_cream->n, cpu->Reg[inst_cream->n]);
+ }
+
+ }
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(vldm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
}
#endif
@@ -3669,91 +3573,76 @@ DYNCOM_FILL_ACTION(vldm),
#ifdef VFP_DYNCOM_TAG
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__);
- //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
- arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
- DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
- *tag |= TAG_NEW_BB;
- if(instr >> 28 != 0xe)
- *tag |= TAG_CONDITIONAL;
+ int instr_size = INSTR_SIZE;
+ //DBG("\t\tin %s instruction is not implemented.\n", __FUNCTION__);
+ //arm_tag_trap(cpu, pc, instr, tag, new_pc, next_pc);
+ arm_tag_continue(cpu, pc, instr, tag, new_pc, next_pc);
+ DBG("In %s, pc=0x%x, next_pc=0x%x\n", __FUNCTION__, pc, *next_pc);
+ *tag |= TAG_NEW_BB;
+ if(instr >> 28 != 0xe)
+ *tag |= TAG_CONDITIONAL;
- return instr_size;
+ return instr_size;
}
#endif
#ifdef VFP_DYNCOM_TRANS
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);
- int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|BIT(22)<<4;
- int n = BITS(16, 19);
- int imm32 = BITS(0, 7)<<2;
- int regs = single ? BITS(0, 7) : BITS(1, 7);
-
- Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32)));
- //if(single)
- // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
- //else
- // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
-
- DBG("VLDM \n");
- int i;
- //Value* phys_addr;
- Value* val;
- for (i = 0; i < regs; i++)
- {
- if (single)
- {
-
- //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
- /* if R(i) is R15? */
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, Addr, 0, 32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- //LETS(d + i, val);
- LETFPS(d + i, FPBITCAST32(val));
- //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
- Addr = ADD(Addr, CONST(4));
- }
- else
- {
- #if 0
- phys_addr = get_phys_addr(cpu, bb, Addr, 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, Addr, 0, 32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- LETFPS((d + i) * 2, FPBITCAST32(val));
- #if 0
- phys_addr = get_phys_addr(cpu, bb, ADD(Addr, CONST(4)), 1);
- bb = cpu->dyncom_engine->bb;
- val = arch_read_memory(cpu,bb,phys_addr,0,32);
- #endif
- memory_read(cpu, bb, Addr, 0, 32);
- bb = cpu->dyncom_engine->bb;
- val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
- LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
-
- //Memory::Write(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
- //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
- //addr += 8;
- Addr = ADD(Addr, CONST(8));
- }
- }
- if (wback){
- //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
- // cpu->Reg[n] - imm32);
- LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
- DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
- }
- return No_exp;
+ int single = BIT(8) == 0;
+ int add = BIT(23);
+ int wback = BIT(21);
+ int d = single ? BITS(12, 15)<<1|BIT(22) : BITS(12, 15)|BIT(22)<<4;
+ int n = BITS(16, 19);
+ int imm32 = BITS(0, 7)<<2;
+ int regs = single ? BITS(0, 7) : BITS(1, 7);
+
+ Value* Addr = SELECT(CONST1(add), R(n), SUB(R(n), CONST(imm32)));
+ //if(single)
+ // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
+ //else
+ // bb = arch_check_mm(cpu, bb, Addr, regs * 4, 1, cpu->dyncom_engine->bb_trap);
+
+ DBG("VLDM \n");
+ int i;
+ //Value* phys_addr;
+ Value* val;
+ for (i = 0; i < regs; i++)
+ {
+ if (single)
+ {
+
+ //Memory::Write32(addr, cpu->ExtReg[inst_cream->d+i]);
+ /* if R(i) is R15? */
+ memory_read(cpu, bb, Addr, 0, 32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ //LETS(d + i, val);
+ LETFPS(d + i, FPBITCAST32(val));
+ //DBG("\taddr[%x] <= s%d=[%x]\n", addr, inst_cream->d+i, cpu->ExtReg[inst_cream->d+i]);
+ Addr = ADD(Addr, CONST(4));
+ }
+ else
+ {
+ memory_read(cpu, bb, Addr, 0, 32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ LETFPS((d + i) * 2, FPBITCAST32(val));
+ memory_read(cpu, bb, Addr, 0, 32);
+ bb = cpu->dyncom_engine->bb;
+ val = new LoadInst(cpu->dyncom_engine->read_value, "", false, bb);
+ LETFPS((d + i) * 2 + 1, FPBITCAST32(val));
+
+ //Memory::Write(addr + 4, phys_addr, cpu->ExtReg[(inst_cream->d+i)*2 + 1], 32);
+ //DBG("\taddr[%x-%x] <= s[%d-%d]=[%x-%x]\n", addr+4, addr, (inst_cream->d+i)*2+1, (inst_cream->d+i)*2, cpu->ExtReg[(inst_cream->d+i)*2+1], cpu->ExtReg[(inst_cream->d+i)*2]);
+ //addr += 8;
+ Addr = ADD(Addr, CONST(8));
+ }
+ }
+ if (wback){
+ //cpu->Reg[n] = (add ? cpu->Reg[n] + imm32 :
+ // cpu->Reg[n] - imm32);
+ LET(n, SELECT(CONST1(add), ADD(R(n), CONST(imm32)), SUB(R(n), CONST(imm32))));
+ DBG("\twback r%d, add=%d, imm32=%d\n", n, add, imm32);
+ }
+ return No_exp;
}
#endif
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 22213d64..8ac4481c 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -53,10 +53,10 @@ int Init() {
g_sys_core = new ARM_Interpreter();
switch (Settings::values.cpu_core) {
- case CPU_FastInterpreter:
+ case CPU_Interpreter:
g_app_core = new ARM_DynCom();
break;
- case CPU_Interpreter:
+ case CPU_OldInterpreter:
default:
g_app_core = new ARM_Interpreter();
break;
diff --git a/src/core/core.h b/src/core/core.h
index 05dbe0ae..ecd58a73 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -13,7 +13,7 @@ namespace Core {
enum CPUCore {
CPU_Interpreter,
- CPU_FastInterpreter
+ CPU_OldInterpreter,
};
extern ARM_Interface* g_app_core; ///< ARM11 application core
diff --git a/src/core/file_sys/archive_backend.h b/src/core/file_sys/archive_backend.h
index 1612c35c..390178f6 100644
--- a/src/core/file_sys/archive_backend.h
+++ b/src/core/file_sys/archive_backend.h
@@ -88,6 +88,7 @@ public:
const std::string DebugStr() const {
switch (GetType()) {
case Invalid:
+ default:
return "[Invalid]";
case Empty:
return "[Empty]";
@@ -117,6 +118,7 @@ public:
return {};
case Invalid:
case Binary:
+ default:
// TODO(yuriks): Add assert
LOG_ERROR(Service_FS, "LowPathType cannot be converted to string!");
return {};
@@ -159,6 +161,7 @@ public:
case Empty:
return {};
case Invalid:
+ default:
// TODO(yuriks): Add assert
LOG_ERROR(Service_FS, "LowPathType cannot be converted to binary!");
return {};
diff --git a/src/core/file_sys/archive_romfs.cpp b/src/core/file_sys/archive_romfs.cpp
index 2fc3831b..a30f73d0 100644
--- a/src/core/file_sys/archive_romfs.cpp
+++ b/src/core/file_sys/archive_romfs.cpp
@@ -5,11 +5,10 @@
#include <memory>
#include "common/common_types.h"
+#include "common/file_util.h"
#include "common/make_unique.h"
#include "core/file_sys/archive_romfs.h"
-#include "core/file_sys/directory_romfs.h"
-#include "core/file_sys/file_romfs.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// FileSys namespace
@@ -23,48 +22,4 @@ Archive_RomFS::Archive_RomFS(const Loader::AppLoader& app_loader) {
}
}
-std::unique_ptr<FileBackend> Archive_RomFS::OpenFile(const Path& path, const Mode mode) const {
- return Common::make_unique<File_RomFS>(this);
-}
-
-bool Archive_RomFS::DeleteFile(const Path& path) const {
- LOG_WARNING(Service_FS, "Attempted to delete a file from ROMFS.");
- return false;
-}
-
-bool Archive_RomFS::RenameFile(const Path& src_path, const Path& dest_path) const {
- LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
- return false;
-}
-
-bool Archive_RomFS::DeleteDirectory(const Path& path) const {
- LOG_WARNING(Service_FS, "Attempted to delete a directory from ROMFS.");
- return false;
-}
-
-ResultCode Archive_RomFS::CreateFile(const Path& path, u32 size) const {
- LOG_WARNING(Service_FS, "Attempted to create a file in ROMFS.");
- // TODO: Verify error code
- return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
-}
-
-bool Archive_RomFS::CreateDirectory(const Path& path) const {
- LOG_WARNING(Service_FS, "Attempted to create a directory in ROMFS.");
- return false;
-}
-
-bool Archive_RomFS::RenameDirectory(const Path& src_path, const Path& dest_path) const {
- LOG_WARNING(Service_FS, "Attempted to rename a file within ROMFS.");
- return false;
-}
-
-std::unique_ptr<DirectoryBackend> Archive_RomFS::OpenDirectory(const Path& path) const {
- return Common::make_unique<Directory_RomFS>();
-}
-
-ResultCode Archive_RomFS::Format(const Path& path) const {
- LOG_WARNING(Service_FS, "Attempted to format ROMFS.");
- return UnimplementedFunction(ErrorModule::FS);
-}
-
} // namespace FileSys
diff --git a/src/core/file_sys/archive_romfs.h b/src/core/file_sys/archive_romfs.h
index d4b1eb7f..5cb75e04 100644
--- a/src/core/file_sys/archive_romfs.h
+++ b/src/core/file_sys/archive_romfs.h
@@ -8,7 +8,7 @@
#include "common/common_types.h"
-#include "core/file_sys/archive_backend.h"
+#include "core/file_sys/ivfc_archive.h"
#include "core/loader/loader.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17,82 +17,12 @@
namespace FileSys {
/// File system interface to the RomFS archive
-class Archive_RomFS final : public ArchiveBackend {
+class Archive_RomFS final : public IVFCArchive {
public:
Archive_RomFS(const Loader::AppLoader& app_loader);
std::string GetName() const override { return "RomFS"; }
-
- /**
- * Open a file specified by its path, using the specified mode
- * @param path Path relative to the archive
- * @param mode Mode to open the file with
- * @return Opened file, or nullptr
- */
- std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
-
- /**
- * Delete a file specified by its path
- * @param path Path relative to the archive
- * @return Whether the file could be deleted
- */
- bool DeleteFile(const Path& path) const override;
-
- /**
- * Rename a File specified by its path
- * @param src_path Source path relative to the archive
- * @param dest_path Destination path relative to the archive
- * @return Whether rename succeeded
- */
- bool RenameFile(const Path& src_path, const Path& dest_path) const override;
-
- /**
- * Delete a directory specified by its path
- * @param path Path relative to the archive
- * @return Whether the directory could be deleted
- */
- bool DeleteDirectory(const Path& path) const override;
-
- /**
- * Create a file specified by its path
- * @param path Path relative to the Archive
- * @param size The size of the new file, filled with zeroes
- * @return File creation result code
- */
- ResultCode CreateFile(const Path& path, u32 size) const override;
-
- /**
- * Create a directory specified by its path
- * @param path Path relative to the archive
- * @return Whether the directory could be created
- */
- bool CreateDirectory(const Path& path) const override;
-
- /**
- * Rename a Directory specified by its path
- * @param src_path Source path relative to the archive
- * @param dest_path Destination path relative to the archive
- * @return Whether rename succeeded
- */
- bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
-
- /**
- * Open a directory specified by its path
- * @param path Path relative to the archive
- * @return Opened directory, or nullptr
- */
- std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
-
- ResultCode Open(const Path& path) override {
- return RESULT_SUCCESS;
- }
-
- ResultCode Format(const Path& path) const override;
-
-private:
- friend class File_RomFS;
-
- std::vector<u8> raw_data;
+ ResultCode Open(const Path& path) override { return RESULT_SUCCESS; }
};
} // namespace FileSys
diff --git a/src/core/file_sys/archive_savedatacheck.cpp b/src/core/file_sys/archive_savedatacheck.cpp
new file mode 100644
index 00000000..233158a0
--- /dev/null
+++ b/src/core/file_sys/archive_savedatacheck.cpp
@@ -0,0 +1,41 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/file_util.h"
+
+#include "core/file_sys/archive_savedatacheck.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// FileSys namespace
+
+namespace FileSys {
+
+Archive_SaveDataCheck::Archive_SaveDataCheck(const std::string& mount_loc) : mount_point(mount_loc) {
+}
+
+ResultCode Archive_SaveDataCheck::Open(const Path& path) {
+ // TODO(Subv): We should not be overwriting raw_data everytime this function is called,
+ // but until we use factory classes to create the archives at runtime instead of creating them beforehand
+ // and allow multiple archives of the same type to be open at the same time without clobbering each other,
+ // we won't be able to maintain the state of each archive, hence we overwrite it every time it's needed.
+ // There are a number of problems with this, for example opening a file in this archive, then opening
+ // this archive again with a different path, will corrupt the previously open file.
+ auto vec = path.AsBinary();
+ const u32* data = reinterpret_cast<u32*>(vec.data());
+ std::string file_path = Common::StringFromFormat("%s%08x%08x.bin", mount_point.c_str(), data[1], data[0]);
+ FileUtil::IOFile file(file_path, "rb");
+
+ std::fill(raw_data.begin(), raw_data.end(), 0);
+
+ if (!file.IsOpen()) {
+ return ResultCode(-1); // TODO(Subv): Find the right error code
+ }
+ auto size = file.GetSize();
+ raw_data.resize(size);
+ file.ReadBytes(raw_data.data(), size);
+ file.Close();
+ return RESULT_SUCCESS;
+}
+
+} // namespace FileSys
diff --git a/src/core/file_sys/archive_savedatacheck.h b/src/core/file_sys/archive_savedatacheck.h
new file mode 100644
index 00000000..f6e73e80
--- /dev/null
+++ b/src/core/file_sys/archive_savedatacheck.h
@@ -0,0 +1,31 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <vector>
+
+#include "common/common_types.h"
+
+#include "core/file_sys/ivfc_archive.h"
+#include "core/loader/loader.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// FileSys namespace
+
+namespace FileSys {
+
+/// File system interface to the SaveDataCheck archive
+class Archive_SaveDataCheck final : public IVFCArchive {
+public:
+ Archive_SaveDataCheck(const std::string& mount_point);
+
+ std::string GetName() const override { return "SaveDataCheck"; }
+ ResultCode Open(const Path& path) override;
+
+private:
+ std::string mount_point;
+};
+
+} // namespace FileSys
diff --git a/src/core/file_sys/directory_romfs.cpp b/src/core/file_sys/directory_romfs.cpp
deleted file mode 100644
index e130aca1..00000000
--- a/src/core/file_sys/directory_romfs.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "common/common_types.h"
-
-#include "core/file_sys/directory_romfs.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// FileSys namespace
-
-namespace FileSys {
-
-Directory_RomFS::Directory_RomFS() {
-}
-
-Directory_RomFS::~Directory_RomFS() {
-}
-
-bool Directory_RomFS::Open() {
- return false;
-}
-
-u32 Directory_RomFS::Read(const u32 count, Entry* entries) {
- return 0;
-}
-
-bool Directory_RomFS::Close() const {
- return false;
-}
-
-} // namespace FileSys
diff --git a/src/core/file_sys/directory_romfs.h b/src/core/file_sys/directory_romfs.h
deleted file mode 100644
index 2297f164..00000000
--- a/src/core/file_sys/directory_romfs.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "common/common_types.h"
-
-#include "core/file_sys/directory_backend.h"
-#include "core/loader/loader.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// FileSys namespace
-
-namespace FileSys {
-
-class Directory_RomFS final : public DirectoryBackend {
-public:
- Directory_RomFS();
- ~Directory_RomFS() override;
-
- /**
- * Open the directory
- * @return true if the directory opened correctly
- */
- bool Open() override;
-
- /**
- * List files contained in the directory
- * @param count Number of entries to return at once in entries
- * @param entries Buffer to read data into
- * @return Number of entries listed
- */
- u32 Read(const u32 count, Entry* entries) override;
-
- /**
- * Close the directory
- * @return true if the directory closed correctly
- */
- bool Close() const override;
-};
-
-} // namespace FileSys
diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp
index 0197f727..c6e033fc 100644
--- a/src/core/file_sys/disk_archive.cpp
+++ b/src/core/file_sys/disk_archive.cpp
@@ -6,6 +6,7 @@
#include "common/common_types.h"
#include "common/file_util.h"
+#include "common/make_unique.h"
#include "core/file_sys/disk_archive.h"
#include "core/settings.h"
@@ -17,10 +18,10 @@ namespace FileSys {
std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const {
LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
- DiskFile* file = new DiskFile(this, path, mode);
+ auto file = Common::make_unique<DiskFile>(this, path, mode);
if (!file->Open())
return nullptr;
- return std::unique_ptr<FileBackend>(file);
+ return std::move(file);
}
bool DiskArchive::DeleteFile(const Path& path) const {
@@ -66,10 +67,10 @@ bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) c
std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const {
LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str());
- DiskDirectory* directory = new DiskDirectory(this, path);
+ auto directory = Common::make_unique<DiskDirectory>(this, path);
if (!directory->Open())
return nullptr;
- return std::unique_ptr<DirectoryBackend>(directory);
+ return std::move(directory);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -100,7 +101,7 @@ bool DiskFile::Open() {
// Open the file in binary mode, to avoid problems with CR/LF on Windows systems
mode_string += "b";
- file = new FileUtil::IOFile(path, mode_string.c_str());
+ file = Common::make_unique<FileUtil::IOFile>(path, mode_string.c_str());
return true;
}
diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h
index f18d96f5..3472f687 100644
--- a/src/core/file_sys/disk_archive.h
+++ b/src/core/file_sys/disk_archive.h
@@ -56,10 +56,6 @@ public:
DiskFile();
DiskFile(const DiskArchive* archive, const Path& path, const Mode mode);
- ~DiskFile() override {
- Close();
- }
-
bool Open() override;
size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
@@ -75,7 +71,7 @@ protected:
const DiskArchive* archive;
std::string path;
Mode mode;
- FileUtil::IOFile* file;
+ std::unique_ptr<FileUtil::IOFile> file;
};
class DiskDirectory : public DirectoryBackend {
diff --git a/src/core/file_sys/file_romfs.cpp b/src/core/file_sys/file_romfs.cpp
deleted file mode 100644
index 7467d6d3..00000000
--- a/src/core/file_sys/file_romfs.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include "common/common_types.h"
-
-#include "core/file_sys/file_romfs.h"
-#include "core/file_sys/archive_romfs.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// FileSys namespace
-
-namespace FileSys {
-
-bool File_RomFS::Open() {
- return true;
-}
-
-size_t File_RomFS::Read(const u64 offset, const u32 length, u8* buffer) const {
- LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
- memcpy(buffer, &archive->raw_data[(u32)offset], length);
- return length;
-}
-
-size_t File_RomFS::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
- LOG_WARNING(Service_FS, "Attempted to write to ROMFS.");
- return 0;
-}
-
-size_t File_RomFS::GetSize() const {
- return sizeof(u8) * archive->raw_data.size();
-}
-
-bool File_RomFS::SetSize(const u64 size) const {
- LOG_WARNING(Service_FS, "Attempted to set the size of ROMFS");
- return false;
-}
-
-bool File_RomFS::Close() const {
- return false;
-}
-
-} // namespace FileSys
diff --git a/src/core/file_sys/file_romfs.h b/src/core/file_sys/file_romfs.h
deleted file mode 100644
index 04d8a16a..00000000
--- a/src/core/file_sys/file_romfs.h
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2014 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "common/common_types.h"
-
-#include "core/file_sys/file_backend.h"
-#include "core/loader/loader.h"
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-// FileSys namespace
-
-namespace FileSys {
-
-class Archive_RomFS;
-
-class File_RomFS final : public FileBackend {
-public:
- File_RomFS(const Archive_RomFS* archive) : archive(archive) {}
-
- /**
- * Open the file
- * @return true if the file opened correctly
- */
- bool Open() override;
-
- /**
- * Read data from the file
- * @param offset Offset in bytes to start reading data from
- * @param length Length in bytes of data to read from file
- * @param buffer Buffer to read data into
- * @return Number of bytes read
- */
- size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
-
- /**
- * Write data to the file
- * @param offset Offset in bytes to start writing data to
- * @param length Length in bytes of data to write to file
- * @param flush The flush parameters (0 == do not flush)
- * @param buffer Buffer to read data from
- * @return Number of bytes written
- */
- size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
-
- /**
- * Get the size of the file in bytes
- * @return Size of the file in bytes
- */
- size_t GetSize() const override;
-
- /**
- * Set the size of the file in bytes
- * @param size New size of the file
- * @return true if successful
- */
- bool SetSize(const u64 size) const override;
-
- /**
- * Close the file
- * @return true if the file closed correctly
- */
- bool Close() const override;
-
- void Flush() const override { }
-
-private:
- const Archive_RomFS* archive;
-};
-
-} // namespace FileSys
diff --git a/src/core/file_sys/ivfc_archive.cpp b/src/core/file_sys/ivfc_archive.cpp
new file mode 100644
index 00000000..68c3c8b8
--- /dev/null
+++ b/src/core/file_sys/ivfc_archive.cpp
@@ -0,0 +1,88 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+
+#include "common/common_types.h"
+#include "common/file_util.h"
+#include "common/make_unique.h"
+
+#include "core/file_sys/ivfc_archive.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// FileSys namespace
+
+namespace FileSys {
+
+IVFCArchive::IVFCArchive() {
+}
+
+std::unique_ptr<FileBackend> IVFCArchive::OpenFile(const Path& path, const Mode mode) const {
+ return Common::make_unique<IVFCFile>(this);
+}
+
+bool IVFCArchive::DeleteFile(const Path& path) const {
+ LOG_CRITICAL(Service_FS, "Attempted to delete a file from an IVFC archive (%s).", GetName().c_str());
+ return false;
+}
+
+bool IVFCArchive::RenameFile(const Path& src_path, const Path& dest_path) const {
+ LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str());
+ return false;
+}
+
+bool IVFCArchive::DeleteDirectory(const Path& path) const {
+ LOG_CRITICAL(Service_FS, "Attempted to delete a directory from an IVFC archive (%s).", GetName().c_str());
+ return false;
+}
+
+ResultCode IVFCArchive::CreateFile(const Path& path, u32 size) const {
+ LOG_CRITICAL(Service_FS, "Attempted to create a file in an IVFC archive (%s).", GetName().c_str());
+ // TODO: Verify error code
+ return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
+}
+
+bool IVFCArchive::CreateDirectory(const Path& path) const {
+ LOG_CRITICAL(Service_FS, "Attempted to create a directory in an IVFC archive (%s).", GetName().c_str());
+ return false;
+}
+
+bool IVFCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const {
+ LOG_CRITICAL(Service_FS, "Attempted to rename a file within an IVFC archive (%s).", GetName().c_str());
+ return false;
+}
+
+std::unique_ptr<DirectoryBackend> IVFCArchive::OpenDirectory(const Path& path) const {
+ return Common::make_unique<IVFCDirectory>();
+}
+
+ResultCode IVFCArchive::Format(const Path& path) const {
+ LOG_CRITICAL(Service_FS, "Attempted to format an IVFC archive (%s).", GetName().c_str());
+ // TODO: Verify error code
+ return ResultCode(ErrorDescription::NotAuthorized, ErrorModule::FS, ErrorSummary::NotSupported, ErrorLevel::Permanent);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+size_t IVFCFile::Read(const u64 offset, const u32 length, u8* buffer) const {
+ LOG_TRACE(Service_FS, "called offset=%llu, length=%d", offset, length);
+ memcpy(buffer, &archive->raw_data[(u32)offset], length);
+ return length;
+}
+
+size_t IVFCFile::Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const {
+ LOG_CRITICAL(Service_FS, "Attempted to write to IVFC file in archive %s.", archive->GetName().c_str());
+ return 0;
+}
+
+size_t IVFCFile::GetSize() const {
+ return sizeof(u8) * archive->raw_data.size();
+}
+
+bool IVFCFile::SetSize(const u64 size) const {
+ LOG_CRITICAL(Service_FS, "Attempted to set the size of an IVFC file in archive %s", archive->GetName().c_str());
+ return false;
+}
+
+} // namespace FileSys
diff --git a/src/core/file_sys/ivfc_archive.h b/src/core/file_sys/ivfc_archive.h
new file mode 100644
index 00000000..6f4cc86d
--- /dev/null
+++ b/src/core/file_sys/ivfc_archive.h
@@ -0,0 +1,66 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <vector>
+
+#include "common/common_types.h"
+
+#include "core/file_sys/archive_backend.h"
+#include "core/loader/loader.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// FileSys namespace
+
+namespace FileSys {
+
+/**
+ * Helper which implements an interface to deal with IVFC images used in some archives
+ * This should be subclassed by concrete archive types, which will provide the
+ * input data (load the raw IVFC archive) and override any required methods
+ */
+class IVFCArchive : public ArchiveBackend {
+public:
+ IVFCArchive();
+
+ std::unique_ptr<FileBackend> OpenFile(const Path& path, const Mode mode) const override;
+ bool DeleteFile(const Path& path) const override;
+ bool RenameFile(const Path& src_path, const Path& dest_path) const override;
+ bool DeleteDirectory(const Path& path) const override;
+ ResultCode CreateFile(const Path& path, u32 size) const override;
+ bool CreateDirectory(const Path& path) const override;
+ bool RenameDirectory(const Path& src_path, const Path& dest_path) const override;
+ std::unique_ptr<DirectoryBackend> OpenDirectory(const Path& path) const override;
+ ResultCode Format(const Path& path) const override;
+
+protected:
+ friend class IVFCFile;
+ std::vector<u8> raw_data;
+};
+
+class IVFCFile : public FileBackend {
+public:
+ IVFCFile(const IVFCArchive* archive) : archive(archive) {}
+
+ bool Open() override { return true; }
+ size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
+ size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
+ size_t GetSize() const override;
+ bool SetSize(const u64 size) const override;
+ bool Close() const override { return false; }
+ void Flush() const override { }
+
+private:
+ const IVFCArchive* archive;
+};
+
+class IVFCDirectory : public DirectoryBackend {
+public:
+ bool Open() override { return false; }
+ u32 Read(const u32 count, Entry* entries) override { return 0; }
+ bool Close() const override { return false; }
+};
+
+} // namespace FileSys
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 38705e3c..736bbc36 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -51,6 +51,17 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
HLE::Reschedule(__func__);
}
break;
+
+ case ArbitrationType::DecrementAndWaitIfLessThan:
+ {
+ s32 memory_value = Memory::Read32(address) - 1;
+ Memory::Write32(address, memory_value);
+ if (memory_value <= value) {
+ Kernel::WaitCurrentThread(WAITTYPE_ARB, handle, address);
+ HLE::Reschedule(__func__);
+ }
+ break;
+ }
default:
LOG_ERROR(Kernel, "unknown type=%d", type);
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 558068c7..3dfeffc9 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -168,9 +168,9 @@ Handle CreateMutex(bool initial_locked, const std::string& name) {
ResultVal<bool> Mutex::WaitSynchronization() {
bool wait = locked;
if (locked) {
+ waiting_threads.push_back(GetCurrentThreadHandle());
Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle());
- }
- else {
+ } else {
// Lock the mutex when the first thread accesses it
locked = true;
MutexAcquireLock(this);
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 2cf4d118..d4affdfb 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -12,9 +12,23 @@
namespace DSP_DSP {
-static u32 read_pipe_count;
-static Handle semaphore_event;
-static Handle interrupt_event;
+static u32 read_pipe_count = 0;
+static Handle semaphore_event = 0;
+static Handle interrupt_event = 0;
+
+void SignalInterrupt() {
+ // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
+ // application that a DSP interrupt occurred, without specifying which one. Since we do not
+ // emulate the DSP yet (and how it works is largely unknown), this is a work around to get games
+ // that check the DSP interrupt signal event to run. We should figure out the different types of
+ // DSP interrupts, and trigger them at the appropriate times.
+
+ if (interrupt_event == 0) {
+ LOG_WARNING(Service_DSP, "cannot signal interrupt until DSP event has been created!");
+ return;
+ }
+ Kernel::SignalEvent(interrupt_event);
+}
/**
* DSP_DSP::ConvertProcessAddressFromDspDram service function
@@ -102,7 +116,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
void WriteReg0x10(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- Kernel::SignalEvent(interrupt_event);
+ SignalInterrupt();
cmd_buff[1] = 0; // No error
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index 0b8b6460..fa13bfb7 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -20,4 +20,7 @@ public:
}
};
+/// Signals that a DSP interrupt has occurred to userland code
+void SignalInterrupt();
+
} // namespace
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index f19ca3a9..f761c6ab 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -10,9 +10,11 @@
#include "common/make_unique.h"
#include "common/math_util.h"
-#include "core/file_sys/archive_savedata.h"
-#include "core/file_sys/archive_extsavedata.h"
#include "core/file_sys/archive_backend.h"
+#include "core/file_sys/archive_extsavedata.h"
+#include "core/file_sys/archive_romfs.h"
+#include "core/file_sys/archive_savedata.h"
+#include "core/file_sys/archive_savedatacheck.h"
#include "core/file_sys/archive_sdmc.h"
#include "core/file_sys/directory_backend.h"
#include "core/hle/service/fs/archive.h"
@@ -50,6 +52,9 @@ enum class FileCommand : u32 {
SetAttributes = 0x08070040,
Close = 0x08080000,
Flush = 0x08090000,
+ SetPriority = 0x080A0040,
+ GetPriority = 0x080B0000,
+ OpenLinkFile = 0x080C0000,
};
// Command to access directory
@@ -63,7 +68,7 @@ enum class DirectoryCommand : u32 {
class Archive {
public:
Archive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code)
- : backend(std::move(backend)), id_code(id_code) {
+ : id_code(id_code), backend(std::move(backend)) {
}
std::string GetName() const { return "Archive: " + backend->GetName(); }
@@ -75,12 +80,13 @@ public:
class File : public Kernel::Session {
public:
File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path)
- : backend(std::move(backend)), path(path) {
+ : path(path), backend(std::move(backend)), priority(0) {
}
std::string GetName() const override { return "Path: " + path.DebugStr(); }
FileSys::Path path; ///< Path of the file
+ u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means
std::unique_ptr<FileSys::FileBackend> backend; ///< File backend interface
ResultVal<bool> SyncRequest() override {
@@ -145,6 +151,27 @@ public:
break;
}
+ case FileCommand::OpenLinkFile:
+ {
+ LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str());
+ cmd_buff[3] = GetHandle();
+ break;
+ }
+
+ case FileCommand::SetPriority:
+ {
+ priority = cmd_buff[1];
+ LOG_TRACE(Service_FS, "SetPriority %u", priority);
+ break;
+ }
+
+ case FileCommand::GetPriority:
+ {
+ cmd_buff[2] = priority;
+ LOG_TRACE(Service_FS, "GetPriority");
+ break;
+ }
+
// Unknown command...
default:
LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd);
@@ -160,7 +187,7 @@ public:
class Directory : public Kernel::Session {
public:
Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path)
- : backend(std::move(backend)), path(path) {
+ : path(path), backend(std::move(backend)) {
}
std::string GetName() const override { return "Directory: " + path.DebugStr(); }
@@ -327,7 +354,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
ErrorSummary::Canceled, ErrorLevel::Status);
}
-ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size) {
+ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size) {
Archive* archive = GetArchive(archive_handle);
if (archive == nullptr)
return InvalidHandle(ErrorModule::FS);
@@ -435,6 +462,11 @@ void ArchiveInit() {
else
LOG_ERROR(Service_FS, "Can't instantiate SharedExtSaveData archive with path %s",
sharedextsavedata_directory.c_str());
+
+ // Create the SaveDataCheck archive, basically a small variation of the RomFS archive
+ std::string savedatacheck_directory = FileUtil::GetUserPath(D_SAVEDATACHECK_IDX);
+ auto savedatacheck_archive = Common::make_unique<FileSys::Archive_SaveDataCheck>(savedatacheck_directory);
+ CreateArchive(std::move(savedatacheck_archive), ArchiveIdCode::SaveDataCheck);
}
/// Shutdown archives
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h
index c23b8cc4..9e9efa01 100644
--- a/src/core/hle/service/fs/archive.h
+++ b/src/core/hle/service/fs/archive.h
@@ -22,6 +22,7 @@ enum class ArchiveIdCode : u32 {
SystemSaveData = 0x00000008,
SDMC = 0x00000009,
SDMCWriteOnly = 0x0000000A,
+ SaveDataCheck = 0x2345678A,
};
typedef u64 ArchiveHandle;
@@ -90,7 +91,7 @@ ResultCode DeleteDirectoryFromArchive(ArchiveHandle archive_handle, const FileSy
* @param file_size The size of the new file, filled with zeroes
* @return File creation result code
*/
-ResultCode CreateFileInArchive(Handle archive_handle, const FileSys::Path& path, u32 file_size);
+ResultCode CreateFileInArchive(ArchiveHandle archive_handle, const FileSys::Path& path, u32 file_size);
/**
* Create a Directory from an Archive
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 0f3cc2aa..c5233e68 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -37,6 +37,7 @@
#include "core/hle/service/soc_u.h"
#include "core/hle/service/srv.h"
#include "core/hle/service/ssl_c.h"
+#include "core/hle/service/y2r_u.h"
namespace Service {
@@ -122,6 +123,7 @@ void Init() {
g_manager->AddService(new PTM_U::Interface);
g_manager->AddService(new SOC_U::Interface);
g_manager->AddService(new SSL_C::Interface);
+ g_manager->AddService(new Y2R_U::Interface);
LOG_DEBUG(Service, "initialized OK");
}
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 3baf8908..f502c6af 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -404,7 +404,7 @@ static void Fcntl(Service::Interface* self) {
}
#endif
} else {
- LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call");
+ LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call", ctr_cmd);
result = TranslateError(EINVAL); // TODO: Find the correct error
posix_ret = -1;
return;
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
new file mode 100644
index 00000000..f9e3619d
--- /dev/null
+++ b/src/core/hle/service/y2r_u.cpp
@@ -0,0 +1,45 @@
+// 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/kernel/event.h"
+#include "core/hle/service/y2r_u.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace Y2R_U
+
+namespace Y2R_U {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010040, nullptr, "SetInputFormat"},
+ {0x00030040, nullptr, "SetOutputFormat"},
+ {0x00050040, nullptr, "SetRotation"},
+ {0x00070040, nullptr, "SetBlockAlignment"},
+ {0x000D0040, nullptr, "SetTransferEndInterrupt"},
+ {0x000F0000, nullptr, "GetTransferEndEvent"},
+ {0x00100102, nullptr, "SetSendingY"},
+ {0x00110102, nullptr, "SetSendingU"},
+ {0x00120102, nullptr, "SetSendingV"},
+ {0x00180102, nullptr, "SetReceiving"},
+ {0x001A0040, nullptr, "SetInputLineWidth"},
+ {0x001C0040, nullptr, "SetInputLines"},
+ {0x00200040, nullptr, "SetStandardCoefficient"},
+ {0x00220040, nullptr, "SetAlpha"},
+ {0x00260000, nullptr, "StartConversion"},
+ {0x00270000, nullptr, "StopConversion"},
+ {0x00280000, nullptr, "IsBusyConversion"},
+ {0x002A0000, nullptr, "PingProcess"},
+ {0x002B0000, nullptr, "DriverInitialize"},
+ {0x002C0000, nullptr, "DriverFinalize"}
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+} // namespace
diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h
new file mode 100644
index 00000000..171aecfd
--- /dev/null
+++ b/src/core/hle/service/y2r_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 Y2R_U
+
+namespace Y2R_U {
+
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "y2r:u";
+ }
+};
+
+} // namespace
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index dd619cb1..e346e0ad 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -10,6 +10,7 @@
#include "core/hle/hle.h"
#include "core/hle/service/gsp_gpu.h"
+#include "core/hle/service/dsp_dsp.h"
#include "core/hw/gpu.h"
@@ -94,11 +95,15 @@ inline void Write(u32 addr, const T data) {
int r, g, b, a;
} source_color = { 0, 0, 0, 0 };
+ // Cheap emulation of horizontal scaling: Just skip each second pixel of the
+ // input framebuffer. We keep track of this in the pixel_skip variable.
+ unsigned pixel_skip = (config.scale_horizontally != 0) ? 2 : 1;
+
switch (config.input_format) {
case Regs::PixelFormat::RGBA8:
{
// TODO: Most likely got the component order messed up.
- u8* srcptr = source_pointer + x * 4 + y * config.input_width * 4;
+ u8* srcptr = source_pointer + x * 4 * pixel_skip + y * config.input_width * 4 * pixel_skip;
source_color.r = srcptr[0]; // blue
source_color.g = srcptr[1]; // green
source_color.b = srcptr[2]; // red
@@ -210,13 +215,18 @@ void Update() {
// - 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();
}
+ // Signal to GSP that GPU interrupt has occurred
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1);
+
+ // TODO(bunnei): Fake a DSP interrupt on each frame. This does not belong here, but
+ // until we can emulate DSP interrupts, this is probably the only reasonable place to do
+ // this. Certain games expect this to be periodically signaled.
+ DSP_DSP::SignalInterrupt();
}
}
}
diff --git a/src/core/hw/gpu.h b/src/core/hw/gpu.h
index 292f496c..7de05523 100644
--- a/src/core/hw/gpu.h
+++ b/src/core/hw/gpu.h
@@ -157,6 +157,9 @@ struct Regs {
BitField< 8, 3, PixelFormat> input_format;
BitField<12, 3, PixelFormat> output_format;
BitField<16, 1, u32> output_tiled; // stores output in a tiled format
+
+ // TODO: Not really sure if this actually scales, or even resizes at all.
+ BitField<24, 1, u32> scale_horizontally;
};
INSERT_PADDING_WORDS(0x1);
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 35433501..3ca60c07 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -222,7 +222,7 @@ public:
int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found
- bool DidRelocate() {
+ bool DidRelocate() const {
return relocate;
}
};
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 87580cb2..45cf425d 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -45,6 +45,8 @@ FileType IdentifyFile(const std::string &filename) {
return FileType::CCI;
} else if (extension == ".bin") {
return FileType::BIN;
+ } else if (extension == ".3ds") {
+ return FileType::CCI;
} else if (extension == ".3dsx") {
return FileType::THREEDSX;
}