aarch64: Add LS64 extension and intrinsics

This patch is adding support for LS64 (Armv8.7-A Load/Store 64 Byte extension)
which is part of Armv8.7-A architecture. Changes include missing plumbing for
TARGET_LS64, LS64 data structure and intrinsics defined in ACLE. Machine
description of intrinsics is using new V8DI mode added in a separate patch.
__ARM_FEATURE_LS64 is defined if the Armv8.7-A LS64 instructions for atomic
64-byte access to device memory are supported.

New compiler internal type is added wrapping ACLE struct data512_t:

typedef struct {
  uint64_t val[8];
} __arm_data512_t;

gcc/ChangeLog:

	* config/aarch64/aarch64-builtins.c (enum aarch64_builtins):
	Define AARCH64_LS64_BUILTIN_LD64B, AARCH64_LS64_BUILTIN_ST64B,
	AARCH64_LS64_BUILTIN_ST64BV, AARCH64_LS64_BUILTIN_ST64BV0.
	(aarch64_init_ls64_builtin_decl): Helper function.
	(aarch64_init_ls64_builtins): Helper function.
	(aarch64_init_ls64_builtins_types): Helper function.
	(aarch64_general_init_builtins): Init LS64 intrisics for
	TARGET_LS64.
	(aarch64_expand_builtin_ls64): LS64 intrinsics expander.
	(aarch64_general_expand_builtin): Handle aarch64_expand_builtin_ls64.
	(ls64_builtins_data): New helper struct.
	(v8di_UP): New define.
	* config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define
	__ARM_FEATURE_LS64.
	* config/aarch64/aarch64.c (aarch64_classify_address): Enforce the
	V8DI range (7-bit signed scaled) for both ends of the range.
	* config/aarch64/aarch64-simd.md (movv8di): New pattern.
	(aarch64_movv8di): New pattern.
	* config/aarch64/aarch64.h (AARCH64_ISA_LS64): New define.
	(TARGET_LS64): New define.
	* config/aarch64/aarch64.md: Add UNSPEC_LD64B, UNSPEC_ST64B,
	UNSPEC_ST64BV and UNSPEC_ST64BV0.
	(ld64b): New define_insn.
	(st64b): New define_insn.
	(st64bv): New define_insn.
	(st64bv0): New define_insn.
	* config/aarch64/arm_acle.h (data512_t): New type derived from
	__arm_data512_t.
	(__arm_data512_t): New internal type.
	(__arm_ld64b): New intrinsic.
	(__arm_st64b): New intrinsic.
	(__arm_st64bv): New intrinsic.
	(__arm_st64bv0): New intrinsic.
	* config/arm/types.md: Add new type ls64.

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/acle/ls64_asm.c: New test.
	* gcc.target/aarch64/acle/ls64_ld64b.c: New test.
	* gcc.target/aarch64/acle/ls64_ld64b-2.c: New test.
	* gcc.target/aarch64/acle/ls64_ld64b-3.c: New test.
	* gcc.target/aarch64/acle/ls64_st64b.c: New test.
	* gcc.target/aarch64/acle/ls64_ld_st_o0.c: New test.
	* gcc.target/aarch64/acle/ls64_st64b-2.c: New test.
	* gcc.target/aarch64/acle/ls64_st64bv.c: New test.
	* gcc.target/aarch64/acle/ls64_st64bv-2.c: New test.
	* gcc.target/aarch64/acle/ls64_st64bv-3.c: New test.
	* gcc.target/aarch64/acle/ls64_st64bv0.c: New test.
	* gcc.target/aarch64/acle/ls64_st64bv0-2.c: New test.
	* gcc.target/aarch64/acle/ls64_st64bv0-3.c: New test.
	* gcc.target/aarch64/pragma_cpp_predefs_2.c: Add checks
	for __ARM_FEATURE_LS64.
