diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/config/arm/constraints.md | 13 | ||||
-rw-r--r-- | gcc/config/arm/sync.md | 108 |
3 files changed, 105 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c833186..c1d8f94 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2016-10-25 Thomas Preud'homme <thomas.preudhomme@arm.com> + + * config/arm/constraints.md (Q constraint): Document its use for + Thumb-1. + (Pf constraint): New constraint for relaxed, consume or relaxed memory + models. + * config/arm/sync.md (atomic_load<mode>): Add new ARMv8-M Baseline only + alternatives to allow any register when memory model matches Pf and + thus lda is used, but only low registers otherwise. Use unpredicated + output template for Thumb-1 targets. + (atomic_store<mode>): Likewise for stl. + (arm_load_exclusive<mode>): Add new ARMv8-M Baseline only alternative + whose output template does not have predication. + (arm_load_acquire_exclusive<mode>): Likewise. + (arm_load_exclusivesi): Likewise. + (arm_load_acquire_exclusivesi): Likewise. + (arm_store_release_exclusive<mode>): Likewise. + (arm_store_exclusive<mode>): Use unpredicated output template for + Thumb-1 targets. + 2016-10-25 Jakub Jelinek <jakub@redhat.com> * internal-fn.def (LAUNDER): New internal function. diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index 562a9fc..5099e69 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -34,11 +34,13 @@ ;; in ARM/Thumb-2 state: Da, Db, Dc, Dd, Dn, Dl, DL, Do, Dv, Dy, Di, Dt, Dp, Dz ;; in Thumb-1 state: Pa, Pb, Pc, Pd, Pe ;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py +;; in all states: Pf ;; The following memory constraints have been used: -;; in ARM/Thumb-2 state: Q, Uh, Ut, Uv, Uy, Un, Um, Us +;; in ARM/Thumb-2 state: Uh, Ut, Uv, Uy, Un, Um, Us ;; in ARM state: Uq ;; in Thumb state: Uu, Uw +;; in all states: Q (define_register_constraint "t" "TARGET_32BIT ? VFP_LO_REGS : NO_REGS" @@ -180,6 +182,13 @@ (and (match_code "const_int") (match_test "TARGET_THUMB1 && ival >= 256 && ival <= 510"))) +(define_constraint "Pf" + "Memory models except relaxed, consume or release ones." + (and (match_code "const_int") + (match_test "!is_mm_relaxed (memmodel_from_int (ival)) + && !is_mm_consume (memmodel_from_int (ival)) + && !is_mm_release (memmodel_from_int (ival))"))) + (define_constraint "Ps" "@internal In Thumb-2 state a constant in the range -255 to +255" (and (match_code "const_int") @@ -407,7 +416,7 @@ (define_memory_constraint "Q" "@internal - In ARM/Thumb-2 state an address that is a single base register." + An address that is a single base register." (and (match_code "mem") (match_test "REG_P (XEXP (op, 0))"))) diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md index d10ede4..d36c24f 100644 --- a/gcc/config/arm/sync.md +++ b/gcc/config/arm/sync.md @@ -63,37 +63,59 @@ (set_attr "predicable" "no")]) (define_insn "atomic_load<mode>" - [(set (match_operand:QHSI 0 "register_operand" "=r") + [(set (match_operand:QHSI 0 "register_operand" "=r,r,l") (unspec_volatile:QHSI - [(match_operand:QHSI 1 "arm_sync_memory_operand" "Q") - (match_operand:SI 2 "const_int_operand")] ;; model + [(match_operand:QHSI 1 "arm_sync_memory_operand" "Q,Q,Q") + (match_operand:SI 2 "const_int_operand" "n,Pf,n")] ;; model VUNSPEC_LDA))] "TARGET_HAVE_LDACQ" { enum memmodel model = memmodel_from_int (INTVAL (operands[2])); if (is_mm_relaxed (model) || is_mm_consume (model) || is_mm_release (model)) - return \"ldr<sync_sfx>%?\\t%0, %1\"; + { + if (TARGET_THUMB1) + return \"ldr<sync_sfx>\\t%0, %1\"; + else + return \"ldr<sync_sfx>%?\\t%0, %1\"; + } else - return \"lda<sync_sfx>%?\\t%0, %1\"; + { + if (TARGET_THUMB1) + return \"lda<sync_sfx>\\t%0, %1\"; + else + return \"lda<sync_sfx>%?\\t%0, %1\"; + } } - [(set_attr "predicable" "yes") + [(set_attr "arch" "32,v8mb,any") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) (define_insn "atomic_store<mode>" - [(set (match_operand:QHSI 0 "memory_operand" "=Q") + [(set (match_operand:QHSI 0 "memory_operand" "=Q,Q,Q") (unspec_volatile:QHSI - [(match_operand:QHSI 1 "general_operand" "r") - (match_operand:SI 2 "const_int_operand")] ;; model + [(match_operand:QHSI 1 "general_operand" "r,r,l") + (match_operand:SI 2 "const_int_operand" "n,Pf,n")] ;; model VUNSPEC_STL))] "TARGET_HAVE_LDACQ" { enum memmodel model = memmodel_from_int (INTVAL (operands[2])); if (is_mm_relaxed (model) || is_mm_consume (model) || is_mm_acquire (model)) - return \"str<sync_sfx>%?\t%1, %0\"; + { + if (TARGET_THUMB1) + return \"str<sync_sfx>\t%1, %0\"; + else + return \"str<sync_sfx>%?\t%1, %0\"; + } else - return \"stl<sync_sfx>%?\t%1, %0\"; + { + if (TARGET_THUMB1) + return \"stl<sync_sfx>\t%1, %0\"; + else + return \"stl<sync_sfx>%?\t%1, %0\"; + } } - [(set_attr "predicable" "yes") + [(set_attr "arch" "32,v8mb,any") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) ;; An LDRD instruction usable by the atomic_loaddi expander on LPAE targets @@ -380,45 +402,57 @@ }) (define_insn "arm_load_exclusive<mode>" - [(set (match_operand:SI 0 "s_register_operand" "=r") + [(set (match_operand:SI 0 "s_register_operand" "=r,r") (zero_extend:SI (unspec_volatile:NARROW - [(match_operand:NARROW 1 "mem_noofs_operand" "Ua")] + [(match_operand:NARROW 1 "mem_noofs_operand" "Ua,Ua")] VUNSPEC_LL)))] "TARGET_HAVE_LDREXBH" - "ldrex<sync_sfx>%?\t%0, %C1" - [(set_attr "predicable" "yes") + "@ + ldrex<sync_sfx>%?\t%0, %C1 + ldrex<sync_sfx>\t%0, %C1" + [(set_attr "arch" "32,v8mb") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) (define_insn "arm_load_acquire_exclusive<mode>" - [(set (match_operand:SI 0 "s_register_operand" "=r") + [(set (match_operand:SI 0 "s_register_operand" "=r,r") (zero_extend:SI (unspec_volatile:NARROW - [(match_operand:NARROW 1 "mem_noofs_operand" "Ua")] + [(match_operand:NARROW 1 "mem_noofs_operand" "Ua,Ua")] VUNSPEC_LAX)))] "TARGET_HAVE_LDACQ" - "ldaex<sync_sfx>%?\\t%0, %C1" - [(set_attr "predicable" "yes") + "@ + ldaex<sync_sfx>%?\\t%0, %C1 + ldaex<sync_sfx>\\t%0, %C1" + [(set_attr "arch" "32,v8mb") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) (define_insn "arm_load_exclusivesi" - [(set (match_operand:SI 0 "s_register_operand" "=r") + [(set (match_operand:SI 0 "s_register_operand" "=r,r") (unspec_volatile:SI - [(match_operand:SI 1 "mem_noofs_operand" "Ua")] + [(match_operand:SI 1 "mem_noofs_operand" "Ua,Ua")] VUNSPEC_LL))] "TARGET_HAVE_LDREX" - "ldrex%?\t%0, %C1" - [(set_attr "predicable" "yes") + "@ + ldrex%?\t%0, %C1 + ldrex\t%0, %C1" + [(set_attr "arch" "32,v8mb") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) (define_insn "arm_load_acquire_exclusivesi" - [(set (match_operand:SI 0 "s_register_operand" "=r") + [(set (match_operand:SI 0 "s_register_operand" "=r,r") (unspec_volatile:SI - [(match_operand:SI 1 "mem_noofs_operand" "Ua")] + [(match_operand:SI 1 "mem_noofs_operand" "Ua,Ua")] VUNSPEC_LAX))] "TARGET_HAVE_LDACQ" - "ldaex%?\t%0, %C1" - [(set_attr "predicable" "yes") + "@ + ldaex%?\t%0, %C1 + ldaex\t%0, %C1" + [(set_attr "arch" "32,v8mb") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) (define_insn "arm_load_exclusivedi" @@ -460,7 +494,10 @@ gcc_assert ((REGNO (operands[2]) & 1) == 0 || TARGET_THUMB2); return "strexd%?\t%0, %2, %H2, %C1"; } - return "strex<sync_sfx>%?\t%0, %2, %C1"; + if (TARGET_THUMB1) + return "strex<sync_sfx>\t%0, %2, %C1"; + else + return "strex<sync_sfx>%?\t%0, %2, %C1"; } [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) @@ -482,13 +519,16 @@ (set_attr "predicable_short_it" "no")]) (define_insn "arm_store_release_exclusive<mode>" - [(set (match_operand:SI 0 "s_register_operand" "=&r") + [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") (unspec_volatile:SI [(const_int 0)] VUNSPEC_SLX)) - (set (match_operand:QHSI 1 "mem_noofs_operand" "=Ua") + (set (match_operand:QHSI 1 "mem_noofs_operand" "=Ua,Ua") (unspec_volatile:QHSI - [(match_operand:QHSI 2 "s_register_operand" "r")] + [(match_operand:QHSI 2 "s_register_operand" "r,r")] VUNSPEC_SLX))] "TARGET_HAVE_LDACQ" - "stlex<sync_sfx>%?\t%0, %2, %C1" - [(set_attr "predicable" "yes") + "@ + stlex<sync_sfx>%?\t%0, %2, %C1 + stlex<sync_sfx>\t%0, %2, %C1" + [(set_attr "arch" "32,v8mb") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no")]) |