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