diff mbox series

[3/5] target/loongarch: Add amcas[_db].{b/h/w/d}

Message ID 20231023153029.269211-5-c@jia.je
State New
Headers show
Series Add LoongArch v1.1 instructions | expand

Commit Message

Jiajie Chen Oct. 23, 2023, 3:29 p.m. UTC
The new instructions are introduced in LoongArch v1.1:

- amcas.b
- amcas.h
- amcas.w
- amcas.d
- amcas_db.b
- amcas_db.h
- amcas_db.w
- amcas_db.d

The new instructions are gated by CPUCFG2.LAMCAS.

Signed-off-by: Jiajie Chen <c@jia.je>
---
 target/loongarch/cpu.h                        |  1 +
 target/loongarch/disas.c                      |  8 +++++++
 .../loongarch/insn_trans/trans_atomic.c.inc   | 24 +++++++++++++++++++
 target/loongarch/insns.decode                 |  8 +++++++
 target/loongarch/translate.h                  |  1 +
 5 files changed, 42 insertions(+)

Comments

Jiajie Chen Oct. 23, 2023, 3:35 p.m. UTC | #1
On 2023/10/23 23:29, Jiajie Chen wrote:
> The new instructions are introduced in LoongArch v1.1:
>
> - amcas.b
> - amcas.h
> - amcas.w
> - amcas.d
> - amcas_db.b
> - amcas_db.h
> - amcas_db.w
> - amcas_db.d
>
> The new instructions are gated by CPUCFG2.LAMCAS.
>
> Signed-off-by: Jiajie Chen <c@jia.je>
> ---
>   target/loongarch/cpu.h                        |  1 +
>   target/loongarch/disas.c                      |  8 +++++++
>   .../loongarch/insn_trans/trans_atomic.c.inc   | 24 +++++++++++++++++++
>   target/loongarch/insns.decode                 |  8 +++++++
>   target/loongarch/translate.h                  |  1 +
>   5 files changed, 42 insertions(+)
>
> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> index 7166c07756..80a476c3f8 100644
> --- a/target/loongarch/cpu.h
> +++ b/target/loongarch/cpu.h
> @@ -156,6 +156,7 @@ FIELD(CPUCFG2, LBT_MIPS, 20, 1)
>   FIELD(CPUCFG2, LSPW, 21, 1)
>   FIELD(CPUCFG2, LAM, 22, 1)
>   FIELD(CPUCFG2, LAM_BH, 27, 1)
> +FIELD(CPUCFG2, LAMCAS, 28, 1)
>   
>   /* cpucfg[3] bits */
>   FIELD(CPUCFG3, CCDMA, 0, 1)
> diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
> index d33aa8173a..4aa67749cf 100644
> --- a/target/loongarch/disas.c
> +++ b/target/loongarch/disas.c
> @@ -575,6 +575,14 @@ INSN(fldx_s,       frr)
>   INSN(fldx_d,       frr)
>   INSN(fstx_s,       frr)
>   INSN(fstx_d,       frr)
> +INSN(amcas_b,      rrr)
> +INSN(amcas_h,      rrr)
> +INSN(amcas_w,      rrr)
> +INSN(amcas_d,      rrr)
> +INSN(amcas_db_b,   rrr)
> +INSN(amcas_db_h,   rrr)
> +INSN(amcas_db_w,   rrr)
> +INSN(amcas_db_d,   rrr)
>   INSN(amswap_b,     rrr)
>   INSN(amswap_h,     rrr)
>   INSN(amadd_b,      rrr)
> diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc b/target/loongarch/insn_trans/trans_atomic.c.inc
> index cd28e217ad..bea567fdaf 100644
> --- a/target/loongarch/insn_trans/trans_atomic.c.inc
> +++ b/target/loongarch/insn_trans/trans_atomic.c.inc
> @@ -45,6 +45,22 @@ static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop)
>       return true;
>   }
>   
> +static bool gen_cas(DisasContext *ctx, arg_rrr *a,
> +                    void (*func)(TCGv, TCGv, TCGv, TCGv, TCGArg, MemOp),
> +                    MemOp mop)
> +{
> +    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
> +    TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
> +    TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
> +
> +    addr = make_address_i(ctx, addr, 0);
> +

I'm unsure if I can use the same TCGv for the first and the third 
argument here. If it violates with the assumption, a temporary register 
can be used.

> +    func(dest, addr, dest, val, ctx->mem_idx, mop);
> +    gen_set_gpr(a->rd, dest, EXT_NONE);
> +
> +    return true;
> +}
> +
>   static bool gen_am(DisasContext *ctx, arg_rrr *a,
>                      void (*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
>                      MemOp mop)
> @@ -73,6 +89,14 @@ TRANS(ll_w, ALL, gen_ll, MO_TESL)
>   TRANS(sc_w, ALL, gen_sc, MO_TESL)
>   TRANS(ll_d, 64, gen_ll, MO_TEUQ)
>   TRANS(sc_d, 64, gen_sc, MO_TEUQ)
> +TRANS(amcas_b, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESB)
> +TRANS(amcas_h, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESW)
> +TRANS(amcas_w, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESL)
> +TRANS(amcas_d, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TEUQ)
> +TRANS(amcas_db_b, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESB)
> +TRANS(amcas_db_h, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESW)
> +TRANS(amcas_db_w, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESL)
> +TRANS(amcas_db_d, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TEUQ)
>   TRANS(amswap_b, LAM_BH, gen_am, tcg_gen_atomic_xchg_tl, MO_TESB)
>   TRANS(amswap_h, LAM_BH, gen_am, tcg_gen_atomic_xchg_tl, MO_TESW)
>   TRANS(amadd_b, LAM_BH, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESB)
> diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
> index 678ce42038..cf4123cd46 100644
> --- a/target/loongarch/insns.decode
> +++ b/target/loongarch/insns.decode
> @@ -261,6 +261,14 @@ ll_w            0010 0000 .............. ..... .....     @rr_i14s2
>   sc_w            0010 0001 .............. ..... .....     @rr_i14s2
>   ll_d            0010 0010 .............. ..... .....     @rr_i14s2
>   sc_d            0010 0011 .............. ..... .....     @rr_i14s2
> +amcas_b         0011 10000101 10000 ..... ..... .....    @rrr
> +amcas_h         0011 10000101 10001 ..... ..... .....    @rrr
> +amcas_w         0011 10000101 10010 ..... ..... .....    @rrr
> +amcas_d         0011 10000101 10011 ..... ..... .....    @rrr
> +amcas_db_b      0011 10000101 10100 ..... ..... .....    @rrr
> +amcas_db_h      0011 10000101 10101 ..... ..... .....    @rrr
> +amcas_db_w      0011 10000101 10110 ..... ..... .....    @rrr
> +amcas_db_d      0011 10000101 10111 ..... ..... .....    @rrr
>   amswap_b        0011 10000101 11000 ..... ..... .....    @rrr
>   amswap_h        0011 10000101 11001 ..... ..... .....    @rrr
>   amadd_b         0011 10000101 11010 ..... ..... .....    @rrr
> diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
> index 0b230530e7..3affefdafc 100644
> --- a/target/loongarch/translate.h
> +++ b/target/loongarch/translate.h
> @@ -23,6 +23,7 @@
>   #define avail_LSPW(C)   (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSPW))
>   #define avail_LAM(C)    (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAM))
>   #define avail_LAM_BH(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAM_BH))
> +#define avail_LAMCAS(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAMCAS))
>   #define avail_LSX(C)    (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSX))
>   #define avail_LASX(C)   (FIELD_EX32((C)->cpucfg2, CPUCFG2, LASX))
>   #define avail_IOCSR(C)  (FIELD_EX32((C)->cpucfg1, CPUCFG1, IOCSR))
Richard Henderson Oct. 23, 2023, 10:59 p.m. UTC | #2
On 10/23/23 08:29, Jiajie Chen wrote:
> +static bool gen_cas(DisasContext *ctx, arg_rrr *a,
> +                    void (*func)(TCGv, TCGv, TCGv, TCGv, TCGArg, MemOp),
> +                    MemOp mop)
> +{
> +    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
> +    TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
> +    TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
> +
> +    addr = make_address_i(ctx, addr, 0);
> +
> +    func(dest, addr, dest, val, ctx->mem_idx, mop);

You need

     TCGv old = gpr_src(ctx, a->rd, EXT_NONE);
     func(dest, addr, old, val, ...);

as otherwise rd=0 will abort.

Correct emulation requires that you perform the memory operation, and then discard the 
result.  But you must provide the (initialized) source of zero for that case.

Do any or all of the AM, LL, SC instructions require aligned memory?
I suspect that they do.

I think probably gen_ll, gen_sc, gen_am, and now gen_cas are missing "mop | MO_ALIGN" 
applied to the memory operation(s).


r~
Richard Henderson Oct. 23, 2023, 11 p.m. UTC | #3
On 10/23/23 08:35, Jiajie Chen wrote:
>> +static bool gen_cas(DisasContext *ctx, arg_rrr *a,
>> +                    void (*func)(TCGv, TCGv, TCGv, TCGv, TCGArg, MemOp),
>> +                    MemOp mop)
>> +{
>> +    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
>> +    TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
>> +    TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
>> +
>> +    addr = make_address_i(ctx, addr, 0);
>> +
> 
> I'm unsure if I can use the same TCGv for the first and the third argument here. If it 
> violates with the assumption, a temporary register can be used.
> 
>> +    func(dest, addr, dest, val, ctx->mem_idx, mop);

Correct, you cannot use dest in both places.
I just replied to the patch itself with that.  :-)


r~
diff mbox series

Patch

diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 7166c07756..80a476c3f8 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -156,6 +156,7 @@  FIELD(CPUCFG2, LBT_MIPS, 20, 1)
 FIELD(CPUCFG2, LSPW, 21, 1)
 FIELD(CPUCFG2, LAM, 22, 1)
 FIELD(CPUCFG2, LAM_BH, 27, 1)
+FIELD(CPUCFG2, LAMCAS, 28, 1)
 
 /* cpucfg[3] bits */
 FIELD(CPUCFG3, CCDMA, 0, 1)
diff --git a/target/loongarch/disas.c b/target/loongarch/disas.c
index d33aa8173a..4aa67749cf 100644
--- a/target/loongarch/disas.c
+++ b/target/loongarch/disas.c
@@ -575,6 +575,14 @@  INSN(fldx_s,       frr)
 INSN(fldx_d,       frr)
 INSN(fstx_s,       frr)
 INSN(fstx_d,       frr)
+INSN(amcas_b,      rrr)
+INSN(amcas_h,      rrr)
+INSN(amcas_w,      rrr)
+INSN(amcas_d,      rrr)
+INSN(amcas_db_b,   rrr)
+INSN(amcas_db_h,   rrr)
+INSN(amcas_db_w,   rrr)
+INSN(amcas_db_d,   rrr)
 INSN(amswap_b,     rrr)
 INSN(amswap_h,     rrr)
 INSN(amadd_b,      rrr)
diff --git a/target/loongarch/insn_trans/trans_atomic.c.inc b/target/loongarch/insn_trans/trans_atomic.c.inc
index cd28e217ad..bea567fdaf 100644
--- a/target/loongarch/insn_trans/trans_atomic.c.inc
+++ b/target/loongarch/insn_trans/trans_atomic.c.inc
@@ -45,6 +45,22 @@  static bool gen_sc(DisasContext *ctx, arg_rr_i *a, MemOp mop)
     return true;
 }
 
+static bool gen_cas(DisasContext *ctx, arg_rrr *a,
+                    void (*func)(TCGv, TCGv, TCGv, TCGv, TCGArg, MemOp),
+                    MemOp mop)
+{
+    TCGv dest = gpr_dst(ctx, a->rd, EXT_NONE);
+    TCGv addr = gpr_src(ctx, a->rj, EXT_NONE);
+    TCGv val = gpr_src(ctx, a->rk, EXT_NONE);
+
+    addr = make_address_i(ctx, addr, 0);
+
+    func(dest, addr, dest, val, ctx->mem_idx, mop);
+    gen_set_gpr(a->rd, dest, EXT_NONE);
+
+    return true;
+}
+
 static bool gen_am(DisasContext *ctx, arg_rrr *a,
                    void (*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
                    MemOp mop)
@@ -73,6 +89,14 @@  TRANS(ll_w, ALL, gen_ll, MO_TESL)
 TRANS(sc_w, ALL, gen_sc, MO_TESL)
 TRANS(ll_d, 64, gen_ll, MO_TEUQ)
 TRANS(sc_d, 64, gen_sc, MO_TEUQ)
+TRANS(amcas_b, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESB)
+TRANS(amcas_h, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESW)
+TRANS(amcas_w, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESL)
+TRANS(amcas_d, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TEUQ)
+TRANS(amcas_db_b, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESB)
+TRANS(amcas_db_h, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESW)
+TRANS(amcas_db_w, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TESL)
+TRANS(amcas_db_d, LAMCAS, gen_cas, tcg_gen_atomic_cmpxchg_tl, MO_TEUQ)
 TRANS(amswap_b, LAM_BH, gen_am, tcg_gen_atomic_xchg_tl, MO_TESB)
 TRANS(amswap_h, LAM_BH, gen_am, tcg_gen_atomic_xchg_tl, MO_TESW)
 TRANS(amadd_b, LAM_BH, gen_am, tcg_gen_atomic_fetch_add_tl, MO_TESB)
diff --git a/target/loongarch/insns.decode b/target/loongarch/insns.decode
index 678ce42038..cf4123cd46 100644
--- a/target/loongarch/insns.decode
+++ b/target/loongarch/insns.decode
@@ -261,6 +261,14 @@  ll_w            0010 0000 .............. ..... .....     @rr_i14s2
 sc_w            0010 0001 .............. ..... .....     @rr_i14s2
 ll_d            0010 0010 .............. ..... .....     @rr_i14s2
 sc_d            0010 0011 .............. ..... .....     @rr_i14s2
+amcas_b         0011 10000101 10000 ..... ..... .....    @rrr
+amcas_h         0011 10000101 10001 ..... ..... .....    @rrr
+amcas_w         0011 10000101 10010 ..... ..... .....    @rrr
+amcas_d         0011 10000101 10011 ..... ..... .....    @rrr
+amcas_db_b      0011 10000101 10100 ..... ..... .....    @rrr
+amcas_db_h      0011 10000101 10101 ..... ..... .....    @rrr
+amcas_db_w      0011 10000101 10110 ..... ..... .....    @rrr
+amcas_db_d      0011 10000101 10111 ..... ..... .....    @rrr
 amswap_b        0011 10000101 11000 ..... ..... .....    @rrr
 amswap_h        0011 10000101 11001 ..... ..... .....    @rrr
 amadd_b         0011 10000101 11010 ..... ..... .....    @rrr
diff --git a/target/loongarch/translate.h b/target/loongarch/translate.h
index 0b230530e7..3affefdafc 100644
--- a/target/loongarch/translate.h
+++ b/target/loongarch/translate.h
@@ -23,6 +23,7 @@ 
 #define avail_LSPW(C)   (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSPW))
 #define avail_LAM(C)    (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAM))
 #define avail_LAM_BH(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAM_BH))
+#define avail_LAMCAS(C) (FIELD_EX32((C)->cpucfg2, CPUCFG2, LAMCAS))
 #define avail_LSX(C)    (FIELD_EX32((C)->cpucfg2, CPUCFG2, LSX))
 #define avail_LASX(C)   (FIELD_EX32((C)->cpucfg2, CPUCFG2, LASX))
 #define avail_IOCSR(C)  (FIELD_EX32((C)->cpucfg1, CPUCFG1, IOCSR))