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: PPro patch for egcs


> Please describe the special cases.
> 
> > if ((code == GT || code == LE)
> >     && (cc_prev_status.flags & CC_NO_OVERFLOW))
> >   return NULL_PTR;
> 
> It's not clear to me that this is correct.  The general form for

That is very tricky.

> a conditional move is:
> 
>   r <- cond ? arg1 : arg2
> 
> It seems that the above code will result in missing move instructions
> in some situations.  A comment in the code describing what's intended
> would be helpful.

Ok, I added some comments. BTW, gcc has been doing it right for all but 
conditional move. My PPro patche also fixes other PPro bugs in i386.c,
i386.md and reg-stack.c. Let me know if there is any other question.
The Pentium Pro/II reference manual is needed to understand them.

> 
> As a personal style issue I prefer using:
> 
>   switch ( variable )
>     {

It is a leftover from old code. I just need to change one place for it.
Here are the new ones.


H.J.
---
char *
output_fp_conditional_move (which_alternative, operands)
     int which_alternative;
     rtx operands[];
{
  switch (which_alternative)
    {
    case 0:
      /* r <- cond ? arg : r */
      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
      break;
  
    case 1:
      /* r <- cond ? r : arg */
      output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
      break;

    case 2:
      /* r <- cond ? r : arg */
      output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
      output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
      break;

    default:
      abort ();
    }

  return "";
}

char *
output_int_conditional_move (which_alternative, operands)
     int which_alternative;
     rtx operands[];
{
  int code = GET_CODE (operands[1]);
  enum machine_mode mode;
  rtx xops[4];

  /* This is very tricky. We have to do it right. For a code segement
     like:

	int foo, bar;
	....
	foo = foo - x;
	if (foo >= 0)
	  bar = y;

     final_scan_insn () may delete the insn which sets CC. We have to
     tell final_scan_insn () if it should be reinserted. When CODE is
     GT or LE, we have to check the CC_NO_OVERFLOW bit and return
     NULL_PTR to tell final to reinsert the test insn because the
     conditional move cannot be handled properly without it. */
  if ((code == GT || code == LE)
      && (cc_prev_status.flags & CC_NO_OVERFLOW))
    return NULL_PTR;

  mode = GET_MODE (operands [0]);
  if (mode == DImode)
    {
      xops [0] = gen_rtx_SUBREG (SImode, operands [0], 1);
      xops [1] = operands [1];
      xops [2] = gen_rtx_SUBREG (SImode, operands [2], 1);
      xops [3] = gen_rtx_SUBREG (SImode, operands [3], 1);
    }

  switch (which_alternative)
    {
    case 0:
      /* r <- cond ? arg : r */
      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
      if (mode == DImode)
	output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
      break;

    case 1:
      /* r <- cond ? r : arg */
      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
      if (mode == DImode)
	output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
      break;

    case 2:
      /* rm <- cond ? arg1 : arg2 */
      output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
      output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
      if (mode == DImode)
	{
	  output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
	  output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
	}
      break;

    default:
      abort ();
    }

  return "";
}


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