public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Assemble labels-as-values correctly for purecap
@ 2021-09-21 9:13 Matthew Malcomson
0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2021-09-21 9:13 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:fa14b3bea9a290617df4f31e4286d4c89e43df9c
commit fa14b3bea9a290617df4f31e4286d4c89e43df9c
Author: Alex Coplan <alex.coplan@arm.com>
Date: Tue Aug 3 11:49:37 2021 +0100
Assemble labels-as-values correctly for purecap
When assembling a pointer to a label, we were just emitting:
.capinit <label>
but this is no good since the label has no size information. This change
instead derives the pointer to the label from the function, using:
.capinit f + ((<label>[+1])-f)
where the +1 is required to preserve the LSB to stay in the C64 state
(for Morello). The +1 is handled by the target hook
(aarch64_asm_output_capability). The generic code generates a
REPLACE_ADDRESS_VALUE rtx which derives the pointer to the label from
the function.
gcc/ChangeLog:
* config/aarch64/aarch64.c (aarch64_asm_output_capability):
Handle REPLACE_ADDRESS_VALUE when we're deriving a local label
from a function symbol. Don't handle CONST_NULL as the first
operand as that is non-canonical RTL, this should be represented
using POINTER_PLUS instead.
* final.c (output_addr_const): Handle REPLACE_ADDRESS_VALUE.
* varasm.c (output_constant): Handle capability ADDR_EXPRs of
LABEL_DECLs specially: for capabilities, they must be derived
from the function instead of trying to materialise a capability
from the label itself.
Diff:
---
gcc/config/aarch64/aarch64.c | 18 +++++++++++++-----
gcc/final.c | 14 ++++++++++++++
gcc/varasm.c | 22 ++++++++++++++++++++--
3 files changed, 47 insertions(+), 7 deletions(-)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 1b2d807b1f3..25016b56c61 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -19657,11 +19657,19 @@ aarch64_asm_output_capability (rtx x, unsigned int size, int aligned_p)
rtx address_value = XEXP (x, 1);
if (TARGET_CAPABILITY_FAKE)
return targetm.asm_out.integer(address_value, size, aligned_p);
- gcc_assert (GET_CODE (cap_val) == CONST_NULL);
- /* MORELLO TODO aligned_p may be true for this 8 byte sized value but
- * not for the 16 byte sized capability. Look into it later. */
- ret = targetm.asm_out.integer (address_value, offset_size, aligned_p);
- return ret && targetm.asm_out.integer (const0_rtx, offset_size, aligned_p);
+
+ if (SYMBOL_REF_P (cap_val)
+ && SUBREG_P (address_value)
+ && subreg_lowpart_p (address_value)
+ && LABEL_REF_P (SUBREG_REG (address_value)))
+ {
+ /* For a pointer to a label, we need to set the LSB to preserve
+ PSTATE.C64 for purecap. */
+ if (TARGET_CAPABILITY_PURE)
+ XEXP (x, 1) = plus_constant (POmode, address_value, 1);
+ }
+ else
+ gcc_unreachable ();
}
/* Fake capability => size is the correct size and just want to emit the
diff --git a/gcc/final.c b/gcc/final.c
index bc59cc16179..d23de908a2d 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -4176,6 +4176,20 @@ output_addr_const (FILE *file, rtx x)
}
break;
+ case REPLACE_ADDRESS_VALUE:
+ /* When assembling a capability, it may be desirable to
+ use a certain symbol to determines the bounds, but adjust the
+ capability value to point elsewhere. We represent this with
+ REPLACE_ADDRESS_VALUE and effect it by subtracting the
+ capability value of the capability symbol in the addend. */
+ output_addr_const (file, XEXP (x, 0));
+ fprintf (file, "+((");
+ output_addr_const (file, XEXP (x, 1));
+ fprintf (file, ")-");
+ output_addr_const (file, XEXP (x, 0));
+ fprintf (file, ")");
+ break;
+
case MINUS:
/* Avoid outputting things like x-x or x+5-x,
since some assemblers can't handle that. */
diff --git a/gcc/varasm.c b/gcc/varasm.c
index b31ec5b632a..b5e07e6fcf4 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -5065,8 +5065,26 @@ output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
case REFERENCE_TYPE:
if (capability_type_p (TREE_TYPE (exp)))
{
- rtx cap;
- cap = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
+ rtx cap = expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
+
+ if (TREE_CODE (exp) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (exp, 0)) == LABEL_DECL)
+ {
+ /* For a pointer to a label, we need to rewrite the expression
+ to derive the capability from the function, as the
+ assembler needs to know the size of the object to
+ determine capability bounds. */
+ tree lab = TREE_OPERAND (exp, 0);
+ tree fn = DECL_CONTEXT (lab);
+ rtx fn_rtl = DECL_RTL (fn);
+ gcc_assert (fn_rtl && MEM_P (fn_rtl));
+ rtx fn_addr = XEXP (fn_rtl, 0);
+
+ cap = gen_rtx_REPLACE_ADDRESS_VALUE (GET_MODE (fn_addr),
+ fn_addr,
+ drop_capability (cap));
+ }
+
if (!assemble_capability (cap, MIN (size, thissize), align, 0))
error ("initializer for capability is too complicated");
break;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-09-21 9:13 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-21 9:13 [gcc(refs/vendors/ARM/heads/morello)] Assemble labels-as-values correctly for purecap 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).