aarch64: Add support for _BitInt

This patch adds support for C23's _BitInt for the AArch64 port when compiling
for little endianness.  Big Endianness requires further target-agnostic
support and we therefor disable it for now.

gcc/ChangeLog:

	* config/aarch64/aarch64.cc (TARGET_C_BITINT_TYPE_INFO): Declare MACRO.
	(aarch64_bitint_type_info): New function.
	(aarch64_return_in_memory_1): Return large _BitInt's in memory.
	(aarch64_function_arg_alignment): Adapt to correctly return the ABI
	mandated alignment of _BitInt(N) where N > 128 as the alignment of
	TImode.
	(aarch64_composite_type_p): Return true for _BitInt(N), where N > 128.

libgcc/ChangeLog:

	* config/aarch64/t-softfp (softfp_extras): Add floatbitinthf,
	floatbitintbf, floatbitinttf and fixtfbitint.
	* config/aarch64/libgcc-softfp.ver (GCC_14.0.0): Add __floatbitinthf,
	__floatbitintbf, __floatbitinttf and __fixtfbitint.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/bitint-alignments.c: New test.
	* gcc.target/aarch64/bitint-args.c: New test.
	* gcc.target/aarch64/bitint-sizes.c: New test.
	* gcc.target/aarch64/bitfield-bitint-abi.h: New header.
	* gcc.target/aarch64/bitfield-bitint-abi-align16.c: New test.
	* gcc.target/aarch64/bitfield-bitint-abi-align8.c: New test.
This commit is contained in:
Andre Vieira 2024-04-10 16:29:46 +01:00
parent 3a787e038f
commit 5aa3fec38c
9 changed files with 1149 additions and 1 deletions

View File

@ -6583,6 +6583,7 @@ aarch64_return_in_memory_1 (const_tree type)
int count;
if (!AGGREGATE_TYPE_P (type)
&& TREE_CODE (type) != BITINT_TYPE
&& TREE_CODE (type) != COMPLEX_TYPE
&& TREE_CODE (type) != VECTOR_TYPE)
/* Simple scalar types always returned in registers. */
@ -21995,6 +21996,11 @@ aarch64_composite_type_p (const_tree type,
if (type && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == COMPLEX_TYPE))
return true;
if (type
&& TREE_CODE (type) == BITINT_TYPE
&& int_size_in_bytes (type) > 16)
return true;
if (mode == BLKmode
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
@ -28476,6 +28482,42 @@ aarch64_excess_precision (enum excess_precision_type type)
return FLT_EVAL_METHOD_UNPREDICTABLE;
}
/* Implement TARGET_C_BITINT_TYPE_INFO.
Return true if _BitInt(N) is supported and fill its details into *INFO. */
bool
aarch64_bitint_type_info (int n, struct bitint_info *info)
{
if (TARGET_BIG_END)
return false;
if (n <= 8)
info->limb_mode = QImode;
else if (n <= 16)
info->limb_mode = HImode;
else if (n <= 32)
info->limb_mode = SImode;
else if (n <= 64)
info->limb_mode = DImode;
else if (n <= 128)
info->limb_mode = TImode;
else
/* The AAPCS for AArch64 defines _BitInt(N > 128) as an array with
type {signed,unsigned} __int128[M] where M*128 >= N. However, to be
able to use libgcc's implementation to support large _BitInt's we need
to use a LIMB_MODE that is no larger than 'long long'. This is why we
use DImode for our internal LIMB_MODE and we define the ABI_LIMB_MODE to
be TImode to ensure we are ABI compliant. */
info->limb_mode = DImode;
if (n > 128)
info->abi_limb_mode = TImode;
else
info->abi_limb_mode = info->limb_mode;
info->big_endian = TARGET_BIG_END;
info->extended = false;
return true;
}
/* Implement TARGET_SCHED_CAN_SPECULATE_INSN. Return true if INSN can be
scheduled for speculative execution. Reject the long-running division
and square-root instructions. */
@ -30600,6 +30642,9 @@ aarch64_run_selftests (void)
#undef TARGET_C_EXCESS_PRECISION
#define TARGET_C_EXCESS_PRECISION aarch64_excess_precision
#undef TARGET_C_BITINT_TYPE_INFO
#define TARGET_C_BITINT_TYPE_INFO aarch64_bitint_type_info
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN aarch64_expand_builtin

View File

