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
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, Kyrilland 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, %1movs %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 attributesdiff --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 usinga 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, ThomasOn 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).