This commit is contained in:
Przemyslaw Wirkus 2021-12-14 14:03:38 +00:00
parent 0dfb1bd944
commit fdcddba8f2
22 changed files with 545 additions and 0 deletions

View File

@ -49,6 +49,7 @@
#include "gimple-fold.h"
#define v8qi_UP E_V8QImode
#define v8di_UP E_V8DImode
#define v4hi_UP E_V4HImode
#define v4hf_UP E_V4HFmode
#define v2si_UP E_V2SImode
@ -607,6 +608,11 @@ enum aarch64_builtins
AARCH64_MEMTAG_BUILTIN_SET_TAG,
AARCH64_MEMTAG_BUILTIN_GET_TAG,
AARCH64_MEMTAG_BUILTIN_END,
/* LS64 builtins. */
AARCH64_LS64_BUILTIN_LD64B,
AARCH64_LS64_BUILTIN_ST64B,
AARCH64_LS64_BUILTIN_ST64BV,
AARCH64_LS64_BUILTIN_ST64BV0,
AARCH64_BUILTIN_MAX
};
@ -1571,6 +1577,70 @@ aarch64_init_memtag_builtins (void)
#undef AARCH64_INIT_MEMTAG_BUILTINS_DECL
}
/* Add builtins for Load/store 64 Byte instructions. */
typedef struct
{
const char *name;
unsigned int code;
tree type;
} ls64_builtins_data;
static GTY(()) tree ls64_arm_data_t = NULL_TREE;
static void
aarch64_init_ls64_builtins_types (void)
{
/* Synthesize:
typedef struct {
uint64_t val[8];
} __arm_data512_t; */
const char *tuple_type_name = "__arm_data512_t";
tree node_type = get_typenode_from_name (UINT64_TYPE);
tree array_type = build_array_type_nelts (node_type, 8);
SET_TYPE_MODE (array_type, V8DImode);
gcc_assert (TYPE_MODE_RAW (array_type) == TYPE_MODE (array_type));
gcc_assert (TYPE_ALIGN (array_type) == 64);
tree field = build_decl (input_location, FIELD_DECL,
get_identifier ("val"), array_type);
ls64_arm_data_t = lang_hooks.types.simulate_record_decl (input_location,
tuple_type_name,
make_array_slice (&field, 1));
gcc_assert (TYPE_MODE (ls64_arm_data_t) == V8DImode);
gcc_assert (TYPE_MODE_RAW (ls64_arm_data_t) == TYPE_MODE (ls64_arm_data_t));
gcc_assert (TYPE_ALIGN (ls64_arm_data_t) == 64);
}
static void
aarch64_init_ls64_builtins (void)
{
aarch64_init_ls64_builtins_types ();
ls64_builtins_data data[4] = {
{"__builtin_aarch64_ld64b", AARCH64_LS64_BUILTIN_LD64B,
build_function_type_list (ls64_arm_data_t,
const_ptr_type_node, NULL_TREE)},
{"__builtin_aarch64_st64b", AARCH64_LS64_BUILTIN_ST64B,
build_function_type_list (void_type_node, ptr_type_node,
ls64_arm_data_t, NULL_TREE)},
{"__builtin_aarch64_st64bv", AARCH64_LS64_BUILTIN_ST64BV,
build_function_type_list (uint64_type_node, ptr_type_node,
ls64_arm_data_t, NULL_TREE)},
{"__builtin_aarch64_st64bv0", AARCH64_LS64_BUILTIN_ST64BV0,
build_function_type_list (uint64_type_node, ptr_type_node,
ls64_arm_data_t, NULL_TREE)},
};
for (size_t i = 0; i < ARRAY_SIZE (data); ++i)
aarch64_builtin_decls[data[i].code]
= aarch64_general_add_builtin (data[i].name, data[i].type, data[i].code);
}
/* Initialize fpsr fpcr getters and setters. */
static void
@ -1660,6 +1730,9 @@ aarch64_general_init_builtins (void)
if (TARGET_MEMTAG)
aarch64_init_memtag_builtins ();
if (TARGET_LS64)
aarch64_init_ls64_builtins ();
}
/* Implement TARGET_BUILTIN_DECL for the AARCH64_BUILTIN_GENERAL group. */
@ -2130,6 +2203,57 @@ aarch64_expand_builtin_tme (int fcode, tree exp, rtx target)
return target;
}
/* Function to expand an expression EXP which calls one of the Load/Store
64 Byte extension (LS64) builtins FCODE with the result going to TARGET. */
static rtx
aarch64_expand_builtin_ls64 (int fcode, tree exp, rtx target)
{
expand_operand ops[3];
switch (fcode)
{
case AARCH64_LS64_BUILTIN_LD64B:
{
rtx op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
create_output_operand (&ops[0], target, V8DImode);
create_input_operand (&ops[1], op0, DImode);
expand_insn (CODE_FOR_ld64b, 2, ops);
return ops[0].value;
}
case AARCH64_LS64_BUILTIN_ST64B:
{
rtx op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
rtx op1 = expand_normal (CALL_EXPR_ARG (exp, 1));
create_output_operand (&ops[0], op0, DImode);
create_input_operand (&ops[1], op1, V8DImode);
expand_insn (CODE_FOR_st64b, 2, ops);
return const0_rtx;
}
case AARCH64_LS64_BUILTIN_ST64BV:
{
rtx op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
rtx op1 = expand_normal (CALL_EXPR_ARG (exp, 1));
create_output_operand (&ops[0], target, DImode);
create_input_operand (&ops[1], op0, DImode);
create_input_operand (&ops[2], op1, V8DImode);
expand_insn (CODE_FOR_st64bv, 3, ops);
return ops[0].value;
}
case AARCH64_LS64_BUILTIN_ST64BV0:
{
rtx op0 = expand_normal (CALL_EXPR_ARG (exp, 0));
rtx op1 = expand_normal (CALL_EXPR_ARG (exp, 1));
create_output_operand (&ops[0], target, DImode);
create_input_operand (&ops[1], op0, DImode);
create_input_operand (&ops[2], op1, V8DImode);
expand_insn (CODE_FOR_st64bv0, 3, ops);
return ops[0].value;
}
}
gcc_unreachable ();
}
/* Expand a random number builtin EXP with code FCODE, putting the result
int TARGET. If IGNORE is true the return value is ignored. */
@ -2388,6 +2512,12 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target,
|| fcode == AARCH64_TME_BUILTIN_TCANCEL)
return aarch64_expand_builtin_tme (fcode, exp, target);
if (fcode == AARCH64_LS64_BUILTIN_LD64B
|| fcode == AARCH64_LS64_BUILTIN_ST64B
|| fcode == AARCH64_LS64_BUILTIN_ST64BV
|| fcode == AARCH64_LS64_BUILTIN_ST64BV0)
return aarch64_expand_builtin_ls64 (fcode, exp, target);
if (fcode >= AARCH64_MEMTAG_BUILTIN_START
&& fcode <= AARCH64_MEMTAG_BUILTIN_END)
return aarch64_expand_builtin_memtag (fcode, exp, target);

