public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Matthew Malcomson <matmal01@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/vendors/ARM/heads/morello)] Hybrid Morello: Introduce IFN for CAP_GLOBAL_DATA_GET to enable accessing the DDC for conversions Date: Thu, 5 May 2022 12:06:00 +0000 (GMT) [thread overview] Message-ID: <20220505120600.D3DB43856274@sourceware.org> (raw) 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);
reply other threads:[~2022-05-05 12:06 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220505120600.D3DB43856274@sourceware.org \ --to=matmal01@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).