Hi Thomas,

On 13 July 2016 at 12:01, Kyrill Tkachov <kyrylo.tkac...@foss.arm.com> wrote:
> Hi Thomas,
>
>
> On 07/07/16 15:32, Thomas Preudhomme wrote:
>>
>> Hi Kyrill,
>>
>> Please find an updated version in attachment. Please note I made quite a
>> few
>> other changes as well. The most important one was to add new ARMv8-M
>> Baseline
>> only alternatives to the two movt insns in order to have non predicable
>> output
>> template for ARMv8-M Baseline. I also inverted the logic for how to detect
>> ARMv8-M Baseline in the testsuite (arm_thumb1_movt_ok rather than *_ko)
>> and
>> fixed a couple of typos. I didn't add MOVT test because it is difficult to
>> generate. Using -mslow-flash-data should help but it is not available for
>> ARMv8-M Baseline as only config/arm/thumb2.md was modified to support this
>> option.
>>
>> Update ChangeLog entries are as follow:
>>
>>
>> *** gcc/ChangeLog ***
>>
>> 2016-06-20  Thomas Preud'homme  <thomas.preudho...@arm.com>
>>
>>          * config/arm/arm.h (TARGET_HAVE_MOVT): Include ARMv8-M as having
>> MOVT.
>>          * config/arm/arm.c (arm_arch_name): (const_ok_for_op): Check
>> MOVT/MOVW
>>          availability with TARGET_HAVE_MOVT.
>>          (thumb_legitimate_constant_p): Strip the high part of a
>> label_ref.
>>          (thumb1_rtx_costs): Also return 0 if setting a half word constant
>> and
>>          MOVW is available and replace (unsigned HOST_WIDE_INT) INTVAL by
>>          UINTVAL.
>>          (thumb1_size_rtx_costs): Make set of half word constant also cost
>> 1
>>          extra instruction if MOVW is available.  Use a cost variable
>>          incremented by COSTS_N_INSNS (1) when the condition match rather
>> than
>>          returning an arithmetic expression based on COSTS_N_INSNS.  Make
>>          constant with bottom half word zero cost 2 instruction if MOVW is
>>          available.
>>          * config/arm/arm.md (define_attr "arch"): Add v8mb.
>>          (define_attr "arch_enabled"): Set to yes if arch value is v8mb
>> and
>>          target is ARMv8-M Baseline.
>>          (arm_movt): New unpredicable alternative for ARMv8-M Baseline.
>>          (arm_movtas_ze): Likewise.
>>          * config/arm/thumb1.md (thumb1_movdi_insn): Add ARMv8-M Baseline
>> only
>>          alternative for constants satisfying j constraint.
>>          (thumb1_movsi_insn): Likewise.
>>          (movsi splitter for K alternative): Tighten condition to not
>> trigger
>>          if movt is available and j constraint is satisfied.
>>          (Pe immediate splitter): Likewise.
>>          (thumb1_movhi_insn): Add ARMv8-M Baseline only alternative for
>>          constant fitting in an halfword to use MOVW.
>>          * doc/sourcebuild.texi (arm_thumb1_movt_ok): Document new ARM
>>          effective target.
>>
>>
>> *** gcc/testsuite/ChangeLog ***
>>
>> 2016-05-23  Thomas Preud'homme  <thomas.preudho...@arm.com>
>>
>>          * lib/target-supports.exp
>> (check_effective_target_arm_thumb1_movt_ok):
>>          Define effective target.
>>          * gcc.target/arm/pr42574.c: Require arm_thumb1_ok and
>>          !arm_thumb1_movt_ok to exclude ARMv8-M Baseline.
>>          * gcc.target/arm/movhi_movw.c: New test.
>>          * gcc.target/arm/movsi_movw.c: Likewise.
>>          * gcc.target/arm/movdi_movw.c: Likewise.
>
>
> Ok.
> Thanks,
> Kyrill
>

I'm seeing:
gcc.target/arm/pr42574.c: syntax error in target selector
"arm_thumb1_ok && { ! arm_thumb1_movt_ok }" for " dg-do 1 compile {
arm_thumb1_ok && { ! arm_thumb1_movt_ok } } "

Can you fix it?

Thanks,

Christophe

