mirror of
https://github.com/qemu/qemu.git
synced 2024-11-25 03:43:37 +08:00
9ee6e8bb85
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3572 c046a42c-6fe2-441c-8c8c-71466251a162
150 lines
3.0 KiB
C
150 lines
3.0 KiB
C
/* 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
|