2947
ctx->base.is_jmp = DISAS_EXIT_UPDATE;
2948
}
2949
2950
-static void gen_load_locked(DisasContext *ctx, MemOp memop)
2951
-{
2952
- TCGv gpr = cpu_gpr[rD(ctx->opcode)];
2953
- TCGv t0 = tcg_temp_new();
2954
-
2955
- gen_set_access_type(ctx, ACCESS_RES);
2956
- gen_addr_reg_index(ctx, t0);
2957
- tcg_gen_qemu_ld_tl(gpr, t0, ctx->mem_idx, DEF_MEMOP(memop) | MO_ALIGN);
2958
- tcg_gen_mov_tl(cpu_reserve, t0);
2959
- tcg_gen_movi_tl(cpu_reserve_length, memop_size(memop));
2960
- tcg_gen_mov_tl(cpu_reserve_val, gpr);
2961
-}
2962
-
2963
-#define LARX(name, memop) \
2964
-static void gen_##name(DisasContext *ctx) \
2965
-{ \
2966
- gen_load_locked(ctx, memop); \
2967
-}
2968
-
2969
-/* lwarx */
2970
-LARX(lbarx, MO_UB)
2971
-LARX(lharx, MO_UW)
2972
-LARX(lwarx, MO_UL)
2973
-
2950
static void gen_fetch_inc_conditional(DisasContext *ctx, MemOp memop,
2951
TCGv EA, TCGCond cond, int addend)
2952
{
3195
STCX(stwcx_, MO_UL)
3196
3197
#if defined(TARGET_PPC64)
3222
-/* ldarx */
3223
-LARX(ldarx, MO_UQ)
3198
/* stdcx. */
3199
STCX(stdcx_, MO_UQ)
3200
3227
-/* lqarx */
3228
-static void gen_lqarx(DisasContext *ctx)
3229
-{
3230
- int rd = rD(ctx->opcode);
3231
- TCGv EA, hi, lo;
3232
- TCGv_i128 t16;
3233
-
3234
- if (unlikely((rd & 1) || (rd == rA(ctx->opcode)) ||
3235
- (rd == rB(ctx->opcode)))) {
3236
- gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
3237
- return;
3238
- }
3239
-
3240
- gen_set_access_type(ctx, ACCESS_RES);
3241
- EA = tcg_temp_new();
3242
- gen_addr_reg_index(ctx, EA);
3243
-
3244
- /* Note that the low part is always in RD+1, even in LE mode. */
3245
- lo = cpu_gpr[rd + 1];
3246
- hi = cpu_gpr[rd];
3247
-
3248
- t16 = tcg_temp_new_i128();
3249
- tcg_gen_qemu_ld_i128(t16, EA, ctx->mem_idx, DEF_MEMOP(MO_128 | MO_ALIGN));
3250
- tcg_gen_extr_i128_i64(lo, hi, t16);
3251
-
3252
- tcg_gen_mov_tl(cpu_reserve, EA);
3253
- tcg_gen_movi_tl(cpu_reserve_length, 16);
3254
- tcg_gen_st_tl(hi, tcg_env, offsetof(CPUPPCState, reserve_val));
3255
- tcg_gen_st_tl(lo, tcg_env, offsetof(CPUPPCState, reserve_val2));
3256
-}
3257
-
3201
/* stqcx. */
3202
static void gen_stqcx_(DisasContext *ctx)
3203
{
5684
return true;
5685
}
5686
5687
+/*
5688
+ * Load-and-reserve core
5689
+ */
5690
+static bool do_load_locked(DisasContext *ctx, arg_X_rc *a, MemOp memop)
5691
+{
5692
+ TCGv EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5693
+ TCGv gpr = cpu_gpr[a->rt];
5694
+
5695
+ gen_set_access_type(ctx, ACCESS_RES);
5696
+
5697
+ tcg_gen_qemu_ld_tl(gpr, EA, ctx->mem_idx, memop | MO_ALIGN);
5698
+
5699
+ tcg_gen_mov_tl(cpu_reserve, EA);
5700
+ tcg_gen_movi_tl(cpu_reserve_length, memop_size(memop));
5701
+
5702
+ tcg_gen_mov_tl(cpu_reserve_val, gpr);
5703
+
5704
+ return true;
5705
+}
5706
+
5707
+TRANS_FLAGS2(ATOMIC_ISA206, LBARX, do_load_locked, DEF_MEMOP(MO_UB))
5708
+TRANS_FLAGS2(ATOMIC_ISA206, LHARX, do_load_locked, DEF_MEMOP(MO_UW))
5709
+TRANS(LWARX, do_load_locked, DEF_MEMOP(MO_UL))
5710
+TRANS64(LDARX, do_load_locked, DEF_MEMOP(MO_UQ))
5711
+
5712
+static bool trans_LQARX(DisasContext *ctx, arg_LQARX *a)
5713
+{
5714
+ REQUIRE_64BIT(ctx);
5715
+ REQUIRE_INSNS_FLAGS2(ctx, ISA207S);
5716
+#if defined(TARGET_PPC64)
5717
+ TCGv EA;
5718
+ TCGv_i128 t16;
5719
+ /* Must use even register and avoid overlap */
5720
+ if (unlikely((a->rt & 1) || (a->rt == a->ra) || (a->rt == a->rb))) {
5721
+ gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
5722
+ return true;
5723
+ }
5724
+
5725
+ gen_set_access_type(ctx, ACCESS_RES);
5726
+ EA = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
5727
+ t16 = tcg_temp_new_i128();
5728
+
5729
+ tcg_gen_qemu_ld_i128(t16, EA, ctx->mem_idx, DEF_MEMOP(MO_128 | MO_ALIGN));
5730
+ tcg_gen_extr_i128_i64(cpu_gpr[a->rt + 1], cpu_gpr[a->rt], t16);
5731
+ tcg_gen_mov_tl(cpu_reserve, EA);
5732
+ tcg_gen_movi_tl(cpu_reserve_length, 16);
5733
+ tcg_gen_st_i64(cpu_gpr[a->rt], tcg_env,
5734
+ offsetof(CPUPPCState, reserve_val));
5735
+ tcg_gen_st_i64(cpu_gpr[a->rt + 1], tcg_env,
5736
+ offsetof(CPUPPCState, reserve_val2));
5737
+#else
5738
+ qemu_build_not_reached();
5739
+#endif
5740
+ return true;
5741
+}
5742
+
5743
#include "translate/fixedpoint-impl.c.inc"
5744
5745
#include "translate/fp-impl.c.inc"
5852
GEN_HANDLER(stswi, 0x1F, 0x15, 0x16, 0x00000001, PPC_STRING),
5853
GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
5854
GEN_HANDLER(isync, 0x13, 0x16, 0x04, 0x03FFF801, PPC_MEM),
5856
-GEN_HANDLER_E(lbarx, 0x1F, 0x14, 0x01, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
5857
-GEN_HANDLER_E(lharx, 0x1F, 0x14, 0x03, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
5858
-GEN_HANDLER(lwarx, 0x1F, 0x14, 0x00, 0x00000000, PPC_RES),
5855
GEN_HANDLER_E(lwat, 0x1F, 0x06, 0x12, 0x00000001, PPC_NONE, PPC2_ISA300),
5856
GEN_HANDLER_E(stwat, 0x1F, 0x06, 0x16, 0x00000001, PPC_NONE, PPC2_ISA300),
5857
GEN_HANDLER_E(stbcx_, 0x1F, 0x16, 0x15, 0, PPC_NONE, PPC2_ATOMIC_ISA206),
5860
#if defined(TARGET_PPC64)
5861
GEN_HANDLER_E(ldat, 0x1F, 0x06, 0x13, 0x00000001, PPC_NONE, PPC2_ISA300),
5862
GEN_HANDLER_E(stdat, 0x1F, 0x06, 0x17, 0x00000001, PPC_NONE, PPC2_ISA300),
5867
-GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000000, PPC_64B),
5868
-GEN_HANDLER_E(lqarx, 0x1F, 0x14, 0x08, 0, PPC_NONE, PPC2_LSQ_ISA207),
5863
GEN_HANDLER2(stdcx_, "stdcx.", 0x1F, 0x16, 0x06, 0x00000000, PPC_64B),
5864
GEN_HANDLER_E(stqcx_, 0x1F, 0x16, 0x05, 0, PPC_NONE, PPC2_LSQ_ISA207),
5865
#endif