3153
}
3154
#endif
3155
3156
-static void gen_conditional_store(DisasContext *ctx, MemOp memop)
3157
-{
3158
- TCGLabel *lfail;
3159
- TCGv EA;
3160
- TCGv cr0;
3161
- TCGv t0;
3162
- int rs = rS(ctx->opcode);
3163
-
3164
- lfail = gen_new_label();
3165
- EA = tcg_temp_new();
3166
- cr0 = tcg_temp_new();
3167
- t0 = tcg_temp_new();
3168
-
3169
- tcg_gen_mov_tl(cr0, cpu_so);
3170
- gen_set_access_type(ctx, ACCESS_RES);
3171
- gen_addr_reg_index(ctx, EA);
3172
- tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lfail);
3173
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, memop_size(memop), lfail);
3174
-
3175
- tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val,
3176
- cpu_gpr[rs], ctx->mem_idx,
3177
- DEF_MEMOP(memop) | MO_ALIGN);
3178
- tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val);
3179
- tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
3180
- tcg_gen_or_tl(cr0, cr0, t0);
3181
-
3182
- gen_set_label(lfail);
3183
- tcg_gen_trunc_tl_i32(cpu_crf[0], cr0);
3184
- tcg_gen_movi_tl(cpu_reserve, -1);
3185
-}
3186
-
3187
-#define STCX(name, memop) \
3188
-static void gen_##name(DisasContext *ctx) \
3189
-{ \
3190
- gen_conditional_store(ctx, memop); \
3191
-}
3192
-
3193
-STCX(stbcx_, MO_UB)
3194
-STCX(sthcx_, MO_UW)
3195
-STCX(stwcx_, MO_UL)
3196
-
3197
-#if defined(TARGET_PPC64)
3198
-/* stdcx. */
3199
-STCX(stdcx_, MO_UQ)
3200
-
3201
-/* stqcx. */
3202
-static void gen_stqcx_(DisasContext *ctx)
3203
-{
3204
- TCGLabel *lfail;
3205
- TCGv EA, t0, t1;
3206
- TCGv cr0;
3207
- TCGv_i128 cmp, val;
3208
- int rs = rS(ctx->opcode);
3209
-
3210
- if (unlikely(rs & 1)) {
3211
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3212
- return;
3213
- }
3214
-
3215
- lfail = gen_new_label();
3216
- EA = tcg_temp_new();
3217
- cr0 = tcg_temp_new();
3218
-
3219
- tcg_gen_mov_tl(cr0, cpu_so);
3220
- gen_set_access_type(ctx, ACCESS_RES);
3221
- gen_addr_reg_index(ctx, EA);
3222
- tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, lfail);
3223
- tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, 16, lfail);
3224
-
3225
- cmp = tcg_temp_new_i128();
3226
- val = tcg_temp_new_i128();
3227
-
3228
- tcg_gen_concat_i64_i128(cmp, cpu_reserve_val2, cpu_reserve_val);
3229
-
3230
- /* Note that the low part is always in RS+1, even in LE mode. */
3231
- tcg_gen_concat_i64_i128(val, cpu_gpr[rs + 1], cpu_gpr[rs]);
3232
-
3233
- tcg_gen_atomic_cmpxchg_i128(val, cpu_reserve, cmp, val, ctx->mem_idx,
3234
- DEF_MEMOP(MO_128 | MO_ALIGN));
3235
-
3236
- t0 = tcg_temp_new();
3237
- t1 = tcg_temp_new();
3238
- tcg_gen_extr_i128_i64(t1, t0, val);
3239
-
3240
- tcg_gen_xor_tl(t1, t1, cpu_reserve_val2);
3241
- tcg_gen_xor_tl(t0, t0, cpu_reserve_val);
3242
- tcg_gen_or_tl(t0, t0, t1);
3243
-
3244
- tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, 0);
3245
- tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
3246
- tcg_gen_or_tl(cr0, cr0, t0);
3247
-
3248
- gen_set_label(lfail);
3249
- tcg_gen_trunc_tl_i32(cpu_crf[0], cr0);
3250
- tcg_gen_movi_tl(cpu_reserve, -1);
3251
-}
3252
-#endif /* defined(TARGET_PPC64) */
3253
-
3156
/* wait */
3157
static void gen_wait(DisasContext *ctx)
3158
{
5788
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
5789
GEN_HANDLER_E(lwat, 0x1F, 0x06, 0x12, 0x00000001, PPC_NONE, PPC2_ISA300),
5790
GEN_HANDLER_E(stwat, 0x1F, 0x06, 0x16, 0x00000001, PPC_NONE, PPC2_ISA300),
5889
-GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
5890
-GEN_HANDLER_E(sthcx_, 0x1F, 0x16, 0x16, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
5891
-GEN_HANDLER2(stwcx_, "stwcx.", 0x1F, 0x16, 0x04, 0x00000000, PPC_RES),
5791
#if defined(TARGET_PPC64)
5792
GEN_HANDLER_E(ldat, 0x1F, 0x06, 0x13, 0x00000001, PPC_NONE, PPC2_ISA300),
5793
GEN_HANDLER_E(stdat, 0x1F, 0x06, 0x17, 0x00000001, PPC_NONE, PPC2_ISA300),
5895
-GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
5896
-GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
5794
#endif
5795
/* ISA v3.0 changed the extended opcode from 62 to 30 */
5796
GEN_HANDLER(wait, 0x1F, 0x1E, 0x01, 0x039FF801, PPC_WAIT),