View File

@ -200,6 +200,8 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
"__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile);
aarch64_def_or_undef (TARGET_BF16_FP,
"__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", pfile);
aarch64_def_or_undef (TARGET_LS64,
"__ARM_FEATURE_LS64", pfile);
/* Not for ACLE, but required to keep "float.h" correct if we switch
target between implementations that do or do not support ARMv8.2-A

View File

@ -7123,6 +7123,15 @@
}
})
(define_expand "movv8di"
[(set (match_operand:V8DI 0 "nonimmediate_operand")
(match_operand:V8DI 1 "general_operand"))]
"TARGET_SIMD"
{
if (can_create_pseudo_p () && MEM_P (operands[0]))
operands[1] = force_reg (V8DImode, operands[1]);
})
(define_expand "aarch64_ld1x3<vstruct_elt>"
[(match_operand:VSTRUCT_3QD 0 "register_operand")
(match_operand:DI 1 "register_operand")]
@ -7253,6 +7262,17 @@
(set_attr "length" "<insn_count>,4,4")]
)
(define_insn "*aarch64_movv8di"
[(set (match_operand:V8DI 0 "nonimmediate_operand" "=r,m,r")
(match_operand:V8DI 1 "general_operand" " r,r,m"))]
"!BYTES_BIG_ENDIAN
&& (register_operand (operands[0], V8DImode)
|| register_operand (operands[1], V8DImode))"
"#"
[(set_attr "type" "multiple,multiple,multiple")
(set_attr "length" "32,16,16")]
)
(define_insn "aarch64_be_ld1<mode>"
[(set (match_operand:VALLDI_F16 0 "register_operand" "=w")
(unspec:VALLDI_F16 [(match_operand:VALLDI_F16 1
@ -7496,6 +7516,34 @@
FAIL;
})
(define_split
[(set (match_operand:V8DI 0 "nonimmediate_operand")
(match_operand:V8DI 1 "general_operand"))]
"TARGET_SIMD && reload_completed"
[(const_int 0)]
{
if (register_operand (operands[0], V8DImode)
&& register_operand (operands[1], V8DImode))
{
aarch64_simd_emit_reg_reg_move (operands, DImode, 8);
DONE;
}
else if ((register_operand (operands[0], V8DImode)
&& memory_operand (operands[1], V8DImode))
|| (memory_operand (operands[0], V8DImode)
&& register_operand (operands[1], V8DImode)))
{
for (int offset = 0; offset < 64; offset += 16)
emit_move_insn (simplify_gen_subreg (TImode, operands[0],
V8DImode, offset),
simplify_gen_subreg (TImode, operands[1],
V8DImode, offset));
DONE;
}
else
FAIL;
})
(define_expand "aarch64_ld<nregs>r<vstruct_elt>"
[(match_operand:VSTRUCT_QD 0 "register_operand")
(match_operand:DI 1 "register_operand")]

View File

@ -10016,6 +10016,10 @@ aarch64_classify_address (struct aarch64_address_info *info,
&& (aarch64_offset_9bit_signed_unscaled_p (mode, offset)
|| offset_12bit_unsigned_scaled_p (mode, offset)));
if (mode == V8DImode)
return (aarch64_offset_7bit_signed_scaled_p (DImode, offset)
&& aarch64_offset_7bit_signed_scaled_p (DImode, offset + 48));
/* A 7bit offset check because OImode will emit a ldp/stp
instruction (only big endian will get here).
For ldp/stp instructions, the offset is scaled for the size of a

View File

@ -319,6 +319,7 @@ extern unsigned aarch64_architecture_version;
#define AARCH64_ISA_PAUTH (aarch64_isa_flags & AARCH64_FL_PAUTH)
#define AARCH64_ISA_V9 (aarch64_isa_flags & AARCH64_FL_V9)
#define AARCH64_ISA_MOPS (aarch64_isa_flags & AARCH64_FL_MOPS)
#define AARCH64_ISA_LS64 (aarch64_isa_flags & AARCH64_FL_LS64)
/* Crypto is an optional extension to AdvSIMD. */
#define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO)
@ -413,6 +414,9 @@ extern unsigned aarch64_architecture_version;
/* MOPS instructions are enabled through +mops. */
#define TARGET_MOPS (AARCH64_ISA_MOPS)
/* LS64 instructions are enabled through +ls64. */
#define TARGET_LS64 (AARCH64_ISA_LS64)
/* Make sure this is always defined so we don't have to check for ifdefs
but rather use normal ifs. */
#ifndef TARGET_FIX_ERR_A53_835769_DEFAULT

