diff options
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_dec.cpp | 11 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_dec.h | 216 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 282 | ||||
| -rw-r--r-- | src/core/hle/service/fs/archive.cpp | 6 | ||||
| -rw-r--r-- | src/core/loader/elf.cpp | 2 |
5 files changed, 286 insertions, 231 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp index 333b40f54..0927eece1 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[] = { | |||
| 136 | { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 }, | 136 | { "pkhbt", 2, 6, 20, 27, 0x00000068, 4, 6, 0x00000001 }, |
| 137 | { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 }, | 137 | { "smul", 3, 4, 20, 27, 0x00000016, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 138 | { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 }, | 138 | { "smlalxy", 3, 4, 20, 27, 0x00000014, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 139 | // {"smlal" , 2 , 4 , 21, 27, 0x00000007, 4, 7, 0x00000009}, | ||
| 140 | { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 }, | 139 | { "smla", 3, 4, 20, 27, 0x00000010, 7, 7, 0x00000001, 4, 4, 0x00000000 }, |
| 141 | { "mcrr", 1, 6, 20, 27, 0x000000c4 }, | 140 | { "mcrr", 1, 6, 20, 27, 0x000000c4 }, |
| 142 | { "mrrc", 1, 6, 20, 27, 0x000000c5 }, | 141 | { "mrrc", 1, 6, 20, 27, 0x000000c5 }, |
| @@ -194,6 +193,10 @@ const ISEITEM arm_instruction[] = { | |||
| 194 | { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 }, | 193 | { "ldc", 2, 0, 25, 27, 0x00000006, 20, 20, 0x00000001 }, |
| 195 | { "swi", 1, 0, 24, 27, 0x0000000f }, | 194 | { "swi", 1, 0, 24, 27, 0x0000000f }, |
| 196 | { "bbl", 1, 0, 25, 27, 0x00000005 }, | 195 | { "bbl", 1, 0, 25, 27, 0x00000005 }, |
| 196 | { "ldrexd", 2, ARMV6K, 20, 27, 0x0000001B, 4, 7, 0x00000009 }, | ||
| 197 | { "strexd", 2, ARMV6K, 20, 27, 0x0000001A, 4, 7, 0x00000009 }, | ||
| 198 | { "ldrexh", 2, ARMV6K, 20, 27, 0x0000001F, 4, 7, 0x00000009 }, | ||
| 199 | { "strexh", 2, ARMV6K, 20, 27, 0x0000001E, 4, 7, 0x00000009 }, | ||
| 197 | }; | 200 | }; |
| 198 | 201 | ||
| 199 | const ISEITEM arm_exclusion_code[] = { | 202 | const ISEITEM arm_exclusion_code[] = { |
| @@ -383,6 +386,11 @@ const ISEITEM arm_exclusion_code[] = { | |||
| 383 | { "ldc", 0, 0, 0 }, | 386 | { "ldc", 0, 0, 0 }, |
| 384 | { "swi", 0, 0, 0 }, | 387 | { "swi", 0, 0, 0 }, |
| 385 | { "bbl", 0, 0, 0 }, | 388 | { "bbl", 0, 0, 0 }, |
| 389 | { "ldrexd", 0, ARMV6K, 0 }, | ||
| 390 | { "strexd", 0, ARMV6K, 0 }, | ||
| 391 | { "ldrexh", 0, ARMV6K, 0 }, | ||
| 392 | { "strexh", 0, ARMV6K, 0 }, | ||
| 393 | |||
| 386 | { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4] | 394 | { "bl_1_thumb", 0, INVALID, 0 }, // Should be table[-4] |
| 387 | { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3] | 395 | { "bl_2_thumb", 0, INVALID, 0 }, // Should be located at the end of the table[-3] |
| 388 | { "blx_1_thumb", 0, INVALID, 0 }, // Should be located at table[-2] | 396 | { "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) { | |||
| 395 | int ret = DECODE_FAILURE; | 403 | int ret = DECODE_FAILURE; |
| 396 | int i = 0; | 404 | int i = 0; |
| 397 | int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); | 405 | int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM); |
| 406 | |||
| 398 | for (i = 0; i < instr_slots; i++) { | 407 | for (i = 0; i < instr_slots; i++) { |
| 399 | n = arm_instruction[i].attribute_value; | 408 | n = arm_instruction[i].attribute_value; |
| 400 | base = 0; | 409 | base = 0; |
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h index 70eb96e93..58784aeea 100644 --- a/src/core/arm/dyncom/arm_dyncom_dec.h +++ b/src/core/arm/dyncom/arm_dyncom_dec.h | |||
| @@ -1,153 +1,117 @@ | |||
| 1 | /* Copyright (C) | 1 | // Copyright 2012 Michael Kang, 2015 Citra Emulator Project |
| 2 | * 2012 - Michael.Kang blackfin.kang@gmail.com | 2 | // Licensed under GPLv2 or any later version |
| 3 | * This program is free software; you can redistribute it and/or | 3 | // Refer to the license.txt file included. |
| 4 | * modify it under the terms of the GNU General Public License | 4 | |
| 5 | * as published by the Free Software Foundation; either version 2 | 5 | #pragma once |
| 6 | * of the License, or (at your option) any later version. | 6 | |
| 7 | * | 7 | #define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1)) |
| 8 | * This program is distributed in the hope that it will be useful, | 8 | #define BIT(n) ((instr >> (n)) & 1) |
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 | #define BAD do { printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); } while(0); |
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 | #define ptr_N cpu->ptr_N |
| 11 | * GNU General Public License for more details. | 11 | #define ptr_Z cpu->ptr_Z |
| 12 | * | 12 | #define ptr_C cpu->ptr_C |
| 13 | * You should have received a copy of the GNU General Public License | 13 | #define ptr_V cpu->ptr_V |
| 14 | * along with this program; if not, write to the Free Software | 14 | #define ptr_I cpu->ptr_I |
| 15 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 15 | #define ptr_T cpu->ptr_T |
| 16 | * | 16 | #define ptr_CPSR cpu->ptr_gpr[16] |
| 17 | */ | 17 | |
| 18 | 18 | // For MUL instructions | |
| 19 | /** | 19 | #define RDHi ((instr >> 16) & 0xF) |
| 20 | * @file arm_dyncom_dec.h | 20 | #define RDLo ((instr >> 12) & 0xF) |
| 21 | * @brief Some common utility for arm instruction decoder | 21 | #define MUL_RD ((instr >> 16) & 0xF) |
| 22 | * @author Michael.Kang blackfin.kang@gmail.com | 22 | #define MUL_RN ((instr >> 12) & 0xF) |
| 23 | * @version 7849 | 23 | #define RS ((instr >> 8) & 0xF) |
| 24 | * @date 2012-03-15 | 24 | #define RD ((instr >> 12) & 0xF) |
| 25 | */ | 25 | #define RN ((instr >> 16) & 0xF) |
| 26 | 26 | #define RM (instr & 0xF) | |
| 27 | #ifndef __ARM_DYNCOM_DEC__ | 27 | |
| 28 | #define __ARM_DYNCOM_DEC__ | 28 | // CP15 registers |
| 29 | 29 | #define OPCODE_1 BITS(21, 23) | |
| 30 | #define BITS(a,b) ((instr >> (a)) & ((1 << (1+(b)-(a)))-1)) | 30 | #define CRn BITS(16, 19) |
| 31 | #define BIT(n) ((instr >> (n)) & 1) | 31 | #define CRm BITS(0, 3) |
| 32 | #define BAD do{printf("meet BAD at %s, instr is %x\n", __FUNCTION__, instr ); /*exit(0);*/}while(0); | 32 | #define OPCODE_2 BITS(5, 7) |
| 33 | #define ptr_N cpu->ptr_N | 33 | |
| 34 | #define ptr_Z cpu->ptr_Z | 34 | #define I BIT(25) |
| 35 | #define ptr_C cpu->ptr_C | 35 | #define S BIT(20) |
| 36 | #define ptr_V cpu->ptr_V | 36 | |
| 37 | #define ptr_I cpu->ptr_I | 37 | #define SHIFT BITS(5,6) |
| 38 | #define ptr_T cpu->ptr_T | 38 | #define SHIFT_IMM BITS(7,11) |
| 39 | #define ptr_CPSR cpu->ptr_gpr[16] | 39 | #define IMMH BITS(8,11) |
| 40 | 40 | #define IMML BITS(0,3) | |
| 41 | /* for MUL instructions */ | 41 | |
| 42 | /*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */ | 42 | #define LSPBIT BIT(24) |
| 43 | #define RDHi ((instr >> 16) & 0xF) | 43 | #define LSUBIT BIT(23) |
| 44 | /*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */ | 44 | #define LSBBIT BIT(22) |
| 45 | #define RDLo ((instr >> 12) & 0xF) | 45 | #define LSWBIT BIT(21) |
| 46 | /*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */ | 46 | #define LSLBIT BIT(20) |
| 47 | #define MUL_RD ((instr >> 16) & 0xF) | 47 | #define LSSHBITS BITS(5,6) |
| 48 | /*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */ | 48 | #define OFFSET12 BITS(0,11) |
| 49 | #define MUL_RN ((instr >> 12) & 0xF) | 49 | #define SBIT BIT(20) |
| 50 | /*xxxx xxxx xxxx xxxx xxxx 1111 xxxx xxxx */ | 50 | #define DESTReg (BITS (12, 15)) |
| 51 | #define RS ((instr >> 8) & 0xF) | 51 | |
| 52 | 52 | // They are in unused state, give a corrent value when using | |
| 53 | /*xxxx xxxx xxxx xxxx 1111 xxxx xxxx xxxx */ | ||
| 54 | #define RD ((instr >> 12) & 0xF) | ||
| 55 | /*xxxx xxxx xxxx 1111 xxxx xxxx xxxx xxxx */ | ||
| 56 | #define RN ((instr >> 16) & 0xF) | ||
| 57 | /*xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 */ | ||
| 58 | #define RM (instr & 0xF) | ||
| 59 | |||
| 60 | /* CP15 registers */ | ||
| 61 | #define OPCODE_1 BITS(21, 23) | ||
| 62 | #define CRn BITS(16, 19) | ||
| 63 | #define CRm BITS(0, 3) | ||
| 64 | #define OPCODE_2 BITS(5, 7) | ||
| 65 | |||
| 66 | /*xxxx xx1x xxxx xxxx xxxx xxxx xxxx xxxx */ | ||
| 67 | #define I BIT(25) | ||
| 68 | /*xxxx xxxx xxx1 xxxx xxxx xxxx xxxx xxxx */ | ||
| 69 | #define S BIT(20) | ||
| 70 | |||
| 71 | #define SHIFT BITS(5,6) | ||
| 72 | #define SHIFT_IMM BITS(7,11) | ||
| 73 | #define IMMH BITS(8,11) | ||
| 74 | #define IMML BITS(0,3) | ||
| 75 | |||
| 76 | #define LSPBIT BIT(24) | ||
| 77 | #define LSUBIT BIT(23) | ||
| 78 | #define LSBBIT BIT(22) | ||
| 79 | #define LSWBIT BIT(21) | ||
| 80 | #define LSLBIT BIT(20) | ||
| 81 | #define LSSHBITS BITS(5,6) | ||
| 82 | #define OFFSET12 BITS(0,11) | ||
| 83 | #define SBIT BIT(20) | ||
| 84 | #define DESTReg (BITS (12, 15)) | ||
| 85 | |||
| 86 | /* they are in unused state, give a corrent value when using */ | ||
| 87 | #define IS_V5E 0 | 53 | #define IS_V5E 0 |
| 88 | #define IS_V5 0 | 54 | #define IS_V5 0 |
| 89 | #define IS_V6 0 | 55 | #define IS_V6 0 |
| 90 | #define LHSReg 0 | 56 | #define LHSReg 0 |
| 91 | 57 | ||
| 92 | /* temp define the using the pc reg need implement a flow */ | 58 | // Temp define the using the pc reg need implement a flow |
| 93 | #define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2)) | 59 | #define STORE_CHECK_RD_PC ADD(R(RD), CONST(INSTR_SIZE * 2)) |
| 94 | 60 | ||
| 95 | #define OPERAND operand(cpu,instr,bb,NULL) | 61 | #define OPERAND operand(cpu,instr,bb,NULL) |
| 96 | #define SCO_OPERAND(sco) operand(cpu,instr,bb,sco) | 62 | #define SCO_OPERAND(sco) operand(cpu,instr,bb,sco) |
| 97 | #define BOPERAND boperand(instr) | 63 | #define BOPERAND boperand(instr) |
| 98 | 64 | ||
| 99 | #define CHECK_RN_PC (RN==15? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)):R(RN)) | 65 | #define CHECK_RN_PC (RN == 15 ? ADD(AND(R(RN), CONST(~0x1)), CONST(INSTR_SIZE * 2)) : R(RN)) |
| 100 | #define CHECK_RN_PC_WA (RN==15? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)):R(RN)) | 66 | #define CHECK_RN_PC_WA (RN == 15 ? ADD(AND(R(RN), CONST(~0x3)), CONST(INSTR_SIZE * 2)) : R(RN)) |
| 101 | 67 | ||
| 102 | #define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE)))) | 68 | #define GET_USER_MODE() (OR(ICMP_EQ(R(MODE_REG), CONST(USER32MODE)), ICMP_EQ(R(MODE_REG), CONST(SYSTEM32MODE)))) |
| 103 | 69 | ||
| 104 | int decode_arm_instr(uint32_t instr, int32_t *idx); | 70 | int decode_arm_instr(uint32_t instr, int32_t *idx); |
| 105 | 71 | ||
| 106 | enum DECODE_STATUS { | 72 | enum DECODE_STATUS { |
| 107 | DECODE_SUCCESS, | 73 | DECODE_SUCCESS, |
| 108 | DECODE_FAILURE | 74 | DECODE_FAILURE |
| 109 | }; | 75 | }; |
| 110 | 76 | ||
| 111 | struct instruction_set_encoding_item { | 77 | struct instruction_set_encoding_item { |
| 112 | const char *name; | 78 | const char *name; |
| 113 | int attribute_value; | 79 | int attribute_value; |
| 114 | int version; | 80 | int version; |
| 115 | u32 content[21]; | 81 | u32 content[21]; |
| 116 | }; | 82 | }; |
| 117 | 83 | ||
| 118 | typedef struct instruction_set_encoding_item ISEITEM; | 84 | typedef struct instruction_set_encoding_item ISEITEM; |
| 119 | 85 | ||
| 120 | #define RECORD_WB(value, flag) {cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag;} | 86 | #define RECORD_WB(value, flag) { cpu->dyncom_engine->wb_value = value;cpu->dyncom_engine->wb_flag = flag; } |
| 121 | #define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag) | 87 | #define INIT_WB(wb_value, wb_flag) RECORD_WB(wb_value, wb_flag) |
| 122 | 88 | ||
| 123 | #define EXECUTE_WB(base_reg) {if(cpu->dyncom_engine->wb_flag) \ | 89 | #define EXECUTE_WB(base_reg) { if(cpu->dyncom_engine->wb_flag) LET(base_reg, cpu->dyncom_engine->wb_value); } |
| 124 | LET(base_reg, cpu->dyncom_engine->wb_value);} | 90 | |
| 125 | inline int get_reg_count(uint32_t instr){ | 91 | inline int get_reg_count(uint32_t instr) { |
| 126 | int i = BITS(0,15); | 92 | int i = BITS(0, 15); |
| 127 | int count = 0; | 93 | int count = 0; |
| 128 | while(i){ | 94 | while (i) { |
| 129 | if(i & 1) | 95 | if (i & 1) |
| 130 | count ++; | 96 | count++; |
| 131 | i = i >> 1; | 97 | i = i >> 1; |
| 132 | } | 98 | } |
| 133 | return count; | 99 | return count; |
| 134 | } | 100 | } |
| 135 | 101 | ||
| 136 | enum ARMVER { | 102 | enum ARMVER { |
| 137 | INVALID = 0, | 103 | INVALID = 0, |
| 138 | ARMALL, | 104 | ARMALL, |
| 139 | ARMV4, | 105 | ARMV4, |
| 140 | ARMV4T, | 106 | ARMV4T, |
| 141 | ARMV5T, | 107 | ARMV5T, |
| 142 | ARMV5TE, | 108 | ARMV5TE, |
| 143 | ARMV5TEJ, | 109 | ARMV5TEJ, |
| 144 | ARMV6, | 110 | ARMV6, |
| 145 | ARM1176JZF_S, | 111 | ARM1176JZF_S, |
| 146 | ARMVFP2, | 112 | ARMVFP2, |
| 147 | ARMVFP3 | 113 | ARMVFP3, |
| 114 | ARMV6K, | ||
| 148 | }; | 115 | }; |
| 149 | 116 | ||
| 150 | //extern const INSTRACT arm_instruction_action[]; | ||
| 151 | extern const ISEITEM arm_instruction[]; | 117 | extern const ISEITEM arm_instruction[]; |
| 152 | |||
| 153 | #endif | ||
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 662b92579..a37e6c94e 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 | |||
| 622 | } | 622 | } |
| 623 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); | 623 | unsigned int rn = CHECK_READ_REG15_WA(cpu, Rn); |
| 624 | unsigned int start_addr = rn - count * 4 + 4; | 624 | unsigned int start_addr = rn - count * 4 + 4; |
| 625 | unsigned int end_addr = rn; | ||
| 626 | 625 | ||
| 627 | virt_addr = end_addr; | ||
| 628 | virt_addr = start_addr; | 626 | virt_addr = start_addr; |
| 629 | 627 | ||
| 630 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { | 628 | if (CondPassed(cpu, BITS(inst, 28, 31)) && BIT(inst, 21)) { |
| @@ -1104,10 +1102,10 @@ typedef struct _blx_1_thumb { | |||
| 1104 | }blx_1_thumb; | 1102 | }blx_1_thumb; |
| 1105 | 1103 | ||
| 1106 | typedef struct _pkh_inst { | 1104 | typedef struct _pkh_inst { |
| 1107 | u32 Rm; | 1105 | unsigned int Rm; |
| 1108 | u32 Rn; | 1106 | unsigned int Rn; |
| 1109 | u32 Rd; | 1107 | unsigned int Rd; |
| 1110 | u8 imm; | 1108 | unsigned char imm; |
| 1111 | } pkh_inst; | 1109 | } pkh_inst; |
| 1112 | 1110 | ||
| 1113 | typedef arm_inst * ARM_INST_PTR; | 1111 | typedef arm_inst * ARM_INST_PTR; |
| @@ -1740,40 +1738,31 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(ldrd)(unsigned int inst, int index) | |||
| 1740 | 1738 | ||
| 1741 | return inst_base; | 1739 | return inst_base; |
| 1742 | } | 1740 | } |
| 1743 | |||
| 1744 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) | 1741 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrex)(unsigned int inst, int index) |
| 1745 | { | 1742 | { |
| 1746 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1743 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 1747 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1744 | generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component; |
| 1748 | 1745 | ||
| 1749 | inst_base->cond = BITS(inst, 28, 31); | 1746 | inst_base->cond = BITS(inst, 28, 31); |
| 1750 | inst_base->idx = index; | 1747 | inst_base->idx = index; |
| 1751 | inst_base->br = NON_BRANCH; | 1748 | inst_base->br = (BITS(inst, 12, 15) == 15) ? INDIRECT_BRANCH : NON_BRANCH; // Branch if dest is R15 |
| 1752 | 1749 | ||
| 1753 | inst_cream->inst = inst; | 1750 | inst_cream->Rn = BITS(inst, 16, 19); |
| 1754 | //inst_cream->get_addr = get_calc_addr_op(inst); | 1751 | inst_cream->Rd = BITS(inst, 12, 15); |
| 1755 | 1752 | ||
| 1756 | if (BITS(inst, 12, 15) == 15) { | ||
| 1757 | inst_base->br = INDIRECT_BRANCH; | ||
| 1758 | } | ||
| 1759 | return inst_base; | 1753 | return inst_base; |
| 1760 | } | 1754 | } |
| 1761 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) | 1755 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexb)(unsigned int inst, int index) |
| 1762 | { | 1756 | { |
| 1763 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 1757 | return INTERPRETER_TRANSLATE(ldrex)(inst, index); |
| 1764 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 1758 | } |
| 1765 | 1759 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexh)(unsigned int inst, int index) | |
| 1766 | inst_base->cond = BITS(inst, 28, 31); | 1760 | { |
| 1767 | inst_base->idx = index; | 1761 | return INTERPRETER_TRANSLATE(ldrex)(inst, index); |
| 1768 | inst_base->br = NON_BRANCH; | 1762 | } |
| 1769 | 1763 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrexd)(unsigned int inst, int index) | |
| 1770 | inst_cream->inst = inst; | 1764 | { |
| 1771 | inst_cream->get_addr = get_calc_addr_op(inst); | 1765 | return INTERPRETER_TRANSLATE(ldrex)(inst, index); |
| 1772 | |||
| 1773 | if (BITS(inst, 12, 15) == 15) { | ||
| 1774 | inst_base->br = INDIRECT_BRANCH; | ||
| 1775 | } | ||
| 1776 | return inst_base; | ||
| 1777 | } | 1766 | } |
| 1778 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) | 1767 | ARM_INST_PTR INTERPRETER_TRANSLATE(ldrh)(unsigned int inst, int index) |
| 1779 | { | 1768 | { |
| @@ -2651,37 +2640,30 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(strd)(unsigned int inst, int index){ | |||
| 2651 | } | 2640 | } |
| 2652 | ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) | 2641 | ARM_INST_PTR INTERPRETER_TRANSLATE(strex)(unsigned int inst, int index) |
| 2653 | { | 2642 | { |
| 2654 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2643 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst)); |
| 2655 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2644 | generic_arm_inst *inst_cream = (generic_arm_inst *)inst_base->component; |
| 2656 | 2645 | ||
| 2657 | inst_base->cond = BITS(inst, 28, 31); | 2646 | inst_base->cond = BITS(inst, 28, 31); |
| 2658 | inst_base->idx = index; | 2647 | inst_base->idx = index; |
| 2659 | inst_base->br = NON_BRANCH; | 2648 | inst_base->br = NON_BRANCH; |
| 2660 | 2649 | ||
| 2661 | inst_cream->inst = inst; | 2650 | inst_cream->Rn = BITS(inst, 16, 19); |
| 2662 | inst_cream->get_addr = get_calc_addr_op(inst); | 2651 | inst_cream->Rd = BITS(inst, 12, 15); |
| 2652 | inst_cream->Rm = BITS(inst, 0, 3); | ||
| 2663 | 2653 | ||
| 2664 | if (BITS(inst, 12, 15) == 15) { | ||
| 2665 | inst_base->br = INDIRECT_BRANCH; | ||
| 2666 | } | ||
| 2667 | return inst_base; | 2654 | return inst_base; |
| 2668 | } | 2655 | } |
| 2669 | ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) | 2656 | ARM_INST_PTR INTERPRETER_TRANSLATE(strexb)(unsigned int inst, int index) |
| 2670 | { | 2657 | { |
| 2671 | arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(ldst_inst)); | 2658 | return INTERPRETER_TRANSLATE(strex)(inst, index); |
| 2672 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 2659 | } |
| 2673 | 2660 | ARM_INST_PTR INTERPRETER_TRANSLATE(strexh)(unsigned int inst, int index) | |
| 2674 | inst_base->cond = BITS(inst, 28, 31); | 2661 | { |
| 2675 | inst_base->idx = index; | 2662 | return INTERPRETER_TRANSLATE(strex)(inst, index); |
| 2676 | inst_base->br = NON_BRANCH; | 2663 | } |
| 2677 | 2664 | ARM_INST_PTR INTERPRETER_TRANSLATE(strexd)(unsigned int inst, int index) | |
| 2678 | inst_cream->inst = inst; | 2665 | { |
| 2679 | inst_cream->get_addr = get_calc_addr_op(inst); | 2666 | return INTERPRETER_TRANSLATE(strex)(inst, index); |
| 2680 | |||
| 2681 | if (BITS(inst, 12, 15) == 15) { | ||
| 2682 | inst_base->br = INDIRECT_BRANCH; | ||
| 2683 | } | ||
| 2684 | return inst_base; | ||
| 2685 | } | 2667 | } |
| 2686 | ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) | 2668 | ARM_INST_PTR INTERPRETER_TRANSLATE(strh)(unsigned int inst, int index) |
| 2687 | { | 2669 | { |
| @@ -3383,6 +3365,11 @@ const transop_fp_t arm_instruction_trans[] = { | |||
| 3383 | INTERPRETER_TRANSLATE(ldc), | 3365 | INTERPRETER_TRANSLATE(ldc), |
| 3384 | INTERPRETER_TRANSLATE(swi), | 3366 | INTERPRETER_TRANSLATE(swi), |
| 3385 | INTERPRETER_TRANSLATE(bbl), | 3367 | INTERPRETER_TRANSLATE(bbl), |
| 3368 | INTERPRETER_TRANSLATE(ldrexd), | ||
| 3369 | INTERPRETER_TRANSLATE(strexd), | ||
| 3370 | INTERPRETER_TRANSLATE(ldrexh), | ||
| 3371 | INTERPRETER_TRANSLATE(strexh), | ||
| 3372 | |||
| 3386 | // All the thumb instructions should be placed the end of table | 3373 | // All the thumb instructions should be placed the end of table |
| 3387 | INTERPRETER_TRANSLATE(b_2_thumb), | 3374 | INTERPRETER_TRANSLATE(b_2_thumb), |
| 3388 | INTERPRETER_TRANSLATE(b_cond_thumb), | 3375 | INTERPRETER_TRANSLATE(b_cond_thumb), |
| @@ -3579,6 +3566,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 3579 | #define CRm inst_cream->crm | 3566 | #define CRm inst_cream->crm |
| 3580 | #define CP15_REG(n) cpu->CP15[CP15(n)] | 3567 | #define CP15_REG(n) cpu->CP15[CP15(n)] |
| 3581 | #define RD cpu->Reg[inst_cream->Rd] | 3568 | #define RD cpu->Reg[inst_cream->Rd] |
| 3569 | #define RD2 cpu->Reg[inst_cream->Rd + 1] | ||
| 3582 | #define RN cpu->Reg[inst_cream->Rn] | 3570 | #define RN cpu->Reg[inst_cream->Rn] |
| 3583 | #define RM cpu->Reg[inst_cream->Rm] | 3571 | #define RM cpu->Reg[inst_cream->Rm] |
| 3584 | #define RS cpu->Reg[inst_cream->Rs] | 3572 | #define RS cpu->Reg[inst_cream->Rs] |
| @@ -3790,14 +3778,18 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 3790 | case 182: goto LDC_INST; \ | 3778 | case 182: goto LDC_INST; \ |
| 3791 | case 183: goto SWI_INST; \ | 3779 | case 183: goto SWI_INST; \ |
| 3792 | case 184: goto BBL_INST; \ | 3780 | case 184: goto BBL_INST; \ |
| 3793 | case 185: goto B_2_THUMB ; \ | 3781 | case 185: goto LDREXD_INST; \ |
| 3794 | case 186: goto B_COND_THUMB ; \ | 3782 | case 186: goto STREXD_INST; \ |
| 3795 | case 187: goto BL_1_THUMB ; \ | 3783 | case 187: goto LDREXH_INST; \ |
| 3796 | case 188: goto BL_2_THUMB ; \ | 3784 | case 188: goto STREXH_INST; \ |
| 3797 | case 189: goto BLX_1_THUMB ; \ | 3785 | case 189: goto B_2_THUMB ; \ |
| 3798 | case 190: goto DISPATCH; \ | 3786 | case 190: goto B_COND_THUMB ; \ |
| 3799 | case 191: goto INIT_INST_LENGTH; \ | 3787 | case 191: goto BL_1_THUMB ; \ |
| 3800 | case 192: goto END; \ | 3788 | case 192: goto BL_2_THUMB ; \ |
| 3789 | case 193: goto BLX_1_THUMB ; \ | ||
| 3790 | case 194: goto DISPATCH; \ | ||
| 3791 | case 195: goto INIT_INST_LENGTH; \ | ||
| 3792 | case 196: goto END; \ | ||
| 3801 | } | 3793 | } |
| 3802 | #endif | 3794 | #endif |
| 3803 | 3795 | ||
| @@ -3858,8 +3850,9 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 3858 | &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, | 3850 | &&MLA_INST,&&SSAT_INST,&&USAT_INST,&&MRS_INST,&&MSR_INST,&&AND_INST,&&BIC_INST,&&LDM_INST,&&EOR_INST,&&ADD_INST,&&RSB_INST,&&RSC_INST, |
| 3859 | &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, | 3851 | &&SBC_INST,&&ADC_INST,&&SUB_INST,&&ORR_INST,&&MVN_INST,&&MOV_INST,&&STM_INST,&&LDM_INST,&&LDRSH_INST,&&STM_INST,&&LDM_INST,&&LDRSB_INST, |
| 3860 | &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, | 3852 | &&STRD_INST,&&LDRH_INST,&&STRH_INST,&&LDRD_INST,&&STRT_INST,&&STRBT_INST,&&LDRBT_INST,&&LDRT_INST,&&MRC_INST,&&MCR_INST,&&MSR_INST, |
| 3861 | &&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, | 3853 | &&LDRB_INST,&&STRB_INST,&&LDR_INST,&&LDRCOND_INST, &&STR_INST,&&CDP_INST,&&STC_INST,&&LDC_INST,&&SWI_INST,&&BBL_INST,&&LDREXD_INST, |
| 3862 | &&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH,&&INIT_INST_LENGTH,&&END | 3854 | &&STREXD_INST,&&LDREXH_INST,&&STREXH_INST,&&B_2_THUMB, &&B_COND_THUMB,&&BL_1_THUMB, &&BL_2_THUMB, &&BLX_1_THUMB, &&DISPATCH, |
| 3855 | &&INIT_INST_LENGTH,&&END | ||
| 3863 | }; | 3856 | }; |
| 3864 | #endif | 3857 | #endif |
| 3865 | arm_inst * inst_base; | 3858 | arm_inst * inst_base; |
| @@ -4460,45 +4453,84 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4460 | 4453 | ||
| 4461 | LDREX_INST: | 4454 | LDREX_INST: |
| 4462 | { | 4455 | { |
| 4463 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4456 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4464 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4457 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4465 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 4458 | unsigned int read_addr = RN; |
| 4466 | 4459 | ||
| 4467 | unsigned int value = Memory::Read32(addr); | 4460 | add_exclusive_addr(cpu, read_addr); |
| 4468 | |||
| 4469 | add_exclusive_addr(cpu, addr); | ||
| 4470 | cpu->exclusive_state = 1; | 4461 | cpu->exclusive_state = 1; |
| 4471 | 4462 | ||
| 4472 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4463 | RD = Memory::Read32(read_addr); |
| 4473 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4464 | if (inst_cream->Rd == 15) { |
| 4474 | INC_PC(sizeof(ldst_inst)); | 4465 | INC_PC(sizeof(generic_arm_inst)); |
| 4475 | goto DISPATCH; | 4466 | goto DISPATCH; |
| 4476 | } | 4467 | } |
| 4477 | } | 4468 | } |
| 4478 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4469 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4479 | INC_PC(sizeof(ldst_inst)); | 4470 | INC_PC(sizeof(generic_arm_inst)); |
| 4480 | FETCH_INST; | 4471 | FETCH_INST; |
| 4481 | GOTO_NEXT_INST; | 4472 | GOTO_NEXT_INST; |
| 4482 | } | 4473 | } |
| 4483 | LDREXB_INST: | 4474 | LDREXB_INST: |
| 4484 | { | 4475 | { |
| 4485 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 4476 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 4486 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 4477 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 4487 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 4478 | unsigned int read_addr = RN; |
| 4488 | 4479 | ||
| 4489 | unsigned int value = Memory::Read8(addr); | 4480 | add_exclusive_addr(cpu, read_addr); |
| 4481 | cpu->exclusive_state = 1; | ||
| 4482 | |||
| 4483 | RD = Memory::Read8(read_addr); | ||
| 4484 | if (inst_cream->Rd == 15) { | ||
| 4485 | INC_PC(sizeof(generic_arm_inst)); | ||
| 4486 | goto DISPATCH; | ||
| 4487 | } | ||
| 4488 | } | ||
| 4489 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4490 | INC_PC(sizeof(generic_arm_inst)); | ||
| 4491 | FETCH_INST; | ||
| 4492 | GOTO_NEXT_INST; | ||
| 4493 | } | ||
| 4494 | LDREXH_INST: | ||
| 4495 | { | ||
| 4496 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 4497 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4498 | unsigned int read_addr = RN; | ||
| 4490 | 4499 | ||
| 4491 | add_exclusive_addr(cpu, addr); | 4500 | add_exclusive_addr(cpu, read_addr); |
| 4492 | cpu->exclusive_state = 1; | 4501 | cpu->exclusive_state = 1; |
| 4493 | 4502 | ||
| 4494 | cpu->Reg[BITS(inst_cream->inst, 12, 15)] = value; | 4503 | RD = Memory::Read16(read_addr); |
| 4495 | if (BITS(inst_cream->inst, 12, 15) == 15) { | 4504 | if (inst_cream->Rd == 15) { |
| 4496 | INC_PC(sizeof(ldst_inst)); | 4505 | INC_PC(sizeof(generic_arm_inst)); |
| 4497 | goto DISPATCH; | 4506 | goto DISPATCH; |
| 4498 | } | 4507 | } |
| 4499 | } | 4508 | } |
| 4500 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 4509 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 4501 | INC_PC(sizeof(ldst_inst)); | 4510 | INC_PC(sizeof(generic_arm_inst)); |
| 4511 | FETCH_INST; | ||
| 4512 | GOTO_NEXT_INST; | ||
| 4513 | } | ||
| 4514 | LDREXD_INST: | ||
| 4515 | { | ||
| 4516 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 4517 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 4518 | unsigned int read_addr = RN; | ||
| 4519 | |||
| 4520 | add_exclusive_addr(cpu, read_addr); | ||
| 4521 | cpu->exclusive_state = 1; | ||
| 4522 | // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive? | ||
| 4523 | |||
| 4524 | RD = Memory::Read32(read_addr); | ||
| 4525 | RD2 = Memory::Read32(read_addr + 4); | ||
| 4526 | |||
| 4527 | if (inst_cream->Rd == 15) { | ||
| 4528 | INC_PC(sizeof(generic_arm_inst)); | ||
| 4529 | goto DISPATCH; | ||
| 4530 | } | ||
| 4531 | } | ||
| 4532 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 4533 | INC_PC(sizeof(generic_arm_inst)); | ||
| 4502 | FETCH_INST; | 4534 | FETCH_INST; |
| 4503 | GOTO_NEXT_INST; | 4535 | GOTO_NEXT_INST; |
| 4504 | } | 4536 | } |
| @@ -5823,46 +5855,96 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5823 | } | 5855 | } |
| 5824 | STREX_INST: | 5856 | STREX_INST: |
| 5825 | { | 5857 | { |
| 5826 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5858 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 5859 | |||
| 5827 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5860 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5828 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5861 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 5829 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)]; | ||
| 5830 | 5862 | ||
| 5831 | int dest_reg = BITS(inst_cream->inst, 12, 15); | 5863 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { |
| 5832 | if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){ | 5864 | remove_exclusive(cpu, write_addr); |
| 5833 | remove_exclusive(cpu, addr); | ||
| 5834 | cpu->Reg[dest_reg] = 0; | ||
| 5835 | cpu->exclusive_state = 0; | 5865 | cpu->exclusive_state = 0; |
| 5836 | 5866 | ||
| 5837 | Memory::Write32(addr, value); | 5867 | Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); |
| 5868 | RD = 0; | ||
| 5838 | } else { | 5869 | } else { |
| 5839 | // Failed to write due to mutex access | 5870 | // Failed to write due to mutex access |
| 5840 | cpu->Reg[dest_reg] = 1; | 5871 | RD = 1; |
| 5841 | } | 5872 | } |
| 5842 | } | 5873 | } |
| 5843 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5874 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5844 | INC_PC(sizeof(ldst_inst)); | 5875 | INC_PC(sizeof(generic_arm_inst)); |
| 5845 | FETCH_INST; | 5876 | FETCH_INST; |
| 5846 | GOTO_NEXT_INST; | 5877 | GOTO_NEXT_INST; |
| 5847 | } | 5878 | } |
| 5848 | STREXB_INST: | 5879 | STREXB_INST: |
| 5849 | { | 5880 | { |
| 5850 | ldst_inst *inst_cream = (ldst_inst *)inst_base->component; | 5881 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; |
| 5882 | |||
| 5851 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | 5883 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { |
| 5852 | addr = cpu->Reg[BITS(inst_cream->inst, 16, 19)]; | 5884 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; |
| 5853 | unsigned int value = cpu->Reg[BITS(inst_cream->inst, 0, 3)] & 0xff; | 5885 | |
| 5854 | int dest_reg = BITS(inst_cream->inst, 12, 15); | 5886 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { |
| 5855 | if((exclusive_detect(cpu, addr) == 0) && (cpu->exclusive_state == 1)){ | 5887 | remove_exclusive(cpu, write_addr); |
| 5856 | remove_exclusive(cpu, addr); | ||
| 5857 | cpu->Reg[dest_reg] = 0; | ||
| 5858 | cpu->exclusive_state = 0; | 5888 | cpu->exclusive_state = 0; |
| 5859 | Memory::Write8(addr, value); | 5889 | |
| 5890 | Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); | ||
| 5891 | RD = 0; | ||
| 5860 | } else { | 5892 | } else { |
| 5861 | cpu->Reg[dest_reg] = 1; | 5893 | // Failed to write due to mutex access |
| 5894 | RD = 1; | ||
| 5862 | } | 5895 | } |
| 5863 | } | 5896 | } |
| 5864 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5897 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
| 5865 | INC_PC(sizeof(ldst_inst)); | 5898 | INC_PC(sizeof(generic_arm_inst)); |
| 5899 | FETCH_INST; | ||
| 5900 | GOTO_NEXT_INST; | ||
| 5901 | } | ||
| 5902 | STREXD_INST: | ||
| 5903 | { | ||
| 5904 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5905 | |||
| 5906 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5907 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | ||
| 5908 | |||
| 5909 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | ||
| 5910 | remove_exclusive(cpu, write_addr); | ||
| 5911 | cpu->exclusive_state = 0; | ||
| 5912 | // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD | ||
| 5913 | |||
| 5914 | Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); | ||
| 5915 | Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); | ||
| 5916 | RD = 0; | ||
| 5917 | } | ||
| 5918 | else { | ||
| 5919 | // Failed to write due to mutex access | ||
| 5920 | RD = 1; | ||
| 5921 | } | ||
| 5922 | } | ||
| 5923 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5924 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5925 | FETCH_INST; | ||
| 5926 | GOTO_NEXT_INST; | ||
| 5927 | } | ||
| 5928 | STREXH_INST: | ||
| 5929 | { | ||
| 5930 | generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; | ||
| 5931 | |||
| 5932 | if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { | ||
| 5933 | unsigned int write_addr = cpu->Reg[inst_cream->Rn]; | ||
| 5934 | |||
| 5935 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | ||
| 5936 | remove_exclusive(cpu, write_addr); | ||
| 5937 | cpu->exclusive_state = 0; | ||
| 5938 | |||
| 5939 | Memory::Write16(write_addr, cpu->Reg[inst_cream->Rm]); | ||
| 5940 | RD = 0; | ||
| 5941 | } else { | ||
| 5942 | // Failed to write due to mutex access | ||
| 5943 | RD = 1; | ||
| 5944 | } | ||
| 5945 | } | ||
| 5946 | cpu->Reg[15] += GET_INST_SIZE(cpu); | ||
| 5947 | INC_PC(sizeof(generic_arm_inst)); | ||
| 5866 | FETCH_INST; | 5948 | FETCH_INST; |
| 5867 | GOTO_NEXT_INST; | 5949 | GOTO_NEXT_INST; |
| 5868 | } | 5950 | } |
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index f19ca3a9f..9a91bcb8b 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp | |||
| @@ -63,7 +63,7 @@ enum class DirectoryCommand : u32 { | |||
| 63 | class Archive { | 63 | class Archive { |
| 64 | public: | 64 | public: |
| 65 | Archive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) | 65 | Archive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, ArchiveIdCode id_code) |
| 66 | : backend(std::move(backend)), id_code(id_code) { | 66 | : id_code(id_code), backend(std::move(backend)) { |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | std::string GetName() const { return "Archive: " + backend->GetName(); } | 69 | std::string GetName() const { return "Archive: " + backend->GetName(); } |
| @@ -75,7 +75,7 @@ public: | |||
| 75 | class File : public Kernel::Session { | 75 | class File : public Kernel::Session { |
| 76 | public: | 76 | public: |
| 77 | File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) | 77 | File(std::unique_ptr<FileSys::FileBackend>&& backend, const FileSys::Path& path) |
| 78 | : backend(std::move(backend)), path(path) { | 78 | : path(path), backend(std::move(backend)) { |
| 79 | } | 79 | } |
| 80 | 80 | ||
| 81 | std::string GetName() const override { return "Path: " + path.DebugStr(); } | 81 | std::string GetName() const override { return "Path: " + path.DebugStr(); } |
| @@ -160,7 +160,7 @@ public: | |||
| 160 | class Directory : public Kernel::Session { | 160 | class Directory : public Kernel::Session { |
| 161 | public: | 161 | public: |
| 162 | Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path) | 162 | Directory(std::unique_ptr<FileSys::DirectoryBackend>&& backend, const FileSys::Path& path) |
| 163 | : backend(std::move(backend)), path(path) { | 163 | : path(path), backend(std::move(backend)) { |
| 164 | } | 164 | } |
| 165 | 165 | ||
| 166 | std::string GetName() const override { return "Directory: " + path.DebugStr(); } | 166 | std::string GetName() const override { return "Directory: " + path.DebugStr(); } |
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 354335014..3ca60c072 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp | |||
| @@ -222,7 +222,7 @@ public: | |||
| 222 | int GetSectionSize(SectionID section) const { return sections[section].sh_size; } | 222 | int GetSectionSize(SectionID section) const { return sections[section].sh_size; } |
| 223 | SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found | 223 | SectionID GetSectionByName(const char *name, int firstSection = 0) const; //-1 for not found |
| 224 | 224 | ||
| 225 | bool DidRelocate() { | 225 | bool DidRelocate() const { |
| 226 | return relocate; | 226 | return relocate; |
| 227 | } | 227 | } |
| 228 | }; | 228 | }; |