public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Hybrid Morello: Introduce IFN for CAP_GLOBAL_DATA_GET to enable accessing the DDC for conversions
@ 2022-05-05 12:06 Matthew Malcomson
  0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-05-05 12:06 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:3283a2d31e0d39f9f34940ff9091bacd4d71cc3c

commit 3283a2d31e0d39f9f34940ff9091bacd4d71cc3c
Author: Stam Markianos-Wright <stam.markianos-wright@arm.com>
Date:   Tue Apr 19 16:11:18 2022 +0100

    Hybrid Morello: Introduce IFN for CAP_GLOBAL_DATA_GET to enable accessing the DDC for conversions
    
    This patch introduces a CAP_GLOBAL_DATA_GET internal function. This
    function is used exclusively in capability architectures which support
    multiple machine modes for pointers accessing memory and require a
    default global capability to be used on non-capability pointer ->
    capability pointer conversions.
    
    This IFN then gets expended with the use of a target-insn and code is
    generated with the same pattern as the cap_global_data_get pattern used
    in the similarly-named cheri builtin.
    
    Note that for PureCap, we will never actually fall into function
    `c_common_cap_from_ptr` from convert (), as non-capability pointers
    don't exist. This preserves the existing behaviour of NULL-deriving
    a capability with no metadata.

Diff:
---
 gcc/c-family/c-common.c               | 18 ++++++++++++------
 gcc/config/aarch64/aarch64-builtins.c |  2 +-
 gcc/config/aarch64/aarch64-morello.md |  2 +-
 gcc/doc/md.texi                       |  6 ++++++
 gcc/internal-fn.c                     | 16 ++++++++++++++++
 gcc/internal-fn.def                   |  2 ++
 gcc/target-insns.def                  |  1 +
 gcc/tree.c                            | 11 +++++++++++
 gcc/tree.h                            |  1 +
 9 files changed, 51 insertions(+), 8 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 6bba7c392d1..394069675cd 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2674,14 +2674,12 @@ c_common_cap_from_noncap (tree type, tree expr)
     expr = c_fully_fold (expr, false, NULL);
 
   location_t loc = EXPR_LOCATION (expr);
-  tree ret = fold_build_replace_address_value_loc (loc, build_int_cst (type, 0),
-						   expr);
-  return ret;
+  return fold_build_replace_address_value_loc (loc, build_int_cst (type, 0),
+					       expr);
 }
 
 /* Generate a cast from a non-capability pointer to a capability pointer.
-   As above, this cast will necessarily create a pointer that does not have
-   valid metadata.  */
+   For Hybrid CHERI this will DDC-derive the capability.  */
 tree
 c_common_cap_from_ptr (tree type, tree ptr_expr)
 {
@@ -2695,7 +2693,15 @@ c_common_cap_from_ptr (tree type, tree ptr_expr)
   gcc_assert (TYPE_ADDR_SPACE (TREE_TYPE (type))
 		  == TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (ptr_expr))));
   tree int_expr = convert (noncapability_type (type), ptr_expr);
-  return c_common_cap_from_noncap (type, int_expr);
+
+  if (!c_dialect_cxx ())
+    int_expr = c_fully_fold (int_expr, false, NULL);
+
+  location_t loc = EXPR_LOCATION (int_expr);
+  tree ret = fold_build_replace_address_value_loc
+	       (loc, build_cap_global_data_get_loc (loc, type), int_expr);
+
+  return ret;
 }
 
 
diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 2ac413c709e..49f308ac507 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -2367,7 +2367,7 @@ aarch64_expand_morello_builtin (tree exp, rtx target, int fcode)
     case AARCH64_MORELLO_BUILTIN_GLOBAL_DATA_GET:
       {
         create_output_operand (&ops[0], target, CADImode);
-        expand_insn (CODE_FOR_aarch64_cap_global_data_get, 1, ops);
+	expand_insn (CODE_FOR_cap_global_data_get, 1, ops);
         return ops[0].value;
       }
     case AARCH64_MORELLO_BUILTIN_LENGTH_GET:
diff --git a/gcc/config/aarch64/aarch64-morello.md b/gcc/config/aarch64/aarch64-morello.md
index e41ca8e8644..db3beac3836 100644
--- a/gcc/config/aarch64/aarch64-morello.md
+++ b/gcc/config/aarch64/aarch64-morello.md
@@ -255,7 +255,7 @@
   "clrperm\\t%0, %1, %2"
 )
 