@ -0,0 +1,384 @@
/* { dg-do compile { target bitint } } */
/* { dg-additional-options "-std=c23 -O2 -fno-stack-protector -save-temps -fno-schedule-insns -fno-schedule-insns2" } */
/* { dg-final { check-function-bodies "**" "" "" } } */
#define ALIGN 16
#include "bitfield-bitint-abi.h"
// f1-f16 are all the same
/*
** f1:
** and x0, x2, 1
** ret
*/
/*
** f8:
** and x0, x2, 1
** ret
*/
/*
** f16:
** and x0, x2, 1
** ret
*/
/* fp seems to be unable to optimize away stack-usage, TODO: to fix. */
/*
** fp:
**...
** and x0, x1, 1
**...
** ret
*/
// all other f1p-f8p generate the same code, for f16p the value comes from x2
/*
** f1p:
** and x0, x1, 1
** ret
*/
/*
** f8p:
** and x0, x1, 1
** ret
*/
/*
** f16p:
** and x0, x2, 1
** ret
*/
// g1-g16 are all the same
/*
** g1:
** mov (x[0-9]+), x0
** mov w0, w1
** sbfx (x[0-9]+), \1, 0, 63
** and x4, \2, 9223372036854775807
** and x2, \2, 1
** mov x3, 0
** b f1
*/
/*
** g8:
** mov (x[0-9]+), x0
** mov w0, w1
** sbfx (x[0-9]+), \1, 0, 63
** and x4, \2, 9223372036854775807
** and x2, \2, 1
** mov x3, 0
** b f8
*/
/*
** g16:
** mov (x[0-9]+), x0
** mov w0, w1
** sbfx (x[0-9]+), \1, 0, 63
** and x4, \2, 9223372036854775807
** and x2, \2, 1
** mov x3, 0
** b f16
*/
// again gp different from the rest
/*
** gp:
** sub sp, sp, #16
** mov (x[0-9]+), x0
** mov w0, w1
** sbfx x([0-9]+), \1, 0, 63
** mov (w[0-9]+), 0
** bfi \3, w\2, 0, 1
** and x3, x\2, 9223372036854775807
** mov x2, 0
** str xzr, \[sp\]
** strb \3, \[sp\]
** ldr x1, \[sp\]
** add sp, sp, 16
** b fp
*/
// g1p-g8p are all the same, g16p uses x2 to pass parameter to f16p
/*
** g1p:
** mov (w[0-9]+), w1
** sbfx (x[0-9]+), x0, 0, 63
** and x3, \2, 9223372036854775807
** and x1, \2, 1
** mov x2, 0
** mov w0, \1
** b f1p
*/
/*
** g8p:
** mov (w[0-9]+), w1
** sbfx (x[0-9]+), x0, 0, 63
** and x3, \2, 9223372036854775807
** and x1, \2, 1
** mov x2, 0
** mov w0, \1
** b f8p
*/
/*
** g16p:
** mov (x[0-9]+), x0
** mov w0, w1
** sbfx (x[0-9]+), \1, 0, 63
** and x4, \2, 9223372036854775807
** and x2, \2, 1
** mov x3, 0
** b f16p
*/
// f*_stack are all the same
/*
** f1_stack:
** ldr (x[0-9]+), \[sp, 16\]
** and x0, \1, 1
** ret
*/
/*
** f8_stack:
** ldr (x[0-9]+), \[sp, 16\]
** and x0, \1, 1
** ret
*/
/*
** f16_stack:
** ldr (x[0-9]+), \[sp, 16\]
** and x0, \1, 1
** ret
*/
// fp{,1,8}_stack are all the same but fp16_stack loads from sp+16
/*
** fp_stack:
** ldr (x[0-9]+), \[sp, 8\]
** and x0, \1, 1
** ret
*/
/*
** f1p_stack:
** ldr (x[0-9]+), \[sp, 8\]
** and x0, \1, 1
** ret
*/
/*
** f8p_stack:
** ldr (x[0-9]+), \[sp, 8\]
** and x0, \1, 1
** ret
*/
/*
** f16p_stack:
** ldr (x[0-9]+), \[sp, 16\]
** and x0, \1, 1
** ret
*/
/*
** gp_stack:
**...
** mov x([0-9]+), x0
** sxtw (x[0-9]+), w1
** mov x0, \2
** and x7, \2, 9223372036854775807
** mov (w[0-9]+), 0
** bfi \3, w\1, 0, 1
** strb wzr, \[sp, 16\]
** mov x6, x7
** mov x5, x7
** mov x4, x7
** mov x3, x7
** mov x2, x7
** str xzr, \[sp, 48\]
** strb \3, \[sp, 48\]
** ldr (x[0-9]+), \[sp, 48\]
** stp x7, \4, \[sp\]
** mov x1, x7
** bl fp_stack
** sbfx x0, x0, 0, 63
**...
** ret
*/
/*
** g1_stack:
**...
** mov (x[0-9]+), x0
** sxtw (x[0-9]+), w1
** mov x0, \2
** and x7, \2, 9223372036854775807
** mov (x[0-9]+), 0
** sbfx (x[0-9]+), \1, 0, 63
** bfi \3, \4, 0, 1
** stp \3, xzr, \[sp, 16\]
** mov x6, x7
** mov x5, x7
** mov x4, x7
** mov x3, x7
** mov x2, x7
** mov x1, x7
** str x7, \[sp\]
** bl f1_stack
** sbfx x0, x0, 0, 63
**...
** ret
*/
/*
** g8_stack:
**...
** mov (x[0-9]+), x0
** sxtw (x[0-9]+), w1
** mov x0, \2
** and x7, \2, 9223372036854775807
** mov (x[0-9]+), 0
** sbfx (x[0-9]+), \1, 0, 63
** bfi \3, \4, 0, 1
** stp \3, xzr, \[sp, 16\]
** mov x6, x7
** mov x5, x7
** mov x4, x7
** mov x3, x7
** mov x2, x7
** mov x1, x7
** str x7, \[sp\]
** bl f8_stack
** sbfx x0, x0, 0, 63
**...
** ret
*/
/*
** g16_stack:
**...
** mov (x[0-9]+), x0
** sxtw (x[0-9]+), w1
** mov x0, \2
** and (x[0-9]+), \2, 9223372036854775807
** mov (x[0-9]+), 0
** sbfx (x[0-9]+), \1, 0, 63
** bfi \4, \5, 0, 1
** stp \4, xzr, \[sp, 16\]
** mov x6, \3
** mov x5, \3
** mov x4, \3
** mov x3, \3
** mov x2, \3
** mov x1, \3
** str x7, \[sp\]
** bl f16_stack
** sbfx x0, x0, 0, 63
**...
** ret
*/
/*
** f1_stdarg:
**...
** and x0, x2, 1
**...
** ret
*/
/*
** f16_stdarg:
**...
** and x0, x2, 1
**...
** ret
*/
/*
** fp_stdarg:
**...
** and x0, x1, 1
**...
** ret
*/
/*
** f1p_stdarg:
**...
** and x0, x1, 1
**...
** ret
*/
/*
** f8p_stdarg:
**...
** and x0, x1, 1
**...
** ret
*/
/*
** f16p_stdarg:
**...
** and x0, x2, 1
**...
** ret
*/
/*
** g1_stdarg:
** and x2, x0, 1
** mov x3, 0
** mov w0, w1
** b f1_stdarg
*/
/*
** g16_stdarg:
** and x2, x0, 1
** mov x3, 0
** mov w0, w1
** b f16_stdarg
*/
/*
** gp_stdarg:
**...
** mov x([0-9]+), x0
** mov w0, w1
** mov (w[0-9]+), 0
** bfi \2, w\1, 0, 1
** mov x2, 0
** str xzr, \[sp\]
** strb \2, \[sp\]
** ldr x1, \[sp\]
**...
** b fp_stdarg
*/
/*
** g1p_stdarg:
** mov (x[0-9]+), x0
** mov w0, w1
** and x1, \1, 1
** mov x2, 0
** b f1p_stdarg
*/
/*
** g8p_stdarg:
** mov (x[0-9]+), x0
** mov w0, w1
** and x1, \1, 1
** mov x2, 0
** b f8p_stdarg
*/
/*
** g16p_stdarg:
** and x2, x0, 1
** mov x3, 0
** mov w0, w1
** b f16p_stdarg
*/

