@@ -22076,6 +22076,21 @@ counter_mode (rtx count_exp)
return SImode;
}
+/* Copy the address to a Pmode register. This is used for x32 to
+ truncate DImode TLS address to a SImode register. */
+
+static rtx
+ix86_copy_addr_to_reg (rtx addr)
+{
+ if (GET_MODE (addr) == Pmode)
+ return copy_addr_to_reg (addr);
+ else
+ {
+ gcc_assert (GET_MODE (addr) == DImode && Pmode == SImode);
+ return gen_rtx_SUBREG (SImode, copy_to_mode_reg (DImode, addr), 0);
+ }
+}
+
/* When SRCPTR is non-NULL, output simple loop to move memory
pointer to SRCPTR to DESTPTR via chunks of MODE unrolled UNROLL times,
overall size is COUNT specified in bytes. When SRCPTR is NULL, output the
@@ -23032,8 +23047,8 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx
align_exp,
if (!count)
count_exp = copy_to_mode_reg (GET_MODE (count_exp), count_exp);
- destreg = copy_addr_to_reg (XEXP (dst, 0));
- srcreg = copy_addr_to_reg (XEXP (src, 0));
+ destreg = ix86_copy_addr_to_reg (XEXP (dst, 0));
+ srcreg = ix86_copy_addr_to_reg (XEXP (src, 0));
unroll_factor = 1;
move_mode = word_mode;
@@ -23436,7 +23451,7 @@ ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp,
rtx align_exp,
if (!count)
count_exp = copy_to_mode_reg (counter_mode (count_exp), count_exp);
- destreg = copy_addr_to_reg (XEXP (dst, 0));
+ destreg = ix86_copy_addr_to_reg (XEXP (dst, 0));
move_mode = word_mode;
unroll_factor = 1;
i386/pr58690.c
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-require-effective-target maybe_x32 } */
+/* { dg-options "-O2 -mx32 -maddress-mode=short" } */
+
+struct gomp_thread
+{
+ char foo[41];
+};
+extern __thread struct gomp_thread gomp_tls_data;
+void
+foo (void)
+{
+ __builtin_memset (&gomp_tls_data, '\0', sizeof (gomp_tls_data));
+}
gnu-6:pts/14[22]> cat /tmp/pr58690.patch /export/gnu/import/git/src
gcc/
2013-10-12 H.J. Lu <hongjiu.lu@intel.com>
PR target/58690
* config/i386/i386.c (ix86_copy_addr_to_reg): New function.
(ix86_expand_movmem): Replace copy_addr_to_reg with
ix86_copy_addr_to_reg.
(ix86_expand_setmem): Likewise.
gcc/testsuite/
2013-10-12 H.J. Lu <hongjiu.lu@intel.com>
PR target/58690
* gcc.target/i386/pr58690.c: New test
@@ -22076,6 +22076,21 @@ counter_mode (rtx count_exp)
return SImode;
}
+/* Copy the address to a Pmode register. This is used for x32 to
+ truncate DImode TLS address to a SImode register. */
+
+static rtx
+ix86_copy_addr_to_reg (rtx addr)
+{
+ if (GET_MODE (addr) == Pmode)
+ return copy_addr_to_reg (addr);
+ else
+ {
+ gcc_assert (GET_MODE (addr) == DImode && Pmode == SImode);
+ return gen_rtx_SUBREG (SImode, copy_to_mode_reg (DImode, addr), 0);
+ }
+}
+
/* When SRCPTR is non-NULL, output simple loop to move memory
pointer to SRCPTR to DESTPTR via chunks of MODE unrolled UNROLL times,
overall size is COUNT specified in bytes. When SRCPTR is NULL, output the
@@ -23032,8 +23047,8 @@ ix86_expand_movmem (rtx dst, rtx src, rtx
count_exp, rtx align_exp,
if (!count)
count_exp = copy_to_mode_reg (GET_MODE (count_exp), count_exp);
- destreg = copy_addr_to_reg (XEXP (dst, 0));
- srcreg = copy_addr_to_reg (XEXP (src, 0));
+ destreg = ix86_copy_addr_to_reg (XEXP (dst, 0));
+ srcreg = ix86_copy_addr_to_reg (XEXP (src, 0));
unroll_factor = 1;
move_mode = word_mode;
@@ -23436,7 +23451,7 @@ ix86_expand_setmem (rtx dst, rtx count_exp,
rtx val_exp, rtx align_exp,
if (!count)
count_exp = copy_to_mode_reg (counter_mode (count_exp), count_exp);
- destreg = copy_addr_to_reg (XEXP (dst, 0));
+ destreg = ix86_copy_addr_to_reg (XEXP (dst, 0));
move_mode = word_mode;
unroll_factor = 1;
b/gcc/testsuite/gcc.target/i386/pr58690.c
new file mode 100644
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-require-effective-target maybe_x32 } */
+/* { dg-options "-O2 -mx32 -maddress-mode=short" } */
+
+struct gomp_thread
+{
+ char foo[41];
+};
+extern __thread struct gomp_thread gomp_tls_data;
+void
+foo (void)
+{
+ __builtin_memset (&gomp_tls_data, '\0', sizeof (gomp_tls_data));
+}