-(define_insn "aarch64_cap_global_data_get"
+(define_insn "cap_global_data_get"
   [(set (match_operand:CADI 0 "register_operand" "=rk")
         (unspec:CADI [(const_int 0)]
             UNSPEC_CHERI_GLOBAL_DATA_GET))]
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 309ab1451f4..062d8c700be 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -6862,6 +6862,12 @@ with @code{__builtin_apply} is stored; operand 1 is a @code{parallel}
 expression where each element is a @code{set} expression that indicates
 the restoring of a function return value from the result block.
 
+@cindex @code{cap_global_data_get} instruction pattern
+@item @samp{cap_global_data_get}
+An instruction that is used on capability architectures that have the concept
+of a global default capability to be used in integer to capability conversions.
+This expands the CAP_GLOBAL_DATA_GET internal function to RTL.
+
 @cindex @code{nop} instruction pattern
 @item @samp{nop}
 No-op instruction.  This instruction pattern name should always be defined
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 8ffa6e25724..c75d8dfa7d1 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -3023,6 +3023,22 @@ expand_REPLACE_ADDRESS_VALUE (internal_fn, gcall *gc)
     emit_move_insn (target, ret);
 }
 
+
+/* Expand CAP_GLOBAL_DATA_GET internal function.
+   This takes no parameters and returns only the value of the target's default
+   global capability.  */
+
+static void
+expand_CAP_GLOBAL_DATA_GET (internal_fn, gcall *gc)
+{
+  tree result = gimple_call_lhs (gc);
+  /* Has no side-effects, hence if return value not used just return now.  */
+  gcc_assert (result);
+  gcc_assert (targetm.have_cap_global_data_get ());
+  rtx target = expand_expr (result, NULL_RTX, VOIDmode, EXPAND_WRITE);
+  emit_insn (targetm.gen_cap_global_data_get (target));
+}
+
 /* Expand a NOP.  */
 
 static void
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index c81c7661d21..f27c0a16750 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -396,6 +396,8 @@ DEF_INTERNAL_FN (CO_FRAME, ECF_PURE | ECF_NOTHROW | ECF_LEAF, NULL)
    dereferenced.  */
 DEF_INTERNAL_FN (REPLACE_ADDRESS_VALUE, ECF_CONST | ECF_LEAF, ".RR")
 
+DEF_INTERNAL_FN (CAP_GLOBAL_DATA_GET, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
+
 /* A NOP function with arbitrary arguments and return value.  */
 DEF_INTERNAL_FN (NOP, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL)
 
diff --git a/gcc/target-insns.def b/gcc/target-insns.def
index 4d7eb92cf68..48ad57d2c72 100644
--- a/gcc/target-insns.def
+++ b/gcc/target-insns.def
@@ -106,3 +106,4 @@ DEF_TARGET_INSN (trap, (void))
 DEF_TARGET_INSN (unique, (void))
 DEF_TARGET_INSN (untyped_call, (rtx x0, rtx x1, rtx x2))
 DEF_TARGET_INSN (untyped_return, (rtx x0, rtx x1))
+DEF_TARGET_INSN (cap_global_data_get, (rtx x0))
\ No newline at end of file
diff --git a/gcc/tree.c b/gcc/tree.c
index a3a7c8972de..d47b13e6d8d 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -8088,6 +8088,17 @@ build_replace_address_value_loc (location_t loc, tree c, tree cv)
 				       2, c, cv);
 }
 
+/* Build a CAP_GLOBAL_DATA_GET internal function.  This function is used
+   exclusively in capability architectures which support multiple machine modes
+   for pointers accessing memory and require a default global capability to be
+   used on non-capability -> capability conversions.  */
+
+tree
+build_cap_global_data_get_loc (location_t loc, tree type)
+{
+  return build_call_expr_internal_loc (loc, IFN_CAP_GLOBAL_DATA_GET, type, 0);
+}
+
 /* Same as build_pointer_type_for_mode, but for REFERENCE_TYPE.  */
 
 tree
diff --git a/gcc/tree.h b/gcc/tree.h
index 0085afb091f..e0d8204edfe 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2017,6 +2017,7 @@ extern tree noncapability_type (tree);
 extern const_tree noncapability_type (const_tree);
 extern tree fold_drop_capability (tree);
 extern tree build_replace_address_value_loc (location_t, tree, tree);
+extern tree build_cap_global_data_get_loc (location_t, tree);
 extern bool valid_capability_code_p (tree_code);
 
 extern scalar_addr_mode pointer_address_mode (const_tree);


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-05-05 12:06 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:06 [gcc(refs/vendors/ARM/heads/morello)] Hybrid Morello: Introduce IFN for CAP_GLOBAL_DATA_GET to enable accessing the DDC for conversions 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).