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