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]

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

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