diff options
-rw-r--r-- | gcc/config/s390/s390.cc | 15 | ||||
-rw-r--r-- | gcc/config/s390/s390.opt | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/aligned-1.c | 101 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/unaligned-1.c | 103 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/s390/unaligned-2.c | 16 |
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 } } */ |