View File

@ -188,6 +188,12 @@
UNSPEC_LD2_LANE
UNSPEC_LD3_LANE
UNSPEC_LD4_LANE
UNSPEC_LD64B
UNSPEC_ST64B
UNSPEC_ST64BV
UNSPEC_ST64BV_RET
UNSPEC_ST64BV0
UNSPEC_ST64BV0_RET
UNSPEC_MB
UNSPEC_MOVMEM
UNSPEC_NOP
@ -7571,6 +7577,52 @@
[(set_attr "type" "memtag")]
)
;; Load/Store 64-bit (LS64) instructions.
(define_insn "ld64b"
[(set (match_operand:V8DI 0 "register_operand" "=r")
(unspec_volatile:V8DI
[(mem:V8DI (match_operand:DI 1 "register_operand" "r"))]
UNSPEC_LD64B)
)]
"TARGET_LS64"
"ld64b\\t%0, [%1]"
[(set_attr "type" "ls64")]
)
(define_insn "st64b"
[(set (mem:V8DI (match_operand:DI 0 "register_operand" "=r"))
(unspec_volatile:V8DI [(match_operand:V8DI 1 "register_operand" "r")]
UNSPEC_ST64B)
)]
"TARGET_LS64"
"st64b\\t%1, [%0]"
[(set_attr "type" "ls64")]
)
(define_insn "st64bv"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(const_int 0)] UNSPEC_ST64BV_RET))
(set (mem:V8DI (match_operand:DI 1 "register_operand" "r"))
(unspec_volatile:V8DI [(match_operand:V8DI 2 "register_operand" "r")]
UNSPEC_ST64BV)
)]
"TARGET_LS64"
"st64bv\\t%0, %2, [%1]"
[(set_attr "type" "ls64")]
)
(define_insn "st64bv0"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec_volatile:DI [(const_int 0)] UNSPEC_ST64BV0_RET))
(set (mem:V8DI (match_operand:DI 1 "register_operand" "r"))
(unspec_volatile:V8DI [(match_operand:V8DI 2 "register_operand" "r")]
UNSPEC_ST64BV0)
)]
"TARGET_LS64"
"st64bv0\\t%0, %2, [%1]"
[(set_attr "type" "ls64")]
)
;; AdvSIMD Stuff
(include "aarch64-simd.md")

