@samitouri / QOSamiQemu / commits / 29387351e0

target/ppc: Move st{b, h, w, d, q}cx instructions to decodetree

Move the following store conditional instructions to decodetree specification: stbcx. : X-form sthcx. : X-form stwcx. : X-form stdcx. : X-form stqcx. : X-form The changes were verified by checking that the generated TCG ops remain semantically identical to the legacy translation, using logs captured with the -d in_asm,op flag. Signed-off-by: Utkarsh Verma <uverma@linux.ibm.com> Reviewed-by: Nikhil Kumar Singh <nikhilks@linux.ibm.com> Reviewed-by: Glenn Miles <milesg@linux.ibm.com> Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com> Signed-off-by: Chinmay Rath <rathc@linux.ibm.com> Tested-by: Aniket Sahu <asahu1x@linux.ibm.com> Link: https://lore.kernel.org/qemu-devel/20260827133010.278889-7-rathc@linux.ibm.com Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>

Utkarsh Verma committed Aug 27, 2026 at 18:59 UTC 29387351e0d4852f58b770aa3ab403099a90e945
3 files changed +92 -103
target/ppc/insn32.decode
+8
@@ -732,6 +732,14 @@ DSCLIQ 111111 ..... ..... ...... 001000010 . @Z22_tap_sh_rc
732 DSCRI 111011 ..... ..... ...... 001100010 . @Z22_ta_sh_rc
733 DSCRIQ 111111 ..... ..... ...... 001100010 . @Z22_tap_sh_rc
734
735 +### Store Conditional Instructions
736 +
737 +STBCX 011111 ..... ..... ..... 1010110110 1 @X
738 +STHCX 011111 ..... ..... ..... 1011010110 1 @X
739 +STWCX 011111 ..... ..... ..... 0010010110 1 @X
740 +STDCX 011111 ..... ..... ..... 0011010110 1 @X
741 +STQCX 011111 ..... ..... ..... 0010110110 1 @X
742 +
743 ## Vector Exclusive-OR-based Instructions
744
745 VPMSUMD 000100 ..... ..... ..... 10011001000 @VX
target/ppc/translate.c
-103
@@ -3153,104 +3153,6 @@ static void gen_stdat(DisasContext *ctx)
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 {
@@ -5886,14 +5788,9 @@ GEN_HANDLER(stswx, 0x1F, 0x15, 0x14, 0x00000001, PPC_STRING),
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),
target/ppc/translate/fixedpoint-impl.c.inc
+84
@@ -204,6 +204,90 @@ TRANS64(PSTD, do_ldst_PLS_D, false, true, MO_UQ)
204 TRANS64(STQ, do_ldst_quad, true, false);
205 TRANS64(PSTQ, do_ldst_quad_PLS_D, true);
206
207 +/* Store Conditional Instructions */
208 +
209 +static bool do_store_cond(DisasContext *ctx, arg_X *a, MemOp mop)
210 +{
211 + TCGLabel *lfail = gen_new_label();
212 + TCGv ea = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
213 + TCGv cr0 = tcg_temp_new();
214 + TCGv t0 = tcg_temp_new();
215 +
216 + tcg_gen_mov_tl(cr0, cpu_so);
217 + gen_set_access_type(ctx, ACCESS_RES);
218 +
219 + tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_reserve, lfail);
220 + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, memop_size(mop), lfail);
221 +
222 + tcg_gen_atomic_cmpxchg_tl(t0, cpu_reserve, cpu_reserve_val,
223 + cpu_gpr[a->rt], ctx->mem_idx,
224 + DEF_MEMOP(mop) | MO_ALIGN);
225 + tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_reserve_val);
226 + tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
227 + tcg_gen_or_tl(cr0, cr0, t0);
228 +
229 + gen_set_label(lfail);
230 + tcg_gen_trunc_tl_i32(cpu_crf[0], cr0);
231 + tcg_gen_movi_tl(cpu_reserve, -1);
232 + return true;
233 +}
234 +
235 +TRANS_FLAGS2(ATOMIC_ISA206, STBCX, do_store_cond, MO_UB);
236 +TRANS_FLAGS2(ATOMIC_ISA206, STHCX, do_store_cond, MO_UW);
237 +TRANS(STWCX, do_store_cond, MO_UL);
238 +TRANS64(STDCX, do_store_cond, MO_UQ);
239 +
240 +static bool trans_STQCX(DisasContext *ctx, arg_STQCX *a)
241 +{
242 + REQUIRE_64BIT(ctx);
243 + REQUIRE_INSNS_FLAGS2(ctx, LSQ_ISA207);
244 +#if defined(TARGET_PPC64)
245 + TCGLabel *lfail = gen_new_label();
246 + TCGv ea = do_ea_calc(ctx, a->ra, cpu_gpr[a->rb]);
247 + TCGv t0 = tcg_temp_new();
248 + TCGv t1 = tcg_temp_new();
249 + TCGv cr0 = tcg_temp_new();
250 + TCGv_i128 cmp = tcg_temp_new_i128();
251 + TCGv_i128 val = tcg_temp_new_i128();
252 +
253 + if (unlikely(a->rt & 1)) {
254 + gen_invalid(ctx);
255 + return true;
256 + }
257 +
258 + tcg_gen_mov_tl(cr0, cpu_so);
259 + gen_set_access_type(ctx, ACCESS_RES);
260 +
261 + tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_reserve, lfail);
262 + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_reserve_length, 16, lfail);
263 +
264 + tcg_gen_concat_i64_i128(cmp, cpu_reserve_val2, cpu_reserve_val);
265 +
266 + /* Note that the low part is always in RS+1, even in LE mode. */
267 + tcg_gen_concat_i64_i128(val, cpu_gpr[a->rt + 1], cpu_gpr[a->rt]);
268 +
269 + tcg_gen_atomic_cmpxchg_i128(val, cpu_reserve, cmp, val, ctx->mem_idx,
270 + DEF_MEMOP(MO_128 | MO_ALIGN));
271 +
272 + tcg_gen_extr_i128_i64(t1, t0, val);
273 +
274 + tcg_gen_xor_tl(t1, t1, cpu_reserve_val2);
275 + tcg_gen_xor_tl(t0, t0, cpu_reserve_val);
276 + tcg_gen_or_tl(t0, t0, t1);
277 +
278 + tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, 0);
279 + tcg_gen_shli_tl(t0, t0, CRF_EQ_BIT);
280 + tcg_gen_or_tl(cr0, cr0, t0);
281 +
282 + gen_set_label(lfail);
283 + tcg_gen_trunc_tl_i32(cpu_crf[0], cr0);
284 + tcg_gen_movi_tl(cpu_reserve, -1);
285 +#else
286 + qemu_build_not_reached();
287 +#endif
288 + return true;
289 +}
290 +
291 /*
292 * Fixed-Point Compare Instructions
293 */