[gnu.gcc.bug] bug in sparc gcc 1.33

trq@MOOSE.CITA.UTORONTO.CA (Tom Quinn) (02/09/89)

The following code will compile incorrectly with the "-O" and
"-fforce-addr" flags.  This is on a Sun4/110 running SunOs 4.0.
The resulting object will generate a Bus Error at line 27 because it
is doing a "std" (store double) with an address that is not aligned on
an 8 byte boundary.

The compile:
gcc -S -g -v -O -fforce-addr -c axis.c -o axis.o
gcc version 1.33
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ axis.c /tmp/cca19292.cpp
GNU CPP version 1.33
 /usr/local/lib/gcc-cc1 /tmp/cca19292.cpp -quiet -dumpbase axis.c -fforce-addr -g -O -version -o axis.o
GNU C version 1.33 (sparc) compiled by GNU C version 1.33.

The bad assembly:
L6:
.stabn 68,0,27,LM12
LM12:
	st %l1,[%fp-4]
	ld [%fp-4],%f8
	fstod %f8,%f6
	std %f6,[%fp-8]
	ldd [%fp-8],%l6
	fstod %f2,%f6
	std %f6,[%fp-8]
	ldd [%fp-8],%l4
	sethi %hi(_xsmall),%l2
	or %lo(_xsmall),%l2,%l2
	ld [%l2],%f2
	sub %sp,32,%sp
	add %sp,92,%o0		#if sp is 8 byte aligned, o0 is not
	sethi %hi(_xbig),%l3
	or %lo(_xbig),%l3,%l3
	ld [%l3],%f4
	fstod %f4,%f4
	std %f4,[%o0]		# this will cause a bus error
	sethi %hi(_gx1),%l0
	or %lo(_gx1),%l0,%l0
	ld [%l0],%i2
	st %i2,[%o0+8]
	sethi %hi(_gy1),%g1
	ld	[%g1+%lo(_gy1)],%i2
	st %i2,[%o0+12]
	sethi %hi(_gx2),%l1
	or %lo(_gx2),%l1,%l1
	ld [%l1],%o1
	ld [%l0],%o2
	sub %o1,%o2,%o1
	st %o1,[%o0+16]
	st %i0,[%o0+20]
	st %g0,[%o0+24]
	mov %l6,%o0
	mov %l7,%o1
	mov %l4,%o2
	mov %l5,%o3
	fstod %f2,%f6
	std %f6,[%fp-8]
	ldd [%fp-8],%o4
	call _axis,0
	nop


The code:
------------------------------------------------------------------------
extern float 
  	     fx1,fx2;      
extern int   gx1,gx2,gy1,gy2;      
extern double pow();
void angle(),
     ltype();
static float xsmall = 0.,
	     xbig   = 0.;
box(labelxl, labelxu)
int labelxl, labelxu;
{
   float a1,a2;
    ltype(0);
    angle(0.);
    if(xsmall < 0) {                        
       if(fabs(fx1) > 37 || fabs(fx2) > 37) {
	  msg("|x-limits| are too large for logarithmic axes\n");
	  a1 = fx1; a2 =fx2;
	  xsmall = 0;
       } else {
	  a1 = pow(10.,fx1);
	  a2 = pow(10.,fx2);
       }
    } else {				 
       a1 = fx1; a2 =fx2;
    }
    (void)axis(a1,a2,xsmall,xbig,gx1,gy1,gx2-gx1,labelxl,0);
    (void)axis(a1,a2,xsmall,xbig,gx1,gy2,gx2-gx1,labelxu,1);
}

trq@MOOSE.CITA.UTORONTO.CA (Tom Quinn) (02/09/89)

The following code compiles incorrectly with the "-g -O" options.
This is gcc version 1.33 on a Sun4/110 running SunOs 4.0.  The problem
appears to be a typo in sparc.md.  A fix is given below.

Tom Quinn                 Canadian Institute for Theoretical Astrophysics
trq@moose.cita.utoronto.ca
UUCP   - decvax!utgpu!moose!trq
BITNET - quinn@utorphys.bitnet
ARPA   - trq%moose.cita.toronto.edu@relay.cs.net

The compile:
gcc -S -g -v -O -c abbrev.c -o abbrev.o
gcc version 1.33
 /usr/local/lib/gcc-cpp -v -undef -D__GNUC__ -Dsparc -Dsun -Dunix -D__sparc__ -D__sun__ -D__unix__ -D__OPTIMIZE__ abbrev.c /tmp/cca22552.cpp
GNU CPP version 1.33
 /usr/local/lib/gcc-cc1 /tmp/cca22552.cpp -quiet -dumpbase abbrev.c -g -O -version -o abbrev.o
