[PATCH] S/390: Addends of larl operand must be in -/+2GB range
Andreas Krebbel
Andreas.Krebbel@de.ibm.com
Fri Nov 24 15:54:00 GMT 2006
Hello,
the attached patch fixes a problem with addends to larl
(load address relative long) operands getting too large.
The patch consists of what Michael proposed in the PR
plus the changes proposed by Ulrich.
I'm about to test the patch for gcc 4.1 4.2 and mainline.
Ok for these 3 - in case there are no testsuite regressions?
Michael, thanks for looking into this.
Bye,
-Andreas-
2006-11-24 Michael Matz <matz@suse.de>
Andreas Krebbel <krebbel1@de.ibm.com>
PR target/29319
* config/s390/s390.c (legitimize_pic_address): Check addend of larl
operand to be in range of -/+2GB.
* config/s390/predicates.md (larl_operand): Likewise.
2006-11-24 Michael Matz <matz@suse.de>
Andreas Krebbel <krebbel1@de.ibm.com>
PR target/29319
* gcc.dg/20061124-2.c: New testcase.
Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig 2006-11-24 13:39:20.000000000 +0100
--- gcc/config/s390/s390.c 2006-11-24 15:52:21.000000000 +0100
*************** legitimize_pic_address (rtx orig, rtx re
*** 3002,3008 ****
|| (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
&& GET_CODE (op1) == CONST_INT)
{
! if (TARGET_CPU_ZARCH && larl_operand (op0, VOIDmode))
{
if (INTVAL (op1) & 1)
{
--- 3002,3011 ----
|| (GET_CODE (op0) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op0)))
&& GET_CODE (op1) == CONST_INT)
{
! if (TARGET_CPU_ZARCH
! && larl_operand (op0, VOIDmode)
! && INTVAL (op1) < (HOST_WIDE_INT)1 << 31
! && INTVAL (op1) >= -((HOST_WIDE_INT)1 << 31))
{
if (INTVAL (op1) & 1)
{
*************** legitimize_pic_address (rtx orig, rtx re
*** 3012,3018 ****
if (!DISP_IN_RANGE (INTVAL (op1)))
{
! int even = INTVAL (op1) - 1;
op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
op0 = gen_rtx_CONST (Pmode, op0);
op1 = const1_rtx;
--- 3015,3021 ----
if (!DISP_IN_RANGE (INTVAL (op1)))
{
! HOST_WIDE_INT even = INTVAL (op1) - 1;
op0 = gen_rtx_PLUS (Pmode, op0, GEN_INT (even));
op0 = gen_rtx_CONST (Pmode, op0);
op1 = const1_rtx;
Index: gcc/config/s390/predicates.md
===================================================================
*** gcc/config/s390/predicates.md.orig 2006-11-24 15:44:13.000000000 +0100
--- gcc/config/s390/predicates.md 2006-11-24 15:52:32.000000000 +0100
***************
*** 126,133 ****
if (GET_CODE (XEXP (op, 1)) != CONST_INT
|| (INTVAL (XEXP (op, 1)) & 1) != 0)
return false;
! if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 32
! || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 32))
return false;
op = XEXP (op, 0);
}
--- 126,133 ----
if (GET_CODE (XEXP (op, 1)) != CONST_INT
|| (INTVAL (XEXP (op, 1)) & 1) != 0)
return false;
! if (INTVAL (XEXP (op, 1)) >= (HOST_WIDE_INT)1 << 31
! || INTVAL (XEXP (op, 1)) < -((HOST_WIDE_INT)1 << 31))
return false;
op = XEXP (op, 0);
}
Index: gcc/testsuite/gcc.dg/20061124-2.c
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gcc.dg/20061124-2.c 2006-11-24 15:59:37.000000000 +0100
***************
*** 0 ****
--- 1,32 ----
+ { dg-compile }
+ { dg-options "-O1 -fPIC" }
+
+ /* PR target/29319 */
+
+ extern void abort(void);
+
+ static char l_info[100];
+
+ void bug1 (unsigned long tag)
+ {
+ char *info = l_info;
+ info[tag - 0x100000000 + 1] = 1;
+ }
+
+ void bug2 (unsigned long tag)
+ {
+ char *info = l_info;
+ info[tag - 0x100000000 + 1] = 2;
+ }
+
+ int main()
+ {
+ unsigned i;
+ for (i = 0; i < sizeof(l_info); i++)
+ l_info[i] = 0;
+ bug1(0x100000000);
+ bug2(0x100000000);
+ if (l_info[2] != 2 || l_info[1] != 1)
+ abort();
+ return 0;
+ }
More information about the Gcc-patches
mailing list