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

ARM port bug



I have founded a bug in ARM port (testcase at end of mail).
gcc version 3.0 20010525 (prerelease)

As I understand the ARM port have a `(define_expand "epilogue" ...)'
And this `define_expand' don't emit the moves on RTL level for restoring
a call-saved registers.

While `update_life_info' executed after reload the `mark_regs_live_at_end'
mark all registers used by the epilogue as being live at the end of
the function and don't unmark it because RTL version of epilogue
havn't a moves.

What's right ?
1. emit a RTL moves in epilogue;
2. remove `(define_expand "epilogue" ...)' (Why it's needed ?)


Fragment from flow.c:mark_regs_live_at_end:

  /* Mark all global registers, and all registers used by the epilogue
     as being live at the end of the function since they may be
     referenced by our caller.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (global_regs[i] || EPILOGUE_USES (i))
      SET_REGNO_REG_SET (set, i);

  if (HAVE_epilogue && reload_completed)
    {
      /* Mark all call-saved registers that we actually used.  */
      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (regs_ever_live[i] && ! call_used_regs[i] && ! LOCAL_REGNO (i))
	  SET_REGNO_REG_SET (set, i);
    }



Command line: arm-elf-linux-gcc -mcpu=strongarm -O2 -S m.i
                                ^^^important^^^
m.i: In function `__dbl_mp':
m.i:46: Internal compiler error in print_rtl_and_abort, at flow.c:6471

Testcase (it's a part of glibc/sysdeps/ieee754/dbl-64/mpa.c):

typedef struct {
  int e;
  double d[40];
} mp_no;

typedef union { int i[2]; double d; } number;

static const number
     radix = {{0x41700000, 0x00000000} },
     zero = {{0x00000000, 0x00000000} },
     one = {{0x3ff00000, 0x00000000} },
     mone = {{0xbff00000, 0x00000000} };

void __dbl_mp(double x, mp_no *y, int p)
{

  int i,n;
  double u;


  if (x == zero.d)
      return;
  else if (x > zero.d)
      y->d[0] = one.d;
  else
    {
      y->d[0] = mone.d;
      x=-x;
    }
    
  for ( ; x < one.d; y->e -= one.d)
    x *= radix.d;

}


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