@ -2976,6 +2976,63 @@ LARX(lbarx, DEF_MEMOP(MO_UB))
LARX ( lharx , DEF_MEMOP ( MO_UW ) )
LARX ( lwarx , DEF_MEMOP ( MO_UL ) )
# define LD_ATOMIC(name, memop, tp, op, eop) \
static void gen_ # # name ( DisasContext * ctx ) \
{ \
int len = MEMOP_GET_SIZE ( memop ) ; \
uint32_t gpr_FC = FC ( ctx - > opcode ) ; \
TCGv EA = tcg_temp_local_new ( ) ; \
TCGv_ # # tp t0 , t1 ; \
\
gen_addr_register ( ctx , EA ) ; \
if ( len > 1 ) { \
gen_check_align ( ctx , EA , len - 1 ) ; \
} \
t0 = tcg_temp_new_ # # tp ( ) ; \
t1 = tcg_temp_new_ # # tp ( ) ; \
tcg_gen_ # # op ( t0 , cpu_gpr [ rD ( ctx - > opcode ) + 1 ] ) ; \
\
switch ( gpr_FC ) { \
case 0 : /* Fetch and add */ \
tcg_gen_atomic_fetch_add_ # # tp ( t1 , EA , t0 , ctx - > mem_idx , memop ) ; \
break ; \
case 1 : /* Fetch and xor */ \
tcg_gen_atomic_fetch_xor_ # # tp ( t1 , EA , t0 , ctx - > mem_idx , memop ) ; \
break ; \
case 2 : /* Fetch and or */ \
tcg_gen_atomic_fetch_or_ # # tp ( t1 , EA , t0 , ctx - > mem_idx , memop ) ; \
break ; \
case 3 : /* Fetch and 'and' */ \
tcg_gen_atomic_fetch_and_ # # tp ( t1 , EA , t0 , ctx - > mem_idx , memop ) ; \
break ; \
case 8 : /* Swap */ \
tcg_gen_atomic_xchg_ # # tp ( t1 , EA , t0 , ctx - > mem_idx , memop ) ; \
break ; \
case 4 : /* Fetch and max unsigned */ \
case 5 : /* Fetch and max signed */ \
case 6 : /* Fetch and min unsigned */ \
case 7 : /* Fetch and min signed */ \
case 16 : /* compare and swap not equal */ \
case 24 : /* Fetch and increment bounded */ \
case 25 : /* Fetch and increment equal */ \
case 28 : /* Fetch and decrement bounded */ \
gen_invalid ( ctx ) ; \
break ; \
default : \
/* invoke data storage error handler */ \
gen_exception_err ( ctx , POWERPC_EXCP_DSI , POWERPC_EXCP_INVAL ) ; \
} \
tcg_gen_ # # eop ( cpu_gpr [ rD ( ctx - > opcode ) ] , t1 ) ; \
tcg_temp_free_ # # tp ( t0 ) ; \
tcg_temp_free_ # # tp ( t1 ) ; \
tcg_temp_free ( EA ) ; \
}
LD_ATOMIC ( lwat , DEF_MEMOP ( MO_UL ) , i32 , trunc_tl_i32 , extu_i32_tl )
# if defined(TARGET_PPC64)
LD_ATOMIC ( ldat , DEF_MEMOP ( MO_Q ) , i64 , mov_i64 , mov_i64 )
# endif
# if defined(CONFIG_USER_ONLY)
static void gen_conditional_store ( DisasContext * ctx , TCGv EA ,
int reg , int memop )
@ -6230,10 +6287,12 @@ GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
GEN_HANDLER_E ( lbarx , 0x1F , 0x14 , 0x01 , 0 , PPC_NONE , PPC2_ATOMIC_ISA206 ) ,
GEN_HANDLER_E ( lharx , 0x1F , 0x14 , 0x03 , 0 , PPC_NONE , PPC2_ATOMIC_ISA206 ) ,
GEN_HANDLER ( lwarx , 0x1F , 0x14 , 0x00 , 0x00000000 , PPC_RES ) ,
GEN_HANDLER_E ( lwat , 0x1F , 0x06 , 0x12 , 0x00000001 , PPC_NONE , PPC2_ISA300 ) ,
GEN_HANDLER_E ( stbcx_ , 0x1F , 0x16 , 0x15 , 0 , PPC_NONE , PPC2_ATOMIC_ISA206 ) ,
GEN_HANDLER_E ( sthcx_ , 0x1F , 0x16 , 0x16 , 0 , PPC_NONE , PPC2_ATOMIC_ISA206 ) ,
GEN_HANDLER2 ( stwcx_ , " stwcx. " , 0x1F , 0x16 , 0x04 , 0x00000000 , PPC_RES ) ,
# if defined(TARGET_PPC64)
GEN_HANDLER_E ( ldat , 0x1F , 0x06 , 0x13 , 0x00000001 , PPC_NONE , PPC2_ISA300 ) ,
GEN_HANDLER ( ldarx , 0x1F , 0x14 , 0x02 , 0x00000000 , PPC_64B ) ,
GEN_HANDLER_E ( lqarx , 0x1F , 0x14 , 0x08 , 0 , PPC_NONE , PPC2_LSQ_ISA207 ) ,
GEN_HANDLER2 ( stdcx_ , " stdcx. " , 0x1F , 0x16 , 0x06 , 0x00000000 , PPC_64B ) ,