summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp12
-rw-r--r--src/core/arm/skyeye_common/armdefs.h22
2 files changed, 18 insertions, 16 deletions
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index 593e0eabd..9b291862c 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);
63typedef arm_core_t arm_processor; 63typedef arm_core_t arm_processor;
64typedef unsigned int (*shtop_fp_t)(arm_processor *cpu, unsigned int sht_oper); 64typedef 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.
69static const ARMword RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
70
66// Exclusive memory access 71// Exclusive memory access
67static int exclusive_detect(ARMul_State* state, ARMword addr){ 72static 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
74static void add_exclusive_addr(ARMul_State* state, ARMword addr){ 79static 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
84unsigned int DPO(Immediate)(arm_processor *cpu, unsigned int sht_oper) { 88unsigned 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);
@@ -4613,7 +4617,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
4613 4617
4614 add_exclusive_addr(cpu, read_addr); 4618 add_exclusive_addr(cpu, read_addr);
4615 cpu->exclusive_state = 1; 4619 cpu->exclusive_state = 1;
4616 // TODO(bunnei): Do we need to also make [read_addr + 4] exclusive?
4617 4620
4618 RD = Memory::Read32(read_addr); 4621 RD = Memory::Read32(read_addr);
4619 RD2 = Memory::Read32(read_addr + 4); 4622 RD2 = Memory::Read32(read_addr + 4);
@@ -6133,7 +6136,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
6133 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { 6136 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) {
6134 remove_exclusive(cpu, write_addr); 6137 remove_exclusive(cpu, write_addr);
6135 cpu->exclusive_state = 0; 6138 cpu->exclusive_state = 0;
6136 // TODO(bunnei): Remove exclusive from [write_addr + 4] if we implement this in LDREXD
6137 6139
6138 Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]); 6140 Memory::Write32(write_addr, cpu->Reg[inst_cream->Rm]);
6139 Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]); 6141 Memory::Write32(write_addr + 4, cpu->Reg[inst_cream->Rm + 1]);
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 3100d7adc..1b2cef451 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -165,20 +165,20 @@ struct ARMul_State
165 unsigned ErrorCode; /* type of illegal instruction */ 165 unsigned ErrorCode; /* type of illegal instruction */
166 166
167 /* Order of the following register should not be modified */ 167 /* Order of the following register should not be modified */
168 ARMword Reg[16]; /* the current register file */ 168 ARMword Reg[16]; /* the current register file */
169 ARMword Cpsr; /* the current psr */ 169 ARMword Cpsr; /* the current psr */
170 ARMword Spsr_copy; 170 ARMword Spsr_copy;
171 ARMword phys_pc; 171 ARMword phys_pc;
172 ARMword Reg_usr[2]; 172 ARMword Reg_usr[2];
173 ARMword Reg_svc[2]; /* R13_SVC R14_SVC */ 173 ARMword Reg_svc[2]; /* R13_SVC R14_SVC */
174 ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */ 174 ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */
175 ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */ 175 ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */
176 ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */ 176 ARMword Reg_irq[2]; /* R13_IRQ R14_IRQ */
177 ARMword Reg_firq[7]; /* R8---R14 FIRQ */ 177 ARMword Reg_firq[7]; /* R8---R14 FIRQ */
178 ARMword Spsr[7]; /* the exception psr's */ 178 ARMword Spsr[7]; /* the exception psr's */
179 ARMword Mode; /* the current mode */ 179 ARMword Mode; /* the current mode */
180 ARMword Bank; /* the current register bank */ 180 ARMword Bank; /* the current register bank */
181 ARMword exclusive_tag; 181 ARMword exclusive_tag; /* the address for which the local monitor is in exclusive access mode */
182 ARMword exclusive_state; 182 ARMword exclusive_state;
183 ARMword exclusive_result; 183 ARMword exclusive_result;
184 ARMword CP15[VFP_BASE - CP15_BASE]; 184 ARMword CP15[VFP_BASE - CP15_BASE];