This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: PPro patch for egcs
- To: john at feith dot com (John Wehle)
- Subject: Re: PPro patch for egcs
- From: hjl at lucon dot org (H.J. Lu)
- Date: Wed, 3 Jun 1998 14:05:36 -0700 (PDT)
- Cc: law at cygnus dot com, egcs at cygnus dot com
> 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 "";
}