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:
parent
0dfb1bd944
commit
fdcddba8f2
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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")]
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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
|
||||
|
@ -1122,6 +1122,7 @@
|
||||
coproc,\
|
||||
tme,\
|
||||
memtag,\
|
||||
ls64,\
|
||||
mve_move,\
|
||||
mve_store,\
|
||||
mve_load"
|
||||
|
58
gcc/testsuite/gcc.target/aarch64/acle/ls64_asm.c
Normal file
58
gcc/testsuite/gcc.target/aarch64/acle/ls64_asm.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_ld64b-2.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_ld64b-2.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_ld64b-3.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_ld64b-3.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_ld64b.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_ld64b.c
Normal 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 } } */
|
30
gcc/testsuite/gcc.target/aarch64/acle/ls64_ld_st_o0.c
Normal file
30
gcc/testsuite/gcc.target/aarch64/acle/ls64_ld_st_o0.c
Normal 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);
|
||||
}
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64b-2.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64b-2.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64b.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64b.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv-2.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv-2.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv-3.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv-3.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv0-2.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv0-2.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv0-3.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv0-3.c
Normal 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 } } */
|
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv0.c
Normal file
15
gcc/testsuite/gcc.target/aarch64/acle/ls64_st64bv0.c
Normal 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 } } */
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user