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