View File

@ -214,6 +214,43 @@ __ttest (void)
#pragma GCC pop_options
#endif
#ifdef __ARM_FEATURE_LS64
#pragma GCC push_options
#pragma GCC target ("+nothing+ls64")
typedef __arm_data512_t data512_t;
__extension__ extern __inline data512_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_ld64b (const void *__addr)
{
return __builtin_aarch64_ld64b (__addr);
}
__extension__ extern __inline void
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_st64b (void *__addr, data512_t __value)
{
__builtin_aarch64_st64b (__addr, __value);
}
__extension__ extern __inline uint64_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_st64bv (void *__addr, data512_t __value)
{
return __builtin_aarch64_st64bv (__addr, __value);
}
__extension__ extern __inline uint64_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__arm_st64bv0 (void *__addr, data512_t __value)
{
return __builtin_aarch64_st64bv0 (__addr, __value);
}
#pragma GCC pop_options
#endif
#pragma GCC push_options
#pragma GCC target ("+nothing+rng")
__extension__ extern __inline int

View File

@ -1122,6 +1122,7 @@
coproc,\
tme,\
memtag,\
ls64,\
mve_move,\
mve_store,\
mve_load"

View File

@ -0,0 +1,58 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
/* Inline assembly for LS64 instructions. */
#include <arm_acle.h>
void
ls64_load (data512_t *output, const void *addr)
{
__asm__ volatile ("ld64b %0, [%1]"
: "=r" (*output)
: "r" (addr)
: "memory");
}
/* { dg-final { scan-assembler-times {ld64b } 1 } } */
void
ls64_store (const data512_t *input, void *addr)
{
__asm__ volatile ("st64b %1, [%0]"
: /* No outputs. */
: "r" (addr), "r" (*input)
: "memory");
}
/* { dg-final { scan-assembler-times {st64b } 1 } } */
uint64_t
ls64_store_v (const data512_t *input, void *addr)
{
uint64_t status;
__asm__ volatile ("st64bv %0, %2, [%1]"
: "=r" (status)
: "r" (addr), "r" (*input)
: "memory");
return status;
}
/* { dg-final { scan-assembler-times {st64bv } 1 } } */
uint64_t
ls64_store_v0 (const data512_t *input, void *addr)
{
uint64_t status;
__asm__ volatile ("st64bv0 %0, %2, [%1]"
: "=r" (status)
: "r" (addr), "r" (*input)
: "memory");
return status;
}
/* { dg-final { scan-assembler-times {st64bv0 } 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
void
func (const void * addr) {
data512_t ret = __arm_ld64b (addr);
}
/* { dg-final { scan-assembler-times {ld64b\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
void
func(const void * addr, data512_t *data) {
*data = __arm_ld64b (addr);
}
/* { dg-final { scan-assembler-times {ld64b\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
data512_t
func(const void * addr) {
return __arm_ld64b (addr);
}
/* { dg-final { scan-assembler-times {ld64b\t} 1 } } */

