aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/s390/s390.cc15
-rw-r--r--gcc/config/s390/s390.opt7
-rw-r--r--gcc/testsuite/gcc.target/s390/aligned-1.c101
-rw-r--r--gcc/testsuite/gcc.target/s390/unaligned-1.c103
-rw-r--r--gcc/testsuite/gcc.target/s390/unaligned-2.c16
5 files changed, 201 insertions, 41 deletions
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index e639655..372a232 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -13802,10 +13802,19 @@ s390_encode_section_info (tree decl, rtx rtl, int first)
that can go wrong (i.e. no FUNC_DECLs).
All symbols without an explicit alignment are assumed to be 2
byte aligned as mandated by our ABI. This behavior can be
- overridden for external symbols with the -munaligned-symbols
- switch. */
+ overridden for external and weak symbols with the
+ -munaligned-symbols switch.
+ For all external symbols without explicit alignment
+ DECL_ALIGN is already trimmed down to 8, however for weak
+ symbols this does not happen. These cases are catched by the
+ type size check. */
+ const_tree size = TYPE_SIZE (TREE_TYPE (decl));
+ unsigned HOST_WIDE_INT size_num = (tree_fits_uhwi_p (size)
+ ? tree_to_uhwi (size) : 0);
if ((DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) % 16)
- || (s390_unaligned_symbols_p && !decl_binds_to_current_def_p (decl)))
+ || (s390_unaligned_symbols_p
+ && !decl_binds_to_current_def_p (decl)
+ && (DECL_USER_ALIGN (decl) ? DECL_ALIGN (decl) % 16 : size_num < 16)))
SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
else if (DECL_ALIGN (decl) % 32)
SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
diff --git a/gcc/config/s390/s390.opt b/gcc/config/s390/s390.opt
index 901ae4b..a5b5aa9 100644
--- a/gcc/config/s390/s390.opt
+++ b/gcc/config/s390/s390.opt
@@ -332,7 +332,8 @@ Store all argument registers on the stack.
munaligned-symbols
Target Var(s390_unaligned_symbols_p) Init(0)
-Assume external symbols to be potentially unaligned. By default all
-symbols without explicit alignment are assumed to reside on a 2 byte
-boundary as mandated by the IBM Z ABI.
+Assume external symbols, whose natural alignment would be 1, to be
+potentially unaligned. By default all symbols without explicit
+alignment are assumed to reside on a 2 byte boundary as mandated by
+the IBM Z ABI.
diff --git a/gcc/testsuite/gcc.target/s390/aligned-1.c b/gcc/testsuite/gcc.target/s390/aligned-1.c
index 2dc99cf..3f5a261 100644
--- a/gcc/testsuite/gcc.target/s390/aligned-1.c
+++ b/gcc/testsuite/gcc.target/s390/aligned-1.c
@@ -1,20 +1,103 @@
-/* Even symbols without explicite alignment are assumed to reside on a
+/* Even symbols without explicit alignment are assumed to reside on a
2 byte boundary, as mandated by the IBM Z ELF ABI, and therefore
can be accessed using the larl instruction. */
/* { dg-do compile } */
/* { dg-options "-O3 -march=z900 -fno-section-anchors" } */
-extern unsigned char extern_implicitly_aligned;
-extern unsigned char extern_explicitly_aligned __attribute__((aligned(2)));
-unsigned char aligned;
+extern unsigned char extern_char;
+extern unsigned char extern_explicitly_aligned_char __attribute__((aligned(2)));
+extern unsigned char extern_explicitly_unaligned_char __attribute__((aligned(1)));
+extern unsigned char __attribute__((weak)) extern_weak_char;
+extern unsigned char extern_explicitly_aligned_weak_char __attribute__((weak,aligned(2)));
+extern unsigned char extern_explicitly_unaligned_weak_char __attribute__((weak,aligned(1)));
-unsigned char
+unsigned char normal_char;
+unsigned char explicitly_unaligned_char __attribute__((aligned(1)));
+unsigned char __attribute__((weak)) weak_char = 0;
+unsigned char explicitly_aligned_weak_char __attribute__((weak,aligned(2)));
+unsigned char explicitly_unaligned_weak_char __attribute__((weak,aligned(1)));
+
+extern unsigned int extern_int;
+extern unsigned int extern_explicitly_aligned_int __attribute__((aligned(4)));
+extern unsigned int extern_explicitly_unaligned_int __attribute__((aligned(1)));
+extern unsigned int __attribute__((weak)) extern_weak_int;
+extern unsigned int extern_explicitly_aligned_weak_int __attribute__((weak,aligned(4)));
+extern unsigned int extern_explicitly_unaligned_weak_int __attribute__((weak,aligned(1)));
+
+unsigned int normal_int;
+unsigned int explicitly_unaligned_int __attribute__((aligned(1)));
+unsigned int __attribute__((weak)) weak_int = 0;
+unsigned int explicitly_aligned_weak_int __attribute__((weak,aligned(4)));
+unsigned int explicitly_unaligned_weak_int __attribute__((weak,aligned(1)));
+
+extern const void extern_void;
+extern const void extern_explicitly_aligned_void __attribute__((aligned(2)));
+extern const void extern_explicitly_unaligned_void __attribute__((aligned(1)));
+extern const void __attribute__((weak)) extern_weak_void;
+extern const void extern_explicitly_aligned_weak_void __attribute__((weak,aligned(2)));
+extern const void extern_explicitly_unaligned_weak_void __attribute__((weak,aligned(1)));
+
+
+unsigned int
foo ()
{
- return extern_implicitly_aligned + extern_explicitly_aligned + aligned;
+ return extern_char + extern_explicitly_aligned_char
+ + extern_explicitly_unaligned_char
+ + extern_weak_char + extern_explicitly_aligned_weak_char
+ + extern_explicitly_unaligned_weak_char
+
+ + normal_char + explicitly_unaligned_char
+ + weak_char + explicitly_aligned_weak_char
+ + explicitly_unaligned_weak_char
+
+ + extern_int + extern_explicitly_aligned_int
+ + extern_explicitly_unaligned_int
+ + extern_weak_int + extern_explicitly_aligned_weak_int
+ + extern_explicitly_unaligned_weak_int
+
+ + normal_int + explicitly_unaligned_int
+ + weak_int + explicitly_aligned_weak_int
+ + explicitly_unaligned_weak_int;
}
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_implicitly_aligned\n" 1 } } */
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned\n" 1 } } */
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,aligned\n" 1 } } */
+const void *f1(void) { return &extern_void; }
+const void *f2(void) { return &extern_explicitly_aligned_void; }
+const void *f3(void) { return &extern_explicitly_unaligned_void; }
+const void *f4(void) { return &extern_weak_void; }
+const void *f5(void) { return &extern_explicitly_aligned_weak_void; }
+const void *f6(void) { return &extern_explicitly_unaligned_weak_void; }
+
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_char\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,normal_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_aligned_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_weak_char\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_int\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_int\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,normal_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_int\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_aligned_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_weak_int\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_void\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_void\n" 0 } } */
diff --git a/gcc/testsuite/gcc.target/s390/unaligned-1.c b/gcc/testsuite/gcc.target/s390/unaligned-1.c
index 421330a..47d7716 100644
--- a/gcc/testsuite/gcc.target/s390/unaligned-1.c
+++ b/gcc/testsuite/gcc.target/s390/unaligned-1.c
@@ -1,20 +1,103 @@
-/* With the -munaligned-symbols option all external symbols without
- explicite alignment are assumed to be potentially unaligned and
- therefore cannot be accessed with larl. */
+/* With the -munaligned-symbols option all external and weak symbols
+ without explicit alignment are assumed to be potentially unaligned
+ and therefore cannot be accessed with larl. */
/* { dg-do compile } */
/* { dg-options "-O3 -march=z900 -fno-section-anchors -munaligned-symbols" } */
-extern unsigned char extern_unaligned;
-extern unsigned char extern_explicitly_aligned __attribute__((aligned(2)));
-unsigned char aligned;
+extern unsigned char extern_char;
+extern unsigned char extern_explicitly_aligned_char __attribute__((aligned(2)));
+extern unsigned char extern_explicitly_unaligned_char __attribute__((aligned(1)));
+extern unsigned char __attribute__((weak)) extern_weak_char;
+extern unsigned char extern_explicitly_aligned_weak_char __attribute__((weak,aligned(2)));
+extern unsigned char extern_explicitly_unaligned_weak_char __attribute__((weak,aligned(1)));
+
+unsigned char normal_char;
+unsigned char explicitly_unaligned_char __attribute__((aligned(1)));
+unsigned char __attribute__((weak)) weak_char = 0;
+unsigned char explicitly_aligned_weak_char __attribute__((weak,aligned(2)));
+unsigned char explicitly_unaligned_weak_char __attribute__((weak,aligned(1)));
+
+extern unsigned int extern_int;
+extern unsigned int extern_explicitly_aligned_int __attribute__((aligned(4)));
+extern unsigned int extern_explicitly_unaligned_int __attribute__((aligned(1)));
+extern unsigned int __attribute__((weak)) extern_weak_int;
+extern unsigned int extern_explicitly_aligned_weak_int __attribute__((weak,aligned(4)));
+extern unsigned int extern_explicitly_unaligned_weak_int __attribute__((weak,aligned(1)));
+
+unsigned int normal_int;
+unsigned int explicitly_unaligned_int __attribute__((aligned(1)));
+unsigned int __attribute__((weak)) weak_int = 0;
+unsigned int explicitly_aligned_weak_int __attribute__((weak,aligned(4)));
+unsigned int explicitly_unaligned_weak_int __attribute__((weak,aligned(1)));
+
+extern const void extern_void;
+extern const void extern_explicitly_aligned_void __attribute__((aligned(2)));
+extern const void extern_explicitly_unaligned_void __attribute__((aligned(1)));
+extern const void __attribute__((weak)) extern_weak_void;
+extern const void extern_explicitly_aligned_weak_void __attribute__((weak,aligned(2)));
+extern const void extern_explicitly_unaligned_weak_void __attribute__((weak,aligned(1)));
+
unsigned char
foo ()
{
- return extern_unaligned + extern_explicitly_aligned + aligned;
+ return extern_char + extern_explicitly_aligned_char
+ + extern_explicitly_unaligned_char
+ + extern_weak_char + extern_explicitly_aligned_weak_char
+ + extern_explicitly_unaligned_weak_char
+
+ + normal_char + explicitly_unaligned_char
+ + weak_char + explicitly_aligned_weak_char
+ + explicitly_unaligned_weak_char
+
+ + extern_int + extern_explicitly_aligned_int
+ + extern_explicitly_unaligned_int
+ + extern_weak_int + extern_explicitly_aligned_weak_int
+ + extern_explicitly_unaligned_weak_int
+
+ + normal_int + explicitly_unaligned_int
+ + weak_int + explicitly_aligned_weak_int
+ + explicitly_unaligned_weak_int;
}
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_unaligned\n" 0 } } */
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned\n" 1 } } */
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,aligned\n" 1 } } */
+const void *f1(void) { return &extern_void; }
+const void *f2(void) { return &extern_explicitly_aligned_void; }
+const void *f3(void) { return &extern_explicitly_unaligned_void; }
+const void *f4(void) { return &extern_weak_void; }
+const void *f5(void) { return &extern_explicitly_aligned_weak_void; }
+const void *f6(void) { return &extern_explicitly_unaligned_weak_void; }
+
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_char\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,normal_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weak_char\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_aligned_weak_char\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_weak_char\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_int\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_int\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,normal_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_int\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_aligned_weak_int\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,explicitly_unaligned_weak_int\n" 0 } } */
+
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_void\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_void\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_weak_void\n" 0 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_aligned_weak_void\n" 1 } } */
+/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,extern_explicitly_unaligned_weak_void\n" 0 } } */
diff --git a/gcc/testsuite/gcc.target/s390/unaligned-2.c b/gcc/testsuite/gcc.target/s390/unaligned-2.c
deleted file mode 100644
index c1ece6d..0000000
--- a/gcc/testsuite/gcc.target/s390/unaligned-2.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* weak symbols might get overridden in another module by symbols
- which are not aligned on a 2-byte boundary. Although this violates
- the zABI we try to handle this gracefully by not using larl on
- these symbols if -munaligned-symbols has been specified. */
-
-/* { dg-do compile } */
-/* { dg-options "-O3 -march=z900 -fno-section-anchors -munaligned-symbols" } */
-unsigned char __attribute__((weak)) weaksym = 0;
-
-unsigned char
-foo ()
-{
- return weaksym;
-}
-
-/* { dg-final { scan-assembler-times "larl\t%r\[0-9\]*,weaksym\n" 0 } } */