public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/vendors/ARM/heads/morello)] Take CHERI headers from LLVM
@ 2022-03-14 10:34 Matthew Malcomson
  0 siblings, 0 replies; only message in thread
From: Matthew Malcomson @ 2022-03-14 10:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:5efe45f95cf351e9c695eaa8e38b7310b23a82fb

commit 5efe45f95cf351e9c695eaa8e38b7310b23a82fb
Author: Matthew Malcomson <matthew.malcomson@arm.com>
Date:   Tue Mar 1 12:14:21 2022 +0000

    Take CHERI headers from LLVM
    
    These modified for use in GCC.
    The original LLVM headers can be seen at the links below.
    https://git.morello_project.org/morello/llvm_project/_/blob/morello/dev/clang/lib/Headers/cheri.h
    https://git.morello_project.org/morello/llvm_project/_/blob/morello/dev/clang/lib/Headers/cheriintrin.h.
    
    At the time they are added, these are mostly commented out in the
    preprocessor since they largely use functionality that is not yet
    implemented in GCC.

Diff:
---
 gcc/ginclude/cheri.h       | 335 +++++++++++++++++++++++++++++++++++++++++++++
 gcc/ginclude/cheriintrin.h | 145 ++++++++++++++++++++
 2 files changed, 480 insertions(+)

