aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2003-09-08 08:41:49 +0200
committerEric Botcazou <ebotcazou@gcc.gnu.org>2003-09-08 06:41:49 +0000
commit7b65ed544822a16bf1786ecab90412bd26cf7f62 (patch)
tree18f46d4c3950b44a19601869093814166470bd2f /gcc
parent6a4f08f318032e79025792157c9aad041ca96968 (diff)
downloadgcc-7b65ed544822a16bf1786ecab90412bd26cf7f62.zip
gcc-7b65ed544822a16bf1786ecab90412bd26cf7f62.tar.gz
gcc-7b65ed544822a16bf1786ecab90412bd26cf7f62.tar.bz2
re PR target/11689 (g++3.3 emits un-assembleable code for k6 architecture)
PR target/11689 * config/i386/i386.c (memory_address_length): Fix computation when the base is esp or ebp. From-SVN: r71198
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c18
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/opt/longbranch2.C62
4 files changed, 87 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index edd91eb..06f8a05 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2003-09-07 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-07 Mark Mitchell <mark@codesourcery.com>
PR c++/11852
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 51cf4e8..04baa3c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11654,10 +11654,15 @@ memory_address_length (rtx 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
@@ -11681,9 +11686,16 @@ memory_address_length (rtx 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;
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 2a65bb2..3ee1a76 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2003-09-07 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * g++.dg/opt/longbranch2.C: New test.
+
2003-09-07 Andrew Pinski <pinskia@physics.uc.edu>
* g++.dg/template/crash10.C: Only compile it.
diff --git a/gcc/testsuite/g++.dg/opt/longbranch2.C b/gcc/testsuite/g++.dg/opt/longbranch2.C
new file mode 100644
index 0000000..b74cedd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/longbranch2.C
@@ -0,0 +1,62 @@
+// PR target/11689
+// Originator: thor@math.tu-berlin.de
+
+// { dg-do compile }
+// { dg-options "-O3 -funroll-loops -mtune=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)))));
+
+ }
+}