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]

Re: Your change to jump.c breaks conditional move?


On Thu, Jun 04, 1998 at 07:40:12AM -0700, H.J. Lu wrote:
> > I'll be happy to fix any problems if you can show me an incorrect
> > transformation in any jump pass.  But I really suspect things go wrong
> > for you in reload.

Well, I was wrong, the problem isn't in reload.  But it isn't in
jump.c either.  The lossage is occurring in force_operand.

Given

(plus:SI (reg:SI 3 %ebx)
    (symbol_ref/v:SI ("*.LC0")))

force_operand is generating

(insn 169 0 170 (set (reg:SI 55)
        (plus:SI (reg:SI 3 %ebx)
            (symbol_ref/v:SI ("*.LC0")))) -1 (nil)
    (nil))

(insn 170 169 172 (set (reg:SI 54)
        (reg:SI 55)) -1 (nil)
    (nil))

(insn 172 170 0 (set (reg:SI 53)
        (plus:SI (reg:SI 3 %ebx)
            (reg:SI 54))) -1 (nil)
    (nil))

I'm not sure what the proper thing to do to curtail this lossage, 
but the following seems to work.

The generated code is actually pretty ugly.  But I think there's
an easy way to fix that up.  


r~


Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.64
diff -c -p -d -r1.64 expr.c
*** expr.c	1998/06/02 22:48:51	1.64
--- expr.c	1998/06/04 18:12:36
*************** force_operand (value, target)
*** 4526,4532 ****
    register rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
  
    if (GET_CODE (value) == PLUS)
!     binoptab = add_optab;
    else if (GET_CODE (value) == MINUS)
      binoptab = sub_optab;
    else if (GET_CODE (value) == MULT)
--- 4526,4543 ----
    register rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
  
    if (GET_CODE (value) == PLUS)
!     {
!       /* Check for a PIC address load.  */
!       if (flag_pic && XEXP (value, 0) == pic_offset_table_rtx)
!         {
! 	  if (!subtarget)
! 	    subtarget = gen_reg_rtx (GET_MODE (value));
! 	  emit_move_insn (subtarget, value);
! 	  return subtarget;
! 	}
! 
!       binoptab = add_optab;
!     }
    else if (GET_CODE (value) == MINUS)
      binoptab = sub_optab;
    else if (GET_CODE (value) == MULT)



HJ's test case:
#include <stdio.h>

struct foo
{
  char buf [256];
  int flags;
};

typedef struct foo foo;

void write_int (foo *s, unsigned long long int val)
{
  char buf [256];
  char *buf_ptr = buf + sizeof (buf);
  int len;
  int i;

  if (s->flags)
  {
    const char *xdigs = s->flags & 0x1
			? "0123456789ABCDEF0X" : "0123456789abcdef0x";
    do
    {
      *--buf_ptr = xdigs[val & 15];
      val = val >> 4;
    } while (val != 0);
  }
  else
  {
    register unsigned int ival = (unsigned int)val;
    do
    {
      *--buf_ptr = (ival % 10) + '0';
      ival /= 10;
    } while (ival != 0);
  }

  len = buf + sizeof (buf) - buf_ptr;
  for (i = 0; i < len; i++)
    s->buf [i] = buf_ptr [i];
}

main ()
{
  foo x;
  x.flags = -1;

  write_int (&x, 0x1234);

  printf ("%s\n", x.buf);
}


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