diff --git a/gcc/ginclude/cheri.h b/gcc/ginclude/cheri.h
new file mode 100644
index 00000000000..a6edbc89936
--- /dev/null
+++ b/gcc/ginclude/cheri.h
@@ -0,0 +1,335 @@
+/*===---- cheri.h - Header for CHERI capabilities -----------------------===*\
+ *
+ * Copyright (c) 2014 David Chisnall
+ * Copyright (c) 2018 Alex Richardson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+\*===----------------------------------------------------------------------===*/
+
+/* Mirorred in the GCC source repo with modifications to work within the GNU
+   environment.  Currently mostly unused since CHERI for GCC is still a WIP.  */
+#ifndef _GCC_CHERI_H
+#define _GCC_CHERI_H
+
+#ifdef __aarch64__
+typedef unsigned int cheri_perms_t;
+#else
+typedef unsigned short cheri_perms_t;
+#endif
+typedef unsigned short cheri_flags_t;
+typedef unsigned __INT32_TYPE__ cheri_type_t;
+#ifdef __cplusplus
+#define __cheri_bool bool
+#else
+#define __cheri_bool _Bool
+#endif
+
+#if __GCC_ARM_CAPABILITY_ANY
+#define __IF_CAPS(x, y) x
+typedef __intcap_t intcap_t;
+typedef __uintcap_t uintcap_t;
+#ifdef WANT_CHERI_QUALIFIER_MACROS
+#define capability __capability
+#define output __cheri_output
+#define input __cheri_input
+#endif
+#else
+#define __IF_CAPS(x, y) y
+typedef __INTPTR_TYPE__ intcap_t;
+typedef __UINTPTR_TYPE__ uintcap_t;
+#define __capability
+#ifdef WANT_CHERI_QUALIFIER_MACROS
+#define capability
+#define output
+#define input
+#endif
+#endif
+
+/* MORELLO TODO Currently disabled until GCC has implemented CHERI builtins.  */
+#if 0
+#define __CHERI_GET(__name, __type, __get, __default)            \
+  static inline __type                                                        \
+  cheri_##__name##__get(void * __capability __cap)                              \
+  {                                                                           \
+    return __IF_CAPS(__builtin_cheri_##__name##__get(__cap), __default);     \
+  }
+
+#define __CHERI_SET(__name, __type, __set)                                     \
+  static inline void *__capability cheri_##__name##__set(                      \
+      void *__capability __cap, __type __val) {                                \
+    return __IF_CAPS(__builtin_cheri_##__name##__set(__cap, __val),            \
+                     (void *)__cap);                                           \
+  }
+
+#define __CHERI_ACCESSOR(__name, __type, __set, __get, __default)            \
+  __CHERI_GET(__name, __type, __get, __default)                              \
+  __CHERI_SET(__name, __type, __set)                                         \
+
+__CHERI_GET(length, __SIZE_TYPE__, _get, __SIZE_MAX__)
+__CHERI_GET(base, __SIZE_TYPE__, _get, __SIZE_MAX__)
+__CHERI_ACCESSOR(offset, __SIZE_TYPE__, _set, _get, __SIZE_MAX__)
+__CHERI_GET(type, cheri_type_t, _get, 0)
+__CHERI_ACCESSOR(perms, cheri_perms_t, _and, _get, 0)
+__CHERI_ACCESSOR(flags, cheri_flags_t, _set, _get, 0)
+__CHERI_GET(tag, __cheri_bool, _get, 0)
+__CHERI_GET(sealed, __cheri_bool, _get, 0)
+
+static inline
+void * __capability cheri_offset_increment(void *__capability __cap,
+                                         __PTRDIFF_TYPE__ __offset) {
+  return __IF_CAPS(__builtin_cheri_offset_increment(__cap, __offset),
+                   ((char*)__cap) + __offset);
+}
+
+static inline
+void * __capability cheri_tag_clear(void * __capability __cap) {
+  return __IF_CAPS(__builtin_cheri_tag_clear(__cap), (void*)__cap);
+}
+
+static inline
+void * __capability cheri_seal(void * __capability __cap,
+                               const void * __capability __type) {
+  return __IF_CAPS(__builtin_cheri_seal(__cap, __type), (void*)__cap);
+}
+
+static inline
+void * __capability cheri_unseal(void * __capability __cap,
+                                 const void * __capability __type) {
+  return __IF_CAPS(__builtin_cheri_unseal(__cap, __type), (void*)__cap);
+}
+
+static inline
+void * __capability cheri_bounds_set(void *__capability __cap,
+                                   __SIZE_TYPE__ __bounds) {
+  return __IF_CAPS(__builtin_cheri_bounds_set(__cap, __bounds), (void*)__cap);
+}
+
+static inline
+__SIZE_TYPE__ cheri_round_representable_length(__SIZE_TYPE__ __length) {
+  return __IF_CAPS(__builtin_cheri_round_representable_length(__length), __length);
+}
+
+static inline
+__SIZE_TYPE__ cheri_round_representable_mask(__SIZE_TYPE__ __mask) {
+  return __IF_CAPS(__builtin_cheri_representable_alignment_mask(__mask), __mask);
+}
+
+static inline
+__SIZE_TYPE__ cheri_copy_from_high(void *__capability __cap) {
+  return __IF_CAPS(__builtin_cheri_copy_from_high(__cap), __SIZE_MAX__);
+}
+
+static inline
+void * __capability
+cheri_copy_to_high(const void *__capability __cap, __SIZE_TYPE__ __high) {
+  return __IF_CAPS(__builtin_cheri_copy_to_high(__cap, __high), (void*)__cap);
+}
+
+static inline __SIZE_TYPE__ cheri_equal_exact(const void * __capability __cap_a,
+    const void * __capability __cap_b) {
+  return __IF_CAPS(__builtin_cheri_equal_exact(__cap_a, __cap_b), 0);
+}
+
+static inline __SIZE_TYPE__ cheri_subset_test(const void * __capability __cap_a,
+    const void * __capability __cap_b) {
+  return __IF_CAPS(__builtin_cheri_subset_test(__cap_a, __cap_b), 0);
+}
+
+#ifndef __CHERI_PURE_CAPABILITY__
+static inline
+void * __capability
+cheri_cap_from_pointer(const void * __capability __cap, void *__ptr) {
+  return __IF_CAPS(__builtin_cheri_cap_from_pointer(__cap, __ptr),
+                   (void *)__ptr);
+}
+
+static inline
+void * cheri_cap_to_pointer(const void * __capability __cap,
+                            void * __capability __offset) {
+  return __IF_CAPS(__builtin_cheri_cap_to_pointer(__cap, __offset),
+                   (void *)__offset);
+}
+#endif
+
+static inline
+void cheri_perms_check(const void * __capability __cap, cheri_perms_t __perms) {
+  __IF_CAPS(__builtin_cheri_perms_check(__cap, __perms), );
+}
+
+static inline
+void cheri_type_check(const void * __capability __cap,
+                      const void * __capability __type) {
+  __IF_CAPS(__builtin_cheri_type_check(__cap, __type), );
+}
+
+static inline
+void * __capability cheri_global_data_get(void) {
+  return __IF_CAPS(__builtin_cheri_global_data_get(), 0);
+}
+
+static inline
+void * __capability cheri_program_counter_get(void) {
+  return __IF_CAPS(__builtin_cheri_program_counter_get(), 0);
+}
+
+/* TODO: Should these be builtins to get better diagnostics? */
+
+static inline __attribute__((always_inline)) __attribute__((warn_unused_result))
+__SIZE_TYPE__
+__cheri_low_bits_get(__UINTPTR_TYPE__ ptr, __SIZE_TYPE__ mask) {
+  /*
+   * Note: we continue to use bitwise and on the uintcap value and silence the
+   * warning instead of using __builtin_cheri_offset_get() in case we decide
+   * to use a virtual-address instead offset interpretation of capabilities in
+   * the future.
+   */
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcheri-bitwise-operations"
+  /*
+   * We mustn't return a LHS-derived capability here so we need to explicitly
+   * cast the result to a non-capability integer
+   */
+  return (__SIZE_TYPE__)(ptr & mask);
+#pragma clang diagnostic pop
+}
+
+static inline __attribute__((always_inline)) __attribute__((warn_unused_result))
+__UINTPTR_TYPE__
+__cheri_low_bits_or(__UINTPTR_TYPE__ ptr, __SIZE_TYPE__ bits) {
+  /*
+   * We want to return a LHS-derived capability here so using the default
+   * uintcap_t semantics is fine.
+   */
+  return ptr | bits;
+}
+
+static inline __attribute__((always_inline)) __attribute__((warn_unused_result))
+__UINTPTR_TYPE__
+__cheri_low_bits_clear(__UINTPTR_TYPE__ ptr, __SIZE_TYPE__ bits_mask) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wcheri-bitwise-operations"
+  /*
+   * We want to return a LHS-derived capability here so using the default
+   * uintcap_t semantics is fine.
+   */
+  return ptr & (~bits_mask);
+#pragma clang diagnostic pop
+}
+
+#ifndef __cheri_usable_low_bits_mask
+#define __cheri_usable_low_bits_mask 31
+#endif
+#define __runtime_assert_sensible_low_bits(bits, mask)                         \
+  __extension__({                                                              \
+    assert(((bits & mask) == bits) && "Bits outside mask used!");              \
+    bits;                                                                      \
+  })
+#define __static_assert_sensible_low_bits(bits)                                \
+  __extension__({                                                              \
+    _Static_assert(bits < (__cheri_usable_low_bits_mask + 1),                  \
+                   "Using too many low pointer bits");                         \
+    _Static_assert((bits & (bits + 1)) == 0, "Mask must be all ones");         \
+    bits;                                                                      \
+  })
+
+/*
+ * Get the low bits defined in @p mask from the capability/pointer @p ptr.
+ * @p mask must be a compile-time constant less than 31.
+ * TODO: should we allow non-constant masks?
+ *
+ * @param ptr the uintptr_t that may have low bits sets
+ * @param mask the mask for the low pointer bits to retrieve
+ * @return a size_t containing the the low bits from @p ptr
+ *
+ * Rationale: this function is needed because extracting the low bits using a
+ * bitwise-and operation returns a LHS-derived capability with the offset
+ * field set to LHS.offset & mask. This is almost certainly not what the user
+ * wanted since it will always compare not equal to any integer constant.
+ * For example lots of mutex code uses something like `if ((x & 1) == 1)` to
+ * detect if the lock is currently contented. This comparison always returns
+ * false under CHERI the LHS of the == is a valid capability with offset 3 and
+ * the RHS is an untagged intcap_t with offset 3.
+ * See https://github.com/CTSRD-CHERI/clang/issues/189
+ */
+#define cheri_low_bits_get(ptr, mask)                                          \
+  __cheri_low_bits_get(ptr, __static_assert_sensible_low_bits(mask))
+
+/*
+ * Bitwise-OR of low bits in a uintptr_t
+ *
+ * @param ptr the uintptr_t that may have low bits sets
+ * @param bits the value to bitwise-or with @p ptr.
+ * @return a uintptr_t that has the low bits  @p bits
+ *
+ * @note this function is not strictly required since a plain bitwise or will
+ * generally give the behaviour that is expected from other platforms.
+ * However, we can't really make the warning "-Wcheri-bitwise-operations"
+ * trigger based on of the right hand side expression since it may not be a
+ * compile-time constant.
+ */
+#define cheri_low_bits_or(ptr, bits)                                           \
+  __cheri_low_bits_or(ptr, __runtime_assert_sensible_low_bits(                 \
+                               bits, __cheri_usable_low_bits_mask))
+
+/*
+ * Set low bits in a uintptr_t
+ *
+ * @param ptr the uintptr_t that may have low bits sets
+ * @param mask the mask for the low pointer bits to be cleared before setting
+ * them to @p bits.
+ * @param bits the value to bitwise-or with @p ptr.
+ * @return a uintptr_t that has the low bits defined in @p mask set to @p bits
+ *
+ * @note this function is not strictly required since a plain bitwise or will
+ * generally give the behaviour that is expected from other platforms.
+ * However, we can't really make the warning "-Wcheri-bitwise-operations"
+ * trigger based on of the right hand side expression since it may not be a
+ * compile-time constant.
+ */
+#define cheri_low_bits_set(ptr, mask, bits)                                    \
+  __cheri_low_bits_or(cheri_low_bits_clear(ptr, mask),                         \
+                      __runtime_assert_sensible_low_bits(bits, mask))
+
+/*
+ * Clear the bits in @p mask from the capability/pointer @p ptr. Mask must be
+ * a compile-time constant less than 31
+ *
+ * TODO: should we allow non-constant masks?
+ *
+ * @param ptr the uintptr_t that may have low bits sets
+ * @param mask this is the mask for the low pointer bits, not the mask for
+ * the bits that should remain set.
+ * @return a uintptr_t that has the low bits defined in @p mask set to zeroes
+ *
+ *
+ */
+#define cheri_low_bits_clear(ptr, mask)                                        \
+  __cheri_low_bits_clear(ptr, __static_assert_sensible_low_bits(mask))
+
+#undef __CHERI_ACCESSOR
+#undef __CHERI_GET
+#undef __CHERI_SET
+
+#endif  /* if 0  (commenting out parts that GCC can't yet use). */
+
+#undef __cheri_bool
+#undef __IF_CAPS
+
+#endif /* _CHERI_H */
diff --git a/gcc/ginclude/cheriintrin.h b/gcc/ginclude/cheriintrin.h
new file mode 100644
index 00000000000..9be560e5cda
--- /dev/null
+++ b/gcc/ginclude/cheriintrin.h
@@ -0,0 +1,145 @@
+/*-------------- cheriintrin.h - CHERI intrinsics -----------------------
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2018-2020 Alex Richardson
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory (Department of Computer Science and
+ * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
+ * DARPA SSITH research programme.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* LLVM header mirorred in the GCC source repo with modifications to work
+   within the GNU environment.  Only for the GCC Morello vendor branch.  */
+#ifndef __GCC_CHERI_INTRIN_H
+#define __GCC_CHERI_INTRIN_H
+
+#ifndef __GCC_ARM_CAPABILITY_ANY
+#error "<cheriintrin.h> should only be included when CHERI is supported"
+#endif
+
+/*
+ * Provide shorter names for CHERI builtins that are portable across all
+ * CHERI-enabled architectures:
+ */
+#define cheri_address_get(x) __builtin_cheri_address_get(x)
+#define cheri_address_set(x, y) __builtin_cheri_address_set((x), (y))
+#define cheri_base_get(x) __builtin_cheri_base_get(x)
+#define cheri_length_get(x) __builtin_cheri_length_get(x)
+#define cheri_offset_get(x) __builtin_cheri_offset_get(x)
+#define cheri_offset_set(x, y) __builtin_cheri_offset_set((x), (y))
+#define cheri_tag_clear(x) __builtin_cheri_tag_clear(x)
+#define cheri_tag_get(x) __builtin_cheri_tag_get(x)
+#define cheri_is_valid(x) __builtin_cheri_tag_get(x)
+#define cheri_is_invalid(x) (!__builtin_cheri_tag_get(x))
+#define cheri_is_equal_exact(x, y) __builtin_cheri_equal_exact((x), (y))
+#define cheri_is_subset(x, y) __builtin_cheri_subset_test((x), (y))
+
+/* Bounds setting intrinsics: */
+#define cheri_representable_length(x)                                          \
+  __builtin_cheri_round_representable_length(x)
+#define cheri_representable_alignment_mask(x)                                  \
+  __builtin_cheri_representable_alignment_mask(x)
+#define cheri_bounds_set(x, y) __builtin_cheri_bounds_set((x), (y))
+#define cheri_bounds_set_exact(x, y) __builtin_cheri_bounds_set_exact((x), (y))
+
+/* Object types, sealing and unsealing: */
+typedef long cheri_otype_t;
+#if defined(__mips__) || defined(__riscv)
+/* CHERI-MIPS and CHERI-RISC-V use negative numbers for hardware-interpreted
+ * otypes */
+#define CHERI_OTYPE_UNSEALED ((cheri_otype_t)-1)
+#define CHERI_OTYPE_SENTRY ((cheri_otype_t)-2)
+#elif defined(__aarch64__)
+#define CHERI_OTYPE_UNSEALED ((cheri_otype_t)0)
+#define CHERI_OTYPE_SENTRY ((cheri_otype_t)1)
+#else
+#error "Unknown architecture"
+#endif
+#define cheri_type_get(x) __builtin_cheri_type_get(x)
+#define cheri_is_sealed(x) __builtin_cheri_sealed_get(x)
+#define cheri_is_sentry(x) (__builtin_cheri_type_get(x) == CHERI_OTYPE_SENTRY)
+#define cheri_is_unsealed(x) (!__builtin_cheri_sealed_get(x))
+/* TODO: builtins for indirect sentries */
+#define cheri_sentry_create(x) __builtin_cheri_seal_entry(x)
+#define cheri_seal(x, y) __builtin_cheri_seal((x), (y))
+#define cheri_unseal(x, y) __builtin_cheri_unseal((x), (y))
+
+/* Reconstruct capabilities from raw data: */
+#define cheri_cap_build(x, y) __builtin_cheri_cap_build((x), (y))
+#define cheri_seal_conditionally(x, y)                                         \
+  __builtin_cheri_conditional_seal((x), (y))
+#define cheri_type_copy(x, y) __builtin_cheri_cap_type_copy((x), (y))
+
+/* Capability permissions: */
+typedef enum __attribute__((flag_enum, enum_extensibility(open))) {
+  CHERI_PERM_GLOBAL = __CHERI_CAP_PERMISSION_GLOBAL__,
+  CHERI_PERM_EXECUTE = __CHERI_CAP_PERMISSION_PERMIT_EXECUTE__,
+  CHERI_PERM_LOAD = __CHERI_CAP_PERMISSION_PERMIT_LOAD__,
+  CHERI_PERM_STORE = __CHERI_CAP_PERMISSION_PERMIT_STORE__,
+  CHERI_PERM_LOAD_CAP = __CHERI_CAP_PERMISSION_PERMIT_LOAD_CAPABILITY__,
+  CHERI_PERM_STORE_CAP = __CHERI_CAP_PERMISSION_PERMIT_STORE_CAPABILITY__,
+  CHERI_PERM_STORE_LOCAL_CAP = __CHERI_CAP_PERMISSION_PERMIT_STORE_LOCAL__,
+  CHERI_PERM_SEAL = __CHERI_CAP_PERMISSION_PERMIT_SEAL__,
+#if !defined(__aarch64__)
+  CHERI_PERM_CCALL = __CHERI_CAP_PERMISSION_PERMIT_CCALL__,
+#else
+  ARM_CAP_PERMISSION_EXECUTIVE = __ARM_CAP_PERMISSION_EXECUTIVE__,
+  ARM_CAP_PERMISSION_MUTABLE_LOAD = __ARM_CAP_PERMISSION_MUTABLE_LOAD__,
+  ARM_CAP_PERMISSION_COMPARTMENT_ID = __ARM_CAP_PERMISSION_COMPARTMENT_ID__,
+  ARM_CAP_PERMISSION_BRANCH_SEALED_PAIR = __ARM_CAP_PERMISSION_BRANCH_SEALED_PAIR__,
+#endif
+  CHERI_PERM_UNSEAL = __CHERI_CAP_PERMISSION_PERMIT_UNSEAL__,
+  CHERI_PERM_SYSTEM_REGS = __CHERI_CAP_PERMISSION_ACCESS_SYSTEM_REGISTERS__,
+  /* TODO: architecture-dependent permissions */
+} cheri_perms_t;
+#define cheri_perms_get(x) ((cheri_perms_t)(__builtin_cheri_perms_get(x)))
+#define cheri_perms_and(x, y) __builtin_cheri_perms_and((x), (__SIZE_TYPE__)(y))
+#define cheri_perms_clear(x, y)                                                \
+  __builtin_cheri_perms_and((x), ~(__SIZE_TYPE__)(y))
+
+/* Accessors for capability registers. Currently exposes DDC and PCC. */
+#define cheri_ddc_get() __builtin_cheri_global_data_get()
+#define cheri_pcc_get() __builtin_cheri_program_counter_get()
+
+/* Partially portable builtins: */
+/* Note: {get,set}flags does nothing for MIPS, but can still be used. */
+#define cheri_flags_get(x) __builtin_cheri_flags_get(x)
+#define cheri_flags_set(x, y) __builtin_cheri_flags_set((x), (y))
+#define cheri_tags_load(x) __builtin_cheri_cap_load_tags(x)
+
+/*
+ * Alignment builtins: Not CHERI-specific, but motivated by CHERI.
+ * https://clang.llvm.org/docs/LanguageExtensions.html#alignment-builtins
+ */
+#define cheri_align_up(x, alignment) __builtin_align_up((x), (alignment))
+#define cheri_align_down(x, alignment) __builtin_align_down((x), (alignment))
+#define cheri_is_aligned(x, alignment) __builtin_is_aligned((x), (alignment))
+
+#endif /* __GCC_CHERIINTRIN_H */


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

only message in thread, other threads:[~2022-03-14 10:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-14 10:34 [gcc(refs/vendors/ARM/heads/morello)] Take CHERI headers from LLVM 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).