public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967)
@ 2020-09-28  9:09 Christophe Lyon
  2020-09-28  9:09 ` [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770) Christophe Lyon
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Christophe Lyon @ 2020-09-28  9:09 UTC (permalink / raw)
  To: gcc-patches

With -mpure-code on v6m (thumb-1), to avoid a useless indirection when
building the address of a symbol, we want to consider SYMBOL_REF as a
legitimate constant. This way, we build the address using a series of
upper/lower relocations instead of loading the address from memory.

This patch also fixes a missing "clob" conds attribute for
thumb1_movsi_insn, needed because that alternative clobbers the flags.

2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>

	gcc/
	* config/arm/arm.c (thumb_legitimate_constant_p): Add support for
	disabled literal pool in thumb-1.
	* config/arm/thumb1.md (thumb1_movsi_symbol_ref): Remove.
	(*thumb1_movsi_insn): Add support for SYMBOL_REF with -mpure-code.

	gcc/testsuite
	* gcc.target/arm/pure-code/pr96767.c: New test.
---
 gcc/config/arm/arm.c                             |   6 ++
 gcc/config/arm/thumb1.md                         | 102 +++++++++++------------
 gcc/testsuite/gcc.target/arm/pure-code/pr96767.c |  10 +++
 3 files changed, 63 insertions(+), 55 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96767.c

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 022ef6c..abe357e 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -9485,6 +9485,12 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 	  || CONST_DOUBLE_P (x)
 	  || CONSTANT_ADDRESS_P (x)
 	  || (TARGET_HAVE_MOVT && GET_CODE (x) == SYMBOL_REF)
+	  /* On Thumb-1 without MOVT/MOVW and literal pool disabled,
+	     we build the symbol address with upper/lower
+	     relocations.  */
+	  || (TARGET_THUMB1
+	      && GET_CODE (x) == SYMBOL_REF
+	      && arm_disable_literal_pool)
 	  || flag_pic);
 }
 
diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
index 4a59d87..3dedcae 100644
--- a/gcc/config/arm/thumb1.md
+++ b/gcc/config/arm/thumb1.md
@@ -43,27 +43,6 @@
 
 
 
-(define_insn "thumb1_movsi_symbol_ref"
-  [(set (match_operand:SI 0 "register_operand" "=l")
-	(match_operand:SI 1 "general_operand" ""))
-   ]
-  "TARGET_THUMB1
-   && arm_disable_literal_pool
-   && GET_CODE (operands[1]) == SYMBOL_REF"
-  "*
-  output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
-  output_asm_insn (\"lsls\\t%0, #8\", operands);
-  output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
-  output_asm_insn (\"lsls\\t%0, #8\", operands);
-  output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
-  output_asm_insn (\"lsls\\t%0, #8\", operands);
-  output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
-  return \"\";
-  "
-  [(set_attr "length" "14")
-   (set_attr "conds" "clob")]
-)
-
 (define_insn "*thumb1_adddi3"
   [(set (match_operand:DI          0 "register_operand" "=l")
 	(plus:DI (match_operand:DI 1 "register_operand" "%0")
@@ -696,40 +675,53 @@ (define_insn "*thumb1_movsi_insn"
       case 7:
       /* pure-code alternative: build the constant byte by byte,
 	 instead of loading it from a constant pool.  */
-	{
-	  int i;
-	  HOST_WIDE_INT op1 = INTVAL (operands[1]);
-	  bool mov_done_p = false;
-	  rtx ops[2];
-	  ops[0] = operands[0];
-
-	  /* Emit upper 3 bytes if needed.  */
-	  for (i = 0; i < 3; i++)
-	    {
-	       int byte = (op1 >> (8 * (3 - i))) & 0xff;
-
-	      if (byte)
-		{
-		  ops[1] = GEN_INT (byte);
-		  if (mov_done_p)
-		    output_asm_insn ("adds\t%0, %1", ops);
-		  else
-		    output_asm_insn ("movs\t%0, %1", ops);
-		  mov_done_p = true;
-		}
-
-	      if (mov_done_p)
-		output_asm_insn ("lsls\t%0, #8", ops);
-	    }
+	if (GET_CODE (operands[1]) == SYMBOL_REF)
+	  {
+	    output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
+	    output_asm_insn (\"lsls\\t%0, #8\", operands);
+	    output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
+	    output_asm_insn (\"lsls\\t%0, #8\", operands);
+	    output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
+	    output_asm_insn (\"lsls\\t%0, #8\", operands);
+	    output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
+	    return \"\";
+	  }
+	else
+	  {
+	    int i;
+	    HOST_WIDE_INT op1 = INTVAL (operands[1]);
+	    bool mov_done_p = false;
+	    rtx ops[2];
+	    ops[0] = operands[0];
+
+	    /* Emit upper 3 bytes if needed.  */
+	    for (i = 0; i < 3; i++)
+	      {
+		int byte = (op1 >> (8 * (3 - i))) & 0xff;
+
+		if (byte)
+		  {
+		    ops[1] = GEN_INT (byte);
+		    if (mov_done_p)
+		      output_asm_insn ("adds\t%0, %1", ops);
+		    else
+		      output_asm_insn ("movs\t%0, %1", ops);
+		    mov_done_p = true;
+		  }
+
+		if (mov_done_p)
+		  output_asm_insn ("lsls\t%0, #8", ops);
+	      }
+
+	    /* Emit lower byte if needed.  */
+	    ops[1] = GEN_INT (op1 & 0xff);
+	    if (!mov_done_p)
+	      output_asm_insn ("movs\t%0, %1", ops);
+	    else if (op1 & 0xff)
+	      output_asm_insn ("adds\t%0, %1", ops);
+	    return "";
+	  }
 
-	  /* Emit lower byte if needed.  */
-	  ops[1] = GEN_INT (op1 & 0xff);
-	  if (!mov_done_p)
-	    output_asm_insn ("movs\t%0, %1", ops);
-	  else if (op1 & 0xff)
-	    output_asm_insn ("adds\t%0, %1", ops);
-	  return "";
-	}
       case 8: return "ldr\t%0, %1";
       case 9: return "str\t%1, %0";
       case 10: return "mov\t%0, %1";
@@ -740,7 +732,7 @@ (define_insn "*thumb1_movsi_insn"
    (set_attr "pool_range" "*,*,*,*,*,*,*, *,1018,*,*")
    (set_attr "arch" "t1,t1,v8mb,t1,t1,t1,t1,t1,t1,t1,t1")
    (set_attr "required_for_purecode" "no,no,no,no,no,no,no,yes,no,no,no")
-   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,nocond,nocond,nocond,nocond")])
+   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,clob,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.
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
new file mode 100644
index 0000000..cb3ee68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+
+int x;
+int f1 (void) { return x; }
+
+/* We expect only one indirect load like ldr r3, [r3]. In some
+   configurations there is an additional ldr rX, [sp], #4 which is not
+   related to what we check here, so make sure not to match it.  */
+/* { dg-final { scan-assembler-times "ldr\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 1 } } */
-- 
2.7.4


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770)
  2020-09-28  9:09 [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967) Christophe Lyon
@ 2020-09-28  9:09 ` Christophe Lyon
  2020-10-06  8:30   ` Christophe Lyon
  2020-10-27 16:22   ` Richard Earnshaw
  2020-10-06  8:30 ` [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967) Christophe Lyon
  2020-10-27 16:06 ` Richard Earnshaw
  2 siblings, 2 replies; 9+ messages in thread
From: Christophe Lyon @ 2020-09-28  9:09 UTC (permalink / raw)
  To: gcc-patches

