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