From 2b9509a34d0f7e25202530a4453afc5eb5d06f6b Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 13 Jul 2016 10:54:01 +0000 Subject: [PATCH] arm.h (TARGET_HAVE_MOVT): Include ARMv8-M as having MOVT. 2016-07-13 Thomas Preud'homme gcc/ * 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/ * 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. From-SVN: r238288 --- gcc/ChangeLog | 31 +++++++++++++ gcc/config/arm/arm.c | 31 ++++++++++--- gcc/config/arm/arm.h | 4 +- gcc/config/arm/arm.md | 34 +++++++++----- gcc/config/arm/thumb1.md | 55 ++++++++++++++--------- gcc/doc/sourcebuild.texi | 4 ++ gcc/testsuite/ChangeLog | 10 +++++ gcc/testsuite/gcc.target/arm/movdi_movw.c | 10 +++++ gcc/testsuite/gcc.target/arm/movhi_movw.c | 10 +++++ gcc/testsuite/gcc.target/arm/movsi_movw.c | 10 +++++ gcc/testsuite/gcc.target/arm/pr42574.c | 2 +- gcc/testsuite/lib/target-supports.exp | 17 +++++++ 12 files changed, 174 insertions(+), 44 deletions(-) create mode 100644 gcc/testsuite/gcc.target/arm/movdi_movw.c create mode 100644 gcc/testsuite/gcc.target/arm/movhi_movw.c create mode 100644 gcc/testsuite/gcc.target/arm/movsi_movw.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e42e288653f..3f7e7f10bd0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2016-07-13 Thomas Preud'homme + + * 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. + 2016-07-13 Richard Biener PR middle-end/71104 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 6af0d365fce..195de4822c8 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -8280,6 +8280,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) @@ -8366,7 +8372,9 @@ 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 + /* 16-bit constant. */ + || (TARGET_HAVE_MOVT && !(INTVAL (x) & 0xffff0000))) return 0; if (thumb_shiftable_const (INTVAL (x))) return COSTS_N_INSNS (2); @@ -9069,7 +9077,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) { @@ -9115,17 +9123,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 an immediate for a 2-byte 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 (UINTVAL (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.h b/gcc/config/arm/arm.h index c9aaa609087..6a0f64537f8 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -263,8 +263,8 @@ extern void (*arm_lang_output_object_attributes_hook)(void); /* Nonzero if this chip supports load-acquire and store-release. */ #define TARGET_HAVE_LDACQ (TARGET_ARM_ARCH >= 8 && arm_arch_notm) -/* Nonzero if this chip provides the MOVW and MOVW instructions. */ -#define TARGET_HAVE_MOVT (arm_arch_thumb2) +/* Nonzero if this chip provides the MOVW and MOVT instructions. */ +#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.md b/gcc/config/arm/arm.md index 3cd76f935a4..8727c6df16e 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,iwmmxt,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"))) @@ -5699,12 +5703,15 @@ ;; LO_SUM adds in the high bits. Fortunately these are opaque operations ;; so this does not matter. (define_insn "*arm_movt" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r") - (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0") - (match_operand:SI 2 "general_operand" "i")))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") + (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") + (match_operand:SI 2 "general_operand" "i,i")))] "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])" - "movt%?\t%0, #:upper16:%c2" - [(set_attr "predicable" "yes") + "@ + movt%?\t%0, #:upper16:%c2 + movt\t%0, #:upper16:%c2" + [(set_attr "arch" "32,v8mb") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set_attr "length" "4") (set_attr "type" "alu_sreg")] @@ -10971,13 +10978,16 @@ ;; We only care about the lower 16 bits of the constant ;; being inserted into the upper 16 bits of the register. (define_insn "*arm_movtas_ze" - [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") + [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r") (const_int 16) (const_int 16)) (match_operand:SI 1 "const_int_operand" ""))] "TARGET_HAVE_MOVT" - "movt%?\t%0, %L1" - [(set_attr "predicable" "yes") + "@ + movt%?\t%0, %L1 + movt\t%0, %L1" + [(set_attr "arch" "32,v8mb") + (set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set_attr "length" "4") (set_attr "type" "alu_sreg")] diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md index 035641b3335..b317f1b0637 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))" @@ -610,36 +610,41 @@ 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}\"; + 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 +652,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_reg") + (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 +693,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 +721,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 +734,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 +747,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 +768,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 23d3c3f0f54..b437c171132 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -1614,6 +1614,10 @@ ARM target supports acquire-release instructions. ARM target prefers @code{LDRD} and @code{STRD} instructions over @code{LDM} and @code{STM} instructions. +@item arm_thumb1_movt_ok +ARM target generates Thumb-1 code for @code{-mthumb} with @code{MOVW} +and @code{MOVT} instructions available. + @end table @subsubsection AArch64-specific attributes diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d4e0fcabdc0..d1204e73e8d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2016-07-13 Thomas Preud'homme + + * 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. + 2016-07-13 Richard Biener PR middle-end/71104 diff --git a/gcc/testsuite/gcc.target/arm/movdi_movw.c b/gcc/testsuite/gcc.target/arm/movdi_movw.c new file mode 100644 index 00000000000..0f6b839da61 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/movdi_movw.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { arm_thumb2 || arm_thumb1_movt_ok } } } */ +/* { dg-options "-O2" } */ + +long long +movdi (int a) +{ + return 0xF0F0; +} + +/* { dg-final { scan-assembler-times "movw\tr0, #61680" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/movhi_movw.c b/gcc/testsuite/gcc.target/arm/movhi_movw.c new file mode 100644 index 00000000000..b097a8a019c --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/movhi_movw.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { arm_thumb2 || arm_thumb1_movt_ok } } } */ +/* { dg-options "-O2" } */ + +short +movsi (void) +{ + return (short) 0x7070; +} + +/* { dg-final { scan-assembler-times "movw\tr0, #28784" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/movsi_movw.c b/gcc/testsuite/gcc.target/arm/movsi_movw.c new file mode 100644 index 00000000000..d50906e76ab --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/movsi_movw.c @@ -0,0 +1,10 @@ +/* { dg-do compile { target { arm_thumb2 || arm_thumb1_movt_ok } } } */ +/* { dg-options "-O2" } */ + +int +movsi (void) +{ + return 0xF0F0; +} + +/* { dg-final { scan-assembler-times "movw\tr0, #61680" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr42574.c b/gcc/testsuite/gcc.target/arm/pr42574.c index 0ccd05f9922..e3476f37788 100644 --- a/gcc/testsuite/gcc.target/arm/pr42574.c +++ b/gcc/testsuite/gcc.target/arm/pr42574.c @@ -1,5 +1,5 @@ +/* { dg-do compile { arm_thumb1_ok && { ! arm_thumb1_movt_ok } } } */ /* { dg-options "-mthumb -Os -fpic" } */ -/* { dg-require-effective-target arm_thumb1_ok } */ /* { 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 b26f8a29c8d..e6a117022f8 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -3485,6 +3485,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 MOVT/MOVW instructions to be available. + +proc check_effective_target_arm_thumb1_movt_ok {} { + if [check_effective_target_arm_thumb1_ok] { + return [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 { } { -- 2.30.2