public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] aarch64: Hybrid support for non-TLS CADI symbols
@ 2022-05-05 12:09 Matthew Malcomson
0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-05-05 12:09 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:c29d908fa60c52faf58f946fcbb2b1f98a83da6b
commit c29d908fa60c52faf58f946fcbb2b1f98a83da6b
Author: Richard Sandiford <richard.sandiford@arm.com>
Date: Wed Apr 13 10:05:22 2022 +0100
aarch64: Hybrid support for non-TLS CADI symbols
I think this patch contains the minimum changes needed to code-generate
an existing non-TLS CAP_ADDR_EXPR for hybrid code. Any non-TLS CADI
symbolic constant needs to be forced into a .data.rel.ro(.local)
.capinit slot and then be loaded from there.
Diff:
---
gcc/config/aarch64/aarch64.c | 19 +++++++----
gcc/explow.c | 9 +++--
gcc/expr.c | 38 +++++++++++++++++-----
.../aarch64/morello/hybrid-addr-expr-1.c | 20 ++++++++++++
.../aarch64/morello/hybrid-addr-expr-2.c | 21 ++++++++++++
.../aarch64/morello/hybrid-addr-expr-3.c | 21 ++++++++++++
.../aarch64/morello/hybrid-addr-expr-4.c | 21 ++++++++++++
.../aarch64/morello/hybrid-addr-expr-5.c | 21 ++++++++++++
.../aarch64/morello/hybrid-addr-expr-6.c | 21 ++++++++++++
.../aarch64/morello/hybrid-addr-expr-7.c | 23 +++++++++++++
.../aarch64/morello/hybrid-addr-expr-8.c | 22 +++++++++++++
11 files changed, 219 insertions(+), 17 deletions(-)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index b503e5dfd65..b5bc8949b2c 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -5537,11 +5537,12 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
}
sty = aarch64_classify_symbol (base, const_offset);
+ scalar_addr_mode mem_mode = TARGET_ILP32 ? ptr_mode : addr_mode;
switch (sty)
{
case SYMBOL_FORCE_TO_MEM:
if (const_offset != 0
- && targetm.cannot_force_const_mem (addr_mode, imm))
+ && targetm.cannot_force_const_mem (mem_mode, imm))
{
gcc_assert (can_create_pseudo_p ());
base = aarch64_force_temporary (addr_mode, dest, base);
@@ -5550,7 +5551,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
return;
}
- mem = force_const_mem (ptr_mode, imm);
+ mem = force_const_mem (mem_mode, imm);
if (TARGET_CAPABILITY_PURE && SYMBOL_REF_P (base))
{
/* Mark the symbol created by `force_const_mem` as one into the
@@ -5570,7 +5571,7 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
we need to expand the literal pool access carefully.
This is something that needs to be done in a number
of places, so could well live as a separate function. */
- if (!memory_operand (mem, ptr_mode))
+ if (!memory_operand (mem, mem_mode))
{
gcc_assert (can_create_pseudo_p ());
if (TARGET_CAPABILITY_PURE && SYMBOL_REF_P (base))
@@ -5605,10 +5606,10 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm)
if (ptr_mode != Pmode)
base = convert_memory_address (Pmode, base);
}
- mem = gen_rtx_MEM (ptr_mode, base);
+ mem = gen_rtx_MEM (mem_mode, base);
}
- if (addr_mode != ptr_mode)
+ if (addr_mode != mem_mode)
mem = gen_rtx_ZERO_EXTEND (addr_mode, mem);
emit_insn (gen_rtx_SET (dest, mem));
@@ -9366,7 +9367,7 @@ aarch64_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
else
/* Avoid generating a 64-bit relocation in ILP32; leave
to aarch64_expand_mov_immediate to handle it properly. */
- return mode != ptr_mode;
+ return TARGET_ILP32 && mode != ptr_mode;
}
return aarch64_tls_referenced_p (x);
@@ -17110,6 +17111,12 @@ aarch64_classify_symbol (rtx x, HOST_WIDE_INT offset)
if (aarch64_sym_indirectly_accessed_p (x))
return aarch64_classify_capability_symbol (x, offset);
+ /* In hybrid mode, the only way of loading a constant capability is
+ to force it into a (.data.rel.ro*) constant pool entry. Unlike
+ for pure capabilities, the GOT option is not available. */
+ if (CAPABILITY_MODE_P (GET_MODE (x)) && !CAPABILITY_MODE_P (Pmode))
+ return SYMBOL_FORCE_TO_MEM;
+
/* -mpc-relative-literal-loads tells us to assume that all (function)
constant pool entries will be within the range of PC-relative LDR,
which means that they must also be in range of ADR. */
diff --git a/gcc/explow.c b/gcc/explow.c
index 00e89e32689..e58e5923f2a 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -363,11 +363,16 @@ convert_memory_address_addr_space_1 (scalar_addr_mode to_mode ATTRIBUTE_UNUSED,
/* If X already has the right mode, just return it. */
if (GET_MODE (x) == to_mode)
return x;
- /* We can't convert a mode to a capability mode.
+ /* Non-capability symbolic constants can be re-expressed as capability
+ constants simply by (recursively) changing the mode. However,
+ we can't convert an arbitrary runtime value to a capability mode.
Even if the from_mode was a capability mode there is no general way to
handle that since we don't know what the extra bits contain in each case
(they're not just simply bits ...). */
- gcc_assert (! CAPABILITY_MODE_P (to_mode));
+ gcc_assert (! CAPABILITY_MODE_P (to_mode)
+ || GET_CODE (x) == LABEL_REF
+ || GET_CODE (x) == SYMBOL_REF
+ || GET_CODE (x) == CONST);
pointer_mode = unqualified_pointer_mode (as);
address_mode = unqualified_address_mode (as);
diff --git a/gcc/expr.c b/gcc/expr.c
index d48dfc6bccf..5fe7e9781f7 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -8178,12 +8178,14 @@ expand_expr_constant (tree exp, int defer, enum expand_modifier modifier)
return mem;
}
-/* A subroutine of expand_expr_addr_expr. Evaluate the address of EXP.
- The TARGET, TMODE and MODIFIER arguments are as for expand_expr. */
+/* A subroutine of expand_expr_addr_expr. Evaluate the address of EXP
+ using code ADDR_CODE. The TARGET, TMODE and MODIFIER arguments are
+ as for expand_expr. */
static rtx
-expand_expr_addr_expr_1 (tree exp, rtx target, scalar_addr_mode tmode,
- enum expand_modifier modifier, addr_space_t as)
+expand_expr_addr_expr_1 (tree_code addr_code, tree exp, rtx target,
+ scalar_addr_mode tmode,
+ enum expand_modifier modifier, addr_space_t as)
{
rtx result, subtarget;
tree inner, offset;
@@ -8191,6 +8193,11 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_addr_mode tmode,
int unsignedp, reversep, volatilep = 0;
machine_mode mode1;
+ /* Detect if we're creating a capability pointer in an environment
+ where that isn't the default behavior. */
+ bool force_capability = (addr_code == CAP_ADDR_EXPR
+ && !CAPABILITY_MODE_P (Pmode));
+
/* If we are taking the address of a constant and are at the top level,
we have to use output_constant_def since we can't call force_const_mem
at top level. */
@@ -8256,7 +8263,8 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_addr_mode tmode,
the initializers aren't gimplified. */
if (COMPOUND_LITERAL_EXPR_DECL (exp)
&& TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp)))
- return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp),
+ return expand_expr_addr_expr_1 (addr_code,
+ COMPOUND_LITERAL_EXPR_DECL (exp),
target, tmode, modifier, as);
/* FALLTHRU */
default:
@@ -8271,8 +8279,13 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_addr_mode tmode,
|| TREE_CODE (exp) == CONSTRUCTOR
|| TREE_CODE (exp) == COMPOUND_LITERAL_EXPR)
{
+ /* If we want a capability pointer, and if normal pointers are
+ not capabilities, try harder to preserve the structure of
+ the original address. In particular, don't try to rewrite
+ the address to use (Pmode) section anchors. */
result = expand_expr (exp, target, tmode,
modifier == EXPAND_INITIALIZER
+ || force_capability
? EXPAND_INITIALIZER : EXPAND_CONST_ADDRESS);
/* If the DECL isn't in memory, then the DECL wasn't properly
@@ -8282,6 +8295,11 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_addr_mode tmode,
gcc_assert (MEM_P (result));
result = XEXP (result, 0);
+ /* Convert a non-capability constant address to a capability
+ while we still have its original form. */
+ if (force_capability)
+ result = convert_memory_address_addr_space (tmode, result, as);
+
/* ??? Is this needed anymore? */
if (DECL_P (exp))
TREE_USED (exp) = 1;
@@ -8317,7 +8335,8 @@ expand_expr_addr_expr_1 (tree exp, rtx target, scalar_addr_mode tmode,
SET_TYPE_ALIGN (TREE_TYPE (inner), TYPE_ALIGN (TREE_TYPE (exp)));
TYPE_USER_ALIGN (TREE_TYPE (inner)) = 1;
}
- result = expand_expr_addr_expr_1 (inner, subtarget, tmode, modifier, as);
+ result = expand_expr_addr_expr_1 (addr_code, inner, subtarget, tmode,
+ modifier, as);
if (offset)
{
@@ -8393,8 +8412,8 @@ expand_expr_addr_expr (tree exp, rtx target, machine_mode tmode,
? pointer_mode
: address_mode);
- result = expand_expr_addr_expr_1 (TREE_OPERAND (exp, 0), target,
- new_tmode, modifier, as);
+ result = expand_expr_addr_expr_1 (TREE_CODE (exp), TREE_OPERAND (exp, 0),
+ target, new_tmode, modifier, as);
/* Despite expand_expr claims concerning ignoring TMODE when not
strictly convenient, stuff breaks if we don't honor it. Note
@@ -10600,7 +10619,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
gracefully. */
addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (exp));
scalar_addr_mode address_mode = unqualified_address_mode (as);
- op0 = expand_expr_addr_expr_1 (exp, NULL_RTX, address_mode,
+ op0 = expand_expr_addr_expr_1 (unqualified_addr_expr (), exp,
+ NULL_RTX, address_mode,
EXPAND_NORMAL, as);
op0 = memory_address_addr_space (mode, op0, as);
temp = gen_rtx_MEM (mode, op0);
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-1.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-1.c
new file mode 100644
index 00000000000..175471ef26f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-1.c
@@ -0,0 +1,20 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-mcmodel=tiny -fno-PIC -fgimple -g0 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-mabi=purecap" "-mfake-capability" } { "" } } */
+
+/*
+** foo:
+** ldr c0, \.LC0
+** ret
+*/
+int x;
+__GIMPLE int *__capability foo() {
+ int *__capability res;
+
+ res = __CAP_ADDR x;
+ return res;
+}
+
+/* { dg-final { scan-assembler {\t\.section\t\.data\.rel\.ro\.local,"aw"\n\t\.align\t4\n\t\.type\t\.LC0, %object\n} } } */
+/* { dg-final { scan-assembler {\t\.size\t\.LC0, 16\n\.LC0:\n\t\.capinit\tx\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-2.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-2.c
new file mode 100644
index 00000000000..b1a724f2158
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-2.c
@@ -0,0 +1,21 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-mcmodel=tiny -fPIC -fgimple -g0 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-mabi=purecap" "-mfake-capability" } { "" } } */
+
+/*
+** foo:
+** ldr c0, \.LC0
+** ret
+*/
+int x;
+__GIMPLE int *__capability foo() {
+ int *__capability res;
+
+ res = __CAP_ADDR x;
+ return res;
+}
+
+/* { dg-final { scan-assembler {\tldr\tc0, \.LC0\n\tret\n} } } */
+/* { dg-final { scan-assembler {\t\.section\t\.data\.rel\.ro,"aw"\n\t\.align\t4\n\t\.type\t\.LC0, %object\n} } } */
+/* { dg-final { scan-assembler {\t\.size\t\.LC0, 16\n\.LC0:\n\t\.capinit\tx\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-3.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-3.c
new file mode 100644
index 00000000000..512c517c8c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-3.c
@@ -0,0 +1,21 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-mcmodel=small -fno-PIC -fgimple -g0 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-mabi=purecap" "-mfake-capability" } { "" } } */
+
+/*
+** foo:
+** adrp (x[0-9]+), \.LC0
+** ldr c0, \[\1, #:lo12:\.LC0\]
+** ret
+*/
+int x;
+__GIMPLE int *__capability foo() {
+ int *__capability res;
+
+ res = __CAP_ADDR x;
+ return res;
+}
+
+/* { dg-final { scan-assembler {\t\.section\t\.data\.rel\.ro\.local,"aw"\n\t\.align\t4\n\t\.type\t\.LC0, %object\n} } } */
+/* { dg-final { scan-assembler {\t\.size\t\.LC0, 16\n\.LC0:\n\t\.capinit\tx\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-4.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-4.c
new file mode 100644
index 00000000000..9f6ab6a54ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-4.c
@@ -0,0 +1,21 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-mcmodel=small -fPIC -fgimple -g0 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-mabi=purecap" "-mfake-capability" } { "" } } */
+
+/*
+** foo:
+** adrp (x[0-9]+), \.LC0
+** ldr c0, \[\1, #:lo12:\.LC0\]
+** ret
+*/
+int x;
+__GIMPLE int *__capability foo() {
+ int *__capability res;
+
+ res = __CAP_ADDR x;
+ return res;
+}
+
+/* { dg-final { scan-assembler {\t\.section\t\.data\.rel\.ro,"aw"\n\t\.align\t4\n\t\.type\t\.LC0, %object\n} } } */
+/* { dg-final { scan-assembler {\t\.size\t\.LC0, 16\n\.LC0:\n\t\.capinit\tx\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-5.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-5.c
new file mode 100644
index 00000000000..53368e6dfab
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-5.c
@@ -0,0 +1,21 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-mcmodel=small -fno-PIC -mpc-relative-literal-loads -fgimple -g0 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-mabi=purecap" "-mfake-capability" } { "" } } */
+
+/*
+** foo:
+** adrp (x[0-9]+), \.LC0
+** ldr c0, \[\1, #:lo12:\.LC0\]
+** ret
+*/
+int x;
+__GIMPLE int *__capability foo() {
+ int *__capability res;
+
+ res = __CAP_ADDR x;
+ return res;
+}
+
+/* { dg-final { scan-assembler {\t\.section\t\.data\.rel\.ro\.local,"aw"\n\t\.align\t4\n\t\.type\t\.LC0, %object\n} } } */
+/* { dg-final { scan-assembler {\t\.size\t\.LC0, 16\n\.LC0:\n\t\.capinit\tx\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-6.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-6.c
new file mode 100644
index 00000000000..7ed909424db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-6.c
@@ -0,0 +1,21 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-mcmodel=small -fPIC -mpc-relative-literal-loads -fgimple -g0 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-mabi=purecap" "-mfake-capability" } { "" } } */
+
+/*
+** foo:
+** adrp (x[0-9]+), \.LC0
+** ldr c0, \[\1, #:lo12:\.LC0\]
+** ret
+*/
+int x;
+__GIMPLE int *__capability foo() {
+ int *__capability res;
+
+ res = __CAP_ADDR x;
+ return res;
+}
+
+/* { dg-final { scan-assembler {\t\.section\t\.data\.rel\.ro,"aw"\n\t\.align\t4\n\t\.type\t\.LC0, %object\n} } } */
+/* { dg-final { scan-assembler {\t\.size\t\.LC0, 16\n\.LC0:\n\t\.capinit\tx\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-7.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-7.c
new file mode 100644
index 00000000000..89ba1759861
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-7.c
@@ -0,0 +1,23 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-mcmodel=large -fno-PIC -fgimple -g0 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-mabi=purecap" "-mfake-capability" } { "" } } */
+
+/*
+** foo:
+** adrp (x[0-9]+), \.LC1
+** ldr (x[0-9]+), \[\1, #:lo12:\.LC1\]
+** ldr c0, \[\2\]
+** ret
+*/
+int x;
+__GIMPLE int *__capability foo() {
+ int *__capability res;
+
+ res = __CAP_ADDR x;
+ return res;
+}
+
+/* { dg-final { scan-assembler {\t\.size\t\.LC1, 8\n\.LC1:\n\t\.xword\t\.LC0\n} } } */
+/* { dg-final { scan-assembler {\t\.section\t\.data\.rel\.ro\.local,"aw"\n\t\.align\t4\n\t\.type\t\.LC0, %object\n} } } */
+/* { dg-final { scan-assembler {\t\.size\t\.LC0, 16\n\.LC0:\n\t\.capinit\tx\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-8.c b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-8.c
new file mode 100644
index 00000000000..ef2129371c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/morello/hybrid-addr-expr-8.c
@@ -0,0 +1,22 @@
+/* { dg-do assemble } */
+/* { dg-additional-options "-mcmodel=large -fno-PIC -mpc-relative-literal-loads -fgimple -g0 -save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-mabi=purecap" "-mfake-capability" } { "" } } */
+
+/*
+** foo:
+** ldr (x[0-9]+), \.LC1
+** ldr c0, \[\1\]
+** ret
+*/
+int x;
+__GIMPLE int *__capability foo() {
+ int *__capability res;
+
+ res = __CAP_ADDR x;
+ return res;
+}
+
+/* { dg-final { scan-assembler {\t\.size\t\.LC1, 8\n\.LC1:\n\t\.xword\t\.LC0\n} } } */
+/* { dg-final { scan-assembler {\t\.section\t\.data\.rel\.ro\.local,"aw"\n\t\.align\t4\n\t\.type\t\.LC0, %object\n} } } */
+/* { dg-final { scan-assembler {\t\.size\t\.LC0, 16\n\.LC0:\n\t\.capinit\tx\n} } } */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2022-05-05 12:09 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-05 12:09 [gcc(refs/vendors/ARM/heads/morello)] aarch64: Hybrid support for non-TLS CADI symbols Matthew Malcomson
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).