>
>>
>> Best regards,
>>
>> Thomas
>>
>> On Friday 20 May 2016 12:14:44 Kyrill Tkachov wrote:
>>>
>>> Hi Thomas,
>>>
>>> On 19/05/16 17:11, Thomas Preudhomme wrote:
>>>>
>>>> On Wednesday 18 May 2016 12:30:41 Kyrill Tkachov wrote:
>>>>>
>>>>> Hi Thomas,
>>>>>
>>>>> This looks mostly good with a few nits inline.
>>>>> Please repost with the comments addressed.
>>>>
>>>> Updated ChangeLog entries:
>>>>
>>>> *** gcc/ChangeLog ***
>>>>
>>>> 2016-05-18  Thomas Preud'homme  <thomas.preudho...@arm.com>
>>>>
>>>>           * config/arm/arm.h (TARGET_HAVE_MOVT): Include ARMv8-M as
>>>> having
>>>>           MOVT.
>>>>           * config/arm/arm.c (arm_arch_name): (const_ok_for_op): Check
>>>>           MOVT/MOVW
>>>>           availability with TARGET_HAVE_MOVT.
>>>>           (thumb_legitimate_constant_p): Strip the high part of a
>>>>           label_ref.
>>>>           (thumb1_rtx_costs): Also return 0 if setting a half word
>>>> constant
>>>>           and
>>>>           MOVW is available and replace (unsigned HOST_WIDE_INT) INTVAL
>>>> by
>>>>           UINTVAL.
>>>>           (thumb1_size_rtx_costs): Make set of half word constant also
>>>> cost
>>>>           1
>>>>           extra instruction if MOVW is available.  Use a cost variable
>>>>           incremented by COSTS_N_INSNS (1) when the condition match
>>>> rather
>>>>           than
>>>>           returning an arithmetic expression based on COSTS_N_INSNS.
>>>> Make
>>>>           constant with bottom half word zero cost 2 instruction if MOVW
>>>> is
>>>>           available.
>>>>           * config/arm/arm.md (define_attr "arch"): Add v8mb.
>>>>           (define_attr "arch_enabled"): Set to yes if arch value is v8mb
>>>>           and
>>>>           target is ARMv8-M Baseline.
>>>>           * config/arm/thumb1.md (thumb1_movdi_insn): Add ARMv8-M
>>>> Baseline
>>>>           only
>>>>           alternative for constants satisfying j constraint.
>>>>           (thumb1_movsi_insn): Likewise.
>>>>           (movsi splitter for K alternative): Tighten condition to not
>>>>           trigger
>>>>           if movt is available and j constraint is satisfied.
>>>>           (Pe immediate splitter): Likewise.
>>>>           (thumb1_movhi_insn): Add ARMv8-M Baseline only alternative for
>>>>           constant fitting in an halfword to use MOVW.
>>>>           * doc/sourcebuild.texi (arm_thumb1_movt_ko): Document new ARM
>>>>           effective target.
>>>>
>>>> *** gcc/testsuite/ChangeLog ***
>>>>
>>>> 2015-11-13  Thomas Preud'homme  <thomas.preudho...@arm.com>
>>>>
>>>>           * lib/target-supports.exp
>>>>           (check_effective_target_arm_thumb1_movt_ko):
>>>>           Define effective target.
>>>>           * gcc.target/arm/pr42574.c: Require arm_thumb1_movt_ko instead
>>>> of
>>>>           arm_thumb1_ok as effective target to exclude ARMv8-M Baseline.
>>>
>>> This is ok now, thanks for the changes.
>>> I'd like to see some tests that generate MOVW/MOVT instructions
>>> on ARMv8-M Baseline. They should be easy, just an:
>>> int
>>> foo ()
>>> {
>>>     return CONST;
>>> }
>>>
>>> and same for short and long long return types
>>> (to exercise the HI, SI and DImode move patterns).
>>>
>>> You can add them as part of this patch or as a separate followup.
>>>
>>> Thanks,
>>> Kyrill
>>>
>>>> and patch:
>>>>
>>>> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
>>>> index
>>>>
>>>> 47216b4a1959ccdb18e329db411bf7f941e67163..f42e996e5a7ce979fe406b8261d50fb2
>>>> ba005f6b 100644
>>>> --- a/gcc/config/arm/arm.h
>>>> +++ b/gcc/config/arm/arm.h
>>>> @@ -269,7 +269,7 @@ extern void
>>>> (*arm_lang_output_object_attributes_hook)
>>>> (void);
>>>>
>>>>    #define TARGET_HAVE_LDACQ    (TARGET_ARM_ARCH >= 8 && arm_arch_notm)
>>>>       /* Nonzero if this chip provides the movw and movt instructions.
>>>> */
>>>>
>>>> -#define TARGET_HAVE_MOVT       (arm_arch_thumb2)
>>>> +#define TARGET_HAVE_MOVT       (arm_arch_thumb2 || arm_arch8)
>>>>
>>>>    /* Nonzero if integer division instructions supported.  */
>>>>    #define TARGET_IDIV  ((TARGET_ARM && arm_arch_arm_hwdiv)     \
>>>>
>>>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
>>>> index
>>>>
>>>> d75a34f10d5ed22cff0a0b5d3ad433f111b059ee..a05e559c905daa55e686491a03834236
>>>> 0c721912 100644
>>>> --- a/gcc/config/arm/arm.c
>>>> +++ b/gcc/config/arm/arm.c
>>>> @@ -8220,6 +8220,12 @@ arm_legitimate_constant_p_1 (machine_mode, rtx x)
>>>>
>>>>    static bool
>>>>    thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx
>>>> x)
>>>>    {
>>>>
>>>> +  /* Splitters for TARGET_USE_MOVT call arm_emit_movpair which creates
>>>> high +     RTX.  These RTX must therefore be allowed for Thumb-1 so that
>>>> when run +     for ARMv8-M baseline or later the result is valid.  */
>>>> +  if (TARGET_HAVE_MOVT && GET_CODE (x) == HIGH)
>>>> +    x = XEXP (x, 0);
>>>> +
>>>>
>>>>      return (CONST_INT_P (x)
>>>>                   || CONST_DOUBLE_P (x)
>>>>           || CONSTANT_ADDRESS_P (x)
>>>>
>>>> @@ -8306,7 +8312,8 @@ thumb1_rtx_costs (rtx x, enum rtx_code code, enum
>>>> rtx_code outer)
>>>>
>>>>        case CONST_INT:
>>>>          if (outer == SET)
>>>>
>>>>         {
>>>>
>>>> -         if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256)
>>>> +         if (UINTVAL (x) < 256
>>>> +             || (TARGET_HAVE_MOVT && !(INTVAL (x) & 0xffff0000)))
>>>>
>>>>             return 0;
>>>>
>>>>           if (thumb_shiftable_const (INTVAL (x)))
>>>>
>>>>             return COSTS_N_INSNS (2);
>>>>
>>>> @@ -9009,7 +9016,7 @@ static inline int
>>>>
>>>>    thumb1_size_rtx_costs (rtx x, enum rtx_code code, enum rtx_code
>>>> outer)
>>>>    {
>>>>         machine_mode mode = GET_MODE (x);
>>>>
>>>> -  int words;
>>>> +  int words, cost;
>>>>
>>>>      switch (code)
>>>>             {
>>>>
>>>> @@ -9055,17 +9062,26 @@ thumb1_size_rtx_costs (rtx x, enum rtx_code
>>>> code,
>>>> enum rtx_code outer)
>>>>
>>>>          /* A SET doesn't have a mode, so let's look at the SET_DEST to
>>>> get
>>>>
>>>>          the mode.  */
>>>>
>>>>          words = ARM_NUM_INTS (GET_MODE_SIZE (GET_MODE (SET_DEST (x))));
>>>>
>>>> -      return COSTS_N_INSNS (words)
>>>> -            + COSTS_N_INSNS (1) * (satisfies_constraint_J (SET_SRC (x))
>>>> -                                   || satisfies_constraint_K (SET_SRC
>>>> (x))
>>>> -                                      /* thumb1_movdi_insn.  */
>>>> -                                   || ((words > 1) && MEM_P (SET_SRC
>>>> (x))));
>>>> +      cost = COSTS_N_INSNS (words);
>>>> +      if (satisfies_constraint_J (SET_SRC (x))
>>>> +         || satisfies_constraint_K (SET_SRC (x))
>>>> +            /* Too big immediate for 2byte mov, using movt.  */
>>>> +         || (UINTVAL (SET_SRC (x)) >= 256
>>>> +             && TARGET_HAVE_MOVT
>>>> +             && satisfies_constraint_j (SET_SRC (x)))
>>>> +            /* thumb1_movdi_insn.  */
>>>> +         || ((words > 1) && MEM_P (SET_SRC (x))))
>>>> +       cost += COSTS_N_INSNS (1);
>>>> +      return cost;
>>>>
>>>>        case CONST_INT:
>>>>          if (outer == SET)
>>>>                     {
>>>>                         if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256)
>>>>                             return COSTS_N_INSNS (1);
>>>>
>>>> +         /* movw is 4byte long.  */
>>>> +         if (TARGET_HAVE_MOVT && !(INTVAL (x) & 0xffff0000))
>>>> +           return COSTS_N_INSNS (2);
>>>>
>>>>           /* See split "TARGET_THUMB1 && satisfies_constraint_J".  */
>>>>           if (INTVAL (x) >= -255 && INTVAL (x) <= -1)
>>>>
>>>>                return COSTS_N_INSNS (2);
>>>>
>>>> diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
>>>> index
>>>>
>>>> 8aa9fedf5c07e78bc7ba793b39bebcc45a4d5921..ce39bdf5904dec3e12003c411f2a8b32
>>>> 6ea939e3 100644
>>>> --- a/gcc/config/arm/arm.md
>>>> +++ b/gcc/config/arm/arm.md
>>>> @@ -118,10 +118,10 @@
>>>>
>>>>    ; This can be "a" for ARM, "t" for either of the Thumbs, "32" for
>>>>    ; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode.  "v6"
>>>>    ; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without
>>>>
>>>> -; arm_arch6.  "v6t2" for Thumb-2 with arm_arch6.  This attribute is
>>>> -; used to compute attribute "enabled", use type "any" to enable an
>>>> -; alternative in all cases.
>>>> -(define_attr "arch"
>>>>
>>>> "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmx
>>>> t,iwmmxt2,armv6_or_vfpv3,neon" +; arm_arch6.  "v6t2" for Thumb-2 with
>>>> arm_arch6 and v8mb for ARMv8-M +; baseline.  This attribute is used to
>>>> compute attribute "enabled", +; use type "any" to enable an alternative
>>>> in all cases.
>>>> +(define_attr "arch"
>>>>
>>>> "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,
>>>> iwmmxt,iwmmxt2,armv6_or_vfpv3,neon">
>>>>      (const_string "any"))
>>>>       (define_attr "arch_enabled" "no,yes"
>>>>
>>>> @@ -160,6 +160,10 @@
>>>>
>>>>               (match_test "TARGET_32BIT && arm_arch6 &&
>>>> arm_arch_thumb2"))
>>>>
>>>>          (const_string "yes")
>>>>
>>>> +        (and (eq_attr "arch" "v8mb")
>>>> +             (match_test "TARGET_THUMB1 && arm_arch8"))
>>>> +        (const_string "yes")
>>>> +
>>>>
>>>>          (and (eq_attr "arch" "avoid_neon_for_64bits")
>>>>
>>>>               (match_test "TARGET_NEON")
>>>>               (not (match_test "TARGET_PREFER_NEON_64BITS")))
>>>>
>>>> diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
>>>> index
>>>>
>>>> 072ed4da47ad164eb406bedc3fccc589ac705e9f..47e569d0c259cd17d86a03061e5b47b3
>>>> dab4579f 100644
>>>> --- a/gcc/config/arm/thumb1.md
>>>> +++ b/gcc/config/arm/thumb1.md
>>>> @@ -590,8 +590,8 @@
>>>>
>>>>    ;;; ??? The 'i' constraint looks funny, but it should always be
>>>> replaced
>>>>    by
>>>>    ;;; thumb_reorg with a memory reference.
>>>>    (define_insn "*thumb1_movdi_insn"
>>>>
>>>> -  [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l,
>>>> m,*r")
>>>> -       (match_operand:DI 1 "general_operand"      "l,
>>>> I,J,>,l,mi,l,*r"))]
>>>> +  [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,r,l,>,l,
>>>> m,*r")
>>>> +       (match_operand:DI 1 "general_operand"      "l,
>>>> I,J,j,>,l,mi,l,*r"))]
>>>>
>>>>      "TARGET_THUMB1
>>>>            && (   register_operand (operands[0], DImode)
>>>>                 || register_operand (operands[1], DImode))"
>>>>
>>>> @@ -609,37 +609,41 @@
>>>>
>>>>        case 2:
>>>>          operands[1] = GEN_INT (- INTVAL (operands[1]));
>>>>          return \"movs\\t%Q0, %1\;rsbs\\t%Q0, %Q0, #0\;asrs\\t%R0, %Q0,
>>>>          #31\";
>>>>
>>>> -    case 3:
>>>> -      return \"ldmia\\t%1, {%0, %H0}\";
>>>> +    case 3: gcc_assert (TARGET_HAVE_MOVT);
>>>> +           return \"movw\\t%Q0, %L1\;movs\\tR0, #0\";
>>>>
>>>>        case 4:
>>>> -      return \"stmia\\t%0, {%1, %H1}\";
>>>> +      return \"ldmia\\t%1, {%0, %H0}\";
>>>>
>>>>        case 5:
>>>> -      return thumb_load_double_from_address (operands);
>>>> +      return \"stmia\\t%0, {%1, %H1}\";
>>>>
>>>>        case 6:
>>>> +      return thumb_load_double_from_address (operands);
>>>>
>>>> +    case 7:
>>>>          operands[2] = gen_rtx_MEM (SImode,
>>>>                                      plus_constant (Pmode, XEXP
>>>> (operands[0], 0), 4));
>>>>                   output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\",
>>>> operands);
>>>>          return \"\";
>>>>
>>>> -    case 7:
>>>>
>>>> +    case 8:
>>>>          if (REGNO (operands[1]) == REGNO (operands[0]) + 1)
>>>>
>>>>         return \"mov\\t%0, %1\;mov\\t%H0, %H1\";
>>>>
>>>>          return \"mov\\t%H0, %H1\;mov\\t%0, %1\";
>>>>               }
>>>>           }"
>>>>
>>>> -  [(set_attr "length" "4,4,6,2,2,6,4,4")
>>>> -   (set_attr "type"
>>>> "multiple,multiple,multiple,load2,store2,load2,store2,multiple")
>>>> -   (set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
>>>> +  [(set_attr "length" "4,4,6,6,2,2,6,4,4")
>>>> +   (set_attr "type"
>>>>
>>>> "multiple,multiple,multiple,multiple,load2,store2,load2,store2,multiple")
>>>> +   (set_attr "arch" "t1,t1,t1,v8mb,t1,t1,t1,t1,t1")
>>>> +   (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")]
>>>>
>>>>    )
>>>>       (define_insn "*thumb1_movsi_insn"
>>>>
>>>> -  [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l,
>>>> m,*l*h*k")
>>>> -       (match_operand:SI 1 "general_operand"      "l,
>>
>> I,J,K,>,l,mi,l,*l*h*k"))]
>>>>
>>>> +  [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,r,l,l,l,>,l,
>>>> m,*l*h*k")
>>>> +       (match_operand:SI 1 "general_operand"      "l,
>>>> I,j,J,K,>,l,mi,l,*l*h*k"))]
>>>>
>>>>      "TARGET_THUMB1
>>>>            && (   register_operand (operands[0], SImode)
>>>>                 || register_operand (operands[1], SImode))"
>>>>           "@
>>>>            movs %0, %1
>>>>       movs      %0, %1
>>>>
>>>> +   movw        %0, %1
>>>>
>>>>       #
>>>>       #
>>>>       ldmia\\t%1, {%0}
>>>>
>>>> @@ -647,10 +651,11 @@
>>>>
>>>>       ldr\\t%0, %1
>>>>       str\\t%1, %0
>>>>       mov\\t%0, %1"
>>>>
>>>> -  [(set_attr "length" "2,2,4,4,2,2,2,2,2")
>>>> -   (set_attr "type"
>>>> "mov_reg,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_reg")
>>>> -   (set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
>>>> -   (set_attr "conds"
>>>> "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
>>>> +  [(set_attr "length" "2,2,4,4,4,2,2,2,2,2")
>>>> +   (set_attr "type"
>>>>
>>>> "mov_reg,mov_imm,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_r
>>>> eg") +   (set_attr "pool_range" "*,*,*,*,*,*,*,1018,*,*")
>>>> +   (set_attr "arch" "t1,t1,v8mb,t1,t1,t1,t1,t1,t1,t1")
>>>> +   (set_attr "conds"
>>>> "set,clob,nocond,*,*,nocond,nocond,nocond,nocond,nocond")])
>>>>
>>>>    ; Split the load of 64-bit constant into two loads for high and low
>>>>    32-bit
>>>>
>>>> parts respectively
>>>>
>>>>    ; to see if we can load them in fewer instructions or fewer cycles.
>>>>
>>>> @@ -687,7 +692,8 @@
>>>>
>>>>    (define_split
>>>>         [(set (match_operand:SI 0 "register_operand" "")
>>>>
>>>>         (match_operand:SI 1 "const_int_operand" ""))]
>>>>
>>>> -  "TARGET_THUMB1 && satisfies_constraint_K (operands[1])"
>>>> +  "TARGET_THUMB1 && satisfies_constraint_K (operands[1])
>>>> +   && !(TARGET_HAVE_MOVT && satisfies_constraint_j (operands[1]))"
>>>>
>>>>      [(set (match_dup 2) (match_dup 1))
>>>>            (set (match_dup 0) (ashift:SI (match_dup 2) (match_dup 3)))]
>>>>           "
>>>>
>>>> @@ -714,7 +720,8 @@
>>>>
>>>>    (define_split
>>>>         [(set (match_operand:SI 0 "register_operand" "")
>>>>
>>>>         (match_operand:SI 1 "const_int_operand" ""))]
>>>>
>>>> -  "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])"
>>>> +  "TARGET_THUMB1 && satisfies_constraint_Pe (operands[1])
>>>> +   && !(TARGET_HAVE_MOVT && satisfies_constraint_j (operands[1]))"
>>>>
>>>>      [(set (match_dup 2) (match_dup 1))
>>>>            (set (match_dup 0) (plus:SI (match_dup 2) (match_dup 3)))]
>>>>           "
>>>>
>>>> @@ -726,8 +733,8 @@
>>>>
>>>>    )
>>>>       (define_insn "*thumb1_movhi_insn"
>>>>
>>>> -  [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,l*r,*h,l")
>>>> -       (match_operand:HI 1 "general_operand"       "l,m,l,k*h,*r,I"))]
>>>> +  [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l,m,l*r,*h,l,r")
>>>> +       (match_operand:HI 1 "general_operand"
>>>> "l,m,l,k*h,*r,I,n"))]
>>>>
>>>>      "TARGET_THUMB1
>>>>            && (   register_operand (operands[0], HImode)
>>>>                 || register_operand (operands[1], HImode))"
>>>>
>>>> @@ -739,6 +746,8 @@
>>>>
>>>>        case 3: return \"mov     %0, %1\";
>>>>        case 4: return \"mov     %0, %1\";
>>>>        case 5: return \"movs    %0, %1\";
>>>>
>>>> +    case 6: gcc_assert (TARGET_HAVE_MOVT);
>>>> +           return \"movw       %0, %L1\";
>>>>
>>>>        default: gcc_unreachable ();
>>>>               case 1:
>>>>          /* The stack pointer can end up being taken as an index
>>>> register.
>>>>
>>>> @@ -758,9 +767,10 @@
>>>>
>>>>         }
>>>>
>>>>          return \"ldrh  %0, %1\";
>>>>               }"
>>>>
>>>> -  [(set_attr "length" "2,4,2,2,2,2")
>>>> -   (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm")
>>>> -   (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
>>>> +  [(set_attr "length" "2,4,2,2,2,2,4")
>>>> +   (set_attr "type"
>>>> "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm,mov_imm") +   (set_attr
>>>> "arch" "t1,t1,t1,t1,t1,t1,v8mb")
>>>> +   (set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob,nocond")])
>>>>
>>>>    (define_expand "thumb_movhi_clobber"
>>>>         [(set (match_operand:HI     0 "memory_operand"   "")
>>>>
>>>> diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
>>>> index
>>>>
>>>> 3142cd53ae53e90bb1af2f595fe53778c1cbfd3b..860b4c0627e094bae8b3801f9256ff4f
>>>> ec5c8fc2 100644
>>>> --- a/gcc/doc/sourcebuild.texi
>>>> +++ b/gcc/doc/sourcebuild.texi
>>>> @@ -1601,6 +1601,10 @@ arm_v8_1a_neon_ok.
>>>>
>>>>    ARM target prefers @code{LDRD} and @code{STRD} instructions over
>>>>    @code{LDM} and @code{STM} instructions.
>>>>
>>>> +@item arm_thumb1_movt_ko
>>>> +ARM target generates Thumb-1 code for @code{-mthumb} with no
>>>> +@code{MOVT} instruction available.
>>>> +
>>>>
>>>>    @end table
>>>>       @subsubsection AArch64-specific attributes
>>>>
>>>> diff --git a/gcc/testsuite/gcc.target/arm/pr42574.c
>>>> b/gcc/testsuite/gcc.target/arm/pr42574.c
>>>> index
>>>>
>>>> 0ccd05f9922c798611e479d97890aa69b180e989..53aea6224be89d2d771a22f8ecb39727
>>>> 6f586234 100644
>>>> --- a/gcc/testsuite/gcc.target/arm/pr42574.c
>>>> +++ b/gcc/testsuite/gcc.target/arm/pr42574.c
>>>> @@ -1,5 +1,5 @@
>>>>
>>>>    /* { dg-options "-mthumb -Os -fpic" }  */
>>>>
>>>> -/* { dg-require-effective-target arm_thumb1_ok } */
>>>> +/* { dg-require-effective-target arm_thumb1_movt_ko } */
>>>>
>>>>    /* { dg-require-effective-target fpic } */
>>>>    /* Make sure the address of glob.c is calculated only once and using
>>>>          a logical shift for the offset (200<<1).  */
>>>>
>>>> diff --git a/gcc/testsuite/lib/target-supports.exp
>>>> b/gcc/testsuite/lib/target- supports.exp
>>>> index
>>>>
>>>> 46352b90de7202960116d93523b017d5dc4a1423..f5d73ad2620fa35f0091a890bca63c7d
>>>> 35de1a85 100644
>>>> --- a/gcc/testsuite/lib/target-supports.exp
>>>> +++ b/gcc/testsuite/lib/target-supports.exp
>>>> @@ -3329,6 +3329,23 @@ proc check_effective_target_arm_cortex_m { } {
>>>>
>>>>        } "-mthumb"]
>>>>       }
>>>>
>>>> +# Return 1 if this is an ARM target where -mthumb causes Thumb-1 to be
>>>> +# used and no movt/movw instructions to be available.
>>>> +
>>>> +proc check_effective_target_arm_thumb1_movt_ko {} {
>>>> +    if [check_effective_target_arm_thumb1_ok] {
>>>> +       return [expr ![check_no_compiler_messages arm_movt object {
>>>> +           int
>>>> +           foo (void)
>>>> +           {
>>>> +             asm ("movt r0, #42");
>>>> +           }
>>>> +       } "-mthumb"]]
>>>> +    } else {
>>>> +       return 0
>>>> +    }
>>>> +}
>>>> +
>>>>
>>>>    # Return 1 if this compilation turns on string_ops_prefer_neon on.
>>>>       proc check_effective_target_arm_tune_string_ops_prefer_neon { } {
>>>>
>>>> Best regards,
>>>>
>>>> Thomas
>>>>
>>>>> On 17/05/16 11:13, Thomas Preudhomme wrote:
>>>>>>
>>>>>> Ping?
>>>>>>
>>>>>> *** gcc/ChangeLog ***
>>>>>>
>>>>>> 2015-11-13  Thomas Preud'homme  <thomas.preudho...@arm.com>
>>>>>>
>>>>>>            * config/arm/arm.h (TARGET_HAVE_MOVT): Include ARMv8-M as
>>>>>>            having
>>>>>>            MOVT.
>>>>>>            * config/arm/arm.c (arm_arch_name): (const_ok_for_op):
>>>>>> Check
>>>>>>            MOVT/MOVW
>>>>>>            availability with TARGET_HAVE_MOVT.
>>>>>>            (thumb_legitimate_constant_p): Legalize high part of a
>>>>>>            label_ref
>>>>>>            as a
>>>>>>            constant.
>>>>>
>>>>> I don't think "Legalize" is the right word here. How about "Strip the
>>>>> HIGH
>>>>> part of a label_ref"?
>>>>>
>>>>>>            (thumb1_rtx_costs): Also return 0 if setting a half word
>>>>>>            constant
>>>>>>            and
>>>>>>            movw is available.
>>>>>>            (thumb1_size_rtx_costs): Make set of half word constant
>>>>>> also
>>>>>>            cost
>>>>>>            1
>>>>>>            extra instruction if MOVW is available.  Make constant with
>>>>>>            bottom
>>>>>>
>>>>>> half
>>>>>>
>>>>>>            word zero cost 2 instruction if MOVW is available.
>>>>>>            * config/arm/arm.md (define_attr "arch"): Add v8mb.
>>>>>>            (define_attr "arch_enabled"): Set to yes if arch value is
>>>>>> v8mb
>>>>>>            and
>>>>>>            target is ARMv8-M Baseline.
>>>>>>            * config/arm/thumb1.md (thumb1_movdi_insn): Add ARMv8-M
>>>>>>            Baseline
>>>>>>            only
>>>>>>            alternative for constants satisfying j constraint.
>>>>>>            (thumb1_movsi_insn): Likewise.
>>>>>>            (movsi splitter for K alternative): Tighten condition to
>>>>>> not
>>>>>>            trigger
>>>>>>            if movt is available and j constraint is satisfied.
>>>>>>            (Pe immediate splitter): Likewise.
>>>>>>            (thumb1_movhi_insn): Add ARMv8-M Baseline only alternative
>>>>>> for
>>>>>>            constant fitting in an halfword to use movw.
>>>>>
>>>>> Please use 'MOVW' consistently in the ChangeLog rather than the
>>>>> lowercase
>>>>> 'movw'
>>>>>
>>>>>>            * doc/sourcebuild.texi (arm_thumb1_movt_ko): Document new
>>>>>> ARM
>>>>>>            effective target.
>>>>>>
>>>>>> *** gcc/testsuite/ChangeLog ***
>>>>>>
>>>>>> 2015-11-13  Thomas Preud'homme  <thomas.preudho...@arm.com>
>>>>>>
>>>>>>            * lib/target-supports.exp
>>>>>>            (check_effective_target_arm_thumb1_movt_ko):
>>>>>>            Define effective target.
>>>>>>            * gcc.target/arm/pr42574.c: Require arm_thumb1_movt_ko
>>>>>> instead
>>>>>>            of
>>>>>>            arm_thumb1_ok as effective target to exclude ARMv8-M
>>>>>> Baseline.
>>>>>>
>>>>>> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
>>>>>> index
>>>>>>
>>>>>> 47216b4a1959ccdb18e329db411bf7f941e67163..f42e996e5a7ce979fe406b8261d50f
>>>>>> b2
>>>>>> ba005f6b 100644
>>>>>> --- a/gcc/config/arm/arm.h
>>>>>> +++ b/gcc/config/arm/arm.h
>>>>>> @@ -269,7 +269,7 @@ extern void
>>>>>> (*arm_lang_output_object_attributes_hook)
>>>>>> (void);
>>>>>>
>>>>>>     #define TARGET_HAVE_LDACQ   (TARGET_ARM_ARCH >= 8 &&
>>>>>> arm_arch_notm)
>>>>>>         /* Nonzero if this chip provides the movw and movt
>>>>>> instructions.  */
>>>>>>
>>>>>> -#define TARGET_HAVE_MOVT       (arm_arch_thumb2)
>>>>>> +#define TARGET_HAVE_MOVT       (arm_arch_thumb2 || arm_arch8)
>>>>>>
>>>>>>     /* Nonzero if integer division instructions supported.  */
>>>>>>     #define TARGET_IDIV ((TARGET_ARM && arm_arch_arm_hwdiv)     \
>>>>>>
>>>>>> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
>>>>>> index
>>>>>>
>>>>>> d75a34f10d5ed22cff0a0b5d3ad433f111b059ee..13b4b71ac8f9c1da8ef1945f7ff698
>>>>>> 5c
>>>>>> a59f6832 100644
>>>>>> --- a/gcc/config/arm/arm.c
>>>>>> +++ b/gcc/config/arm/arm.c
>>>>>> @@ -8220,6 +8220,12 @@ arm_legitimate_constant_p_1 (machine_mode, rtx
>>>>>> x)
>>>>>>
>>>>>>     static bool
>>>>>>     thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED,
>>>>>> rtx
>>>>>>     x)
>>>>>>     {
>>>>>>
>>>>>> +  /* Splitters for TARGET_USE_MOVT call arm_emit_movpair which
>>>>>> creates
>>>>>> high +     RTX.  These RTX must therefore be allowed for Thumb-1 so
>>>>>> that
>>>>>> when run +     for ARMv8-M baseline or later the result is valid.  */
>>>>>> +  if (TARGET_HAVE_MOVT && GET_CODE (x) == HIGH)
>>>>>> +    x = XEXP (x, 0);
>>>>>> +
>>>>>>
>>>>>>       return (CONST_INT_P (x)
>>>>>>                   || CONST_DOUBLE_P (x)
>>>>>>           || CONSTANT_ADDRESS_P (x)
>>>>>>
>>>>>> @@ -8306,7 +8312,8 @@ thumb1_rtx_costs (rtx x, enum rtx_code code,
>>>>>> enum
>>>>>> rtx_code outer)
>>>>>>
>>>>>>         case CONST_INT:
>>>>>>           if (outer == SET)
>>>>>>
>>>>>>         {
>>>>>>
>>>>>> -         if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256)
>>>>>> +         if ((unsigned HOST_WIDE_INT) INTVAL (x) < 256
>>>>>> +             || (TARGET_HAVE_MOVT && !(INTVAL (x) & 0xffff0000)))
>>>>>>
>>>>>>             return 0;
>>>>>
>>>>> Since you're modifying this line please replace (unsigned
>>>>> HOST_WIDE_INT)
>>>>> INTVAL (x) with UINTVAL (x).
>
>

Reply via email to