Skip to content

Commit 99e4411

Browse files
rth7680pm215
authored andcommitted
target/arm: Implement FEAT_LSE128
This feature contains the LDCLRP, LDSETP, and SWPP instructions. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Message-id: 20250815122653.701782-7-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
1 parent 905c2c3 commit 99e4411

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

target/arm/cpu-features.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,11 @@ static inline bool isar_feature_aa64_lse(const ARMISARegisters *id)
411411
return FIELD_EX64_IDREG(id, ID_AA64ISAR0, ATOMIC) >= 2;
412412
}
413413

414+
static inline bool isar_feature_aa64_lse128(const ARMISARegisters *id)
415+
{
416+
return FIELD_EX64_IDREG(id, ID_AA64ISAR0, ATOMIC) >= 3;
417+
}
418+
414419
static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id)
415420
{
416421
return FIELD_EX64_IDREG(id, ID_AA64ISAR0, RDM) != 0;

target/arm/tcg/a64.decode

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,13 @@ SWP .. 111 0 00 . . 1 ..... 1000 00 ..... ..... @atomic
546546

547547
LDAPR sz:2 111 0 00 1 0 1 11111 1100 00 rn:5 rt:5
548548

549+
# Atomic 128-bit memory operations
550+
&atomic128 rn rt rt2 a r
551+
@atomic128 ........ a:1 r:1 . rt2:5 ...... rn:5 rt:5 &atomic128
552+
LDCLRP 00011001 . . 1 ..... 000100 ..... ..... @atomic128
553+
LDSETP 00011001 . . 1 ..... 001100 ..... ..... @atomic128
554+
SWPP 00011001 . . 1 ..... 100000 ..... ..... @atomic128
555+
549556
# Load/store register (pointer authentication)
550557

551558
# LDRA immediate is 10 bits signed and scaled, but the bits aren't all contiguous

target/arm/tcg/translate-a64.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3753,6 +3753,55 @@ TRANS_FEAT(LDUMAX, aa64_lse, do_atomic_ld, a, tcg_gen_atomic_fetch_umax_i64, 0,
37533753
TRANS_FEAT(LDUMIN, aa64_lse, do_atomic_ld, a, tcg_gen_atomic_fetch_umin_i64, 0, false)
37543754
TRANS_FEAT(SWP, aa64_lse, do_atomic_ld, a, tcg_gen_atomic_xchg_i64, 0, false)
37553755

3756+
typedef void Atomic128ThreeOpFn(TCGv_i128, TCGv_i64, TCGv_i128, TCGArg, MemOp);
3757+
3758+
static bool do_atomic128_ld(DisasContext *s, arg_atomic128 *a,
3759+
Atomic128ThreeOpFn *fn, bool invert)
3760+
{
3761+
MemOp mop;
3762+
int rlo, rhi;
3763+
TCGv_i64 clean_addr, tlo, thi;
3764+
TCGv_i128 t16;
3765+
3766+
if (a->rt == 31 || a->rt2 == 31 || a->rt == a->rt2) {
3767+
return false;
3768+
}
3769+
if (a->rn == 31) {
3770+
gen_check_sp_alignment(s);
3771+
}
3772+
mop = check_atomic_align(s, a->rn, MO_128);
3773+
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, a->rn), false,
3774+
a->rn != 31, mop);
3775+
3776+
rlo = (s->be_data == MO_LE ? a->rt : a->rt2);
3777+
rhi = (s->be_data == MO_LE ? a->rt2 : a->rt);
3778+
3779+
tlo = read_cpu_reg(s, rlo, true);
3780+
thi = read_cpu_reg(s, rhi, true);
3781+
if (invert) {
3782+
tcg_gen_not_i64(tlo, tlo);
3783+
tcg_gen_not_i64(thi, thi);
3784+
}
3785+
/*
3786+
* The tcg atomic primitives are all full barriers. Therefore we
3787+
* can ignore the Acquire and Release bits of this instruction.
3788+
*/
3789+
t16 = tcg_temp_new_i128();
3790+
tcg_gen_concat_i64_i128(t16, tlo, thi);
3791+
3792+
fn(t16, clean_addr, t16, get_mem_index(s), mop);
3793+
3794+
tcg_gen_extr_i128_i64(cpu_reg(s, rlo), cpu_reg(s, rhi), t16);
3795+
return true;
3796+
}
3797+
3798+
TRANS_FEAT(LDCLRP, aa64_lse128, do_atomic128_ld,
3799+
a, tcg_gen_atomic_fetch_and_i128, true)
3800+
TRANS_FEAT(LDSETP, aa64_lse128, do_atomic128_ld,
3801+
a, tcg_gen_atomic_fetch_or_i128, false)
3802+
TRANS_FEAT(SWPP, aa64_lse128, do_atomic128_ld,
3803+
a, tcg_gen_atomic_xchg_i128, false)
3804+
37563805
static bool trans_LDAPR(DisasContext *s, arg_LDAPR *a)
37573806
{
37583807
bool iss_sf = ldst_iss_sf(a->sz, false, false);

0 commit comments

Comments
 (0)