Reload problem on ppc64 (was: Analysis of high priority PR c/2454)

Michael Matz matzmich@cs.tu-berlin.de
Tue Jul 2 01:58:00 GMT 2002


Hi,

On Mon, 1 Jul 2002, Jeff Law wrote:

> Yes, it's true that any paradoxical subreg which exists at reload time
> will be loaded from memory,

Unfortunately this is not entirely true on the 3.1 branch for ppc64.
In one testcase (attached) reload starts with this insn:
(set (reg:DF 229) (float:DF (subreg:DI (reg:SI 338) 0)))

and pseudo 338 gets no hardreg.  It's the floatdidf2 insn, so the
constraints are "=f" resp. "f".  Operand 1 is (subreg:DI (reg:SI 338) 0).

Now reload allocates a stackslot for 338, but obviously somewhen the
reload isn't correctly produced for this, as it looks like:

(set (subreg:SI (reg:DI 43 f11) 4) (mem:SI (plus:DI (reg/f:DI ...

Look at how it tries to produce a subreg of a floating point register.
This is a mode change, but nevertheless it tried to use class FLOAT_REGS
(which is CLASS_CANNOT_CHANGE_MODE) for it.  Of course that insn can't be
recognized.

I tried to analyze it yesterday, but am not sure, why reload doesn't
produce all needed reloads.  First it should create a reload to load the
paradoxical subreg into an integer reg (i.e. to implement the mode
change), and then a second reload to get it into the float reg.  I'm not
yet sure, why it doesn't.


Ciao,
Michael.
-------------- next part --------------
typedef struct _GuppiAlphaTemplate {
  int x_base_point, y_base_point;
  int width, height;
  unsigned char *data;
}GuppiAlphaTemplate;


void
guppi_alpha_template_gradient_print (GuppiAlphaTemplate *atemp,
                                     int x, int y,
                                     unsigned int rgba1, unsigned int rgba2,
                                     int start)
{
  int w, h;
  unsigned int c, rnow, gnow, bnow, anow;
  double t;


    int atpr_x0, atpr_y0, atpr_x1, atpr_y1;
    int atpr_i, atpr_j;
    unsigned char *atpr_ap;
    unsigned char *atpr_arun;
    unsigned char *atpr_rgbp;
    char *atpr_rgbrun;


    atpr_x0 = (((x) > (0)) ? (x) : (0));
    atpr_y0 = (((y) > (0)) ? (y) : (0));
    atpr_x1 = (((x + atemp->width - 1) < (w - 1)) ? (x + atemp->width - 1) : (w - 1));
    atpr_y1 = (((y + atemp->height - 1) < (h - 1)) ? (y + atemp->height - 1) : (h - 1));

    atpr_ap = atemp->data + atemp->width * (atpr_y0 - y) + (atpr_x0 - x);
    atpr_rgbp = 2 * atpr_y0 + 3 * atpr_x0;
    for (atpr_j = atpr_y0; atpr_j <= atpr_y1; ++atpr_j) {
      atpr_arun = atpr_ap;
      atpr_rgbrun = atpr_rgbp;

      t = (atpr_j-y) / (double) (atemp->height-1);
      c = (((((((unsigned int)(((int)rint(((((unsigned int)(rgba2))>>24))*(t)+((((unsigned int)(rgba1))>>24))*(1-(t))))))<<16)|(((unsigned int)(((int)rint((((((unsigned int)(rgba2))>>16)&0xff))*(t)+(((((unsigned int)(rgba1))>>16)&0xff))*(1-(t))))))<<8)|((unsigned int)(((int)rint((((((unsigned int)(rgba2))>>8)&0xff))*(t)+(((((unsigned int)(rgba1))>>8)&0xff))*(1-(t)))))))) << 8) | ((((unsigned int)((int)rint(((((unsigned int)(rgba2))&0xff))*(t)+((((unsigned int)(rgba1))&0xff))*(1-(t))))) & 0xff)));
      { { (*(&rnow)) = ((((c)>>8))>>16)&0xff; (*(&gnow)) = ((((c)>>8))>>8)&0xff; (*(&bnow)) = (((c)>>8))&0xff; }; (*(&anow)) = (c)&0xff; };

      for (atpr_i = atpr_x0; atpr_i <= atpr_x1; ++atpr_i) {
         {
          { if ((((1 + anow) * (1 + *atpr_arun)) >> 8)>=0xff) { {((unsigned char*)(atpr_rgbrun))[0]=(rnow); ((unsigned char*)(atpr_rgbrun))[1]=(gnow); ((unsigned char*)(atpr_rgbrun))[2]=(bnow);} } else if ((((1 + anow) * (1 + *atpr_arun)) >> 8)>0) { unsigned int pixel_tmp; pixel_tmp = ((unsigned char*)(atpr_rgbrun))[0]; ((unsigned char*)(atpr_rgbrun))[0] = pixel_tmp + ((((rnow)-pixel_tmp)*(((1 + anow) * (1 + *atpr_arun)) >> 8)+0x80) >> 8); pixel_tmp = ((unsigned char*)(atpr_rgbrun))[1]; ((unsigned char*)(atpr_rgbrun))[1] = pixel_tmp + ((((gnow)-pixel_tmp)*(((1 + anow) * (1 + *atpr_arun)) >> 8)+0x80) >> 8); pixel_tmp = ((unsigned char*)(atpr_rgbrun))[2]; ((unsigned char*)(atpr_rgbrun))[2] = pixel_tmp + ((((bnow)-pixel_tmp)*(((1 + anow) * (1 + *atpr_arun)) >> 8)+0x80) >> 8); }};

        }
        ++atpr_arun;
        atpr_rgbrun += 3;
      }
    }
}


More information about the Gcc mailing list