+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...
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,
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;
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. */
#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
+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.
--- /dev/null
+/* { 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 } } */
-/* dg-do run */
+/* { dg-do run } */
+/* { dg-require-effective-target aarch64_variant_pcs } */
/* { dg-additional-options "-std=c99" } */
}
}
+# 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.