From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2049) id D3DB43856274; Thu, 5 May 2022 12:06:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D3DB43856274 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Matthew Malcomson 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 X-Act-Checkin: gcc X-Git-Author: Stam Markianos-Wright X-Git-Refname: refs/vendors/ARM/heads/morello X-Git-Oldrev: 2912ef897f2684d69ee05eca50a42ac2e61749ab X-Git-Newrev: 3283a2d31e0d39f9f34940ff9091bacd4d71cc3c Message-Id: <20220505120600.D3DB43856274@sourceware.org> Date: Thu, 5 May 2022 12:06:00 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 May 2022 12:06:00 -0000 https://gcc.gnu.org/g:3283a2d31e0d39f9f34940ff9091bacd4d71cc3c commit 3283a2d31e0d39f9f34940ff9091bacd4d71cc3c Author: Stam Markianos-Wright 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);