This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR target/11044 (x86)
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 1 Jun 2003 17:47:11 +0200
- Subject: [PATCH] Fix PR target/11044 (x86)
Hi,
This is again a case for which GCC emits an out-of-range 'loop' instruction
when optimizing for the K6 family of processors, this time for FP code. It
occurs when compiling QuakeForge with GCC 3.3, a regression from GCC 3.2.3.
The x86 floating-point compare instructions (type "fcmp") are given a length
of 2 bytes while they are emitted by output_fp_compare() which can issue up
to two instructions; the maximum length is then 4 bytes.
Bootstrapped/regtested on k6-redhat-linux-gnu (c,c++,objc,f77 3.3 branch) and
I manually verified that the compiler gives the correct length for all
instructions in the loop (except two conservative estimates for branch
instructions).
Applied to mainline and 3.3 branch as obvious.
--
Eric Botcazou
2003-06-01 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/11044
* config/i386/i386.md (length attribute): Set length to 4
for instructions of type "fcmp".
2003-06-01 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/i386-loop-3.c: New test.
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.404.2.14
diff -u -r1.404.2.14 i386.md
--- config/i386/i386.md 7 Apr 2003 20:14:14 -0000 1.404.2.14
+++ config/i386/i386.md 1 Jun 2003 08:32:01 -0000
@@ -268,6 +268,8 @@
(define_attr "length" ""
(cond [(eq_attr "type" "other,multi,fistp")
(const_int 16)
+ (eq_attr "type" "fcmp")
+ (const_int 4)
(eq_attr "unit" "i387")
(plus (const_int 2)
(plus (attr "prefix_data16")
/* PR target/11044 */
/* Originator: Tim McGrath <misty-@charter.net> */
/* Testcase contributed by Eric Botcazou <ebotcazou@libertysurf.fr> */
/* { dg-do run { target i?86-*-* } } */
/* { dg-options "-mcpu=k6 -O3 -ffast-math -funroll-loops" } */
typedef struct
{
unsigned char colormod;
} entity_state_t;
typedef struct
{
int num_entities;
entity_state_t *entities;
} packet_entities_t;
typedef struct
{
double senttime;
float ping_time;
packet_entities_t entities;
} client_frame_t;
typedef enum
{
cs_free,
cs_server,
cs_zombie,
cs_connected,
cs_spawned
} sv_client_state_t;
typedef struct client_s
{
sv_client_state_t state;
int ping;
client_frame_t frames[64];
} client_t;
int CalcPing (client_t *cl)
{
float ping;
int count, i;
register client_frame_t *frame;
if (cl->state == cs_server)
return cl->ping;
ping = 0;
count = 0;
for (frame = cl->frames, i = 0; i < 64; i++, frame++) {
if (frame->ping_time > 0) {
ping += frame->ping_time;
count++;
}
}
if (!count)
return 9999;
ping /= count;
return ping * 1000;
}
int main(void)
{
client_t cl;
memset(&cl, 0, sizeof(cl));
cl.frames[0].ping_time = 1.0f;
if (CalcPing(&cl) != 1000)
abort();
return 0;
}