On Tue, 2025-06-10 at 16:59 +0800, mengqinggang wrote:
> Add support for atomic_<atomic_optab><mode>, 
> atomic_fetch_<atomic_optab><mode>,
> atomic_exchange<mode> on LA32.
> 
> gcc/ChangeLog:
> 
>       * config/loongarch/sync.md: Add la32 support.
> ---
>  gcc/config/loongarch/sync.md | 56 ++++++++++++++++++++++++++++++------
>  1 file changed, 47 insertions(+), 9 deletions(-)
> 
> diff --git a/gcc/config/loongarch/sync.md b/gcc/config/loongarch/sync.md
> index fd8d732dd67..dd9c362ca4f 100644
> --- a/gcc/config/loongarch/sync.md
> +++ b/gcc/config/loongarch/sync.md
> @@ -38,6 +38,10 @@ (define_code_iterator any_atomic [plus ior xor and])
>  (define_code_attr atomic_optab
>    [(plus "add") (ior "or") (xor "xor") (and "and")])
>  
> +;; For 32 bit.
> +(define_code_attr atomic_optab_insn
> +  [(plus "add.w") (ior "or") (xor "xor") (and "and")])
> +
>  ;; This attribute gives the format suffix for atomic memory operations.
>  (define_mode_attr amo [(QI "b") (HI "h") (SI "w") (DI "d")])
>  
> @@ -181,10 +185,21 @@ (define_insn "atomic_<atomic_optab><mode>"
>         [(any_atomic:GPR (match_dup 0)
>                          (match_operand:GPR 1 "reg_or_0_operand" "rJ"))
>          (match_operand:SI 2 "const_int_operand")] ;; model
> -      UNSPEC_SYNC_OLD_OP))]
> +      UNSPEC_SYNC_OLD_OP))
> +   (clobber (match_scratch:SI 3 "=&r"))]

Let's use a different define_insn for LA32, and in define_expand we can
expand to different insns based on TARGET_64BIT.  We don't want to
unnecessarily allocate a register on LA64.

>    ""
> -  "am<amop>%A2.<amo>\t$zero,%z1,%0"
> -  [(set (attr "length") (const_int 4))])
> +{
> +  if (TARGET_64BIT)
> +    return "am<amop>%A2.<amo>\t$zero,%z1,%0";
> +  else
> +    return "%G2\n\t"
> +        "1:\n\t"
> +        "ll.w\t%3,%0\n\t"
> +        "<atomic_optab_insn>\t%3,%z1,%3\n\t"
> +        "sc.w\t%3,%0\n\t"
> +        "beq\t$zero,%3,1b\n\t"
> +        "2:";
> +})
>  
>  (define_insn "atomic_add<mode>"
>    [(set (match_operand:SHORT 0 "memory_operand" "+ZB")
> @@ -205,10 +220,22 @@ (define_insn "atomic_fetch_<atomic_optab><mode>"
>         [(any_atomic:GPR (match_dup 1)
>                          (match_operand:GPR 2 "reg_or_0_operand" "rJ"))
>          (match_operand:SI 3 "const_int_operand")] ;; model
> -      UNSPEC_SYNC_OLD_OP))]
> +      UNSPEC_SYNC_OLD_OP))
> +   (clobber (match_scratch:SI 4 "=&r"))]

Likewise.

>    ""
> -  "am<amop>%A3.<amo>\t%0,%z2,%1"
> -  [(set (attr "length") (const_int 4))])
> +{
> +  if (TARGET_64BIT)
> +    return "am<amop>%A3.<amo>\t%0,%z2,%1";
> +  else
> +    return "%G3\n\t"
> +         "1:\n\t"
> +         "ll.w\t%0,%1\n\t"
> +         "<atomic_optab_insn>\t%4,%z2,%0\n\t"
> +         "sc.w\t%4,%1\n\t"
> +         "beq\t$zero,%4,1b\n\t"
> +         "2:";
> +}
> +  [(set (attr "length") (const_int 20))])
>  
>  (define_insn "atomic_exchange<mode>"
>    [(set (match_operand:GPR 0 "register_operand" "=&r")
> @@ -217,10 +244,21 @@ (define_insn "atomic_exchange<mode>"
>          (match_operand:SI 3 "const_int_operand")] ;; model
>         UNSPEC_SYNC_EXCHANGE))
>     (set (match_dup 1)
> -     (match_operand:GPR 2 "register_operand" "r"))]
> +     (match_operand:GPR 2 "register_operand" "r"))
> +   (clobber (match_scratch:SI 4 "=&r"))]

Likewise.

>    ""
> -  "amswap%A3.<amo>\t%0,%z2,%1"
> -  [(set (attr "length") (const_int 4))])
> +{
> +  if (TARGET_64BIT)
> +    return "amswap%A3.<amo>\t%0,%z2,%1";
> +  else
> +    return "%G3\n\t"
> +        "1:\n\t"
> +        "ll.w\t%0,%1\n\t"
> +        "or\t%4,$zero,%2\n\t"
> +        "sc.w\t%4,%1\n\t"
> +        "beq\t$zero,%4,1b\n\t"
> +        "2:";
> +})
>  
>  (define_insn "atomic_exchange<mode>_short"
>    [(set (match_operand:SHORT 0 "register_operand" "=&r")

-- 
Xi Ruoyao <xry...@xry111.site>
School of Aerospace Science and Technology, Xidian University

Reply via email to