mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-11 02:54:30 +08:00
i386.c (output_fp_conditional_move): New function to output floating point conditional move.
* i386/i386.c (output_fp_conditional_move): New function to output floating point conditional move. (output_int_conditional_move): New function to output integer conditional move. * i386/i386.md (movsicci+5, movhicc+5, movdicc+5): Call output_int_conditional_move () to output int conditional move. (movsfcc+5, movdfcc+5, movxfcc+5): Call output_fp_conditional_move () to output floating point conditional move. * i386/i386.c (put_condition_code): In INT mode, check cc_prev_status.flags & CC_NO_OVERFLOW for GE and LT. From-SVN: r20233
This commit is contained in:
parent
265078b93f
commit
b657fc397e
@ -1,3 +1,19 @@
|
||||
Fri Jun 5 01:12:15 1998 H.J. Lu (hjl@gnu.org)
|
||||
|
||||
* i386/i386.c (output_fp_conditional_move): New function
|
||||
to output floating point conditional move.
|
||||
(output_int_conditional_move): New function to output integer
|
||||
conditional move.
|
||||
|
||||
* i386/i386.md (movsicci+5, movhicc+5, movdicc+5): Call
|
||||
output_int_conditional_move () to output int conditional move.
|
||||
(movsfcc+5, movdfcc+5, movxfcc+5): Call
|
||||
output_fp_conditional_move () to output floating point
|
||||
conditional move.
|
||||
|
||||
* i386/i386.c (put_condition_code): In INT mode, check
|
||||
cc_prev_status.flags & CC_NO_OVERFLOW for GE and LT.
|
||||
|
||||
Thu Jun 4 16:09:51 1998 Dave Brolley <brolley@cygnus.com>
|
||||
|
||||
* dbxout.c (dbxout_type): Output arrays of bits as if
|
||||
|
@ -3097,7 +3097,10 @@ put_condition_code (code, reverse_cc, mode, file)
|
||||
return;
|
||||
|
||||
case GE:
|
||||
fputs ("ge", file);
|
||||
if (cc_prev_status.flags & CC_NO_OVERFLOW)
|
||||
fputs ("ns", file);
|
||||
else
|
||||
fputs ("ge", file);
|
||||
return;
|
||||
|
||||
case GT:
|
||||
@ -3109,7 +3112,10 @@ put_condition_code (code, reverse_cc, mode, file)
|
||||
return;
|
||||
|
||||
case LT:
|
||||
fputs ("l", file);
|
||||
if (cc_prev_status.flags & CC_NO_OVERFLOW)
|
||||
fputs ("s", file);
|
||||
else
|
||||
fputs ("l", file);
|
||||
return;
|
||||
|
||||
case GEU:
|
||||
@ -5132,3 +5138,124 @@ output_strlen_unroll (operands)
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
char *
|
||||
output_fp_conditional_move (which_alternative, operands)
|
||||
int which_alternative;
|
||||
rtx operands[];
|
||||
{
|
||||
int code = GET_CODE (operands[1]);
|
||||
|
||||
/* This is very tricky. We have to do it right. For a code segement
|
||||
like:
|
||||
|
||||
int foo;
|
||||
double 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;
|
||||
|
||||
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 "";
|
||||
}
|
||||
|
@ -7307,35 +7307,7 @@ byte_xor_operation:
|
||||
(match_operand:SI 2 "nonimmediate_operand" "rm,0,rm")
|
||||
(match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))]
|
||||
"TARGET_CMOVE && reload_completed"
|
||||
"*
|
||||
{
|
||||
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
/* r <- cond ? arg : r */
|
||||
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* r <- cond ? r : arg */
|
||||
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* r <- cond ? arg1 : arg2 */
|
||||
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
|
||||
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
|
||||
RET;
|
||||
}")
|
||||
"* return output_int_conditional_move (which_alternative, operands);")
|
||||
|
||||
(define_expand "movhicc"
|
||||
[(set (match_operand:HI 0 "register_operand" "")
|
||||
@ -7410,35 +7382,7 @@ byte_xor_operation:
|
||||
(match_operand:HI 2 "nonimmediate_operand" "rm,0,rm")
|
||||
(match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))]
|
||||
"TARGET_CMOVE && reload_completed"
|
||||
"*
|
||||
{
|
||||
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
/* r <- cond ? arg : r */
|
||||
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
/* r <- cond ? r : arg */
|
||||
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* r <- cond ? arg1 : arg2 */
|
||||
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
|
||||
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
|
||||
RET;
|
||||
}")
|
||||
"* return output_int_conditional_move (which_alternative, operands);")
|
||||
|
||||
(define_expand "movsfcc"
|
||||
[(set (match_operand:SF 0 "register_operand" "")
|
||||
@ -7512,35 +7456,7 @@ byte_xor_operation:
|
||||
(match_operand:SF 2 "register_operand" "f,0,f")
|
||||
(match_operand:SF 3 "register_operand" "0,f,f")))]
|
||||
"TARGET_CMOVE && reload_completed"
|
||||
"*
|
||||
{
|
||||
|
||||
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();
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
|
||||
RET;
|
||||
}")
|
||||
"* return output_fp_conditional_move (which_alternative, operands);")
|
||||
|
||||
(define_expand "movdfcc"
|
||||
[(set (match_operand:DF 0 "register_operand" "")
|
||||
@ -7614,35 +7530,7 @@ byte_xor_operation:
|
||||
(match_operand:DF 2 "register_operand" "f,0,f")
|
||||
(match_operand:DF 3 "register_operand" "0,f,f")))]
|
||||
"TARGET_CMOVE && reload_completed"
|
||||
"*
|
||||
{
|
||||
|
||||
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();
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
|
||||
RET;
|
||||
}")
|
||||
"* return output_fp_conditional_move (which_alternative, operands);")
|
||||
|
||||
(define_expand "movxfcc"
|
||||
[(set (match_operand:XF 0 "register_operand" "")
|
||||
@ -7716,35 +7604,7 @@ byte_xor_operation:
|
||||
(match_operand:XF 2 "register_operand" "f,0,f")
|
||||
(match_operand:XF 3 "register_operand" "0,f,f")))]
|
||||
"TARGET_CMOVE && reload_completed"
|
||||
"*
|
||||
{
|
||||
|
||||
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();
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
|
||||
RET;
|
||||
}")
|
||||
"* return output_fp_conditional_move (which_alternative, operands);")
|
||||
|
||||
(define_expand "movdicc"
|
||||
[(set (match_operand:DI 0 "register_operand" "")
|
||||
@ -7818,49 +7678,7 @@ byte_xor_operation:
|
||||
(match_operand:DI 2 "nonimmediate_operand" "ro,0,ro")
|
||||
(match_operand:DI 3 "nonimmediate_operand" "0,ro,ro")))]
|
||||
"TARGET_CMOVE && reload_completed"
|
||||
"*
|
||||
{
|
||||
rtx xops[4];
|
||||
|
||||
xops[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
|
||||
xops[1] = operands[1];
|
||||
xops[2] = REG_P (operands[2])
|
||||
? gen_rtx_REG (SImode, REGNO (operands[2]) + 1)
|
||||
: adj_offsettable_operand (operands[2], 4);
|
||||
xops[3] = REG_P (operands[3])
|
||||
? gen_rtx_REG (SImode, REGNO (operands[3]) + 1)
|
||||
: adj_offsettable_operand (operands[3], 4);
|
||||
|
||||
switch (which_alternative)
|
||||
{
|
||||
case 0:
|
||||
/* r <- cond ? arg : r */
|
||||
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
|
||||
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);
|
||||
output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
/* r <- cond ? arg1 : arg2 */
|
||||
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
|
||||
output_asm_insn (AS2 (cmov%C1,%2,%0), xops);
|
||||
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
|
||||
output_asm_insn (AS2 (cmov%c1,%3,%0), xops);
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
/* NOTREACHED */
|
||||
break;
|
||||
}
|
||||
|
||||
RET;
|
||||
}")
|
||||
"* return output_int_conditional_move (which_alternative, operands);")
|
||||
|
||||
(define_insn "strlensi_unroll"
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r,&r")
|
||||
|
Loading…
Reference in New Issue
Block a user