View File

@ -0,0 +1,30 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O0" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
/* Make sure no issues when compile with -O0. */
data512_t
func1 (const void * addr) {
return __arm_ld64b (addr);
}
void
func2 (void *addr, data512_t value) {
__arm_st64b (addr, value);
}
uint64_t
func3 (void *addr, data512_t value) {
return __arm_st64bv (addr, value);
}
uint64_t
func4 (void *addr, data512_t value) {
return __arm_st64bv0 (addr, value);
}

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
void
func(void *addr, data512_t *value) {
__arm_st64b (addr, *value);
}
/* { dg-final { scan-assembler-times {st64b\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
void
func(void *addr, data512_t value) {
__arm_st64b (addr, value);
}
/* { dg-final { scan-assembler-times {st64b\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
void
func(void *addr, data512_t value) {
__arm_st64bv (addr, value);
}
/* { dg-final { scan-assembler-times {st64bv\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
void
func(void *addr, data512_t *value) {
__arm_st64bv (addr, *value);
}
/* { dg-final { scan-assembler-times {st64bv\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
uint64_t
func(void *addr, data512_t value) {
return __arm_st64bv (addr, value);
}
/* { dg-final { scan-assembler-times {st64bv\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
void
func(void *addr, data512_t value) {
__arm_st64bv0 (addr, value);
}
/* { dg-final { scan-assembler-times {st64bv0\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
void
func(void *addr, data512_t *value) {
__arm_st64bv0 (addr, *value);
}
/* { dg-final { scan-assembler-times {st64bv0\t} 1 } } */

View File

@ -0,0 +1,15 @@
/* { dg-do compile } */
/* { dg-options "-march=armv8-a+ls64 -O2" } */
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#include <arm_acle.h>
uint64_t
func(void *addr, data512_t value) {
return __arm_st64bv0 (addr, value);
}
/* { dg-final { scan-assembler-times {st64bv0\t} 1 } } */

View File

@ -240,6 +240,20 @@
#endif
#pragma GCC pop_options
#pragma GCC push_options
#pragma GCC target ("arch=armv8.7-a")
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#pragma GCC pop_options
#pragma GCC push_options
#pragma GCC target ("arch=armv8.7-a+ls64")
#ifndef __ARM_FEATURE_LS64
#error "__ARM_FEATURE_LS64 is not defined but should be!"
#endif
#pragma GCC pop_options
#pragma GCC pop_options
int