This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[3.3] Fix PR target/11689 (x86)
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 6 Sep 2003 15:47:06 +0200
- Subject: [3.3] Fix PR target/11689 (x86)
Hi,
This is yet another testcase for which GCC produces unassemblable code for
the K6 family of processors, a regression from GCC 3.2.3 present on the 3.3
branch.
As usual, the compiler produces out-of-range 'loop' insns because of
underestimated instruction lengths. The bug has been latent since egcs.
Bootstrapped/regtested on k6-redhat-linux-gnu (c,c++,objc,f77 3.3 branch).
Ok for 3.3 branch and mainline?
2003-09-06 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/11689
* config/i386/i386.c (memory_address_length): Fix computation when
the base is esp or ebp.
2003-09-06 Eric Botcazou <ebotcazou@libertysurf.fr>
* g++.dg/opt/longbranch2.C: New test.
--
Eric Botcazou
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.495.2.25
diff -u -p -r1.495.2.25 i386.c
--- config/i386/i386.c 26 Aug 2003 21:29:36 -0000 1.495.2.25
+++ config/i386/i386.c 6 Sep 2003 13:30:48 -0000
@@ -11183,10 +11183,15 @@ memory_address_length (addr)
disp = parts.disp;
len = 0;
+ /* Rule of thumb:
+ - esp as the base always wants an index,
+ - ebp as the base always wants a displacement. */
+
/* Register Indirect. */
if (base && !index && !disp)
{
- /* Special cases: ebp and esp need the two-byte modrm form. */
+ /* esp (for its index) and ebp (for its displacement) need
+ the two-byte modrm form. */
if (addr == stack_pointer_rtx
|| addr == arg_pointer_rtx
|| addr == frame_pointer_rtx
@@ -11210,9 +11215,16 @@ memory_address_length (addr)
else
len = 4;
}
+ /* ebp always wants a displacement. */
+ else if (base == hard_frame_pointer_rtx)
+ len = 1;
- /* An index requires the two-byte modrm form. */
- if (index)
+ /* An index requires the two-byte modrm form... */
+ if (index
+ /* ...like esp, which always wants an index. */
+ || base == stack_pointer_rtx
+ || base == arg_pointer_rtx
+ || base == frame_pointer_rtx)
len += 1;
}
// PR target/11689
// Originator: thor@math.tu-berlin.de
// { dg-do compile }
// { dg-options "-O3 -funroll-loops -mcpu=k6 -fomit-frame-pointer" { target i?86-*-* } }
// This used to fail to assemble because of an out-of-range 'loop' instructions.
class JKeeper {
public:
unsigned long a0;
};
class EBCOTLut : public JKeeper {
unsigned char a1[1<<8];
unsigned char a2[1<<8];
unsigned char a3[1<<8];
long a4[1<<9];
public:
EBCOTLut(void);
};
EBCOTLut::EBCOTLut(void)
{
unsigned char inter[36]; // intermediate lookup table;
unsigned long i;
for(i=0;i<36;i++) {
inter[i] = 0;
}
for(i=1;i<16;i++) {
a1[i | (1<<7)] = 8<<1;
a1[i | (1<<6)] = 8<<1;
}
for(i=0;i < ((1<<9)-1);i++) {
int ds = (i>>0) & 0x01; // significance of DOWN
int us = (i>>1) & 0x01; // significance of UP
int rs = (i>>2) & 0x01; // significance of RIGHT
int ls = (i>>3) & 0x01; // significance of LEFT
int dn = (i>>5) & 0x01; // sign of DOWN
int un = (i>>6) & 0x01; // sign of UP
int rn = (i>>7) & 0x01; // sign of RIGHT
int ln = (i>>8) & 0x01; // sign of LEFT
int h,v; // h and v as in the VM description
h = ls*(1-ln*2) + rs*(1-2*rn);
v = us*(1-un*2) + ds*(1-2*dn);
h = (h >= -1)?(h):(-1);
v = (v >= -1)?(v):(-1);
h = (h <= 1)?(h):(1);
v = (v <= 1)?(v):(1);
a2[i] = inter[((h+1)<<3) | (v+1)];
a3[i] = inter[((h+1)<<3) | (v+1)] & (unsigned char)(~1);
}
for(i=0;i< 1<<9; i++) {
a4[i] = 2*(i-(1<<(9-1)))*(i-(1<<(9-1))) -
((i< (1<<(9-1)))?
(2*(i-(1<<(9-2)))*(i-(1<<(9-2)))):
(2*(i-(3<<(9-2)))*(i-(3<<(9-2)))));
}
}