This is the mail archive of the gcc-bugs@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]

Re: More linpack on i386-linux analysis


I wrote:

>> This must be a specific failure of the ix86 backend - on
>> m68k-next-nextstep3 I get for the Fortran equivalent code:

[ ... wrong part of assembly code deleted ... ]

>  If you reduced the number of general-purpose registers
>  to 6, I would suspect you would see a similar problem on
>  the 680x0.

Well, looking at your (two) code examples a little bit harder, I  
have to agree with you.  The correct version of "my" assembly reads:

L11:
        fmoves a1@,fp0
        addl d1,a1
        fsglmulx fp1,fp0
        fadds a0@,fp0
        fmoves fp0,a0@
        addl d0,a0
        dbra d2,L11

which doesn't use a stack-slotted variable.

I think the reason is (contemplating the three n(%ebp) addressing  
modes), that your code is a very litteral C translation of the  
Fortran code (e.g. by f2c), which passes pointers to sa, incx and  
incy to the routine.  Although g77 will do the same, internally,  
because of the Fortran alias semantics, all three scalars will be  
copied to a (pseudo) register and treated as local variables.

For those who want to try out for themselves, here's the canonical  
saxpy.f:

      subroutine saxpy(n,sa,sx,incx,sy,incy)
c
c     constant times a vector plus a vector.
c     uses unrolled loop for increments equal to one.
c     jack dongarra, linpack, 3/11/78.
c     modified 12/3/93, array(1) declarations changed to array(*)
c
      real sx(*),sy(*),sa
      integer i,incx,incy,ix,iy,m,mp1,n
c
      if(n.le.0)return
      if (sa .eq. 0.0) return
      if(incx.eq.1.and.incy.eq.1)go to 20
c
c        code for unequal increments or equal increments
c          not equal to 1
c
      ix = 1
      iy = 1
      if(incx.lt.0)ix = (-n+1)*incx + 1
      if(incy.lt.0)iy = (-n+1)*incy + 1
      do 10 i = 1,n
        sy(iy) = sy(iy) + sa*sx(ix)
        ix = ix + incx
        iy = iy + incy
   10 continue
      return
c
c        code for both increments equal to 1
c
c
c        clean-up loop
c
   20 m = mod(n,4)
      if( m .eq. 0 ) go to 40
      do 30 i = 1,m
        sy(i) = sy(i) + sa*sx(i)
   30 continue
      if( n .lt. 4 ) return
   40 mp1 = m + 1
      do 50 i = mp1,n,4
        sy(i) = sy(i) + sa*sx(i)
        sy(i + 1) = sy(i + 1) + sa*sx(i + 1)
        sy(i + 2) = sy(i + 2) + sa*sx(i + 2)
        sy(i + 3) = sy(i + 3) + sa*sx(i + 3)
   50 continue
      return
      end

HTH,
Toon.


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