View File

@ -0,0 +1,386 @@
/* { dg-do compile { target bitint } } */
/* { dg-additional-options "-std=c23 -O2 -fno-stack-protector -save-temps -fno-schedule-insns -fno-schedule-insns2" } */
/* { dg-final { check-function-bodies "**" "" "" } } */
#define ALIGN 8
#include "bitfield-bitint-abi.h"
// f1-f16 are all the same
/*
** f1:
** and x0, x1, 1
** ret
*/
/*
** f8:
** and x0, x1, 1
** ret
*/
/*
** f16:
** and x0, x2, 1
** ret
*/
/* fp seems to be unable to optimize away stack-usage, TODO: to fix. */
/*
** fp:
**...
** and x0, x1, 1
**...
** ret
*/
// all other f1p-f8p generate the same code, for f16p the value comes from x2
/*
** f1p:
** and x0, x1, 1
** ret
*/
/*
** f8p:
** and x0, x1, 1
** ret
*/
/*
** f16p:
** and x0, x2, 1
** ret
*/
// g1-g16 are all the same
/*
** g1:
** mov (w[0-9]+), w1
** sbfx (x[0-9]+), x0, 0, 63
** and x3, \2, 9223372036854775807
** and x1, \2, 1
** mov x2, 0
** mov w0, \1
** b f1
*/
/*
** g8:
** mov (w[0-9]+), w1
** sbfx (x[0-9]+), x0, 0, 63
** and x3, \2, 9223372036854775807
** and x1, \2, 1
** mov x2, 0
** mov w0, \1
** b f8
*/
/*
** g16:
** mov (x[0-9]+), x0
** mov w0, w1
** sbfx (x[0-9]+), \1, 0, 63
** and x4, \2, 9223372036854775807
** and x2, \2, 1
** mov x3, 0
** b f16
*/
// again gp different from the rest
/*
** gp:
** sub sp, sp, #16
** mov (x[0-9]+), x0
** mov w0, w1
** sbfx x([0-9]+), \1, 0, 63
** mov (w[0-9]+), 0
** bfi \3, w\2, 0, 1
** and x3, x\2, 9223372036854775807
** mov x2, 0
** str xzr, \[sp\]
** strb \3, \[sp\]
** ldr x1, \[sp\]
** add sp, sp, 16
** b fp
*/
// g1p-g8p are all the same, g16p uses x2 to pass parameter to f16p
/*
** g1p:
** mov (w[0-9]+), w1
** sbfx (x[0-9]+), x0, 0, 63
** and x3, \2, 9223372036854775807
** and x1, \2, 1
** mov x2, 0
** mov w0, \1
** b f1p
*/
/*
** g8p:
** mov (w[0-9]+), w1
** sbfx (x[0-9]+), x0, 0, 63
** and x3, \2, 9223372036854775807
** and x1, \2, 1
** mov x2, 0
** mov w0, \1
** b f8p
*/
/*
** g16p:
** mov (x[0-9]+), x0
** mov w0, w1
** sbfx (x[0-9]+), \1, 0, 63
** and x4, \2, 9223372036854775807
** and x2, \2, 1
** mov x3, 0
** b f16p
*/
// f*_stack are all the same
/*
** f1_stack:
** ldr (x[0-9]+), \[sp, 8\]
** and x0, \1, 1
** ret
*/
/*
** f8_stack:
** ldr (x[0-9]+), \[sp, 8\]
** and x0, \1, 1
** ret
*/
/*
** f16_stack:
** ldr (x[0-9]+), \[sp, 16\]
** and x0, \1, 1
** ret
*/
// fp{,1,8}_stack are all the same but fp16_stack loads from sp+16
/*
** fp_stack:
** ldr (x[0-9]+), \[sp, 8\]
** and x0, \1, 1
** ret
*/
/*
** f1p_stack:
** ldr (x[0-9]+), \[sp, 8\]
** and x0, \1, 1
** ret
*/
/*
** f8p_stack:
** ldr (x[0-9]+), \[sp, 8\]
** and x0, \1, 1
** ret
*/
/*
** f16p_stack:
** ldr (x[0-9]+), \[sp, 16\]
** and x0, \1, 1
** ret
*/
/*
** gp_stack:
**...
** mov x([0-9]+), x0
** sxtw (x[0-9]+), w1
** mov x0, \2
** and x7, \2, 9223372036854775807
** mov (w[0-9]+), 0
** bfi \3, w\1, 0, 1
** strb wzr, \[sp, 16\]
** mov x6, x7
** mov x5, x7
** mov x4, x7
** mov x3, x7
** mov x2, x7
** str xzr, \[sp, 48\]
** strb \3, \[sp, 48\]
** ldr (x[0-9]+), \[sp, 48\]
** stp x7, \4, \[sp\]
** mov x1, x7
** bl fp_stack
** sbfx x0, x0, 0, 63
**...
** ret
*/
/* g1 and g8 are the same. */
/*
** g1_stack:
**...
** mov (x[0-9]+), x0
** sxtw (x[0-9]+), w1
** mov x0, \2
** and x7, \2, 9223372036854775807
** mov (x[0-9]+), 0
** sbfx (x[0-9]+), \1, 0, 63
** bfi \3, \4, 0, 1
** stp x7, x1, \[sp\]
** mov x6, x7
** mov x5, x7
** mov x4, x7
** mov x3, x7
** mov x2, x7
** mov x1, x7
** str xzr, \[sp, 16\]
** bl f1_stack
** sbfx x0, x0, 0, 63
**...
** ret
*/
/*
** g8_stack:
**...
** mov (x[0-9]+), x0
** sxtw (x[0-9]+), w1
** mov x0, \2
** and x7, \2, 9223372036854775807
** mov (x[0-9]+), 0
** sbfx (x[0-9]+), \1, 0, 63
** bfi \3, \4, 0, 1
** stp x7, x1, \[sp\]
** mov x6, x7
** mov x5, x7
** mov x4, x7
** mov x3, x7
** mov x2, x7
** mov x1, x7
** str xzr, \[sp, 16\]
** bl f8_stack
** sbfx x0, x0, 0, 63
**...
** ret
*/
/*
** g16_stack:
**...
** mov (x[0-9]+), x0
** sxtw (x[0-9]+), w1
** mov x0, \2
** and x7, \2, 9223372036854775807
** mov (x[0-9]+), 0
** sbfx (x[0-9]+), \1, 0, 63
** bfi \3, \4, 0, 1
** stp \3, xzr, \[sp, 16\]
** mov x6, x7
** mov x5, x7
** mov x4, x7
** mov x3, x7
** mov x2, x7
** mov x1, x7
** str x7, \[sp\]
** bl f16_stack
** sbfx x0, x0, 0, 63
**...
** ret
*/
/*
** f1_stdarg:
**...
** and x0, x1, 1
**...
** ret
*/
/*
** f16_stdarg:
**...
** and x0, x2, 1
**...
** ret
*/
/*
** fp_stdarg:
**...
** and x0, x1, 1
**...
** ret
*/
/*
** f1p_stdarg:
**...
** and x0, x1, 1
**...
** ret
*/
/*
** f8p_stdarg:
**...
** and x0, x1, 1
**...
** ret
*/
/*
** f16p_stdarg:
**...
** and x0, x2, 1
**...
** ret
*/
/*
** g1_stdarg:
** mov (x[0-9]+), x0
** mov w0, w1
** and x1, \1, 1
** mov x2, 0
** b f1_stdarg
*/
/*
** g16_stdarg:
** and x2, x0, 1
** mov x3, 0
** mov w0, w1
** b f16_stdarg
*/
/*
** gp_stdarg:
**...
** mov x([0-9]+), x0
** mov w0, w1
** mov (w[0-9]+), 0
** bfi \2, w\1, 0, 1
** mov x2, 0
** str xzr, \[sp\]
** strb \2, \[sp\]
** ldr x1, \[sp\]
**...
** b fp_stdarg
*/
/*
** g1p_stdarg:
** mov (x[0-9]+), x0
** mov w0, w1
** and x1, \1, 1
** mov x2, 0
** b f1p_stdarg
*/
/*
** g8p_stdarg:
** mov (x[0-9]+), x0
** mov w0, w1
** and x1, \1, 1
** mov x2, 0
** b f8p_stdarg
*/
/*
** g16p_stdarg:
** and x2, x0, 1
** mov x3, 0
** mov w0, w1
** b f16p_stdarg
*/

