diff options
| author | 2015-01-05 02:17:00 -0500 | |
|---|---|---|
| committer | 2015-01-05 22:29:51 -0500 | |
| commit | 8132c01830c9e71e75e6bc1e365326cf07c5b00f (patch) | |
| tree | ad7c0dc3e66c477a42280a9672d68d0be48607cc /src/core/arm/dyncom | |
| parent | Merge pull request #397 from bunnei/vfp-cleanup (diff) | |
| download | yuzu-8132c01830c9e71e75e6bc1e365326cf07c5b00f.tar.gz yuzu-8132c01830c9e71e75e6bc1e365326cf07c5b00f.tar.xz yuzu-8132c01830c9e71e75e6bc1e365326cf07c5b00f.zip | |
Added exclusive reservation granule from ARMv7 spec to dyncom to protect LDR/STREX.
Diffstat (limited to 'src/core/arm/dyncom')
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index 64335b9c2..ba23ef383 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -63,16 +63,21 @@ extern void switch_mode(arm_core_t *core, uint32_t mode); | |||
| 63 | typedef arm_core_t arm_processor; | 63 | typedef arm_core_t arm_processor; |
| 64 | typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); | 64 | typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); |
| 65 | 65 | ||
| 66 | // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag. | ||
| 67 | // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to | ||
| 68 | // support LDR/STREXD. | ||
| 69 | static const ARMword RESERVATION_GRANULE_MASK = 0xFFFFFFF8; | ||
| 70 | |||
| 66 | // Exclusive memory access | 71 | // Exclusive memory access |
| 67 | static int exclusive_detect(ARMul_State* state, ARMword addr){ | 72 | static int exclusive_detect(ARMul_State* state, ARMword addr){ |
| 68 | if(state->exclusive_tag == addr) | 73 | if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK)) |
| 69 | return 0; | 74 | return 0; |
| 70 | else | 75 | else |
| 71 | return -1; | 76 | return -1; |
| 72 | } | 77 | } |
| 73 | 78 | ||
| 74 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ | 79 | static void add_exclusive_addr(ARMul_State* state, ARMword addr){ |
| 75 | state->exclusive_tag = addr; | 80 | state->exclusive_tag = addr & RESERVATION_GRANULE_MASK; |
| 76 | return; | 81 | return; |
| 77 | } | 82 | } |
| 78 | 83 | ||
| @@ -80,7 +85,6 @@ static void remove_exclusive(ARMul_State* state, ARMword addr){ | |||
| 80 | state->exclusive_tag = 0xFFFFFFFF; | 85 | state->exclusive_tag = 0xFFFFFFFF; |
| 81 | } | 86 | } |
| 82 | 87 | ||
| 83 | |||
| 84 | unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { | 88 | unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { |
| 85 | unsigned int immed_8 = BITS(sht_oper, 0, 7); | 89 | unsigned int immed_8 = BITS(sht_oper, 0, 7); |
| 86 | unsigned int rotate_imm = BITS(sht_oper, 8, 11); | 90 | unsigned int rotate_imm = BITS(sht_oper, 8, 11); |
| @@ -4551,7 +4555,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4551 | 4555 | ||
| 4552 | add_exclusive_addr(cpu, read_addr); | 4556 | add_exclusive_addr(cpu, read_addr); |
| 4553 | cpu->exclusive_state = 1; | 4557 | cpu->exclusive_state = 1; |
| 4554 | // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive? | ||
| 4555 | 4558 | ||
| 4556 | RD = Memory::Read32(read_addr); | 4559 | RD = Memory::Read32(read_addr); |
| 4557 | RD2 = Memory::Read32(read_addr + 4); | 4560 | RD2 = Memory::Read32(read_addr + 4); |
| @@ -5978,7 +5981,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 5978 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { | 5981 | if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { |
| 5979 | remove_exclusive(cpu, write_addr); | 5982 | remove_exclusive(cpu, write_addr); |
| 5980 | cpu->exclusive_state = 0; | 5983 | cpu->exclusive_state = 0; |
| 5981 | // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD | ||
| 5982 | 5984 | ||
| 5983 | Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); | 5985 | Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); |
| 5984 | Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); | 5986 | Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); |