qemu/target-arm/op_mem.h

150 lines
3.0 KiB
C
Raw Normal View History

/* 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) \
{ \
T0 = glue(ld##name,MEMSUFFIX)(T1); \
FORCE_RET(); \
}
MEM_LD_OP(ub)
MEM_LD_OP(sb)
MEM_LD_OP(uw)
MEM_LD_OP(sw)
MEM_LD_OP(l)
#undef MEM_LD_OP
/* Store T0 to address T1. */
#define MEM_ST_OP(name) \
void OPPROTO glue(op_st##name,MEMSUFFIX)(void) \
{ \
glue(st##name,MEMSUFFIX)(T1, T0); \
FORCE_RET(); \
}
MEM_ST_OP(b)
MEM_ST_OP(w)
MEM_ST_OP(l)
#undef MEM_ST_OP
/* Swap T0 with memory at address T1. */
/* ??? Is this exception safe? */
#define MEM_SWP_OP(name, lname) \
void OPPROTO glue(op_swp##name,MEMSUFFIX)(void) \
{ \
uint32_t tmp; \
cpu_lock(); \
tmp = glue(ld##lname,MEMSUFFIX)(T1); \
glue(st##name,MEMSUFFIX)(T1, T0); \
T0 = tmp; \
cpu_unlock(); \
FORCE_RET(); \
}
MEM_SWP_OP(b, ub)
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) \
{ \
FT0##p = glue(ldf##w,MEMSUFFIX)(T1); \
FORCE_RET(); \
} \
void OPPROTO glue(op_vfp_st##p,MEMSUFFIX)(void) \
{ \
glue(stf##w,MEMSUFFIX)(T1, FT0##p); \
FORCE_RET(); \
}
VFP_MEM_OP(s,l)
VFP_MEM_OP(d,q)
#undef VFP_MEM_OP
/* iwMMXt load/store. Address is in T1 */
#define MMX_MEM_OP(name, ldname) \
void OPPROTO glue(op_iwmmxt_ld##name,MEMSUFFIX)(void) \
{ \
M0 = glue(ld##ldname,MEMSUFFIX)(T1); \
FORCE_RET(); \
} \
void OPPROTO glue(op_iwmmxt_st##name,MEMSUFFIX)(void) \
{ \
glue(st##name,MEMSUFFIX)(T1, M0); \
FORCE_RET(); \
}
MMX_MEM_OP(b, ub)
MMX_MEM_OP(w, uw)
MMX_MEM_OP(l, l)
MMX_MEM_OP(q, q)
#undef MMX_MEM_OP
#undef MEMSUFFIX