View File

@ -0,0 +1,101 @@
#include <stdarg.h>
typedef unsigned _BitInt(63) BI __attribute__((aligned(ALIGN)));
#ifndef EXTRA
#define EXTRA unsigned long long x;
#endif
struct S1 { __attribute__((aligned(1))) BI i : 1; EXTRA };
struct S8 { __attribute__((aligned(8))) BI i : 1; EXTRA };
struct S16 { __attribute__((aligned(16))) BI i : 1; EXTRA };
struct Sp { BI i : 1; EXTRA }__attribute__((packed));
struct S1p { __attribute__((packed, aligned(1))) BI i : 1; EXTRA };
struct S8p { __attribute__((packed, aligned(8))) BI i : 1; EXTRA };
struct S16p { __attribute__((packed, aligned(16))) BI i : 1; EXTRA };
/* Bitfield in registers. */
#define PARAMS(xx) int a0, struct S##xx s, BI a1
/* Bitfield passed by the stack. */
#define PARAMS_STACK(xx) int a0, BI a1, BI a2, BI a3, BI a4, BI a5, BI a6, BI a7, BI a8, struct S##xx t
/* Bitfield passed via stdarg. */
#define PARAMS_STDARG(xx) int a0, ...
#define CODE(xx) \
return s.i;
#define CODE_STACK(xx) \
return t.i;
#define CODE_STDARG(xx) \
va_list ap; \
struct S##xx arg; \
__builtin_va_start(ap,a0); \
arg = __builtin_va_arg(ap, struct S##xx); \
return arg.i;
#define ARGS(xx) y, (struct S##xx) { x }, x
#define ARGS_STACK(xx) y, y, y, y, y, y, y, y, y, (struct S##xx) { x }
#define ARGS_STDARG(xx) y, (struct S##xx) { x }
/* Bitfield in registers. */
_BitInt(63) __attribute__ ((noipa)) f1 (PARAMS(1)) { CODE(1) }
_BitInt(63) __attribute__ ((noipa)) f8 (PARAMS(8)) { CODE(8) }
_BitInt(63) __attribute__ ((noipa)) f16(PARAMS(16)) { CODE(16) }
_BitInt(63) __attribute__ ((noipa)) fp (PARAMS(p)) { CODE(p) }
_BitInt(63) __attribute__ ((noipa)) f1p (PARAMS(1p)) { CODE(1p) }
_BitInt(63) __attribute__ ((noipa)) f8p (PARAMS(8p)) { CODE(8p) }
_BitInt(63) __attribute__ ((noipa)) f16p(PARAMS(16p)) { CODE(16p) }
_BitInt(63) g1 (_BitInt(63) x, int y) { return f1 (ARGS(1)); }
_BitInt(63) g8 (_BitInt(63) x, int y) { return f8 (ARGS(8)); }
_BitInt(63) g16(_BitInt(63) x, int y) { return f16 (ARGS(16)); }
_BitInt(63) gp (_BitInt(63) x, int y) { return fp (ARGS(p)); }
_BitInt(63) g1p (_BitInt(63) x, int y) { return f1p (ARGS(1p)); }
_BitInt(63) g8p (_BitInt(63) x, int y) { return f8p (ARGS(8p)); }
_BitInt(63) g16p(_BitInt(63) x, int y) { return f16p (ARGS(16p)); }
/* Bitfield in the stack. */
_BitInt(63) __attribute__ ((noipa)) f1_stack (PARAMS_STACK(1)) { CODE_STACK(1) }
_BitInt(63) __attribute__ ((noipa)) f8_stack (PARAMS_STACK(8)) { CODE_STACK(8) }
_BitInt(63) __attribute__ ((noipa)) f16_stack(PARAMS_STACK(16)) { CODE_STACK(16) }
_BitInt(63) __attribute__ ((noipa)) fp_stack (PARAMS_STACK(p)) { CODE_STACK(p) }
_BitInt(63) __attribute__ ((noipa)) f1p_stack (PARAMS_STACK(1p)) { CODE_STACK(1p) }
_BitInt(63) __attribute__ ((noipa)) f8p_stack (PARAMS_STACK(8p)) { CODE_STACK(8p) }
_BitInt(63) __attribute__ ((noipa)) f16p_stack(PARAMS_STACK(16p)) { CODE_STACK(16p) }
_BitInt(63) g1_stack (_BitInt(63) x, int y) { return f1_stack (ARGS_STACK(1)); }
_BitInt(63) g8_stack (_BitInt(63) x, int y) { return f8_stack (ARGS_STACK(8)); }
_BitInt(63) g16_stack(_BitInt(63) x, int y) { return f16_stack (ARGS_STACK(16)); }
_BitInt(63) gp_stack (_BitInt(63) x, int y) { return fp_stack (ARGS_STACK(p)); }
_BitInt(63) g1p_stack (_BitInt(63) x, int y) { return f1p_stack (ARGS_STACK(1p)); }
_BitInt(63) g8p_stack (_BitInt(63) x, int y) { return f8p_stack (ARGS_STACK(8p)); }
_BitInt(63) g16p_stack(_BitInt(63) x, int y) { return f16p_stack (ARGS_STACK(16p)); }
/* Bitfield via stdarg. */
_BitInt(63) __attribute__ ((noipa)) f1_stdarg (PARAMS_STDARG(1)) { CODE_STDARG(1) }
_BitInt(63) __attribute__ ((noipa)) f8_stdarg (PARAMS_STDARG(8)) { CODE_STDARG(8) }
_BitInt(63) __attribute__ ((noipa)) f16_stdarg(PARAMS_STDARG(16)) { CODE_STDARG(16) }
_BitInt(63) __attribute__ ((noipa)) fp_stdarg (PARAMS_STDARG(p)) { CODE_STDARG(p) }
_BitInt(63) __attribute__ ((noipa)) f1p_stdarg (PARAMS_STDARG(1p)) { CODE_STDARG(1p) }
_BitInt(63) __attribute__ ((noipa)) f8p_stdarg (PARAMS_STDARG(8p)) { CODE_STDARG(8p) }
_BitInt(63) __attribute__ ((noipa)) f16p_stdarg(PARAMS_STDARG(16p)) { CODE_STDARG(16p) }
_BitInt(63) g1_stdarg (_BitInt(63) x, int y) { return f1_stdarg (ARGS_STDARG(1)); }
_BitInt(63) g8_stdarg (_BitInt(63) x, int y) { return f8_stdarg (ARGS_STDARG(8)); }
_BitInt(63) g16_stdarg(_BitInt(63) x, int y) { return f16_stdarg (ARGS_STDARG(16)); }
_BitInt(63) gp_stdarg (_BitInt(63) x, int y) { return fp_stdarg (ARGS_STDARG(p)); }
_BitInt(63) g1p_stdarg (_BitInt(63) x, int y) { return f1p_stdarg (ARGS_STDARG(1p)); }
_BitInt(63) g8p_stdarg (_BitInt(63) x, int y) { return f8p_stdarg (ARGS_STDARG(8p)); }
_BitInt(63) g16p_stdarg(_BitInt(63) x, int y) { return f16p_stdarg (ARGS_STDARG(16p)); }

View File

@ -0,0 +1,58 @@
/* { dg-do run { target bitint } } */
/* { dg-additional-options "-std=c23" } */
static long unsigned int
calc_alignof (int n)
{
if (n > 64)
return alignof(__int128_t);
if (n > 32)
return alignof(long long);
if (n > 16)
return alignof(int);
if (n > 8)
return alignof(short);
else
return alignof(char);
}
#define CHECK_ALIGNMENT(N) \
if (alignof(_BitInt(N)) != calc_alignof(N)) \
__builtin_abort ();
int main (void)
{
CHECK_ALIGNMENT(2);
CHECK_ALIGNMENT(3);
CHECK_ALIGNMENT(7);
CHECK_ALIGNMENT(8);
CHECK_ALIGNMENT(9);
CHECK_ALIGNMENT(13);
CHECK_ALIGNMENT(15);
CHECK_ALIGNMENT(16);
CHECK_ALIGNMENT(17);
CHECK_ALIGNMENT(24);
CHECK_ALIGNMENT(31);
CHECK_ALIGNMENT(32);
CHECK_ALIGNMENT(33);
CHECK_ALIGNMENT(42);
CHECK_ALIGNMENT(53);
CHECK_ALIGNMENT(63);
CHECK_ALIGNMENT(64);
CHECK_ALIGNMENT(65);
CHECK_ALIGNMENT(79);
CHECK_ALIGNMENT(96);
CHECK_ALIGNMENT(113);
CHECK_ALIGNMENT(127);
CHECK_ALIGNMENT(128);
CHECK_ALIGNMENT(129);
CHECK_ALIGNMENT(153);
CHECK_ALIGNMENT(255);
CHECK_ALIGNMENT(256);
CHECK_ALIGNMENT(257);
CHECK_ALIGNMENT(353);
CHECK_ALIGNMENT(512);
CHECK_ALIGNMENT(620);
CHECK_ALIGNMENT(1024);
CHECK_ALIGNMENT(30000);
}

View File

@ -0,0 +1,105 @@
/* { dg-do compile { target bitint } } */
/* { dg-additional-options "-std=c23 -O -fno-stack-clash-protection -g" } */
/* { dg-final { check-function-bodies "**" "" } } */
#define CHECK_ARG(N) \
void f##N(_BitInt(N) *ptr, _BitInt(N) y) \
{ \
*ptr = y; \
}
CHECK_ARG(2)
/*
** f2:
** sbfiz (w[0-9]+), w1, 6, 2
** asr (w[0-9]+), \1, 6
** strb \2, \[x0\]
** ret
*/
CHECK_ARG(8)
/*
** f8:
** strb w1, \[x0\]
** ret
*/
CHECK_ARG(9)
/*
** f9:
** sbfiz (w[0-9]+), w1, 7, 9
** asr (w[0-9]+), \1, 7
** strh \2, \[x0\]
** ret
*/
CHECK_ARG(16)
/*
** f16:
** strh w1, \[x0\]
** ret
*/
CHECK_ARG(19)
/*
** f19:
** sbfx x([0-9]+), x1, 0, 19
** str w\1, \[x0\]
** ret
*/
CHECK_ARG(32)
/*
** f32:
** str w1, \[x0\]
** ret
*/
CHECK_ARG(42)
/*
** f42:
** sbfx (x[0-9]+), x1, 0, 42
** str \1, \[x0\]
** ret
*/
CHECK_ARG(64)
/*
** f64:
** str x1, \[x0\]
** ret
*/
CHECK_ARG(65)
/*
** f65:
** extr (x[0-9]+), x3, x2, 1
** and (x[0-9]+), x2, 1
** orr (x[0-9]+), \2, \1, lsl 1
** asr (x[0-9]+), \1, 63
** stp \3, \4, \[x0\]
** ret
*/
CHECK_ARG(127)
/*
** f127:
** extr (x[0-9]+), x3, x2, 63
** and (x[0-9]+), x2, 9223372036854775807
** orr (x[0-9]+), \2, \1, lsl 63
** asr (x[0-9]+), \1, 1
** stp \3, \4, \[x0\]
** ret
*/
CHECK_ARG(128)
/*
** f128:
** stp x2, x3, \[x0\]
** ret
*/
CHECK_ARG(129)
/*
** f129:
** ldp (x[0-9]+), (x[0-9]+), \[x1\]
** stp \1, \2, \[x0\]
** ldr (x[0-9]+), \[x1, 16\]
** sbfx (x[0-9]+), \3, 0, 1
** str \4, \[x0, 16\]
** ret
*/

View File

@ -0,0 +1,60 @@
/* { dg-do run { target bitint } } */
/* { dg-additional-options "-std=c23" } */
static long unsigned int
calc_size (int n)
{
if (n > 128)
return ((n - 1)/128 + 1) * sizeof(__int128_t);
if (n > 64)
return sizeof(__int128_t);
if (n > 32)
return sizeof(long long);
if (n > 16)
return sizeof(int);
if (n > 8)
return sizeof(short);
else
return sizeof(char);
}
#define CHECK_SIZE(N) \
if (sizeof(_BitInt(N)) != calc_size(N)) \
__builtin_abort ();
int main (void)
{
CHECK_SIZE(2);
CHECK_SIZE(3);
CHECK_SIZE(7);
CHECK_SIZE(8);
CHECK_SIZE(9);
CHECK_SIZE(13);
CHECK_SIZE(15);
CHECK_SIZE(16);
CHECK_SIZE(17);
CHECK_SIZE(24);
CHECK_SIZE(31);
CHECK_SIZE(32);
CHECK_SIZE(33);
CHECK_SIZE(42);
CHECK_SIZE(53);
CHECK_SIZE(63);
CHECK_SIZE(64);
CHECK_SIZE(65);
CHECK_SIZE(79);
CHECK_SIZE(96);
CHECK_SIZE(113);
CHECK_SIZE(127);
CHECK_SIZE(128);
CHECK_SIZE(129);
CHECK_SIZE(153);
CHECK_SIZE(255);
CHECK_SIZE(256);
CHECK_SIZE(257);
CHECK_SIZE(353);
CHECK_SIZE(512);
CHECK_SIZE(620);
CHECK_SIZE(1024);
CHECK_SIZE(30000);
}

View File

@ -39,3 +39,11 @@ GCC_13.0.0 {
__trunctfbf2
__trunchfbf2
}
%inherit GCC_14.0.0 GCC_13.0.0
GCC_14.0.0 {
__fixtfbitint
__floatbitintbf
__floatbitinthf
__floatbitinttf
}

View File

@ -4,7 +4,8 @@ softfp_extensions := sftf dftf hftf bfsf
softfp_truncations := tfsf tfdf tfhf tfbf dfbf sfbf hfbf
softfp_exclude_libgcc2 := n
softfp_extras += fixhfti fixunshfti floattihf floatuntihf \
floatdibf floatundibf floattibf floatuntibf
floatdibf floatundibf floattibf floatuntibf \
floatbitinthf floatbitintbf floatbitinttf fixtfbitint
TARGET_LIBGCC2_CFLAGS += -Wno-missing-prototypes