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]

egcs-19981226 bug: post_inc?



An egcs-19981226 cross compiler from sparc-sun-solaris2.5 to
vax-dec-vms stumbles over  c-torture compile/951206-1.c.

./xgcc -B./ -c -O 950612-1.c
950612-1.c: In function `f':
950612-1.c:134: internal error--insn does not satisfy its constraints:
(insn 82 661 83 (set (mem:DI (plus:SI (reg:SI 13 fp)
                (const_int -144)) 0)
        (plus:DI (mem:DI (plus:SI (reg:SI 13 fp)
                    (const_int -144)) 0)
            (mem:DI (post_inc:SI (reg:SI 2 r2)) 0))) 53 {adddi3} (nil)
    (expr_list:REG_INC (reg:SI 2 r2)
        (expr_list:REG_INC (reg:SI 2 r2)
            (nil))))
../ccdir/gcc/toplev.c:1397: Internal compiler error in function fatal_insn


951206-1.c
---------------
typedef enum
{
  LODI,
  STO,
  ADDI,
  ADD,
  SUBI,
  SUB,
  MULI,
  MUL,
  DIVI,
  DIV,
  INC,
  DEC
} INSN;

f (pc)
     short *pc;
{
  long long stack[16], *sp = &stack[16], acc = 0;

  for (;;)
    {
      switch ((INSN)*pc++)
	{
	case LODI:
	  *--sp = acc;
	  acc = ((long long)*pc++) << 32;
	  break;
	case STO:
	  return (acc >> 32) + (((((unsigned long long) acc) & 0xffffffff)  & (1 << 31)) != 0);
	  break;
	case ADDI:
	  acc += ((long long)*pc++) << 32;
	  break;
	case ADD:
	  acc = *sp++ + acc;
	  break;
	case SUBI:
	  acc -= ((long long)*pc++) << 32;
	  break;
	case SUB:
	  acc = *sp++ - acc;
	  break;
	case MULI:
	  acc *= *pc++;
	  break;
	case MUL:
	  {
	    long long aux;
	    unsigned char minus;

	    minus = 0;
	    aux = *sp++;
	    if (aux < 0)
	      {
		minus = ~minus;
		aux = -aux;
	      }
	    if (acc < 0)
	      {
		minus = ~minus;
		acc = -acc;
	      }
	    acc = ((((((unsigned long long) acc) & 0xffffffff)  * (((unsigned long long) aux) & 0xffffffff)) >> 32)
		   + ((((unsigned long long) acc) >> 32)  * (((unsigned long long) aux) & 0xffffffff)  + (((unsigned long long) acc) & 0xffffffff)  + (((unsigned long long) aux) >> 32))
		   + (((((unsigned long long) acc) >> 32)  * (((unsigned long long) aux) >> 32)) << 32));
	    if (minus)
	      acc = -acc;
	  }
	  break;
	case DIVI:
	  {
	    short aux;

	    aux = *pc++;
	    acc = (acc + aux / 2) / aux;
	  }
	  break;
	case DIV:
	  {
	    long long aux;
	    unsigned char minus;

	    minus = 0;
	    aux = *sp++;
	    if (aux < 0)
	      {
		minus = ~minus;
		aux = -aux;
	      }
	    if (acc < 0)
	      {
		minus = ~minus;
		acc = -acc;
	      }

	    if (((unsigned long long)acc)  == 0)
	      acc = (unsigned long long)-1 / 2;
	    else if ((((unsigned long long) ((unsigned long long)acc)) & 0xffffffff)  == 0)
	      acc = ((unsigned long long)aux)  / (((unsigned long long) ((unsigned long long)acc)) >> 32);
	    else if ((((unsigned long long) ((unsigned long long)acc)) >> 32)  == 0)
	      acc = ((((unsigned long long)aux)  / ((unsigned long long)acc)) << 32)
		+ ((((unsigned long long)aux)  % ((unsigned long long)acc)) << 32) / ((unsigned long long)acc);
	    else
	      {
		unsigned char shift;
		unsigned long hi;

		shift = 32;
		hi = (((unsigned long long) ((unsigned long long)acc)) >> 32);
		do {
		  if (hi & ((unsigned long)1 << (shift - 1)))
		    break;
		} while (--shift != 0);
		printf("shift = %d\n", shift);
		acc = ((((unsigned long long)aux)  / ((unsigned long long)acc)) << 32)
		  + (((((unsigned long long)aux)  % ((unsigned long long)acc)) << (32 - shift)) + ((((unsigned long long)acc)  >> shift) / 2)) / (((unsigned long long)acc)  >> shift);
	      }

	    if (minus)
	      acc = -acc;
	  }
	  break;
	case INC:
	  acc += 1;
	  break;
	case DEC:
	  acc -= 1;
	  break;
	}
      printf("%08lx.%08lx\n", (long)(((unsigned long long) acc) >> 32) , (long)(((unsigned long long) acc) & 0xffffffff));
    }
}



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