diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b4c38d6ea9546a0da1ec0048c146e424c2c4cc1b..5833d7fc8ff1151dac85c0551666f62eae024dfa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-06-03 Szabolcs Nagy <szabolcs.nagy@arm.com> + + * config/aarch64/aarch64-protos.h (aarch64_asm_output_alias): Declare. + (aarch64_asm_output_external): Declare. + * config/aarch64/aarch64.c (aarch64_asm_output_variant_pcs): New. + (aarch64_declare_function_name): Call aarch64_asm_output_variant_pcs. + (aarch64_asm_output_alias): New. + (aarch64_asm_output_external): New. + * config/aarch64/aarch64.h (ASM_OUTPUT_DEF_FROM_DECLS): Define. + (ASM_OUTPUT_EXTERNAL): Define. + 2019-06-03 Aldy Hernandez <aldyh@redhat.com> * tree-vrp.h (value_range_base::nonzero_p): New. (value_range_base::set_nonnull): Rename to... diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index a42d352ac11d811a37c1a1f4c0d30925925bcaf7..6dccabc8cf79dfa000c062a5c6a2ad141615efa9 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -436,6 +436,8 @@ bool aarch64_is_long_call_p (rtx); bool aarch64_is_noplt_call_p (rtx); bool aarch64_label_mentioned_p (rtx); void aarch64_declare_function_name (FILE *, const char*, tree); +void aarch64_asm_output_alias (FILE *, const tree, const tree); +void aarch64_asm_output_external (FILE *, const tree, const char*); bool aarch64_legitimate_pic_operand_p (rtx); bool aarch64_mask_and_shift_for_ubfiz_p (scalar_int_mode, rtx, rtx); bool aarch64_masks_and_shift_for_bfi_p (scalar_int_mode, unsigned HOST_WIDE_INT, diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index db0249b4607bef789ceab8ec844d37dfc2899de9..263ed21442c4e028f2b6c77950dbc726cb380cd4 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -15566,6 +15566,19 @@ aarch64_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED, int global) return (global ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | type; } +/* Output .variant_pcs for aarch64_vector_pcs function symbols. */ + +static void +aarch64_asm_output_variant_pcs (FILE *stream, const tree decl, const char* name) +{ + if (aarch64_simd_decl_p (decl)) + { + fprintf (stream, "\t.variant_pcs\t"); + assemble_name (stream, name); + fprintf (stream, "\n"); + } +} + /* The last .arch and .tune assembly strings that we printed. */ static std::string aarch64_last_printed_arch_string; static std::string aarch64_last_printed_tune_string; @@ -15615,11 +15628,33 @@ aarch64_declare_function_name (FILE *stream, const char* name, aarch64_last_printed_tune_string = this_tune->name; } + aarch64_asm_output_variant_pcs (stream, fndecl, name); + /* Don't forget the type directive for ELF. */ ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "function"); ASM_OUTPUT_LABEL (stream, name); } +/* Implement ASM_OUTPUT_DEF_FROM_DECLS. Output .variant_pcs for aliases. */ + +void +aarch64_asm_output_alias (FILE *stream, const tree decl, const tree target) +{ + const char *name = XSTR (XEXP (DECL_RTL (decl), 0), 0); + const char *value = IDENTIFIER_POINTER (target); + aarch64_asm_output_variant_pcs (stream, decl, name); + ASM_OUTPUT_DEF (stream, name, value); +} + +/* Implement ASM_OUTPUT_EXTERNAL. Output .variant_pcs for undefined + function symbol references. */ + +void +aarch64_asm_output_external (FILE *stream, const tree decl, const char* name) +{ + aarch64_asm_output_variant_pcs (stream, decl, name); +} + /* Triggered after a .cfi_startproc directive is emitted into the assembly file. Used to output the .cfi_b_key_frame directive when signing the current function with the B key. */ diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h index 516f63689c4fe17ffcdde57f19dd101b8e34fb71..bf06caa06ee65c5216493deb030784630b7ed2db 100644 --- a/gcc/config/aarch64/aarch64.h +++ b/gcc/config/aarch64/aarch64.h @@ -516,6 +516,15 @@ extern unsigned aarch64_architecture_version; #define ASM_DECLARE_FUNCTION_NAME(STR, NAME, DECL) \ aarch64_declare_function_name (STR, NAME, DECL) +/* Output assembly strings for alias definition. */ +#define ASM_OUTPUT_DEF_FROM_DECLS(STR, DECL, TARGET) \ + aarch64_asm_output_alias (STR, DECL, TARGET) + +/* Output assembly strings for undefined extern symbols. */ +#undef ASM_OUTPUT_EXTERNAL +#define ASM_OUTPUT_EXTERNAL(STR, DECL, NAME) \ + aarch64_asm_output_external (STR, DECL, NAME) + /* Output assembly strings after .cfi_startproc is emitted. */ #define ASM_POST_CFI_STARTPROC aarch64_post_cfi_startproc diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 112cf11f58ed48737696ec09836181462af4d848..6ed70b44cd501190def399af8934e4413e2d696f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2019-06-03 Szabolcs Nagy <szabolcs.nagy@arm.com> + + * gcc.target/aarch64/pcs_attribute-2.c: New test. + * gcc.target/aarch64/torture/simd-abi-4.c: Check .variant_pcs support. + * lib/target-supports.exp (check_effective_target_aarch64_variant_pcs): + New. + 2019-06-03 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * gcc.target/aarch64/ssadv16qi.c: Add +nodotprod to pragma. diff --git a/gcc/testsuite/gcc.target/aarch64/pcs_attribute-2.c b/gcc/testsuite/gcc.target/aarch64/pcs_attribute-2.c new file mode 100644 index 0000000000000000000000000000000000000000..d997f52921c0afc5db348ba4dd0a8d9560b87c39 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pcs_attribute-2.c @@ -0,0 +1,114 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target aarch64_variant_pcs } */ + +/* Test that .variant_pcs is emitted for vector PCS symbol references. */ + +#define ATTR __attribute__ ((aarch64_vector_pcs)) + +void f_undef_basepcs (void); + +void f_def_basepcs (void) +{ +} + +ATTR void f_undef_vpcs (void); + +ATTR void f_def_vpcs (void) +{ +} + +__attribute__ ((alias ("f_def_vpcs"))) +ATTR void f_alias_vpcs (void); + +__attribute__ ((weak, alias ("f_def_vpcs"))) +ATTR void f_weak_alias_vpcs (void); + +__attribute__ ((weak)) +ATTR void f_weak_undef_vpcs (void); + +__attribute__ ((visibility ("protected"))) +ATTR void f_protected_vpcs (void) +{ +} + +__attribute__ ((visibility ("hidden"))) +ATTR void f_hidden_vpcs (void) +{ +} + +ATTR static void f_local_vpcs (void) +{ +} + +__attribute__((weakref ("f_undef_vpcs"))) +ATTR static void f_local_weakref_undef_vpcs (void); + +__attribute__((weakref ("f_hidden_vpcs"))) +ATTR static void f_local_weakref_def_vpcs (void); + +ATTR void bar_undef_vpcs (void) __asm__ ("f_undef_renamed_vpcs"); + +ATTR void bar_def_vpcs (void) __asm__ ("f_def_renamed_vpcs"); +ATTR void bar_def_vpcs (void) +{ +} + +static void (*f_ifunc_resolver ()) (void) +{ + return (void (*)(void))f_local_vpcs; +} + +__attribute__ ((ifunc ("f_ifunc_resolver"))) +ATTR void f_ifunc_vpcs (void); + +__attribute__ ((visibility ("hidden"))) +__attribute__ ((ifunc ("f_ifunc_resolver"))) +ATTR void f_hidden_ifunc_vpcs (void); + +__attribute__ ((ifunc ("f_ifunc_resolver"))) +ATTR static void f_local_ifunc_vpcs (void); + +void (*refs_basepcs[]) (void) = { + f_undef_basepcs, + f_def_basepcs, +}; + +void (*ATTR refs_vpcs[]) (void) = { + f_undef_vpcs, + f_def_vpcs, + f_alias_vpcs, + f_weak_alias_vpcs, + f_weak_undef_vpcs, + f_protected_vpcs, + f_hidden_vpcs, + f_local_vpcs, + f_local_weakref_undef_vpcs, + f_local_weakref_def_vpcs, + bar_undef_vpcs, + bar_def_vpcs, + f_ifunc_vpcs, + f_hidden_ifunc_vpcs, + f_local_ifunc_vpcs, +}; + +/* Note: local symbols don't need .variant_pcs, but gcc generates it, so + we check them here. An undefined weakref does not show up in the + symbol table, only the target symbol, so it does not need .variant_pcs. */ + +/* { dg-final { scan-assembler-not {\.variant_pcs\tf_undef_basepcs} } } */ +/* { dg-final { scan-assembler-not {\.variant_pcs\tf_def_basepcs} } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_undef_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_def_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_alias_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_weak_alias_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_weak_undef_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_protected_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_hidden_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_local_vpcs} 1 } } */ +/* { dg-final { scan-assembler-not {\.variant_pcs\tf_local_weakref_undef_vpcs} } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_local_weakref_def_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_undef_renamed_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_def_renamed_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_ifunc_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_hidden_ifunc_vpcs} 1 } } */ +/* { dg-final { scan-assembler-times {\.variant_pcs\tf_local_ifunc_vpcs} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/torture/simd-abi-4.c b/gcc/testsuite/gcc.target/aarch64/torture/simd-abi-4.c index e399690f364987bbe028cd97dfb28edbcc9db0d1..b8d7ce09b74f08940ae0cdb687313c7921536542 100644 --- a/gcc/testsuite/gcc.target/aarch64/torture/simd-abi-4.c +++ b/gcc/testsuite/gcc.target/aarch64/torture/simd-abi-4.c @@ -1,4 +1,5 @@ -/* dg-do run */ +/* { dg-do run } */ +/* { dg-require-effective-target aarch64_variant_pcs } */ /* { dg-additional-options "-std=c99" } */ diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 0d3d9f452957adc249f0c0063319a466cc2a8fd8..916be2b607a328d60518df575d297df869082a10 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -8669,6 +8669,17 @@ proc check_effective_target_aarch64_large { } { } } +# Return 1 if the assembler accepts the aarch64 .variant_pcs directive. + +proc check_effective_target_aarch64_variant_pcs { } { + if { [istarget aarch64*-*-*] } { + return [check_no_compiler_messages aarch64_variant_pcs object { + __asm__ (".variant_pcs foo"); + }] + } else { + return 0 + } +} # Return 1 if this is a reduced AVR Tiny core. Such cores have different # register set, instruction set, addressing capabilities and ABI.