Workaround PR middle-end/55142
gcc/ 2012-11-19 H.J. Lu <hongjiu.lu@intel.com> Backported from mainline 2012-11-13 Eric Botcazou <ebotcazou@adacore.com> H.J. Lu <hongjiu.lu@intel.com> PR middle-end/55142 * config/i386/i386.c (legitimize_pic_address): Properly handle REG + CONST. (ix86_print_operand_address): Set code to 'k' when forcing addr32 prefix. For x32, zero-extend negative displacement if it < -16*1024*1024. gcc/testsuite/ 2012-11-19 H.J. Lu <hongjiu.lu@intel.com> Backported from mainline 2012-11-13 H.J. Lu <hongjiu.lu@intel.com> PR middle-end/55142 * gcc.target/i386/pr55142-1.c: New file. * gcc.target/i386/pr55142-2.c: Likewise. From-SVN: r193635
This commit is contained in:
parent
ffafac224c
commit
7b7d1fb9b2
|
@ -1,3 +1,16 @@
|
|||
2012-11-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
Backported from mainline
|
||||
2012-11-13 Eric Botcazou <ebotcazou@adacore.com>
|
||||
H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR middle-end/55142
|
||||
* config/i386/i386.c (legitimize_pic_address): Properly handle
|
||||
REG + CONST.
|
||||
(ix86_print_operand_address): Set code to 'k' when forcing
|
||||
addr32 prefix. For x32, zero-extend negative displacement if
|
||||
it < -16*1024*1024.
|
||||
|
||||
2012-11-12 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* common.opt (fvar-tracking-uninit): Document.
|
||||
|
|
|
@ -12330,7 +12330,6 @@ legitimize_pic_address (rtx orig, rtx reg)
|
|||
{
|
||||
rtx addr = orig;
|
||||
rtx new_rtx = orig;
|
||||
rtx base;
|
||||
|
||||
#if TARGET_MACHO
|
||||
if (TARGET_MACHO && !TARGET_64BIT)
|
||||
|
@ -12535,20 +12534,33 @@ legitimize_pic_address (rtx orig, rtx reg)
|
|||
}
|
||||
else
|
||||
{
|
||||
base = legitimize_pic_address (XEXP (addr, 0), reg);
|
||||
new_rtx = legitimize_pic_address (XEXP (addr, 1),
|
||||
base == reg ? NULL_RTX : reg);
|
||||
rtx base = legitimize_pic_address (op0, reg);
|
||||
enum machine_mode mode = GET_MODE (base);
|
||||
new_rtx
|
||||
= legitimize_pic_address (op1, base == reg ? NULL_RTX : reg);
|
||||
|
||||
if (CONST_INT_P (new_rtx))
|
||||
new_rtx = plus_constant (base, INTVAL (new_rtx));
|
||||
{
|
||||
if (INTVAL (new_rtx) < -16*1024*1024
|
||||
|| INTVAL (new_rtx) >= 16*1024*1024)
|
||||
{
|
||||
if (!x86_64_immediate_operand (new_rtx, mode))
|
||||
new_rtx = force_reg (mode, new_rtx);
|
||||
new_rtx
|
||||
= gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
|
||||
}
|
||||
else
|
||||
new_rtx = plus_constant (base, INTVAL (new_rtx));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GET_CODE (new_rtx) == PLUS && CONSTANT_P (XEXP (new_rtx, 1)))
|
||||
if (GET_CODE (new_rtx) == PLUS
|
||||
&& CONSTANT_P (XEXP (new_rtx, 1)))
|
||||
{
|
||||
base = gen_rtx_PLUS (Pmode, base, XEXP (new_rtx, 0));
|
||||
base = gen_rtx_PLUS (mode, base, XEXP (new_rtx, 0));
|
||||
new_rtx = XEXP (new_rtx, 1);
|
||||
}
|
||||
new_rtx = gen_rtx_PLUS (Pmode, base, new_rtx);
|
||||
new_rtx = gen_rtx_PLUS (mode, base, new_rtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -14642,7 +14654,30 @@ ix86_print_operand_address (FILE *file, rtx addr)
|
|||
}
|
||||
#endif
|
||||
gcc_assert (!code);
|
||||
code = 'l';
|
||||
code = 'k';
|
||||
}
|
||||
else if (code == 0
|
||||
&& TARGET_X32
|
||||
&& disp
|
||||
&& CONST_INT_P (disp)
|
||||
&& INTVAL (disp) < -16*1024*1024)
|
||||
{
|
||||
/* X32 runs in 64-bit mode, where displacement, DISP, in
|
||||
address DISP(%r64), is encoded as 32-bit immediate sign-
|
||||
extended from 32-bit to 64-bit. For -0x40000300(%r64),
|
||||
address is %r64 + 0xffffffffbffffd00. When %r64 <
|
||||
0x40000300, like 0x37ffe064, address is 0xfffffffff7ffdd64,
|
||||
which is invalid for x32. The correct address is %r64
|
||||
- 0x40000300 == 0xf7ffdd64. To properly encode
|
||||
-0x40000300(%r64) for x32, we zero-extend negative
|
||||
displacement by forcing addr32 prefix which truncates
|
||||
0xfffffffff7ffdd64 to 0xf7ffdd64. In theory, we should
|
||||
zero-extend all negative displacements, including -1(%rsp).
|
||||
However, for small negative displacements, sign-extension
|
||||
won't cause overflow. We only zero-extend negative
|
||||
displacements if they < -16*1024*1024, which is also used
|
||||
to check legitimate address displacements for PIC. */
|
||||
code = 'k';
|
||||
}
|
||||
|
||||
if (ASSEMBLER_DIALECT == ASM_ATT)
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2012-11-19 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
Backported from mainline
|
||||
2012-11-13 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR middle-end/55142
|
||||
* gcc.target/i386/pr55142-1.c: New file.
|
||||
* gcc.target/i386/pr55142-2.c: Likewise.
|
||||
|
||||
2012-11-09 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/stack_check3.ad[sb]: New test.
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* { dg-do compile { target { ! { ia32 } } } } */
|
||||
/* { dg-require-effective-target fpic } */
|
||||
/* { dg-options "-O2 -mx32 -fpic" } */
|
||||
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Sword d_tag;
|
||||
} Elf32_Dyn;
|
||||
struct link_map
|
||||
{
|
||||
Elf32_Dyn *l_ld;
|
||||
Elf32_Dyn *l_info[34];
|
||||
};
|
||||
extern struct link_map _dl_rtld_map __attribute__ ((visibility ("hidden")));
|
||||
static void elf_get_dynamic_info (struct link_map *l)
|
||||
{
|
||||
Elf32_Dyn *dyn = l->l_ld;
|
||||
Elf32_Dyn **info;
|
||||
info = l->l_info;
|
||||
while (dyn->d_tag != 0)
|
||||
{
|
||||
if ((uint32_t) (0x6ffffeff - dyn->d_tag) < 11)
|
||||
info[0x6ffffeff - dyn->d_tag + 12] = dyn;
|
||||
++dyn;
|
||||
}
|
||||
}
|
||||
void
|
||||
foo (void)
|
||||
{
|
||||
elf_get_dynamic_info (&_dl_rtld_map);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/* { dg-do compile { target { ! { ia32 } } } } */
|
||||
/* { dg-require-effective-target fpic } */
|
||||
/* { dg-options "-O3 -mx32 -fpic" } */
|
||||
/* { dg-final { scan-assembler-not "movl\[\\t \]*%.*,\[\\t \]*-1073742592\\(%r(.x|.i|.p|\[1-9\]*)\\)" } } */
|
||||
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef uint32_t Elf32_Word;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef struct {
|
||||
Elf32_Sword d_tag;
|
||||
union {
|
||||
Elf32_Word d_val;
|
||||
Elf32_Addr d_ptr;
|
||||
} d_un;
|
||||
} Elf32_Dyn;
|
||||
struct link_map {
|
||||
Elf32_Dyn *l_ld;
|
||||
Elf32_Dyn *l_info[34 + 16 + 3 + 12 + 11];
|
||||
};
|
||||
void
|
||||
elf_get_dynamic_info (struct link_map *l)
|
||||
{
|
||||
Elf32_Dyn *dyn = l->l_ld;
|
||||
Elf32_Dyn **info = l->l_info;
|
||||
typedef Elf32_Word d_tag_utype;
|
||||
while (dyn->d_tag != 0) {
|
||||
if ((d_tag_utype) (0x6ffffeff - dyn->d_tag) < 11)
|
||||
info[(0x6ffffeff - dyn->d_tag) + 34 + 16 + 3 + 12] = dyn;
|
||||
++dyn;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue