@@ -13709,8 +13709,13 @@ s390_encode_section_info (tree decl, rtx rtl, int first)
a larl/load-relative instruction. We only handle the cases
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. */
- if (DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) % 16)
+ byte aligned as mandated by our ABI. This behavior can be
+ overridden for external symbols with the -munaligned-symbols
+ switch. */
+ if (DECL_ALIGN (decl) % 16
+ && (DECL_USER_ALIGN (decl)
+ || (!SYMBOL_REF_LOCAL_P (XEXP (rtl, 0))
+ && s390_unaligned_symbols_p)))
SYMBOL_FLAG_SET_NOTALIGN2 (XEXP (rtl, 0));
else if (DECL_ALIGN (decl) % 32)
SYMBOL_FLAG_SET_NOTALIGN4 (XEXP (rtl, 0));
@@ -329,3 +329,10 @@ Target Undocumented Var(unroll_only_small_loops) Init(0) Save
mpreserve-args
Target Var(s390_preserve_args_p) Init(0)
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.
+
new file mode 100644
@@ -0,0 +1,20 @@
+/* Even symbols without explicite 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;
+
+unsigned char
+foo ()
+{
+ return extern_implicitly_aligned + extern_explicitly_aligned + aligned;
+}
+
+/* { 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 } } */
new file mode 100644
@@ -0,0 +1,20 @@
+/* With the -munaligned-symbols option all external symbols without
+ explicite 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;
+
+unsigned char
+foo ()
+{
+ return extern_unaligned + extern_explicitly_aligned + aligned;
+}
+
+/* { 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 } } */