Hi Claudio, > On 19 Sep 2024, at 15:09, Claudio Bantaloukas <claudio.bantalou...@arm.com> > wrote: > > External email: Use caution opening links or attachments > > > The ACLE defines a new scalar type, __mfp8. This is an opaque 8bit types that > can only be used by fp8 intrinsics. Additionally, the mfloat8_t type is made > available in arm_neon.h and arm_sve.h as an alias of the same. > > This implementation uses an unsigned INTEGER_TYPE, with precision 8 to > represent __mfp8. Conversions to int and other types are disabled via the > TARGET_INVALID_CONVERSION hook. > Additionally, operations that are typically available to integer types are > disabled via TARGET_INVALID_UNARY_OP and TARGET_INVALID_BINARY_OP hooks. > > gcc/ChangeLog: > > * config/aarch64/aarch64-builtins.cc (aarch64_mfp8_type_node): Add node > for __mfp8 type. > (aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type. > (aarch64_init_fp8_types): New function to initialise fp8 types and > register with language backends. > * config/aarch64/aarch64.cc (aarch64_mangle_type): Add ABI mangling for > new type. > (aarch64_invalid_conversion): Add function implementing > TARGET_INVALID_CONVERSION hook that blocks conversion to and from the > __mfp8 type. > (aarch64_invalid_unary_op): Add function implementing TARGET_UNARY_OP > hook that blocks operations on __mfp8 other than &. > (aarch64_invalid_binary_op): Extend TARGET_BINARY_OP hook to disallow > operations on __mfp8 type. > (TARGET_INVALID_CONVERSION): Add define. > (TARGET_INVALID_UNARY_OP): Likewise. > * config/aarch64/aarch64.h (aarch64_mfp8_type_node): Add node for > __mfp8 > type. > (aarch64_mfp8_ptr_type_node): Add node for __mfp8 pointer type. > * config/aarch64/arm_neon.h (mfloat8_t): Add typedef. > * config/aarch64/arm_sve.h (mfloat8_t): Likewise.
Looks like this typedef is a good candidate to go into arm_private_fp8.h so that arm_neon.h, arm_sve.h and arm_sme.h inherit it. Thanks, Kyrill > > gcc/testsuite/ChangeLog: > > * g++.target/aarch64/fp8_mangling.C: New tests exercising mangling. > * g++.target/aarch64/fp8_scalar_typecheck_2.C: New tests in C++. > * gcc.target/aarch64/fp8_scalar_1.c: New tests in C. > * gcc.target/aarch64/fp8_scalar_typecheck_1.c: Likewise. > --- > Hi, > Is this ok for master? I do not have commit rights yet, if ok, can someone > commit it on my behalf? > > Regression tested with aarch64-unknown-linux-gnu. > > Compared to V1 of the patch, in version 2: > - mangling for the __mfp8 type was added along with tests > - unneeded comments were removed > - simplified type checks in hooks > - simplified initialization of aarch64_mfp8_type_node > - separated mfloat8_t define from other fp types in arm_sve.h > - C++ tests were moved to g++.target/aarch64 > - added more tests around binary operations, function declaration, > type traits > - added tests exercising loads and stores from floating point registers > > > Thanks, > Claudio Bantaloukas > > gcc/config/aarch64/aarch64-builtins.cc | 20 + > gcc/config/aarch64/aarch64.cc | 54 ++- > gcc/config/aarch64/aarch64.h | 5 + > gcc/config/aarch64/arm_neon.h | 2 + > gcc/config/aarch64/arm_sve.h | 2 + > .../g++.target/aarch64/fp8_mangling.C | 44 ++ > .../aarch64/fp8_scalar_typecheck_2.C | 381 ++++++++++++++++++ > .../gcc.target/aarch64/fp8_scalar_1.c | 134 ++++++ > .../aarch64/fp8_scalar_typecheck_1.c | 356 ++++++++++++++++ > 9 files changed, 996 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/g++.target/aarch64/fp8_mangling.C > create mode 100644 gcc/testsuite/g++.target/aarch64/fp8_scalar_typecheck_2.C > create mode 100644 gcc/testsuite/gcc.target/aarch64/fp8_scalar_1.c > create mode 100644 gcc/testsuite/gcc.target/aarch64/fp8_scalar_typecheck_1.c > > diff --git a/gcc/config/aarch64/aarch64-builtins.cc > b/gcc/config/aarch64/aarch64-builtins.cc > index eb878b933fe..7d17df05a0f 100644 > --- a/gcc/config/aarch64/aarch64-builtins.cc > +++ b/gcc/config/aarch64/aarch64-builtins.cc > @@ -961,6 +961,11 @@ static GTY(()) tree aarch64_simd_intOI_type_node = > NULL_TREE; > static GTY(()) tree aarch64_simd_intCI_type_node = NULL_TREE; > static GTY(()) tree aarch64_simd_intXI_type_node = NULL_TREE; > > +/* The user-visible __mfp8 type, and a pointer to that type. Used > + across the back-end. */ > +tree aarch64_mfp8_type_node = NULL_TREE; > +tree aarch64_mfp8_ptr_type_node = NULL_TREE; > + > /* The user-visible __fp16 type, and a pointer to that type. Used > across the back-end. */ > tree aarch64_fp16_type_node = NULL_TREE; > @@ -1721,6 +1726,19 @@ aarch64_init_builtin_rsqrt (void) > } > } > > +/* Initialize the backend type that supports the user-visible __mfp8 > + type and its relative pointer type. */ > + > +static void > +aarch64_init_fp8_types (void) > +{ > + aarch64_mfp8_type_node = make_unsigned_type (8); > + SET_TYPE_MODE (aarch64_mfp8_type_node, QImode); > + > + lang_hooks.types.register_builtin_type (aarch64_mfp8_type_node, "__mfp8"); > + aarch64_mfp8_ptr_type_node = build_pointer_type (aarch64_mfp8_type_node); > +} > + > /* Initialize the backend types that support the user-visible __fp16 > type, also initialize a pointer to that type, to be used when > forming HFAs. */ > @@ -2125,6 +2143,8 @@ aarch64_general_init_builtins (void) > { > aarch64_init_fpsr_fpcr_builtins (); > > + aarch64_init_fp8_types (); > + > aarch64_init_fp16_types (); > > aarch64_init_bf16_types (); > diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc > index 92763d403c7..0ac00027502 100644 > --- a/gcc/config/aarch64/aarch64.cc > +++ b/gcc/config/aarch64/aarch64.cc > @@ -22467,6 +22467,10 @@ aarch64_mangle_type (const_tree type) > return "Dh"; > } > > + /* Modal 8 bit floating point types. */ > + if (TYPE_MAIN_VARIANT (type) == aarch64_mfp8_type_node) > + return "u6__mfp8"; > + > /* Mangle AArch64-specific internal types. TYPE_NAME is non-NULL_TREE for > builtin types. */ > if (TYPE_NAME (type) != NULL) > @@ -22481,6 +22485,29 @@ aarch64_mangle_type (const_tree type) > return NULL; > } > > +/* Implement TARGET_INVALID_CONVERSION. */ > + > +static const char * > +aarch64_invalid_conversion (const_tree fromtype, const_tree totype) > +{ > + /* Do not allow conversions to/from FP8. But do allow conversions between > + volatile and const variants of __mfp8. */ > + bool fromtype_is_fp8 > + = (TYPE_MAIN_VARIANT (fromtype) == aarch64_mfp8_type_node); > + bool totype_is_fp8 = (TYPE_MAIN_VARIANT (totype) == > aarch64_mfp8_type_node); > + > + if (fromtype_is_fp8 && totype_is_fp8) > + return NULL; > + > + if (fromtype_is_fp8) > + return N_ ("invalid conversion from type %<mfloat8_t%>"); > + if (totype_is_fp8) > + return N_ ("invalid conversion to type %<mfloat8_t%>"); > + > + /* Conversion allowed. */ > + return NULL; > +} > + > /* Implement TARGET_VERIFY_TYPE_CONTEXT. */ > > static bool > @@ -29031,8 +29058,20 @@ aarch64_stack_protect_guard (void) > return NULL_TREE; > } > > -/* Return the diagnostic message string if the binary operation OP is > - not permitted on TYPE1 and TYPE2, NULL otherwise. */ > +/* Implement TARGET_INVALID_UNARY_OP. */ > + > +static const char * > +aarch64_invalid_unary_op (int op, const_tree type) > +{ > + /* Reject all single-operand operations on __mfp8 except for &. */ > + if (TYPE_MAIN_VARIANT (type) == aarch64_mfp8_type_node && op != ADDR_EXPR) > + return N_ ("operation not permitted on type %<mfloat8_t%>"); > + > + /* Operation allowed. */ > + return NULL; > +} > + > +/* Implement TARGET_INVALID_BINARY_OP. */ > > static const char * > aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, const_tree type1, > @@ -29046,6 +29085,11 @@ aarch64_invalid_binary_op (int op ATTRIBUTE_UNUSED, > const_tree type1, > != aarch64_sve::builtin_type_p (type2))) > return N_("cannot combine GNU and SVE vectors in a binary operation"); > > + /* Reject all 2-operand operations on __mfp8. */ > + if (TYPE_MAIN_VARIANT (type1) == aarch64_mfp8_type_node > + || TYPE_MAIN_VARIANT (type2) == aarch64_mfp8_type_node) > + return N_ ("operation not permitted on type %<mfloat8_t%>"); > + > /* Operation allowed. */ > return NULL; > } > @@ -30763,6 +30807,12 @@ aarch64_libgcc_floating_mode_supported_p > #undef TARGET_MANGLE_TYPE > #define TARGET_MANGLE_TYPE aarch64_mangle_type > > +#undef TARGET_INVALID_CONVERSION > +#define TARGET_INVALID_CONVERSION aarch64_invalid_conversion > + > +#undef TARGET_INVALID_UNARY_OP > +#define TARGET_INVALID_UNARY_OP aarch64_invalid_unary_op > + > #undef TARGET_INVALID_BINARY_OP > #define TARGET_INVALID_BINARY_OP aarch64_invalid_binary_op > > diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h > index 2dfb999bea5..7ef82ce3587 100644 > --- a/gcc/config/aarch64/aarch64.h > +++ b/gcc/config/aarch64/aarch64.h > @@ -1447,6 +1447,11 @@ extern const char *aarch64_rewrite_mcpu (int argc, > const char **argv); > > #define ASM_OUTPUT_POOL_EPILOGUE aarch64_asm_output_pool_epilogue > > +/* This type is the user-visible __mfp8, and a pointer to that type. We > + need it in many places in the backend. Defined in aarch64-builtins.cc. > */ > +extern GTY(()) tree aarch64_mfp8_type_node; > +extern GTY(()) tree aarch64_mfp8_ptr_type_node; > + > /* This type is the user-visible __fp16, and a pointer to that type. We > need it in many places in the backend. Defined in aarch64-builtins.cc. */ > extern GTY(()) tree aarch64_fp16_type_node; > diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h > index e376685489d..0092314cf75 100644 > --- a/gcc/config/aarch64/arm_neon.h > +++ b/gcc/config/aarch64/arm_neon.h > @@ -72,6 +72,8 @@ typedef __Poly16_t poly16_t; > typedef __Poly64_t poly64_t; > typedef __Poly128_t poly128_t; > > +typedef __mfp8 mfloat8_t; > + > typedef __fp16 float16_t; > typedef float float32_t; > typedef double float64_t; > diff --git a/gcc/config/aarch64/arm_sve.h b/gcc/config/aarch64/arm_sve.h > index aa0bd9909f9..dbc61650df2 100644 > --- a/gcc/config/aarch64/arm_sve.h > +++ b/gcc/config/aarch64/arm_sve.h > @@ -29,6 +29,8 @@ > #include <arm_private_fp8.h> > #include <arm_bf16.h> > > +typedef __mfp8 mfloat8_t; > + > typedef __fp16 float16_t; > typedef float float32_t; > typedef double float64_t; > diff --git a/gcc/testsuite/g++.target/aarch64/fp8_mangling.C > b/gcc/testsuite/g++.target/aarch64/fp8_mangling.C > new file mode 100644 > index 00000000000..1dfcaa71f15 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/fp8_mangling.C > @@ -0,0 +1,44 @@ > +/* Test that mfloat8_t mangles differently from uint8_t */ > +/* { dg-options "-O1 -march=armv9.4-a+fp8" } */ > + > +int > +foo (__mfp8) > +{ > + return 1; > +} > + > +int > +foo (unsigned char) > +{ > + return 2; > +} > + > +int > +bar (__mfp8 x) > +{ > + return foo (x); > +} > +/* { dg-final { scan-assembler-times "\n_Z3fooh:\n" 1 } } */ > +/* { dg-final { scan-assembler-times "\n_Z3foou6__mfp8:\n" 1 } } */ > + > +constexpr __mfp8 cfp8{}; > + > +constexpr int > +fooc (unsigned char) > +{ > + return 3; > +} > + > +constexpr int > +fooc (__mfp8) > +{ > + return 4; > +} > + > +constexpr int > +barc (__mfp8 x) > +{ > + return fooc (x); > +} > + > +static_assert (barc (cfp8) == 4, "constexpr selects incorrect overload"); > diff --git a/gcc/testsuite/g++.target/aarch64/fp8_scalar_typecheck_2.C > b/gcc/testsuite/g++.target/aarch64/fp8_scalar_typecheck_2.C > new file mode 100644 > index 00000000000..61557c95663 > --- /dev/null > +++ b/gcc/testsuite/g++.target/aarch64/fp8_scalar_typecheck_2.C > @@ -0,0 +1,381 @@ > +/* Test that mfloat8_t is only usable with intrinsics, thus not convertible. > */ > +/* { dg-do assemble } */ > +/* { dg-options "-O1 -march=armv9.4-a+fp8 -Wno-narrowing" } */ > + > +#include <arm_neon.h> > +#include <stdint.h> > +#include <type_traits> > + > +mfloat8_t glob_fp8; > + > +int is_an_int; > +uint8_t is_a_uint8; > +int8_t is_an_int8; > +short is_a_short_int; > +float is_a_float; > +double is_a_double; > + > +uint8_t *uint8_ptr; > + > +mfloat8_t > +invalid_from_fp8 (uint16_t __a) > +{ > + mfloat8_t b = __a; /* { dg-error "invalid conversion to type 'mfloat8_t'" > } */ > + return b; > +} > + > +uint16_t > +invalid_to_fp8 (mfloat8_t __a) > +{ > + uint16_t b = __a; /*{ dg-error "invalid conversion from type 'mfloat8_t'" > } */ > + return b; > +} > + > +mfloat8_t > +foo1 (void) > +{ > + return (mfloat8_t)0x1234; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > +} > + > +mfloat8_t > +foo2 (void) > +{ > + return (mfloat8_t)(short)0x1234; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > +} > + > +mfloat8_t > +footest (mfloat8_t scalar0) > +{ > + > + /* Initialisation */ > + > + mfloat8_t scalar1_1; > + mfloat8_t scalar1_2 = glob_fp8; > + mfloat8_t scalar1_3 > + = 0; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar1_4 > + = 0.1; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar1_5 > + = is_a_float; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + mfloat8_t scalar1_6 > + = is_an_int; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + mfloat8_t scalar1_8 > + = is_a_double; /* { dg-error {invalid conversion to type 'mfloat8_t'} > } */ > + mfloat8_t scalar1_9 = is_a_short_int; /* { dg-error {invalid conversion to > type 'mfloat8_t'} } */ > + mfloat8_t scalar1_10 > + = is_a_uint8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + mfloat8_t scalar1_11 > + = is_an_int8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + > + int initi_1_1 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + float initi_1_2 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + short initi_1_4 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + double initi_1_5 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + uint8_t initi_1_6 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + int8_t initi_1_7 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + > + mfloat8_t scalar2_1 = {}; > + mfloat8_t scalar2_2 = { glob_fp8 }; > + mfloat8_t scalar2_3 > + = { 0 }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar2_4 > + = { 0.1 }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar2_5 = { > + is_a_float /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + mfloat8_t scalar2_6 = { > + is_an_int /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + mfloat8_t scalar2_8 = { > + is_a_double /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + mfloat8_t scalar2_9 = { > + is_a_short_int /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + }; > + mfloat8_t scalar2_10 = { > + is_a_uint8 /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + mfloat8_t scalar2_11 = { > + is_an_int8 /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + > + int initi_2_1 = { > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + float initi_2_2 = { > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + short initi_2_4 = { > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + double initi_2_5 = { > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + uint8_t initi_2_6 = { > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + int8_t initi_2_7 = { > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + > + /* Assignments. */ > + > + glob_fp8 = glob_fp8; > + glob_fp8 = 0; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + glob_fp8 = 0.1; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + glob_fp8 > + = is_a_float; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + glob_fp8 > + = is_an_int; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + glob_fp8 > + = is_a_double; /* { dg-error {invalid conversion to type 'mfloat8_t'} > } */ > + glob_fp8 = is_a_short_int; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + glob_fp8 > + = is_a_uint8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + glob_fp8 > + = is_an_int8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + > + is_an_int > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_a_float > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_a_double > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_a_short_int > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_a_uint8 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_an_int8 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + > + /* Casting. */ > + > + (void)glob_fp8; > + (mfloat8_t) glob_fp8; > + > + (int)glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + (float)glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + (double) > + glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + (short)glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + (uint8_t) > + glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + (int8_t) > + glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + > + (mfloat8_t) > + is_an_int; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + (mfloat8_t) > + is_a_float; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + (mfloat8_t) > + is_a_double; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + (mfloat8_t) is_a_short_int; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + (mfloat8_t) > + is_a_uint8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + (mfloat8_t) > + is_an_int8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + > + /* Compound literals. */ > + > + (mfloat8_t){}; > + (mfloat8_t){ glob_fp8 }; > + (mfloat8_t){ 0 }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + (mfloat8_t){ > + 0.1 /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + (mfloat8_t){ > + is_a_float /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + (mfloat8_t){ > + is_an_int /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + (mfloat8_t){ > + is_a_double /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + (mfloat8_t){ > + is_a_short_int /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + }; > + (mfloat8_t){ > + is_a_uint8 /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + (mfloat8_t){ > + is_an_int8 /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + }; > + > + (int){ > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + (float){ > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + (double){ > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + (short){ > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + (uint8_t){ > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + (int8_t){ > + glob_fp8 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + }; > + > + /* Arrays and Structs. */ > + > + typedef mfloat8_t array_type[2]; > + extern mfloat8_t extern_array[]; > + > + mfloat8_t array[2]; > + mfloat8_t zero_length_array[0]; > + mfloat8_t empty_init_array[] = {}; > + typedef mfloat8_t some_other_type[is_an_int]; > + > + struct struct1 > + { > + mfloat8_t a; > + }; > + > + union union1 > + { > + mfloat8_t a; > + }; > + > + /* Addressing and dereferencing. */ > + > + mfloat8_t *fp8_ptr = &scalar0; > + scalar0 = *fp8_ptr; > + > + /* Pointer assignment. */ > + > + mfloat8_t *fp8_ptr2 = fp8_ptr; > + mfloat8_t *fp8_ptr3 = array; > + > + /* Pointer arithmetic. */ > + > + ++fp8_ptr; > + --fp8_ptr; > + fp8_ptr++; > + fp8_ptr--; > + fp8_ptr += 1; > + fp8_ptr -= 1; > + fp8_ptr - fp8_ptr2; > + fp8_ptr = &fp8_ptr3[0]; > + fp8_ptr = &fp8_ptr3[1]; > + > + /* Simple comparison. */ > + scalar0 > + > glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + glob_fp8 > + == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + scalar0 > is_a_float; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + is_a_float > + == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + scalar0 > 0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + 0 == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + scalar0 > 0.1; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + 0.1 == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + scalar0 > + > is_an_int; /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + is_an_int > + == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + > + /* Pointer comparison. */ > + > + fp8_ptr == &scalar0; > + fp8_ptr != &scalar0; > + fp8_ptr < &scalar0; > + fp8_ptr <= &scalar0; > + fp8_ptr > &scalar0; > + fp8_ptr >= &scalar0; > + fp8_ptr == fp8_ptr2; > + fp8_ptr != fp8_ptr2; > + fp8_ptr < fp8_ptr2; > + fp8_ptr <= fp8_ptr2; > + fp8_ptr > fp8_ptr2; > + fp8_ptr >= fp8_ptr2; > + > + /* Conditional expressions. */ > + > + 0 ? scalar0 : scalar0; > + 0 ? scalar0 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + : is_a_float; > + 0 ? is_a_float > + : scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + 0 ? scalar0 : 0; /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + 0 ? 0 : scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + 0 ? 0.1 > + : scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + 0 ? scalar0 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + : 0.1; > + 0 ? fp8_ptr : fp8_ptr2; > + 0 ? fp8_ptr : uint8_ptr; /* { dg-error {conditional expression between > distinct pointer types} } */ > + 0 ? uint8_ptr : fp8_ptr; /* { dg-error {conditional expression between > distinct pointer types} } */ > + > + scalar0 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + ? scalar0 > + : scalar0; > + scalar0 /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + ? is_a_float > + : scalar0; > + scalar0 ? scalar0 : is_a_float; /* { dg-error {invalid conversion from > type 'mfloat8_t'} } */ > + scalar0 ? is_a_float : is_a_float; /* { dg-error {invalid conversion from > type 'mfloat8_t'} } */ > + > + /* Unary operators. */ > + > + +scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + -scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + ~scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + !scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + *scalar0; /* { dg-error {invalid type argument of unary} } */ > + __real scalar0; /* { dg-error {operation not permitted on type > 'mfloat8_t'} } */ > + __imag scalar0; /* { dg-error {operation not permitted on type > 'mfloat8_t'} } */ > + ++scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + --scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + scalar0++; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + scalar0--; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + > + /* Binary arithmetic operations. */ > + > + scalar0 = glob_fp8 + scalar1_2; /* { dg-error {invalid conversion from > type 'mfloat8_t'} } */ > + scalar0 = glob_fp8 + *fp8_ptr; /* { dg-error {invalid conversion from > type 'mfloat8_t'} } */ > + scalar0 = glob_fp8 > + + 0.1; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + scalar0 = glob_fp8 > + + 0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + scalar0 = glob_fp8 + is_a_float; /* { dg-error {invalid conversion from > type 'mfloat8_t'} } */ > + > + glob_fp8 + glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 - glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 * glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 / glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 && glob_fp8; /* { dg-error {operation not permitted on type > 'mfloat8_t'} } */ > + glob_fp8 || glob_fp8; /* { dg-error {operation not permitted on type > 'mfloat8_t'} } */ > + > + return scalar0; > +} > + > +/* Check that function decls for mfloat8_t and unsigned char differ */ > + > +mfloat8_t extern_fn1(void); > +unsigned char extern_fn1(void); /* { dg-error {ambiguating new declaration > of 'unsigned char extern_fn1\(\)'} } */ > + > +mfloat8_t extern_fn2(void); > +uint8_t extern_fn2(void); /* { dg-error {ambiguating new declaration of > 'uint8_t extern_fn2\(\)} } */ > + > +unsigned char extern_fn3(void); > +mfloat8_t extern_fn3(void); /* { dg-error {ambiguating new declaration of > 'mfloat8_t extern_fn3\(\)} } */ > + > +uint8_t extern_fn4(void); > +mfloat8_t extern_fn4(void); /* { dg-error {ambiguating new declaration of > 'mfloat8_t extern_fn4\(\)} } */ > + > +/* Check that the type conforms to the contract */ > +static_assert(!std::is_integral<__mfp8>(), "not integral"); > +static_assert(!std::is_signed<__mfp8>(), "not signed"); > +static_assert(!std::is_unsigned<__mfp8>(), "not unsigned"); > diff --git a/gcc/testsuite/gcc.target/aarch64/fp8_scalar_1.c > b/gcc/testsuite/gcc.target/aarch64/fp8_scalar_1.c > new file mode 100644 > index 00000000000..1bc2ac26b2a > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/fp8_scalar_1.c > @@ -0,0 +1,134 @@ > +/* Test the fp8 ACLE intrinsics family. */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -march=armv9.4-a+fp8" } */ > +/* { dg-final { check-function-bodies "**" "" "" } } */ > + > +#include <arm_neon.h> > + > +/* > +**stacktest1: > +** sub sp, sp, #16 > +** and w0, w0, 255 > +** strb w0, \[sp, 15\] > +** ldrb w0, \[sp, 15\] > +** add sp, sp, 16 > +** ret > +*/ > +mfloat8_t > +stacktest1 (mfloat8_t __a) > +{ > + volatile mfloat8_t b = __a; > + return b; > +} > + > +/* > +**fp8_mov_ww: > +** dup b1, v2.b\[0\] > +** ret > +*/ > +void > +fp8_mov_ww (void) > +{ > + register mfloat8_t x asm ("h2"); > + register mfloat8_t y asm ("h1"); > + asm volatile ("" : "=w"(x)); > + y = x; > + asm volatile ("" ::"w"(y)); > +} > + > +/* > +**fp8_mov_rw: > +** dup v1.8b, w1 > +** ret > +*/ > +void > +fp8_mov_rw (void) > +{ > + register mfloat8_t x asm ("w1"); > + register mfloat8_t y asm ("h1"); > + asm volatile ("" : "=r"(x)); > + y = x; > + asm volatile ("" ::"w"(y)); > +} > + > +/* > +**fp8_mov_wr: > +** umov w1, v1.b\[0\] > +** ret > +*/ > +void > +fp8_mov_wr (void) > +{ > + register mfloat8_t x asm ("h1"); > + register mfloat8_t y asm ("w1"); > + asm volatile ("" : "=w"(x)); > + y = x; > + asm volatile ("" ::"r"(y)); > +} > + > +/* > +**fp8_mov_rr: > +** mov w1, w2 > +** ret > +*/ > +void > +fp8_mov_rr (void) > +{ > + register mfloat8_t x asm ("w2"); > + register mfloat8_t y asm ("w1"); > + asm volatile ("" : "=r"(x)); > + y = x; > + asm volatile ("" ::"r"(y)); > +} > + > +/* > +**fp8_mov_rm: > +** strb w2, \[x0\] > +** ret > +*/ > +void > +fp8_mov_rm (mfloat8_t *ptr) > +{ > + register mfloat8_t x asm ("w2"); > + asm volatile ("" : "=r"(x)); > + *ptr = x; > +} > + > +/* > +**fp8_mov_mr: > +** ldrb w2, \[x0\] > +** ret > +*/ > +void > +fp8_mov_mr (mfloat8_t *ptr) > +{ > + register mfloat8_t y asm ("w2"); > + y = *ptr; > + asm volatile ("" ::"r"(y)); > +} > + > +/* > +**fp8_str_r: > +** str b2, \[x0\] > +** ret > +*/ > +void > +fp8_str_r (mfloat8_t *ptr) > +{ > + register mfloat8_t x asm ("v2"); > + asm volatile ("" : "=w"(x)); > + *ptr = x; > +} > + > +/* > +**fp8_ldr_r: > +** ldr b2, \[x0\] > +** ret > +*/ > +void > +fp8_ldr_r (mfloat8_t *ptr) > +{ > + register mfloat8_t y asm ("v2"); > + y = *ptr; > + asm volatile ("" ::"w"(y)); > +} > diff --git a/gcc/testsuite/gcc.target/aarch64/fp8_scalar_typecheck_1.c > b/gcc/testsuite/gcc.target/aarch64/fp8_scalar_typecheck_1.c > new file mode 100644 > index 00000000000..9169f40c4b7 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/fp8_scalar_typecheck_1.c > @@ -0,0 +1,356 @@ > +/* Test that there is no conversion between ints and mfloat8_t. */ > +/* { dg-do assemble } */ > +/* { dg-options "-O1 -march=armv9.4-a+fp8" } */ > + > +#include <arm_neon.h> > +#include <stdint.h> > + > +mfloat8_t glob_fp8; > + > +int is_an_int; > +uint8_t is_a_uint8; > +int8_t is_an_int8; > +short is_a_short_int; > +float is_a_float; > +double is_a_double; > + > +uint8_t *uint8_ptr; > + > +mfloat8_t > +invalid_from_fp8 (uint16_t __a) > +{ > + mfloat8_t b = __a; // { dg-error "invalid conversion to type 'mfloat8_t'" } > + return b; > +} > + > +uint16_t > +invalid_to_fp8 (mfloat8_t __a) > +{ > + uint16_t b = __a; // { dg-error "invalid conversion from type 'mfloat8_t'" > } > + return b; > +} > + > +mfloat8_t > +foo1 (void) > +{ > + return (mfloat8_t)0x1234; // { dg-error {invalid conversion to type > 'mfloat8_t'} } > +} > +mfloat8_t > +foo2 (void) > +{ > + return (mfloat8_t)(short)0x1234; // { dg-error {invalid conversion to type > 'mfloat8_t'} } > +} > + > +mfloat8_t > +footest (mfloat8_t scalar0) > +{ > + > + /* Initialisation */ > + > + mfloat8_t scalar1_1; > + mfloat8_t scalar1_2 = glob_fp8; > + mfloat8_t scalar1_3 = 0; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + mfloat8_t scalar1_4 > + = 0.1; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar1_5 > + = is_a_float; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + mfloat8_t scalar1_6 > + = is_an_int; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + mfloat8_t scalar1_8 > + = is_a_double; /* { dg-error {invalid conversion to type 'mfloat8_t'} > } */ > + mfloat8_t scalar1_9 > + = is_a_short_int; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + mfloat8_t scalar1_10 > + = is_a_uint8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + mfloat8_t scalar1_11 > + = is_an_int8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + > + int initi_1_1 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + float initi_1_2 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + short initi_1_4 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + double initi_1_5 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + uint8_t initi_1_6 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + int8_t initi_1_7 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + > + mfloat8_t scalar2_1 = {}; > + mfloat8_t scalar2_2 = { glob_fp8 }; > + mfloat8_t scalar2_3 > + = { 0 }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar2_4 > + = { 0.1 }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar2_5 > + = { is_a_float }; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + mfloat8_t scalar2_6 > + = { is_an_int }; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + mfloat8_t scalar2_8 = { > + is_a_double > + }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar2_9 = { > + is_a_short_int > + }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + mfloat8_t scalar2_10 > + = { is_a_uint8 }; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + mfloat8_t scalar2_11 > + = { is_an_int8 }; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + > + int initi_2_1 > + = { glob_fp8 }; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + float initi_2_2 > + = { glob_fp8 }; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + short initi_2_4 > + = { glob_fp8 }; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + double initi_2_5 > + = { glob_fp8 }; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + uint8_t initi_2_6 > + = { glob_fp8 }; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + int8_t initi_2_7 > + = { glob_fp8 }; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + > + /* Assignments. */ > + > + glob_fp8 = glob_fp8; > + glob_fp8 = 0; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + glob_fp8 = 0.1; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + glob_fp8 > + = is_a_float; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + glob_fp8 = is_an_int; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + glob_fp8 > + = is_a_double; /* { dg-error {invalid conversion to type 'mfloat8_t'} > } */ > + glob_fp8 > + = is_a_short_int; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + glob_fp8 > + = is_a_uint8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + glob_fp8 > + = is_an_int8; /* { dg-error {invalid conversion to type 'mfloat8_t'} } > */ > + > + is_an_int > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_a_float > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_a_double > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_a_short_int > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_a_uint8 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + is_an_int8 > + = glob_fp8; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + > + /* Casting. */ > + > + (void)glob_fp8; > + (mfloat8_t) glob_fp8; > + > + (int)glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + (float)glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + (double)glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + (short)glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + (uint8_t)glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + (int8_t)glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + > + (mfloat8_t) is_an_int; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + (mfloat8_t) is_a_float; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + (mfloat8_t) is_a_double; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + (mfloat8_t) > + is_a_short_int; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + (mfloat8_t) is_a_uint8; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + (mfloat8_t) is_an_int8; /* { dg-error {invalid conversion to type > 'mfloat8_t'} } */ > + > + /* Compound literals. */ > + > + (mfloat8_t){}; > + (mfloat8_t){ glob_fp8 }; > + (mfloat8_t){ 0 }; /* { dg-error {invalid conversion to type 'mfloat8_t'} > } */ > + (mfloat8_t){ 0.1 }; /* { dg-error {invalid conversion to type 'mfloat8_t'} > } */ > + (mfloat8_t){ > + is_a_float > + }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + (mfloat8_t){ > + is_an_int > + }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + (mfloat8_t){ > + is_a_double > + }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + (mfloat8_t){ > + is_a_short_int > + }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + (mfloat8_t){ > + is_a_uint8 > + }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + (mfloat8_t){ > + is_an_int8 > + }; /* { dg-error {invalid conversion to type 'mfloat8_t'} } */ > + > + (int){ glob_fp8 }; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + (float){ > + glob_fp8 > + }; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + (double){ > + glob_fp8 > + }; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + (short){ > + glob_fp8 > + }; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + (uint8_t){ > + glob_fp8 > + }; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + (int8_t){ > + glob_fp8 > + }; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + > + /* Arrays and Structs. */ > + > + typedef mfloat8_t array_type[2]; > + extern mfloat8_t extern_array[]; > + > + mfloat8_t array[2]; > + mfloat8_t zero_length_array[0]; > + mfloat8_t empty_init_array[] = {}; > + typedef mfloat8_t some_other_type[is_an_int]; > + > + struct struct1 > + { > + mfloat8_t a; > + }; > + > + union union1 > + { > + mfloat8_t a; > + }; > + > + /* Addressing and dereferencing. */ > + > + mfloat8_t *fp8_ptr = &scalar0; > + scalar0 = *fp8_ptr; > + > + /* Pointer assignment. */ > + > + mfloat8_t *fp8_ptr2 = fp8_ptr; > + mfloat8_t *fp8_ptr3 = array; > + > + /* Pointer arithmetic. */ > + > + ++fp8_ptr; > + --fp8_ptr; > + fp8_ptr++; > + fp8_ptr--; > + fp8_ptr += 1; > + fp8_ptr -= 1; > + fp8_ptr - fp8_ptr2; > + fp8_ptr = &fp8_ptr3[0]; > + fp8_ptr = &fp8_ptr3[1]; > + > + /* Simple comparison. */ > + scalar0 > glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 > + == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + scalar0 > is_a_float; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + is_a_float > + == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + scalar0 > 0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + 0 == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + scalar0 > 0.1; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + 0.1 == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + scalar0 > + > is_an_int; /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + is_an_int > + == scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + > + /* Pointer comparison. */ > + > + fp8_ptr == &scalar0; > + fp8_ptr != &scalar0; > + fp8_ptr < &scalar0; > + fp8_ptr <= &scalar0; > + fp8_ptr > &scalar0; > + fp8_ptr >= &scalar0; > + fp8_ptr == fp8_ptr2; > + fp8_ptr != fp8_ptr2; > + fp8_ptr < fp8_ptr2; > + fp8_ptr <= fp8_ptr2; > + fp8_ptr > fp8_ptr2; > + fp8_ptr >= fp8_ptr2; > + > + /* Conditional expressions. */ > + > + 0 ? scalar0 : scalar0; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + 0 ? scalar0 > + : is_a_float; /* { dg-error {invalid conversion from type 'mfloat8_t'} } > */ > + 0 ? is_a_float > + : scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + 0 ? scalar0 : 0; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + 0 ? 0 : scalar0; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + 0 ? 0.1 : scalar0; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + 0 ? scalar0 : 0.1; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + 0 ? fp8_ptr : fp8_ptr2; > + 0 ? fp8_ptr : uint8_ptr; /* { dg-error {pointer type mismatch in > conditional expression} } */ > + 0 ? uint8_ptr : fp8_ptr; /* { dg-error {pointer type mismatch in > conditional expression} } */ > + > + scalar0 ? scalar0 /* { dg-error {invalid conversion from type 'mfloat8_t'} > } */ > + : scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + scalar0 ? is_a_float /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + : scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + scalar0 ? scalar0 : is_a_float; /* { dg-error {invalid conversion from > type 'mfloat8_t'} } */ > + scalar0 ? is_a_float : is_a_float; /* { dg-error {invalid conversion from > type 'mfloat8_t'} } */ > + > + /* Unary operators. */ > + > + +scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + -scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + ~scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + !scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } */ > + *scalar0; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + __real scalar0; /* { dg-error {operation not permitted on type > 'mfloat8_t'} } */ > + __imag scalar0; /* { dg-error {operation not permitted on type > 'mfloat8_t'} } */ > + ++scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } > */ > + --scalar0; /* { dg-error {operation not permitted on type 'mfloat8_t'} } > */ > + scalar0++; /* { dg-error {operation not permitted on type 'mfloat8_t'} } > */ > + scalar0--; /* { dg-error {operation not permitted on type 'mfloat8_t'} } > */ > + > + /* Binary arithmetic operations. */ > + > + scalar0 = glob_fp8 + scalar1_2; /* { dg-error {invalid conversion from > type 'mfloat8_t'} } */ > + scalar0 = glob_fp8 + *fp8_ptr; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + scalar0 = glob_fp8 > + + 0.1; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + scalar0 > + = glob_fp8 + 0; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + scalar0 > + = glob_fp8 > + + is_a_float; /* { dg-error {invalid conversion from type 'mfloat8_t'} } */ > + > + glob_fp8 + glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 - glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 * glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 / glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 && glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + glob_fp8 || glob_fp8; /* { dg-error {invalid conversion from type > 'mfloat8_t'} } */ > + > + return scalar0; > +} > + > +/* Check that function decls for mfloat8_t and unsigned char differ */ > + > +mfloat8_t extern_fn1(void); > +unsigned char extern_fn1(void); /* { dg-error {conflicting types for > 'extern_fn1'; have 'unsigned char\(void\)'} } */ > + > +mfloat8_t extern_fn2(void); > +uint8_t extern_fn2(void); /* { dg-error {conflicting types for 'extern_fn2'; > have 'uint8_t\(void\)'} } */ > + > +unsigned char extern_fn3(void); > +mfloat8_t extern_fn3(void); /* { dg-error {conflicting types for > 'extern_fn3'; have 'mfloat8_t\(void\)'} } */ > + > +uint8_t extern_fn4(void); > +mfloat8_t extern_fn4(void); /* { dg-error {conflicting types for > 'extern_fn4'; have 'mfloat8_t\(void\)'} } */ > + > +void extern_fn5(mfloat8_t); > +void extern_fn5(unsigned char); /* { dg-error {conflicting types for > 'extern_fn5'; have 'void\(unsigned char\)'} } */ > + > +void extern_fn6(mfloat8_t); > +void extern_fn6(uint8_t); /* { dg-error {conflicting types for 'extern_fn6'; > have 'void\(uint8_t\)'} } */