This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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)))));

  }
} 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]