GNU C version 1.33 (sparc) compiled by GNU C version 1.33.

The bad assembly:
.stabn 68,0,64,LM7
LM7:
	sethi %hi(_Vlast_abbrev_text),%g1
	ldsb [%g1+%lo(a1)],%o0            # a1???
	cmp %o0,3
	bne L4
	nop

A fix to sparc.md:
diff -c -r1.1 sparc.md
*** /tmp/,RCSt1a22560   Thu Feb  9 10:00:21 1989
--- sparc.md    Thu Feb  9 08:18:57 1989
***************
*** 1696,1702
      {
        cc_status.flags |= CC_KNOW_HI_G1;
        cc_status.mdep = XEXP (operands[1], 0);
!       return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(a1)],%0\";
      }
    return \"ldsb %1,%0\";
  }")

--- 1696,1702 -----
      {
        cc_status.flags |= CC_KNOW_HI_G1;
        cc_status.mdep = XEXP (operands[1], 0);
!       return \"sethi %%hi(%m1),%%g1\;ldsb [%%g1+%%lo(%m1)],%0\";
      }
    return \"ldsb %1,%0\";
  }")
***************
*** 1712,1718
      {
        cc_status.flags |= CC_KNOW_HI_G1;
        cc_status.mdep = XEXP (operands[1], 0);
!       return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(a1)],%0\";
      }
    return \"ldub %1,%0\";
  }")

--- 1712,1718 -----
      {
        cc_status.flags |= CC_KNOW_HI_G1;
        cc_status.mdep = XEXP (operands[1], 0);
!       return \"sethi %%hi(%m1),%%g1\;ldub [%%g1+%%lo(%m1)],%0\";
      }
    return \"ldub %1,%0\";
  }")

The code:
enum Lisp_Type
  {
    Lisp_Int,
    Lisp_Symbol,
    Lisp_Marker,
    Lisp_String,
    Lisp_Vector,
    Lisp_Cons,
    Lisp_Object_Unused_1,
    Lisp_Buffer,
    Lisp_Subr,
    Lisp_Internal,
    Lisp_Intfwd,
    Lisp_Boolfwd,
    Lisp_Process,
    Lisp_Objfwd,
    Lisp_Object_Unused_2,
    Lisp_Internal_Stream,
    Lisp_Buffer_Local_Value,
    Lisp_Some_Buffer_Local_Value,
    Lisp_Buffer_Objfwd,
    Lisp_Void,
    Lisp_Window,
    Lisp_Window_Configuration
  };
struct Lisp_String
  {
    int size;
    unsigned char data[1];
  };
struct Lisp_Symbol
  {
    struct Lisp_String *name;
    int  value;
    int  function;
    int  plist;
    struct Lisp_Symbol *next;	 
  };
struct buffer_text
  {
    unsigned char *p1;		 
    unsigned char *p2;		 
    int size1;			 
    int size2;			 
    int gap;			 
    int modified;		 
    int head_clip;		 
    int tail_clip;		 
    int pointloc;		 
  };
extern int  Qnil;
int  Vlast_abbrev;
int  Vlast_abbrev_text;
int last_abbrev_point;
extern struct buffer_text bf_text;
int   Funexpand_abbrev ()
{
  int opoint = bf_text.pointloc ;
  int adjust = 0;
  if (last_abbrev_point < bf_text.head_clip 
      || last_abbrev_point > (bf_text.size1+bf_text.size2-bf_text.tail_clip) )
    return Qnil;
   bf_text.pointloc  =  (last_abbrev_point);
  if (((enum Lisp_Type) ((Vlast_abbrev_text) >> 24 ))  == Lisp_String)
    {
      int  val;
      ((val) = ((int)( Lisp_String) << 24 ) + ((int) ( ((struct Lisp_Symbol *) ((Vlast_abbrev) & ((1<<24 ) - 1) )  ) ->value) & ((1<<24 ) - 1) )) ;
      adjust = ((struct Lisp_String *) ((val) & ((1<<24 ) - 1) )  ) ->size;
      del_range (bf_text.pointloc , bf_text.pointloc  + adjust);
      InsCStr (((struct Lisp_String *) ((Vlast_abbrev_text) & ((1<<24 ) - 1) )  ) ->data,
	       ((struct Lisp_String *) ((Vlast_abbrev_text) & ((1<<24 ) - 1) )  ) ->size);
      adjust -= ((struct Lisp_String *) ((Vlast_abbrev_text) & ((1<<24 ) - 1) )  ) ->size;
      Vlast_abbrev_text = Qnil;
    }
   bf_text.pointloc  =  (last_abbrev_point < opoint ? opoint - adjust : opoint);
  return Qnil;
}