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). > >