@@ -13989,6 +13989,39 @@ aarch64_optab_supported_p (int op, machine_mode, machine_mode,
}
}
+/* A subroutine of aarch64_asm_file_end. Callback to align the
+ given section if it contains code. */
+
+static void
+aarch64_align_code_section (section *s)
+{
+ if (s->common.flags & SECTION_CODE)
+ {
+ switch_to_section (s);
+ ASM_OUTPUT_ALIGN (asm_out_file, 2);
+ }
+}
+
+/* Implement the TARGET_ASM_FILE_END hook. */
+
+static void
+aarch64_asm_file_end (void)
+{
+ /* When using per-function literal pools, we must ensure that any code
+ section is aligned to the minimal instruction length, lest we get
+ errors from the assembler re "unaligned instructions". */
+ if (aarch64_can_use_per_function_literal_pools_p ())
+ for_each_section (aarch64_align_code_section);
+
+ /* If a subtarget has already defined this hook, call it. */
+#ifdef TARGET_ASM_FILE_END
+ TARGET_ASM_FILE_END ();
+#endif
+}
+
+#undef TARGET_ASM_FILE_END
+#define TARGET_ASM_FILE_END aarch64_asm_file_end
+
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST aarch64_address_cost
new file mode 100644
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-Og -fschedule-insns -mno-pc-relative-literal-loads -g" } */
+
+typedef short v32u16 __attribute__ ((vector_size (32)));
+typedef int v32u32 __attribute__ ((vector_size (32)));
+typedef long v32u64 __attribute__ ((vector_size (32)));
+typedef __int128 u128;
+typedef __int128 v32u128 __attribute__ ((vector_size (32)));
+
+int
+foo(int u16_0, int u32_0, int u64_0, u128 u128_0, int u16_1, int u32_1, int u64_1, u128 u128_1, v32u16 v32u16_0, v32u32 v32u32_0, v32u64 v32u64_0, v32u128 v32u128_0, v32u16 v32u16_1, v32u32 v32u32_1, v32u64 v32u64_1, v32u128 v32u128_1)
+{
+ v32u32_1 ^= (v32u32) ~ v32u64_0;
+ v32u32_1 %= (v32u32) - v32u16_1 | 1;
+ v32u16_1 -= (v32u16) v32u16_1;
+ v32u64_0 *= (v32u64){~ u128_0, v32u16_1[5], v32u16_0[15], v32u32_1[4]};
+ v32u16_0 /= (v32u16){0x574c, ~u128_1, v32u128_1[0], u64_1, v32u64_0[1], v32u64_1[2], 0, 0x8ce6, u128_1, 0x5e69} |1;
+ return v32u16_0[0] + v32u16_0[6] + v32u16_0[8] + v32u16_0[9] + v32u32_0[0] + v32u32_0[1] + v32u32_0[2] + v32u32_0[3] + v32u32_0[4] + v32u32_0[6] + v32u64_0[0] + v32u64_0[2] + v32u64_0[3] + v32u128_0[0] + v32u128_0[1] + v32u32_1[0] + v32u32_1[2] + v32u64_1[2] + v32u64_1[3] + v32u128_1[1];
+}
new file mode 100644
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-Og -freorder-functions -g3 -mcmodel=large" } */
+
+typedef short v32u16 __attribute__ ((vector_size (32)));
+typedef int v32u32 __attribute__ ((vector_size (32)));
+typedef long v32u64 __attribute__ ((vector_size (32)));
+typedef __int128 u128;
+typedef __int128 v32u128 __attribute__ ((vector_size (32)));
+
+int
+foo (int u16_0, int u32_0, int u64_0, u128 u128_0, int u16_1, int u32_1, v32u16 v32u16_0, v32u32 v32u32_0, v32u64 v32u64_0, v32u128 v32u128_0, v32u16 v32u16_1, v32u32 v32u32_1, v32u64 v32u64_1, v32u128 v32u128_1)
+{
+ u128_0 <<= 0x6c;
+ v32u16_1 %= (v32u16) { 1, 64, 0xf294, 0, u32_1, v32u32_1[6], ~u128_0, 0x2912, v32u32_0[2]} | 1;
+ v32u16_0 ^= (v32u16){-v32u16_1[11], -u32_1, 64, ~u128_0, 0, 1, 64, ~u64_0, 0};
+ return u16_0 + u32_0 + u16_1 + v32u16_0[0] + v32u32_0[1] + v32u32_0[2] + v32u32_0[4] + v32u32_0[6] + v32u64_0[0] + v32u64_0[1] + v32u64_0[2] + v32u64_0[3] + v32u128_0[0] + v32u128_0[1] + v32u16_1[0] + v32u32_1[7] + v32u64_1[0] + v32u64_1[1] + v32u64_1[2] + v32u64_1[3] + v32u128_1[0] + v32u128_1[1];
+}
new file mode 100644
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -ffunction-sections -mno-pc-relative-literal-loads -g3" } */
+
+typedef unsigned short u16;
+typedef unsigned short v32u16 __attribute__((vector_size(32)));
+typedef unsigned int u32;
+typedef unsigned int v32u32 __attribute__((vector_size(32)));
+typedef unsigned long long u64;
+typedef unsigned long long v32u64 __attribute__((vector_size(32)));
+typedef unsigned __int128 u128;
+typedef unsigned __int128 v32u128 __attribute__((vector_size(32)));
+u128 __attribute__((noinline, noclone))
+foo(u16 u16_0, u32 u32_0, u64 u64_0, u128 u128_0, u16 u16_1, u32 u32_1, u64 u64_1, u128 u128_1, v32u16 v32u16_0, v32u32 v32u32_0, v32u64 v32u64_0, v32u128 v32u128_0, v32u16 v32u16_1, v32u32 v32u32_1, v32u64 v32u64_1, v32u128 v32u128_1)
+{
+ v32u128_1 %= (v32u128)v32u32_1 | 1;
+ u16_1 /= ((u32)~(u128)(((u128)0xa1 << 0))) | 1;
+ v32u32_0 += (v32u32){(u16)v32u16_1[9], (u16)v32u16_1[14], (u32)-v32u32_0[7], ((u64)(u32)(((u128)0x43bc59e9 << 0))), ((u32)(u32)(((u128)0x14a47ba8f240a6 << 0))), (u128)v32u128_1[1], (u16)u16_1, (u64)-u64_1};
+ return u16_0 + u32_0 + u64_0 + u128_0 + u16_1 + u32_1 + u64_1 + u128_1 + v32u16_0[0] + v32u16_0[1] + v32u16_0[2] + v32u16_0[3] + v32u16_0[4] + v32u16_0[5] + v32u16_0[6] + v32u16_0[7] + v32u16_0[8] + v32u16_0[9] + v32u16_0[10] + v32u16_0[11] + v32u16_0[12] + v32u16_0[13] + v32u16_0[14] + v32u16_0[15] + v32u32_0[0] + v32u32_0[1] + v32u32_0[2] + v32u32_0[3] + v32u32_0[4] + v32u32_0[5] + v32u32_0[6] + v32u32_0[7] + v32u64_0[0] + v32u64_0[1] + v32u64_0[2] + v32u64_0[3] + v32u128_0[0] + v32u128_0[1] + v32u16_1[0] + v32u16_1[1] + v32u16_1[2] + v32u16_1[3] + v32u16_1[4] + v32u16_1[5] + v32u16_1[6] + v32u16_1[7] + v32u16_1[8] + v32u16_1[9] + v32u16_1[10] + v32u16_1[11] + v32u16_1[12] + v32u16_1[13] + v32u16_1[14] + v32u16_1[15] + v32u32_1[0] + v32u32_1[1] + v32u32_1[2] + v32u32_1[3] + v32u32_1[4] + v32u32_1[5] + v32u32_1[6] + v32u32_1[7] + v32u64_1[0] + v32u64_1[1] + v32u64_1[2] + v32u64_1[3] + v32u128_1[0] + v32u128_1[1];
+}
+int main()
+{
+}
@@ -849,6 +849,21 @@ mergeable_constant_section (machine_mode mode ATTRIBUTE_UNUSED,
}
return readonly_data_section;
}
+
+/* Iterate over all created sections. */
+
+void
+for_each_section (void (*callback)(section *))
+{
+ hash_table<section_hasher>::iterator iter;
+ section *s;
+
+ for (s = unnamed_sections; s != NULL; s = s->unnamed.next)
+ callback(s);
+ FOR_EACH_HASH_TABLE_ELEMENT (*section_htab, s, section *s, iter)
+ callback(s);
+}
+
/* Given NAME, a putative register name, discard any customary prefixes. */
@@ -41,6 +41,7 @@ extern void process_pending_assemble_externals (void);
extern bool decl_replaceable_p (tree);
extern bool decl_binds_to_current_def_p (const_tree);
extern enum tls_model decl_default_tls_model (const_tree);
+extern void for_each_section (void (*callback)(section *));
/* Declare DECL to be a weak symbol. */
extern void declare_weak (tree);