With -mpure-code on v6m (thumb-1), we can use small offsets with
upper/lower relocations to avoid the extra addition of the
offset.

This patch accepts expressions symbol+offset as legitimate constants
when the literal pool is disabled, making sure that the offset is
within the range supported by thumb-1 [0..255].

It also makes sure that thumb1_movsi_insn emits an error in case we
try to use it with an unsupported RTL construct.

2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>

	gcc/
	* config/arm/arm.c (thumb_legitimate_constant_p): Accept
	(symbol_ref + addend) when literal pool is disabled.
	(arm_valid_symbolic_address_p): Add support for thumb-1 without
	MOVT/MOVW.
	* config/arm/thumb1.md (*thumb1_movsi_insn): Accept (symbol_ref +
	addend) in the pure-code alternative.

	gcc/testsuite/
	* gcc.target/arm/pure-code/pr96770.c: New test.
---
 gcc/config/arm/arm.c                             | 15 ++++++++++++---
 gcc/config/arm/thumb1.md                         |  5 +++--
 gcc/testsuite/gcc.target/arm/pure-code/pr96770.c | 21 +++++++++++++++++++++
 3 files changed, 36 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96770.c

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index abe357e..ceeb91f 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -9489,7 +9489,8 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
 	     we build the symbol address with upper/lower
 	     relocations.  */
 	  || (TARGET_THUMB1
-	      && GET_CODE (x) == SYMBOL_REF
+	      && !label_mentioned_p (x)
+	      && arm_valid_symbolic_address_p (x)
 	      && arm_disable_literal_pool)
 	  || flag_pic);
 }
@@ -31495,7 +31496,10 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
    According to the ARM ELF ABI, the initial addend of REL-type relocations
    processing MOVW and MOVT instructions is formed by interpreting the 16-bit
    literal field of the instruction as a 16-bit signed value in the range
-   -32768 <= A < 32768.  */
+   -32768 <= A < 32768.
+
+   In Thumb-1 mode, we use upper/lower relocations which have an 8-bit
+   unsigned range of 0 <= A < 256.  */
 
 bool
 arm_valid_symbolic_address_p (rtx addr)
@@ -31519,7 +31523,12 @@ arm_valid_symbolic_address_p (rtx addr)
       xop1 = XEXP (tmp, 1);
 
       if (GET_CODE (xop0) == SYMBOL_REF && CONST_INT_P (xop1))
-	  return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
+	{
+	  if (TARGET_THUMB1 && !TARGET_HAVE_MOVT)
+	    return IN_RANGE (INTVAL (xop1), 0, 0xff);
+	  else
+	    return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
+	}
     }
 
   return false;
diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
index 3dedcae..2258a52 100644
--- a/gcc/config/arm/thumb1.md
+++ b/gcc/config/arm/thumb1.md
@@ -675,7 +675,7 @@ (define_insn "*thumb1_movsi_insn"
       case 7:
       /* pure-code alternative: build the constant byte by byte,
 	 instead of loading it from a constant pool.  */
-	if (GET_CODE (operands[1]) == SYMBOL_REF)
+	if (arm_valid_symbolic_address_p (operands[1]))
 	  {
 	    output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
 	    output_asm_insn (\"lsls\\t%0, #8\", operands);
@@ -686,7 +686,7 @@ (define_insn "*thumb1_movsi_insn"
 	    output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
 	    return \"\";
 	  }
-	else
+	else if (GET_CODE (operands[1]) == CONST_INT)
 	  {
 	    int i;
 	    HOST_WIDE_INT op1 = INTVAL (operands[1]);
@@ -721,6 +721,7 @@ (define_insn "*thumb1_movsi_insn"
 	      output_asm_insn ("adds\t%0, %1", ops);
 	    return "";
 	  }
+	  gcc_unreachable ();
 
       case 8: return "ldr\t%0, %1";
       case 9: return "str\t%1, %0";
diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
new file mode 100644
index 0000000..a43d71f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-mpure-code" } */
+
+int arr[1000];
+int *f4 (void) { return &arr[1]; }
+
+/* For cortex-m0 (thumb-1/v6m), we generate 4 movs with upper/lower:#arr+4.  */
+/* { dg-final { scan-assembler-times "\\+4" 4 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
+
+/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
+   generate a movt/movw pair with upper/lower:#arr+4.  */
+/* { dg-final { scan-assembler-times "\\+4" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
+
+int *f5 (void) { return &arr[80]; }
+
+/* For cortex-m0 (thumb-1/v6m), we generate 1 ldr from rodata pointer to arr+320.  */
+/* { dg-final { scan-assembler-times "\\+320" 1 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
+
+/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
+   generate a movt/movw pair with upper/lower:arr+320.  */
+/* { dg-final { scan-assembler-times "\\+320" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
-- 
2.7.4


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967)
  2020-09-28  9:09 [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967) Christophe Lyon
  2020-09-28  9:09 ` [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770) Christophe Lyon
@ 2020-10-06  8:30 ` Christophe Lyon
  2020-10-22  8:47   ` Christophe Lyon
  2020-10-27 16:06 ` Richard Earnshaw
  2 siblings, 1 reply; 9+ messages in thread
From: Christophe Lyon @ 2020-10-06  8:30 UTC (permalink / raw)
  To: gcc Patches

ping?

On Mon, 28 Sep 2020 at 11:09, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
>
> With -mpure-code on v6m (thumb-1), to avoid a useless indirection when
> building the address of a symbol, we want to consider SYMBOL_REF as a
> legitimate constant. This way, we build the address using a series of
> upper/lower relocations instead of loading the address from memory.
>
> This patch also fixes a missing "clob" conds attribute for
> thumb1_movsi_insn, needed because that alternative clobbers the flags.
>
> 2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
>
>         gcc/
>         * config/arm/arm.c (thumb_legitimate_constant_p): Add support for
>         disabled literal pool in thumb-1.
>         * config/arm/thumb1.md (thumb1_movsi_symbol_ref): Remove.
>         (*thumb1_movsi_insn): Add support for SYMBOL_REF with -mpure-code.
>
>         gcc/testsuite
>         * gcc.target/arm/pure-code/pr96767.c: New test.
> ---
>  gcc/config/arm/arm.c                             |   6 ++
>  gcc/config/arm/thumb1.md                         | 102 +++++++++++------------
>  gcc/testsuite/gcc.target/arm/pure-code/pr96767.c |  10 +++
>  3 files changed, 63 insertions(+), 55 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
>
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index 022ef6c..abe357e 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -9485,6 +9485,12 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
>           || CONST_DOUBLE_P (x)
>           || CONSTANT_ADDRESS_P (x)
>           || (TARGET_HAVE_MOVT && GET_CODE (x) == SYMBOL_REF)
> +         /* On Thumb-1 without MOVT/MOVW and literal pool disabled,
> +            we build the symbol address with upper/lower
> +            relocations.  */
> +         || (TARGET_THUMB1
> +             && GET_CODE (x) == SYMBOL_REF
> +             && arm_disable_literal_pool)
>           || flag_pic);
>  }
>
> diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
> index 4a59d87..3dedcae 100644
> --- a/gcc/config/arm/thumb1.md
> +++ b/gcc/config/arm/thumb1.md
> @@ -43,27 +43,6 @@
>
>
>
> -(define_insn "thumb1_movsi_symbol_ref"
> -  [(set (match_operand:SI 0 "register_operand" "=l")
> -       (match_operand:SI 1 "general_operand" ""))
> -   ]
> -  "TARGET_THUMB1
> -   && arm_disable_literal_pool
> -   && GET_CODE (operands[1]) == SYMBOL_REF"
> -  "*
> -  output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
> -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> -  output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
> -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> -  output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
> -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> -  output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
> -  return \"\";
> -  "
> -  [(set_attr "length" "14")
> -   (set_attr "conds" "clob")]
> -)
> -
>  (define_insn "*thumb1_adddi3"
>    [(set (match_operand:DI          0 "register_operand" "=l")
>         (plus:DI (match_operand:DI 1 "register_operand" "%0")
> @@ -696,40 +675,53 @@ (define_insn "*thumb1_movsi_insn"
>        case 7:
>        /* pure-code alternative: build the constant byte by byte,
>          instead of loading it from a constant pool.  */
> -       {
> -         int i;
> -         HOST_WIDE_INT op1 = INTVAL (operands[1]);
> -         bool mov_done_p = false;
> -         rtx ops[2];
> -         ops[0] = operands[0];
> -
> -         /* Emit upper 3 bytes if needed.  */
> -         for (i = 0; i < 3; i++)
> -           {
> -              int byte = (op1 >> (8 * (3 - i))) & 0xff;
> -
> -             if (byte)
> -               {
> -                 ops[1] = GEN_INT (byte);
> -                 if (mov_done_p)
> -                   output_asm_insn ("adds\t%0, %1", ops);
> -                 else
> -                   output_asm_insn ("movs\t%0, %1", ops);
> -                 mov_done_p = true;
> -               }
> -
> -             if (mov_done_p)
> -               output_asm_insn ("lsls\t%0, #8", ops);
> -           }
> +       if (GET_CODE (operands[1]) == SYMBOL_REF)
> +         {
> +           output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
> +           output_asm_insn (\"lsls\\t%0, #8\", operands);
> +           output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
> +           output_asm_insn (\"lsls\\t%0, #8\", operands);
> +           output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
> +           output_asm_insn (\"lsls\\t%0, #8\", operands);
> +           output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
> +           return \"\";
> +         }
> +       else
> +         {
> +           int i;
> +           HOST_WIDE_INT op1 = INTVAL (operands[1]);
> +           bool mov_done_p = false;
> +           rtx ops[2];
> +           ops[0] = operands[0];
> +
> +           /* Emit upper 3 bytes if needed.  */
> +           for (i = 0; i < 3; i++)
> +             {
> +               int byte = (op1 >> (8 * (3 - i))) & 0xff;
> +
> +               if (byte)
> +                 {
> +                   ops[1] = GEN_INT (byte);
> +                   if (mov_done_p)
> +                     output_asm_insn ("adds\t%0, %1", ops);
> +                   else
> +                     output_asm_insn ("movs\t%0, %1", ops);
> +                   mov_done_p = true;
> +                 }
> +
> +               if (mov_done_p)
> +                 output_asm_insn ("lsls\t%0, #8", ops);
> +             }
> +
> +           /* Emit lower byte if needed.  */
> +           ops[1] = GEN_INT (op1 & 0xff);
> +           if (!mov_done_p)
> +             output_asm_insn ("movs\t%0, %1", ops);
> +           else if (op1 & 0xff)
> +             output_asm_insn ("adds\t%0, %1", ops);
> +           return "";
> +         }
>
> -         /* Emit lower byte if needed.  */
> -         ops[1] = GEN_INT (op1 & 0xff);
> -         if (!mov_done_p)
> -           output_asm_insn ("movs\t%0, %1", ops);
> -         else if (op1 & 0xff)
> -           output_asm_insn ("adds\t%0, %1", ops);
> -         return "";
> -       }
>        case 8: return "ldr\t%0, %1";
>        case 9: return "str\t%1, %0";
>        case 10: return "mov\t%0, %1";
> @@ -740,7 +732,7 @@ (define_insn "*thumb1_movsi_insn"
>     (set_attr "pool_range" "*,*,*,*,*,*,*, *,1018,*,*")
>     (set_attr "arch" "t1,t1,v8mb,t1,t1,t1,t1,t1,t1,t1,t1")
>     (set_attr "required_for_purecode" "no,no,no,no,no,no,no,yes,no,no,no")
> -   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,nocond,nocond,nocond,nocond")])
> +   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,clob,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.
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
> new file mode 100644
> index 0000000..cb3ee68
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mpure-code" } */
> +
> +int x;
> +int f1 (void) { return x; }
> +
> +/* We expect only one indirect load like ldr r3, [r3]. In some
> +   configurations there is an additional ldr rX, [sp], #4 which is not
> +   related to what we check here, so make sure not to match it.  */
> +/* { dg-final { scan-assembler-times "ldr\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 1 } } */
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770)
  2020-09-28  9:09 ` [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770) Christophe Lyon
@ 2020-10-06  8:30   ` Christophe Lyon
  2020-10-22  8:48     ` Christophe Lyon
  2020-10-27 16:22   ` Richard Earnshaw
  1 sibling, 1 reply; 9+ messages in thread
From: Christophe Lyon @ 2020-10-06  8:30 UTC (permalink / raw)
  To: gcc Patches

ping?

On Mon, 28 Sep 2020 at 11:09, Christophe Lyon
<christophe.lyon@linaro.org> wrote:
>
> With -mpure-code on v6m (thumb-1), we can use small offsets with
> upper/lower relocations to avoid the extra addition of the
> offset.
>
> This patch accepts expressions symbol+offset as legitimate constants
> when the literal pool is disabled, making sure that the offset is
> within the range supported by thumb-1 [0..255].
>
> It also makes sure that thumb1_movsi_insn emits an error in case we
> try to use it with an unsupported RTL construct.
>
> 2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
>
>         gcc/
>         * config/arm/arm.c (thumb_legitimate_constant_p): Accept
>         (symbol_ref + addend) when literal pool is disabled.
>         (arm_valid_symbolic_address_p): Add support for thumb-1 without
>         MOVT/MOVW.
>         * config/arm/thumb1.md (*thumb1_movsi_insn): Accept (symbol_ref +
>         addend) in the pure-code alternative.
>
>         gcc/testsuite/
>         * gcc.target/arm/pure-code/pr96770.c: New test.
> ---
>  gcc/config/arm/arm.c                             | 15 ++++++++++++---
>  gcc/config/arm/thumb1.md                         |  5 +++--
>  gcc/testsuite/gcc.target/arm/pure-code/pr96770.c | 21 +++++++++++++++++++++
>  3 files changed, 36 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
>
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index abe357e..ceeb91f 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -9489,7 +9489,8 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
>              we build the symbol address with upper/lower
>              relocations.  */
>           || (TARGET_THUMB1
> -             && GET_CODE (x) == SYMBOL_REF
> +             && !label_mentioned_p (x)
> +             && arm_valid_symbolic_address_p (x)
>               && arm_disable_literal_pool)
>           || flag_pic);
>  }
> @@ -31495,7 +31496,10 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
>     According to the ARM ELF ABI, the initial addend of REL-type relocations
>     processing MOVW and MOVT instructions is formed by interpreting the 16-bit
>     literal field of the instruction as a 16-bit signed value in the range
> -   -32768 <= A < 32768.  */
> +   -32768 <= A < 32768.
> +
> +   In Thumb-1 mode, we use upper/lower relocations which have an 8-bit
> +   unsigned range of 0 <= A < 256.  */
>
>  bool
>  arm_valid_symbolic_address_p (rtx addr)
> @@ -31519,7 +31523,12 @@ arm_valid_symbolic_address_p (rtx addr)
>        xop1 = XEXP (tmp, 1);
>
>        if (GET_CODE (xop0) == SYMBOL_REF && CONST_INT_P (xop1))
> -         return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> +       {
> +         if (TARGET_THUMB1 && !TARGET_HAVE_MOVT)
> +           return IN_RANGE (INTVAL (xop1), 0, 0xff);
> +         else
> +           return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> +       }
>      }
>
>    return false;
> diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
> index 3dedcae..2258a52 100644
> --- a/gcc/config/arm/thumb1.md
> +++ b/gcc/config/arm/thumb1.md
> @@ -675,7 +675,7 @@ (define_insn "*thumb1_movsi_insn"
>        case 7:
>        /* pure-code alternative: build the constant byte by byte,
>          instead of loading it from a constant pool.  */
> -       if (GET_CODE (operands[1]) == SYMBOL_REF)
> +       if (arm_valid_symbolic_address_p (operands[1]))
>           {
>             output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
>             output_asm_insn (\"lsls\\t%0, #8\", operands);
> @@ -686,7 +686,7 @@ (define_insn "*thumb1_movsi_insn"
>             output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
>             return \"\";
>           }
> -       else
> +       else if (GET_CODE (operands[1]) == CONST_INT)
>           {
>             int i;
>             HOST_WIDE_INT op1 = INTVAL (operands[1]);
> @@ -721,6 +721,7 @@ (define_insn "*thumb1_movsi_insn"
>               output_asm_insn ("adds\t%0, %1", ops);
>             return "";
>           }
> +         gcc_unreachable ();
>
>        case 8: return "ldr\t%0, %1";
>        case 9: return "str\t%1, %0";
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> new file mode 100644
> index 0000000..a43d71f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mpure-code" } */
> +
> +int arr[1000];
> +int *f4 (void) { return &arr[1]; }
> +
> +/* For cortex-m0 (thumb-1/v6m), we generate 4 movs with upper/lower:#arr+4.  */
> +/* { dg-final { scan-assembler-times "\\+4" 4 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
> +
> +/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
> +   generate a movt/movw pair with upper/lower:#arr+4.  */
> +/* { dg-final { scan-assembler-times "\\+4" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
> +
> +int *f5 (void) { return &arr[80]; }
> +
> +/* For cortex-m0 (thumb-1/v6m), we generate 1 ldr from rodata pointer to arr+320.  */
> +/* { dg-final { scan-assembler-times "\\+320" 1 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
> +
> +/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
> +   generate a movt/movw pair with upper/lower:arr+320.  */
> +/* { dg-final { scan-assembler-times "\\+320" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967)
  2020-10-06  8:30 ` [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967) Christophe Lyon
@ 2020-10-22  8:47   ` Christophe Lyon
  0 siblings, 0 replies; 9+ messages in thread
From: Christophe Lyon @ 2020-10-22  8:47 UTC (permalink / raw)
  To: gcc Patches

ping?

On Tue, 6 Oct 2020 at 10:30, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>
> ping?
>
> On Mon, 28 Sep 2020 at 11:09, Christophe Lyon
> <christophe.lyon@linaro.org> wrote:
> >
> > With -mpure-code on v6m (thumb-1), to avoid a useless indirection when
> > building the address of a symbol, we want to consider SYMBOL_REF as a
> > legitimate constant. This way, we build the address using a series of
> > upper/lower relocations instead of loading the address from memory.
> >
> > This patch also fixes a missing "clob" conds attribute for
> > thumb1_movsi_insn, needed because that alternative clobbers the flags.
> >
> > 2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
> >
> >         gcc/
> >         * config/arm/arm.c (thumb_legitimate_constant_p): Add support for
> >         disabled literal pool in thumb-1.
> >         * config/arm/thumb1.md (thumb1_movsi_symbol_ref): Remove.
> >         (*thumb1_movsi_insn): Add support for SYMBOL_REF with -mpure-code.
> >
> >         gcc/testsuite
> >         * gcc.target/arm/pure-code/pr96767.c: New test.
> > ---
> >  gcc/config/arm/arm.c                             |   6 ++
> >  gcc/config/arm/thumb1.md                         | 102 +++++++++++------------
> >  gcc/testsuite/gcc.target/arm/pure-code/pr96767.c |  10 +++
> >  3 files changed, 63 insertions(+), 55 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
> >
> > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> > index 022ef6c..abe357e 100644
> > --- a/gcc/config/arm/arm.c
> > +++ b/gcc/config/arm/arm.c
> > @@ -9485,6 +9485,12 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
> >           || CONST_DOUBLE_P (x)
> >           || CONSTANT_ADDRESS_P (x)
> >           || (TARGET_HAVE_MOVT && GET_CODE (x) == SYMBOL_REF)
> > +         /* On Thumb-1 without MOVT/MOVW and literal pool disabled,
> > +            we build the symbol address with upper/lower
> > +            relocations.  */
> > +         || (TARGET_THUMB1
> > +             && GET_CODE (x) == SYMBOL_REF
> > +             && arm_disable_literal_pool)
> >           || flag_pic);
> >  }
> >
> > diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
> > index 4a59d87..3dedcae 100644
> > --- a/gcc/config/arm/thumb1.md
> > +++ b/gcc/config/arm/thumb1.md
> > @@ -43,27 +43,6 @@
> >
> >
> >
> > -(define_insn "thumb1_movsi_symbol_ref"
> > -  [(set (match_operand:SI 0 "register_operand" "=l")
> > -       (match_operand:SI 1 "general_operand" ""))
> > -   ]
> > -  "TARGET_THUMB1
> > -   && arm_disable_literal_pool
> > -   && GET_CODE (operands[1]) == SYMBOL_REF"
> > -  "*
> > -  output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
> > -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> > -  output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
> > -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> > -  output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
> > -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> > -  output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
> > -  return \"\";
> > -  "
> > -  [(set_attr "length" "14")
> > -   (set_attr "conds" "clob")]
> > -)
> > -
> >  (define_insn "*thumb1_adddi3"
> >    [(set (match_operand:DI          0 "register_operand" "=l")
> >         (plus:DI (match_operand:DI 1 "register_operand" "%0")
> > @@ -696,40 +675,53 @@ (define_insn "*thumb1_movsi_insn"
> >        case 7:
> >        /* pure-code alternative: build the constant byte by byte,
> >          instead of loading it from a constant pool.  */
> > -       {
> > -         int i;
> > -         HOST_WIDE_INT op1 = INTVAL (operands[1]);
> > -         bool mov_done_p = false;
> > -         rtx ops[2];
> > -         ops[0] = operands[0];
> > -
> > -         /* Emit upper 3 bytes if needed.  */
> > -         for (i = 0; i < 3; i++)
> > -           {
> > -              int byte = (op1 >> (8 * (3 - i))) & 0xff;
> > -
> > -             if (byte)
> > -               {
> > -                 ops[1] = GEN_INT (byte);
> > -                 if (mov_done_p)
> > -                   output_asm_insn ("adds\t%0, %1", ops);
> > -                 else
> > -                   output_asm_insn ("movs\t%0, %1", ops);
> > -                 mov_done_p = true;
> > -               }
> > -
> > -             if (mov_done_p)
> > -               output_asm_insn ("lsls\t%0, #8", ops);
> > -           }
> > +       if (GET_CODE (operands[1]) == SYMBOL_REF)
> > +         {
> > +           output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
> > +           output_asm_insn (\"lsls\\t%0, #8\", operands);
> > +           output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
> > +           output_asm_insn (\"lsls\\t%0, #8\", operands);
> > +           output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
> > +           output_asm_insn (\"lsls\\t%0, #8\", operands);
> > +           output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
> > +           return \"\";
> > +         }
> > +       else
> > +         {
> > +           int i;
> > +           HOST_WIDE_INT op1 = INTVAL (operands[1]);
> > +           bool mov_done_p = false;
> > +           rtx ops[2];
> > +           ops[0] = operands[0];
> > +
> > +           /* Emit upper 3 bytes if needed.  */
> > +           for (i = 0; i < 3; i++)
> > +             {
> > +               int byte = (op1 >> (8 * (3 - i))) & 0xff;
> > +
> > +               if (byte)
> > +                 {
> > +                   ops[1] = GEN_INT (byte);
> > +                   if (mov_done_p)
> > +                     output_asm_insn ("adds\t%0, %1", ops);
> > +                   else
> > +                     output_asm_insn ("movs\t%0, %1", ops);
> > +                   mov_done_p = true;
> > +                 }
> > +
> > +               if (mov_done_p)
> > +                 output_asm_insn ("lsls\t%0, #8", ops);
> > +             }
> > +
> > +           /* Emit lower byte if needed.  */
> > +           ops[1] = GEN_INT (op1 & 0xff);
> > +           if (!mov_done_p)
> > +             output_asm_insn ("movs\t%0, %1", ops);
> > +           else if (op1 & 0xff)
> > +             output_asm_insn ("adds\t%0, %1", ops);
> > +           return "";
> > +         }
> >
> > -         /* Emit lower byte if needed.  */
> > -         ops[1] = GEN_INT (op1 & 0xff);
> > -         if (!mov_done_p)
> > -           output_asm_insn ("movs\t%0, %1", ops);
> > -         else if (op1 & 0xff)
> > -           output_asm_insn ("adds\t%0, %1", ops);
> > -         return "";
> > -       }
> >        case 8: return "ldr\t%0, %1";
> >        case 9: return "str\t%1, %0";
> >        case 10: return "mov\t%0, %1";
> > @@ -740,7 +732,7 @@ (define_insn "*thumb1_movsi_insn"
> >     (set_attr "pool_range" "*,*,*,*,*,*,*, *,1018,*,*")
> >     (set_attr "arch" "t1,t1,v8mb,t1,t1,t1,t1,t1,t1,t1,t1")
> >     (set_attr "required_for_purecode" "no,no,no,no,no,no,no,yes,no,no,no")
> > -   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,nocond,nocond,nocond,nocond")])
> > +   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,clob,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.
> > diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
> > new file mode 100644
> > index 0000000..cb3ee68
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
> > @@ -0,0 +1,10 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-mpure-code" } */
> > +
> > +int x;
> > +int f1 (void) { return x; }
> > +
> > +/* We expect only one indirect load like ldr r3, [r3]. In some
> > +   configurations there is an additional ldr rX, [sp], #4 which is not
> > +   related to what we check here, so make sure not to match it.  */
> > +/* { dg-final { scan-assembler-times "ldr\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 1 } } */
> > --
> > 2.7.4
> >

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770)
  2020-10-06  8:30   ` Christophe Lyon
@ 2020-10-22  8:48     ` Christophe Lyon
  0 siblings, 0 replies; 9+ messages in thread
From: Christophe Lyon @ 2020-10-22  8:48 UTC (permalink / raw)
  To: gcc Patches

ping?

On Tue, 6 Oct 2020 at 10:30, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>
> ping?
>
> On Mon, 28 Sep 2020 at 11:09, Christophe Lyon
> <christophe.lyon@linaro.org> wrote:
> >
> > With -mpure-code on v6m (thumb-1), we can use small offsets with
> > upper/lower relocations to avoid the extra addition of the
> > offset.
> >
> > This patch accepts expressions symbol+offset as legitimate constants
> > when the literal pool is disabled, making sure that the offset is
> > within the range supported by thumb-1 [0..255].
> >
> > It also makes sure that thumb1_movsi_insn emits an error in case we
> > try to use it with an unsupported RTL construct.
> >
> > 2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
> >
> >         gcc/
> >         * config/arm/arm.c (thumb_legitimate_constant_p): Accept
> >         (symbol_ref + addend) when literal pool is disabled.
> >         (arm_valid_symbolic_address_p): Add support for thumb-1 without
> >         MOVT/MOVW.
> >         * config/arm/thumb1.md (*thumb1_movsi_insn): Accept (symbol_ref +
> >         addend) in the pure-code alternative.
> >
> >         gcc/testsuite/
> >         * gcc.target/arm/pure-code/pr96770.c: New test.
> > ---
> >  gcc/config/arm/arm.c                             | 15 ++++++++++++---
> >  gcc/config/arm/thumb1.md                         |  5 +++--
> >  gcc/testsuite/gcc.target/arm/pure-code/pr96770.c | 21 +++++++++++++++++++++
> >  3 files changed, 36 insertions(+), 5 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> >
> > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> > index abe357e..ceeb91f 100644
> > --- a/gcc/config/arm/arm.c
> > +++ b/gcc/config/arm/arm.c
> > @@ -9489,7 +9489,8 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
> >              we build the symbol address with upper/lower
> >              relocations.  */
> >           || (TARGET_THUMB1
> > -             && GET_CODE (x) == SYMBOL_REF
> > +             && !label_mentioned_p (x)
> > +             && arm_valid_symbolic_address_p (x)
> >               && arm_disable_literal_pool)
> >           || flag_pic);
> >  }
> > @@ -31495,7 +31496,10 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
> >     According to the ARM ELF ABI, the initial addend of REL-type relocations
> >     processing MOVW and MOVT instructions is formed by interpreting the 16-bit
> >     literal field of the instruction as a 16-bit signed value in the range
> > -   -32768 <= A < 32768.  */
> > +   -32768 <= A < 32768.
> > +
> > +   In Thumb-1 mode, we use upper/lower relocations which have an 8-bit
> > +   unsigned range of 0 <= A < 256.  */
> >
> >  bool
> >  arm_valid_symbolic_address_p (rtx addr)
> > @@ -31519,7 +31523,12 @@ arm_valid_symbolic_address_p (rtx addr)
> >        xop1 = XEXP (tmp, 1);
> >
> >        if (GET_CODE (xop0) == SYMBOL_REF && CONST_INT_P (xop1))
> > -         return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> > +       {
> > +         if (TARGET_THUMB1 && !TARGET_HAVE_MOVT)
> > +           return IN_RANGE (INTVAL (xop1), 0, 0xff);
> > +         else
> > +           return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> > +       }
> >      }
> >
> >    return false;
> > diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
> > index 3dedcae..2258a52 100644
> > --- a/gcc/config/arm/thumb1.md
> > +++ b/gcc/config/arm/thumb1.md
> > @@ -675,7 +675,7 @@ (define_insn "*thumb1_movsi_insn"
> >        case 7:
> >        /* pure-code alternative: build the constant byte by byte,
> >          instead of loading it from a constant pool.  */
> > -       if (GET_CODE (operands[1]) == SYMBOL_REF)
> > +       if (arm_valid_symbolic_address_p (operands[1]))
> >           {
> >             output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
> >             output_asm_insn (\"lsls\\t%0, #8\", operands);
> > @@ -686,7 +686,7 @@ (define_insn "*thumb1_movsi_insn"
> >             output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
> >             return \"\";
> >           }
> > -       else
> > +       else if (GET_CODE (operands[1]) == CONST_INT)
> >           {
> >             int i;
> >             HOST_WIDE_INT op1 = INTVAL (operands[1]);
> > @@ -721,6 +721,7 @@ (define_insn "*thumb1_movsi_insn"
> >               output_asm_insn ("adds\t%0, %1", ops);
> >             return "";
> >           }
> > +         gcc_unreachable ();
> >
> >        case 8: return "ldr\t%0, %1";
> >        case 9: return "str\t%1, %0";
> > diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> > new file mode 100644
> > index 0000000..a43d71f
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> > @@ -0,0 +1,21 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-mpure-code" } */
> > +
> > +int arr[1000];
> > +int *f4 (void) { return &arr[1]; }
> > +
> > +/* For cortex-m0 (thumb-1/v6m), we generate 4 movs with upper/lower:#arr+4.  */
> > +/* { dg-final { scan-assembler-times "\\+4" 4 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
> > +
> > +/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
> > +   generate a movt/movw pair with upper/lower:#arr+4.  */
> > +/* { dg-final { scan-assembler-times "\\+4" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
> > +
> > +int *f5 (void) { return &arr[80]; }
> > +
> > +/* For cortex-m0 (thumb-1/v6m), we generate 1 ldr from rodata pointer to arr+320.  */
> > +/* { dg-final { scan-assembler-times "\\+320" 1 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
> > +
> > +/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
> > +   generate a movt/movw pair with upper/lower:arr+320.  */
> > +/* { dg-final { scan-assembler-times "\\+320" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
> > --
> > 2.7.4
> >

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967)
  2020-09-28  9:09 [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967) Christophe Lyon
  2020-09-28  9:09 ` [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770) Christophe Lyon
  2020-10-06  8:30 ` [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967) Christophe Lyon
@ 2020-10-27 16:06 ` Richard Earnshaw
  2 siblings, 0 replies; 9+ messages in thread
From: Richard Earnshaw @ 2020-10-27 16:06 UTC (permalink / raw)
  To: Christophe Lyon, gcc-patches

On 28/09/2020 10:09, Christophe Lyon via Gcc-patches wrote:
> With -mpure-code on v6m (thumb-1), to avoid a useless indirection when
> building the address of a symbol, we want to consider SYMBOL_REF as a
> legitimate constant. This way, we build the address using a series of
> upper/lower relocations instead of loading the address from memory.
> 
> This patch also fixes a missing "clob" conds attribute for
> thumb1_movsi_insn, needed because that alternative clobbers the flags.
> 
> 2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
> 
> 	gcc/
> 	* config/arm/arm.c (thumb_legitimate_constant_p): Add support for
> 	disabled literal pool in thumb-1.
> 	* config/arm/thumb1.md (thumb1_movsi_symbol_ref): Remove.
> 	(*thumb1_movsi_insn): Add support for SYMBOL_REF with -mpure-code.
> 
> 	gcc/testsuite
> 	* gcc.target/arm/pure-code/pr96767.c: New test.
> ---
>  gcc/config/arm/arm.c                             |   6 ++
>  gcc/config/arm/thumb1.md                         | 102 +++++++++++------------
>  gcc/testsuite/gcc.target/arm/pure-code/pr96767.c |  10 +++
>  3 files changed, 63 insertions(+), 55 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
> 
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index 022ef6c..abe357e 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -9485,6 +9485,12 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
>  	  || CONST_DOUBLE_P (x)
>  	  || CONSTANT_ADDRESS_P (x)
>  	  || (TARGET_HAVE_MOVT && GET_CODE (x) == SYMBOL_REF)
> +	  /* On Thumb-1 without MOVT/MOVW and literal pool disabled,
> +	     we build the symbol address with upper/lower
> +	     relocations.  */
> +	  || (TARGET_THUMB1
> +	      && GET_CODE (x) == SYMBOL_REF
> +	      && arm_disable_literal_pool)
>  	  || flag_pic);
>  }
>  
> diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
> index 4a59d87..3dedcae 100644
> --- a/gcc/config/arm/thumb1.md
> +++ b/gcc/config/arm/thumb1.md
> @@ -43,27 +43,6 @@
>  
>  
>  
> -(define_insn "thumb1_movsi_symbol_ref"
> -  [(set (match_operand:SI 0 "register_operand" "=l")
> -	(match_operand:SI 1 "general_operand" ""))
> -   ]
> -  "TARGET_THUMB1
> -   && arm_disable_literal_pool
> -   && GET_CODE (operands[1]) == SYMBOL_REF"
> -  "*
> -  output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
> -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> -  output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
> -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> -  output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
> -  output_asm_insn (\"lsls\\t%0, #8\", operands);
> -  output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
> -  return \"\";
> -  "
> -  [(set_attr "length" "14")
> -   (set_attr "conds" "clob")]
> -)
> -
>  (define_insn "*thumb1_adddi3"
>    [(set (match_operand:DI          0 "register_operand" "=l")
>  	(plus:DI (match_operand:DI 1 "register_operand" "%0")
> @@ -696,40 +675,53 @@ (define_insn "*thumb1_movsi_insn"
>        case 7:
>        /* pure-code alternative: build the constant byte by byte,
>  	 instead of loading it from a constant pool.  */
> -	{
> -	  int i;
> -	  HOST_WIDE_INT op1 = INTVAL (operands[1]);
> -	  bool mov_done_p = false;
> -	  rtx ops[2];
> -	  ops[0] = operands[0];
> -
> -	  /* Emit upper 3 bytes if needed.  */
> -	  for (i = 0; i < 3; i++)
> -	    {
> -	       int byte = (op1 >> (8 * (3 - i))) & 0xff;
> -
> -	      if (byte)
> -		{
> -		  ops[1] = GEN_INT (byte);
> -		  if (mov_done_p)
> -		    output_asm_insn ("adds\t%0, %1", ops);
> -		  else
> -		    output_asm_insn ("movs\t%0, %1", ops);
> -		  mov_done_p = true;
> -		}
> -
> -	      if (mov_done_p)
> -		output_asm_insn ("lsls\t%0, #8", ops);
> -	    }
> +	if (GET_CODE (operands[1]) == SYMBOL_REF)
> +	  {
> +	    output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
> +	    output_asm_insn (\"lsls\\t%0, #8\", operands);
> +	    output_asm_insn (\"adds\\t%0, #:upper0_7:%1\", operands);
> +	    output_asm_insn (\"lsls\\t%0, #8\", operands);
> +	    output_asm_insn (\"adds\\t%0, #:lower8_15:%1\", operands);
> +	    output_asm_insn (\"lsls\\t%0, #8\", operands);
> +	    output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
> +	    return \"\";
> +	  }
> +	else
> +	  {
> +	    int i;
> +	    HOST_WIDE_INT op1 = INTVAL (operands[1]);
> +	    bool mov_done_p = false;
> +	    rtx ops[2];
> +	    ops[0] = operands[0];
> +
> +	    /* Emit upper 3 bytes if needed.  */
> +	    for (i = 0; i < 3; i++)
> +	      {
> +		int byte = (op1 >> (8 * (3 - i))) & 0xff;
> +
> +		if (byte)
> +		  {
> +		    ops[1] = GEN_INT (byte);
> +		    if (mov_done_p)
> +		      output_asm_insn ("adds\t%0, %1", ops);
> +		    else
> +		      output_asm_insn ("movs\t%0, %1", ops);
> +		    mov_done_p = true;
> +		  }
> +
> +		if (mov_done_p)
> +		  output_asm_insn ("lsls\t%0, #8", ops);
> +	      }
> +
> +	    /* Emit lower byte if needed.  */
> +	    ops[1] = GEN_INT (op1 & 0xff);
> +	    if (!mov_done_p)
> +	      output_asm_insn ("movs\t%0, %1", ops);
> +	    else if (op1 & 0xff)
> +	      output_asm_insn ("adds\t%0, %1", ops);
> +	    return "";
> +	  }
>  
> -	  /* Emit lower byte if needed.  */
> -	  ops[1] = GEN_INT (op1 & 0xff);
> -	  if (!mov_done_p)
> -	    output_asm_insn ("movs\t%0, %1", ops);
> -	  else if (op1 & 0xff)
> -	    output_asm_insn ("adds\t%0, %1", ops);
> -	  return "";
> -	}
>        case 8: return "ldr\t%0, %1";
>        case 9: return "str\t%1, %0";
>        case 10: return "mov\t%0, %1";
> @@ -740,7 +732,7 @@ (define_insn "*thumb1_movsi_insn"
>     (set_attr "pool_range" "*,*,*,*,*,*,*, *,1018,*,*")
>     (set_attr "arch" "t1,t1,v8mb,t1,t1,t1,t1,t1,t1,t1,t1")
>     (set_attr "required_for_purecode" "no,no,no,no,no,no,no,yes,no,no,no")
> -   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,nocond,nocond,nocond,nocond")])
> +   (set_attr "conds" "set,clob,nocond,*,*,nocond,nocond,clob,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.
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
> new file mode 100644
> index 0000000..cb3ee68
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96767.c
> @@ -0,0 +1,10 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mpure-code" } */
> +
> +int x;
> +int f1 (void) { return x; }
> +
> +/* We expect only one indirect load like ldr r3, [r3]. In some
> +   configurations there is an additional ldr rX, [sp], #4 which is not
> +   related to what we check here, so make sure not to match it.  */
> +/* { dg-final { scan-assembler-times "ldr\tr\[0-9\]+, \\\[r\[0-9\]+\\\]" 1 } } */
> 

OK.

R.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770)
  2020-09-28  9:09 ` [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770) Christophe Lyon
  2020-10-06  8:30   ` Christophe Lyon
@ 2020-10-27 16:22   ` Richard Earnshaw
  2020-11-02  7:36     ` Christophe Lyon
  1 sibling, 1 reply; 9+ messages in thread
From: Richard Earnshaw @ 2020-10-27 16:22 UTC (permalink / raw)
  To: Christophe Lyon, gcc-patches

On 28/09/2020 10:09, Christophe Lyon via Gcc-patches wrote:
> With -mpure-code on v6m (thumb-1), we can use small offsets with
> upper/lower relocations to avoid the extra addition of the
> offset.
> 
> This patch accepts expressions symbol+offset as legitimate constants
> when the literal pool is disabled, making sure that the offset is
> within the range supported by thumb-1 [0..255].
> 
> It also makes sure that thumb1_movsi_insn emits an error in case we
> try to use it with an unsupported RTL construct.
> 
> 2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
> 
> 	gcc/
> 	* config/arm/arm.c (thumb_legitimate_constant_p): Accept
> 	(symbol_ref + addend) when literal pool is disabled.
> 	(arm_valid_symbolic_address_p): Add support for thumb-1 without
> 	MOVT/MOVW.
> 	* config/arm/thumb1.md (*thumb1_movsi_insn): Accept (symbol_ref +
> 	addend) in the pure-code alternative.
> 
> 	gcc/testsuite/
> 	* gcc.target/arm/pure-code/pr96770.c: New test.
> ---
>  gcc/config/arm/arm.c                             | 15 ++++++++++++---
>  gcc/config/arm/thumb1.md                         |  5 +++--
>  gcc/testsuite/gcc.target/arm/pure-code/pr96770.c | 21 +++++++++++++++++++++
>  3 files changed, 36 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> 
> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> index abe357e..ceeb91f 100644
> --- a/gcc/config/arm/arm.c
> +++ b/gcc/config/arm/arm.c
> @@ -9489,7 +9489,8 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
>  	     we build the symbol address with upper/lower
>  	     relocations.  */
>  	  || (TARGET_THUMB1
> -	      && GET_CODE (x) == SYMBOL_REF
> +	      && !label_mentioned_p (x)
> +	      && arm_valid_symbolic_address_p (x)
>  	      && arm_disable_literal_pool)
>  	  || flag_pic);
>  }
> @@ -31495,7 +31496,10 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
>     According to the ARM ELF ABI, the initial addend of REL-type relocations
>     processing MOVW and MOVT instructions is formed by interpreting the 16-bit
>     literal field of the instruction as a 16-bit signed value in the range
> -   -32768 <= A < 32768.  */
> +   -32768 <= A < 32768.
> +
> +   In Thumb-1 mode, we use upper/lower relocations which have an 8-bit
> +   unsigned range of 0 <= A < 256.  */

I think it should be made clear that the range comes from the AAELF32
relocation encoding for REL-type relocations (which is an unsigned value
in this case).

Otherwise, OK.

>  
>  bool
>  arm_valid_symbolic_address_p (rtx addr)
> @@ -31519,7 +31523,12 @@ arm_valid_symbolic_address_p (rtx addr)
>        xop1 = XEXP (tmp, 1);
>  
>        if (GET_CODE (xop0) == SYMBOL_REF && CONST_INT_P (xop1))
> -	  return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> +	{
> +	  if (TARGET_THUMB1 && !TARGET_HAVE_MOVT)
> +	    return IN_RANGE (INTVAL (xop1), 0, 0xff);
> +	  else
> +	    return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> +	}
>      }
>  
>    return false;
> diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
> index 3dedcae..2258a52 100644
> --- a/gcc/config/arm/thumb1.md
> +++ b/gcc/config/arm/thumb1.md
> @@ -675,7 +675,7 @@ (define_insn "*thumb1_movsi_insn"
>        case 7:
>        /* pure-code alternative: build the constant byte by byte,
>  	 instead of loading it from a constant pool.  */
> -	if (GET_CODE (operands[1]) == SYMBOL_REF)
> +	if (arm_valid_symbolic_address_p (operands[1]))
>  	  {
>  	    output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
>  	    output_asm_insn (\"lsls\\t%0, #8\", operands);
> @@ -686,7 +686,7 @@ (define_insn "*thumb1_movsi_insn"
>  	    output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
>  	    return \"\";
>  	  }
> -	else
> +	else if (GET_CODE (operands[1]) == CONST_INT)
>  	  {
>  	    int i;
>  	    HOST_WIDE_INT op1 = INTVAL (operands[1]);
> @@ -721,6 +721,7 @@ (define_insn "*thumb1_movsi_insn"
>  	      output_asm_insn ("adds\t%0, %1", ops);
>  	    return "";
>  	  }
> +	  gcc_unreachable ();
>  
>        case 8: return "ldr\t%0, %1";
>        case 9: return "str\t%1, %0";
> diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> new file mode 100644
> index 0000000..a43d71f
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> @@ -0,0 +1,21 @@
> +/* { dg-do compile } */
> +/* { dg-options "-mpure-code" } */
> +
> +int arr[1000];
> +int *f4 (void) { return &arr[1]; }
> +
> +/* For cortex-m0 (thumb-1/v6m), we generate 4 movs with upper/lower:#arr+4.  */
> +/* { dg-final { scan-assembler-times "\\+4" 4 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
> +
> +/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
> +   generate a movt/movw pair with upper/lower:#arr+4.  */
> +/* { dg-final { scan-assembler-times "\\+4" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
> +
> +int *f5 (void) { return &arr[80]; }
> +
> +/* For cortex-m0 (thumb-1/v6m), we generate 1 ldr from rodata pointer to arr+320.  */
> +/* { dg-final { scan-assembler-times "\\+320" 1 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
> +
> +/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
> +   generate a movt/movw pair with upper/lower:arr+320.  */
> +/* { dg-final { scan-assembler-times "\\+320" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770)
  2020-10-27 16:22   ` Richard Earnshaw
@ 2020-11-02  7:36     ` Christophe Lyon
  0 siblings, 0 replies; 9+ messages in thread
From: Christophe Lyon @ 2020-11-02  7:36 UTC (permalink / raw)
  To: Richard Earnshaw; +Cc: gcc Patches

On Tue, 27 Oct 2020 at 17:22, Richard Earnshaw
<Richard.Earnshaw@foss.arm.com> wrote:
>
> On 28/09/2020 10:09, Christophe Lyon via Gcc-patches wrote:
> > With -mpure-code on v6m (thumb-1), we can use small offsets with
> > upper/lower relocations to avoid the extra addition of the
> > offset.
> >
> > This patch accepts expressions symbol+offset as legitimate constants
> > when the literal pool is disabled, making sure that the offset is
> > within the range supported by thumb-1 [0..255].
> >
> > It also makes sure that thumb1_movsi_insn emits an error in case we
> > try to use it with an unsupported RTL construct.
> >
> > 2020-09-28  Christophe Lyon  <christophe.lyon@linaro.org>
> >
> >       gcc/
> >       * config/arm/arm.c (thumb_legitimate_constant_p): Accept
> >       (symbol_ref + addend) when literal pool is disabled.
> >       (arm_valid_symbolic_address_p): Add support for thumb-1 without
> >       MOVT/MOVW.
> >       * config/arm/thumb1.md (*thumb1_movsi_insn): Accept (symbol_ref +
> >       addend) in the pure-code alternative.
> >
> >       gcc/testsuite/
> >       * gcc.target/arm/pure-code/pr96770.c: New test.
> > ---
> >  gcc/config/arm/arm.c                             | 15 ++++++++++++---
> >  gcc/config/arm/thumb1.md                         |  5 +++--
> >  gcc/testsuite/gcc.target/arm/pure-code/pr96770.c | 21 +++++++++++++++++++++
> >  3 files changed, 36 insertions(+), 5 deletions(-)
> >  create mode 100644 gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> >
> > diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
> > index abe357e..ceeb91f 100644
> > --- a/gcc/config/arm/arm.c
> > +++ b/gcc/config/arm/arm.c
> > @@ -9489,7 +9489,8 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
> >            we build the symbol address with upper/lower
> >            relocations.  */
> >         || (TARGET_THUMB1
> > -           && GET_CODE (x) == SYMBOL_REF
> > +           && !label_mentioned_p (x)
> > +           && arm_valid_symbolic_address_p (x)
> >             && arm_disable_literal_pool)
> >         || flag_pic);
> >  }
> > @@ -31495,7 +31496,10 @@ arm_emit_coreregs_64bit_shift (enum rtx_code code, rtx out, rtx in,
> >     According to the ARM ELF ABI, the initial addend of REL-type relocations
> >     processing MOVW and MOVT instructions is formed by interpreting the 16-bit
> >     literal field of the instruction as a 16-bit signed value in the range
> > -   -32768 <= A < 32768.  */
> > +   -32768 <= A < 32768.
> > +
> > +   In Thumb-1 mode, we use upper/lower relocations which have an 8-bit
> > +   unsigned range of 0 <= A < 256.  */
>
> I think it should be made clear that the range comes from the AAELF32
> relocation encoding for REL-type relocations (which is an unsigned value
> in this case).
>
> Otherwise, OK.
>

Thanks Richard, I've just pushed the patch with updated comment &
commit message.

Christophe

> >
> >  bool
> >  arm_valid_symbolic_address_p (rtx addr)
> > @@ -31519,7 +31523,12 @@ arm_valid_symbolic_address_p (rtx addr)
> >        xop1 = XEXP (tmp, 1);
> >
> >        if (GET_CODE (xop0) == SYMBOL_REF && CONST_INT_P (xop1))
> > -       return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> > +     {
> > +       if (TARGET_THUMB1 && !TARGET_HAVE_MOVT)
> > +         return IN_RANGE (INTVAL (xop1), 0, 0xff);
> > +       else
> > +         return IN_RANGE (INTVAL (xop1), -0x8000, 0x7fff);
> > +     }
> >      }
> >
> >    return false;
> > diff --git a/gcc/config/arm/thumb1.md b/gcc/config/arm/thumb1.md
> > index 3dedcae..2258a52 100644
> > --- a/gcc/config/arm/thumb1.md
> > +++ b/gcc/config/arm/thumb1.md
> > @@ -675,7 +675,7 @@ (define_insn "*thumb1_movsi_insn"
> >        case 7:
> >        /* pure-code alternative: build the constant byte by byte,
> >        instead of loading it from a constant pool.  */
> > -     if (GET_CODE (operands[1]) == SYMBOL_REF)
> > +     if (arm_valid_symbolic_address_p (operands[1]))
> >         {
> >           output_asm_insn (\"movs\\t%0, #:upper8_15:%1\", operands);
> >           output_asm_insn (\"lsls\\t%0, #8\", operands);
> > @@ -686,7 +686,7 @@ (define_insn "*thumb1_movsi_insn"
> >           output_asm_insn (\"adds\\t%0, #:lower0_7:%1\", operands);
> >           return \"\";
> >         }
> > -     else
> > +     else if (GET_CODE (operands[1]) == CONST_INT)
> >         {
> >           int i;
> >           HOST_WIDE_INT op1 = INTVAL (operands[1]);
> > @@ -721,6 +721,7 @@ (define_insn "*thumb1_movsi_insn"
> >             output_asm_insn ("adds\t%0, %1", ops);
> >           return "";
> >         }
> > +       gcc_unreachable ();
> >
> >        case 8: return "ldr\t%0, %1";
> >        case 9: return "str\t%1, %0";
> > diff --git a/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> > new file mode 100644
> > index 0000000..a43d71f
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.target/arm/pure-code/pr96770.c
> > @@ -0,0 +1,21 @@
> > +/* { dg-do compile } */
> > +/* { dg-options "-mpure-code" } */
> > +
> > +int arr[1000];
> > +int *f4 (void) { return &arr[1]; }
> > +
> > +/* For cortex-m0 (thumb-1/v6m), we generate 4 movs with upper/lower:#arr+4.  */
> > +/* { dg-final { scan-assembler-times "\\+4" 4 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
> > +
> > +/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
> > +   generate a movt/movw pair with upper/lower:#arr+4.  */
> > +/* { dg-final { scan-assembler-times "\\+4" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
> > +
> > +int *f5 (void) { return &arr[80]; }
> > +
> > +/* For cortex-m0 (thumb-1/v6m), we generate 1 ldr from rodata pointer to arr+320.  */
> > +/* { dg-final { scan-assembler-times "\\+320" 1 { target { { ! arm_thumb1_movt_ok } && { ! arm_thumb2_ok } } } } } */
> > +
> > +/* For cortex-m with movt/movw (thumb-1/v8m.base or thumb-2), we
> > +   generate a movt/movw pair with upper/lower:arr+320.  */
> > +/* { dg-final { scan-assembler-times "\\+320" 2 { target { arm_thumb1_movt_ok || arm_thumb2_ok } } } } */
> >
>

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-11-02  7:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-28  9:09 [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967) Christophe Lyon
2020-09-28  9:09 ` [PATCH 2/2] arm: Improve handling of relocations with small offsets with -mpure-code on v6m (PR96770) Christophe Lyon
2020-10-06  8:30   ` Christophe Lyon
2020-10-22  8:48     ` Christophe Lyon
2020-10-27 16:22   ` Richard Earnshaw
2020-11-02  7:36     ` Christophe Lyon
2020-10-06  8:30 ` [PATCH 1/2] arm: Avoid indirection with -mpure-code on v6m (PR96967) Christophe Lyon
2020-10-22  8:47   ` Christophe Lyon
2020-10-27 16:06 ` Richard Earnshaw

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).