aboutsummaryrefslogtreecommitdiff
path: root/target-arm/op_mem.h
diff options
context:
space:
mode:
Diffstat (limited to 'target-arm/op_mem.h')
-rw-r--r--target-arm/op_mem.h59
1 files changed, 59 insertions, 0 deletions
diff --git a/target-arm/op_mem.h b/target-arm/op_mem.h
index 6bccb0651..b12b63c5f 100644
--- a/target-arm/op_mem.h
+++ b/target-arm/op_mem.h
@@ -1,5 +1,6 @@
/* ARM memory operations. */
+void helper_ld(uint32_t);
/* Load from address T1 into T0. */
#define MEM_LD_OP(name) \
void OPPROTO glue(op_ld##name,MEMSUFFIX)(void) \
@@ -49,6 +50,64 @@ MEM_SWP_OP(l, l)
#undef MEM_SWP_OP
+/* Load-locked, store exclusive. */
+#define EXCLUSIVE_OP(suffix, ldsuffix) \
+void OPPROTO glue(op_ld##suffix##ex,MEMSUFFIX)(void) \
+{ \
+ cpu_lock(); \
+ helper_mark_exclusive(env, T1); \
+ T0 = glue(ld##ldsuffix,MEMSUFFIX)(T1); \
+ cpu_unlock(); \
+ FORCE_RET(); \
+} \
+ \
+void OPPROTO glue(op_st##suffix##ex,MEMSUFFIX)(void) \
+{ \
+ int failed; \
+ cpu_lock(); \
+ failed = helper_test_exclusive(env, T1); \
+ /* ??? Is it safe to hold the cpu lock over a store? */ \
+ if (!failed) { \
+ glue(st##suffix,MEMSUFFIX)(T1, T0); \
+ } \
+ T0 = failed; \
+ cpu_unlock(); \
+ FORCE_RET(); \
+}
+
+EXCLUSIVE_OP(b, ub)
+EXCLUSIVE_OP(w, uw)
+EXCLUSIVE_OP(l, l)
+
+#undef EXCLUSIVE_OP
+
+/* Load exclusive T0:T1 from address T1. */
+void OPPROTO glue(op_ldqex,MEMSUFFIX)(void)
+{
+ cpu_lock();
+ helper_mark_exclusive(env, T1);
+ T0 = glue(ldl,MEMSUFFIX)(T1);
+ T1 = glue(ldl,MEMSUFFIX)((T1 + 4));
+ cpu_unlock();
+ FORCE_RET();
+}
+
+/* Store exclusive T0:T2 to address T1. */
+void OPPROTO glue(op_stqex,MEMSUFFIX)(void)
+{
+ int failed;
+ cpu_lock();
+ failed = helper_test_exclusive(env, T1);
+ /* ??? Is it safe to hold the cpu lock over a store? */
+ if (!failed) {
+ glue(stl,MEMSUFFIX)(T1, T0);
+ glue(stl,MEMSUFFIX)((T1 + 4), T2);
+ }
+ T0 = failed;
+ cpu_unlock();
+ FORCE_RET();
+}
+
/* Floating point load/store. Address is in T1 */
#define VFP_MEM_OP(p, w) \
void OPPROTO glue(op_vfp_ld##p,MEMSUFFIX)(void) \