This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
i386 conditional move patch
- To: egcs-patches at cygnus dot com
- Subject: i386 conditional move patch
- From: john at feith dot com (John Wehle)
- Date: Fri, 29 May 1998 12:21:29 -0400
Hello,
This change enables support for i386 conditional moves.
ChangeLog:
Thu May 28 22:16:49 EDT 1998 John Wehle (john@feith.com)
* reload.c (find_reloads): Record the existing mode if
operand_mode == VOIDmode before replacing a register with
a constant.
* i386.md (tstsi, tsthi, tstqi, tstsf, tstdf, tstxf): Set
i386_compare_op1 to const0_rtx for the benefit of the
conditional move patterns.
(movsicc, movhicc, movsfcc, movdfcc, movxfcc, movdicc): Rewrite
based on suggestions from Jim Wilson.
Notes:
1) Currently conditional moves are only implemented for integer
comparisons.
2) The change to find_reloads is necessary in order for reload to
handle what happens when it changes:
(note 2540 2539 2542 ("optabs.c") 897)
(insn 2542 2540 2543 (set (reg/v:SI 369)
(const_int 1)) 53 {movsi+2} (nil)
(expr_list:REG_EQUIV (const_int 1)
(nil)))
(insn 5763 5716 2768 (set (reg:SI 385)
(if_then_else:SI (ne:SI (reg/v:SI 369)
(const_int 1))
(reg/v:SI 358)
(reg/v:SI 22))) 377 {movsicc+2} (nil)
(nil))
into:
(insn 5763 5716 2768 (set (reg:SI 0 %eax)
(if_then_else:SI (ne:SI (const_int 1)
(const_int 1))
(reg/v:SI 358)
(reg/v:SI 22))) 377 {movsicc+2} (nil)
(nil))
Without the patch reload fails to recognize that operand 2
no longer respects the constraints.
Enjoy!
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/reload.c.ORIGINAL Thu May 14 15:54:35 1998
--- gcc/reload.c Thu May 28 22:18:32 1998
***************
*** 2641,2648 ****
register int regno = REGNO (recog_operand[i]);
if (reg_equiv_constant[regno] != 0
&& (set == 0 || &SET_DEST (set) != recog_operand_loc[i]))
! substed_operand[i] = recog_operand[i]
! = reg_equiv_constant[regno];
#if 0 /* This might screw code in reload1.c to delete prior output-reload
that feeds this insn. */
if (reg_equiv_mem[regno] != 0)
--- 2641,2656 ----
register int regno = REGNO (recog_operand[i]);
if (reg_equiv_constant[regno] != 0
&& (set == 0 || &SET_DEST (set) != recog_operand_loc[i]))
! {
! /* Record the existing mode so that the check if constants are
! allowed will work when operand_mode isn't specified. */
!
! if (operand_mode[i] == VOIDmode)
! operand_mode[i] = GET_MODE (recog_operand[i]);
!
! substed_operand[i] = recog_operand[i]
! = reg_equiv_constant[regno];
! }
#if 0 /* This might screw code in reload1.c to delete prior output-reload
that feeds this insn. */
if (reg_equiv_mem[regno] != 0)
*** gcc/config/i386/i386.md.ORIGINAL Fri May 15 16:41:47 1998
--- gcc/config/i386/i386.md Thu May 28 01:08:21 1998
***************
*** 164,169 ****
--- 164,170 ----
{
i386_compare_gen = gen_tstsi_1;
i386_compare_op0 = operands[0];
+ i386_compare_op1 = const0_rtx;
DONE;
}")
***************
*** 188,193 ****
--- 189,195 ----
{
i386_compare_gen = gen_tsthi_1;
i386_compare_op0 = operands[0];
+ i386_compare_op1 = const0_rtx;
DONE;
}")
***************
*** 212,217 ****
--- 214,220 ----
{
i386_compare_gen = gen_tstqi_1;
i386_compare_op0 = operands[0];
+ i386_compare_op1 = const0_rtx;
DONE;
}")
***************
*** 245,250 ****
--- 248,254 ----
{
i386_compare_gen = gen_tstsf_cc;
i386_compare_op0 = operands[0];
+ i386_compare_op1 = const0_rtx;
DONE;
}")
***************
*** 278,283 ****
--- 282,288 ----
{
i386_compare_gen = gen_tstdf_cc;
i386_compare_op0 = operands[0];
+ i386_compare_op1 = const0_rtx;
DONE;
}")
***************
*** 311,316 ****
--- 316,322 ----
{
i386_compare_gen = gen_tstxf_cc;
i386_compare_op0 = operands[0];
+ i386_compare_op1 = const0_rtx;
DONE;
}")
***************
*** 7229,7446 ****
/* Conditional move define_insns. */
- ;; These are all disabled, because they are buggy. They are all susceptible
- ;; to problems with input reloads clobbering the condition code registers.
- ;; It appears the only safe way to write a integer/FP conditional move pattern
- ;; is to write one which emits both the compare and the cmov, and which can be
- ;; split only after reload.
-
(define_expand "movsicc"
! [(match_dup 4)
! (parallel [(set (match_operand 0 "register_operand" "")
(if_then_else:SI (match_operand 1 "comparison_operator" "")
! (match_operand:SI 2 "general_operand" "")
! (match_operand:SI 3 "general_operand" "")))
! (clobber (match_scratch:SI 4 "=&r"))])]
! "0 && TARGET_CMOVE"
"
{
! operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
! }")
! (define_expand "movhicc"
! [(match_dup 4)
! (parallel [(set (match_operand 0 "register_operand" "")
! (if_then_else:HI (match_operand 1 "comparison_operator" "")
! (match_operand:HI 2 "general_operand" "")
! (match_operand:HI 3 "general_operand" "")))
! (clobber (match_scratch:SI 4 "=&r"))])]
! "0 && TARGET_CMOVE"
! "
! {
! operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
}")
! (define_insn "movsicc_1"
! [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r,rm")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
! (match_operand:SI 2 "general_operand" "rm,0,rm,g")
! (match_operand:SI 3 "general_operand" "0,rm,rm,g")))
! (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
! "0 && TARGET_CMOVE"
"*
{
! if (which_alternative == 0)
{
/* r <- cond ? arg : r */
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
! }
! else if (which_alternative == 1)
! {
/* r <- cond ? r : arg */
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
! }
! else if (which_alternative == 2)
! {
/* r <- cond ? arg1 : arg2 */
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
}
- else if (which_alternative == 3)
- {
- /* r <- cond ? arg1 : arg2 */
- rtx xops[3];
- xops[0] = gen_label_rtx ();
- xops[1] = gen_label_rtx ();
- xops[2] = operands[1];
-
- output_asm_insn (\"j%c2 %l0\", xops);
- if (! rtx_equal_p (operands[0], operands[2]))
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
- {
- output_asm_insn (AS2 (mov%z2,%2,%4), operands);
- output_asm_insn (AS2 (mov%z2,%4,%0), operands);
- }
- else
- output_asm_insn (AS2 (mov%z0,%2,%0), operands);
- output_asm_insn (\"jmp %l1\", xops);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
- if (! rtx_equal_p (operands[0], operands[3]))
- {
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
- {
- output_asm_insn (AS2 (mov%z3,%3,%4), operands);
- output_asm_insn (AS2 (mov%z3,%4,%0), operands);
- }
- else
- output_asm_insn (AS2 (mov%z0,%3,%0), operands);
- }
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
- }
RET;
}")
! (define_insn "movhicc_1"
! [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,&r,rm")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
! (match_operand:HI 2 "general_operand" "rm,0,rm,g")
! (match_operand:HI 3 "general_operand" "0,rm,rm,g")))
! (clobber (match_scratch:SI 4 "X,X,X,=&r"))]
! "0 && TARGET_CMOVE"
"*
{
! if (which_alternative == 0)
{
/* r <- cond ? arg : r */
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
! }
! else if (which_alternative == 1)
! {
/* r <- cond ? r : arg */
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
! }
! else if (which_alternative == 2)
! {
/* r <- cond ? arg1 : arg2 */
output_asm_insn (AS2 (cmov%C1,%2,%0), operands);
output_asm_insn (AS2 (cmov%c1,%3,%0), operands);
}
- else if (which_alternative == 3)
- {
- /* r <- cond ? arg1 : arg2 */
- rtx xops[3];
- xops[0] = gen_label_rtx ();
- xops[1] = gen_label_rtx ();
- xops[2] = operands[1];
-
- output_asm_insn (\"j%c2 %l0\", xops);
- if (! rtx_equal_p (operands[0], operands[2]))
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[2]) == MEM)
- {
- output_asm_insn (AS2 (mov%z2,%2,%4), operands);
- output_asm_insn (AS2 (mov%z2,%4,%0), operands);
- }
- else
- output_asm_insn (AS2 (mov%z0,%2,%0), operands);
- output_asm_insn (\"jmp %l1\", xops);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[0]));
- if (! rtx_equal_p (operands[0], operands[3]))
- {
- if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[3]) == MEM)
- {
- output_asm_insn (AS2 (mov%z3,%3,%4), operands);
- output_asm_insn (AS2 (mov%z3,%4,%0), operands);
- }
- else
- output_asm_insn (AS2 (mov%z0,%3,%0), operands);
- }
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (xops[1]));
- }
RET;
}")
- ;; We need to disable the FP forms of these since they do not support
- ;; memory as written, but no input reloads are permitted for insns
- ;; that use cc0. Also, movxfcc is not present.
(define_expand "movsfcc"
! [(match_dup 4)
! (set (match_operand 0 "register_operand" "")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
(match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "register_operand" "")))]
! "0 && TARGET_CMOVE"
"
{
! operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
}")
(define_expand "movdfcc"
! [(match_dup 4)
! (set (match_operand 0 "register_operand" "t")
(if_then_else:DF (match_operand 1 "comparison_operator" "")
(match_operand:DF 2 "register_operand" "")
(match_operand:DF 3 "register_operand" "")))]
! "0 && TARGET_CMOVE"
"
{
! operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
}")
(define_expand "movxfcc"
! [(match_dup 4)
! (set (match_operand 0 "register_operand" "")
(if_then_else:XF (match_operand 1 "comparison_operator" "")
(match_operand:XF 2 "register_operand" "")
(match_operand:XF 3 "register_operand" "")))]
! "0 && TARGET_CMOVE"
"
{
! operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1);
}")
! (define_insn "movsfcc_1"
! [(set (match_operand:SF 0 "general_operand" "=f,f,&f")
! (if_then_else:SF (match_operator 1 "comparison_operator"
! [(cc0) (const_int 0)])
! (match_operand:SF 2 "register_operand" "0,f,f")
! (match_operand:SF 3 "register_operand" "f,0,f")))]
! "0 && TARGET_CMOVE"
"*
{
switch (which_alternative)
{
case 0:
/* r <- cond ? arg : r */
! output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
break;
case 1:
/* r <- cond ? r : arg */
! output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
break;
case 2:
--- 7235,7734 ----
/* Conditional move define_insns. */
(define_expand "movsicc"
! [(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI (match_operand 1 "comparison_operator" "")
! (match_operand:SI 2 "nonimmediate_operand" "")
! (match_operand:SI 3 "nonimmediate_operand" "")))]
! "TARGET_CMOVE"
"
{
! if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
! FAIL;
! operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
! GET_MODE (i386_compare_op0),
! i386_compare_op0, i386_compare_op1);
}")
! (define_insn ""
! [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
! (if_then_else:SI (match_operator 1 "comparison_operator"
! [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
! (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
! (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
! (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
! "TARGET_CMOVE"
! "#")
!
! (define_insn ""
! [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r")
! (if_then_else:SI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
! (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
! (match_operand:SI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
! (match_operand:SI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
! "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
! "#")
!
! (define_split
! [(set (match_operand:SI 0 "register_operand" "=r,r,r")
! (if_then_else:SI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (const_int 0)])
! (match_operand:SI 3 "nonimmediate_operand" "rm,0,rm")
! (match_operand:SI 4 "nonimmediate_operand" "0,rm,rm")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0)
! (match_dup 2))
! (set (match_dup 0)
! (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 3) (match_dup 4)))]
! "")
!
! (define_split
! [(set (match_operand:SI 0 "register_operand" "=r,r,r")
! (if_then_else:SI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (match_operand 3 "general_operand" "")])
! (match_operand:SI 4 "nonimmediate_operand" "rm,0,rm")
! (match_operand:SI 5 "nonimmediate_operand" "0,rm,rm")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0) (compare (match_dup 2) (match_dup 3)))
! (set (match_dup 0)
! (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 4) (match_dup 5)))]
! "")
!
! (define_insn ""
! [(set (match_operand:SI 0 "register_operand" "=r,r,r")
(if_then_else:SI (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
! (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;
}")
! (define_expand "movhicc"
! [(set (match_operand:HI 0 "register_operand" "")
! (if_then_else:HI (match_operand 1 "comparison_operator" "")
! (match_operand:HI 2 "nonimmediate_operand" "")
! (match_operand:HI 3 "nonimmediate_operand" "")))]
! "TARGET_CMOVE"
! "
! {
! if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
! FAIL;
!
! operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
! GET_MODE (i386_compare_op0),
! i386_compare_op0, i386_compare_op1);
! }")
!
! (define_insn ""
! [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
! (if_then_else:HI (match_operator 1 "comparison_operator"
! [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
! (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
! (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
! (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
! "TARGET_CMOVE"
! "#")
!
! (define_insn ""
! [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r")
! (if_then_else:HI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
! (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
! (match_operand:HI 4 "nonimmediate_operand" "rm,rm,0,0,rm,rm")
! (match_operand:HI 5 "nonimmediate_operand" "0,0,rm,rm,rm,rm")))]
! "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
! "#")
!
! (define_split
! [(set (match_operand:HI 0 "register_operand" "=r,r,r")
! (if_then_else:HI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (const_int 0)])
! (match_operand:HI 3 "nonimmediate_operand" "rm,0,rm")
! (match_operand:HI 4 "nonimmediate_operand" "0,rm,rm")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0)
! (match_dup 2))
! (set (match_dup 0)
! (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 3) (match_dup 4)))]
! "")
!
! (define_split
! [(set (match_operand:HI 0 "register_operand" "=r,r,r")
! (if_then_else:HI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (match_operand 3 "general_operand" "")])
! (match_operand:HI 4 "nonimmediate_operand" "rm,0,rm")
! (match_operand:HI 5 "nonimmediate_operand" "0,rm,rm")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0)
! (compare (match_dup 2) (match_dup 3)))
! (set (match_dup 0)
! (if_then_else:HI (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 4) (match_dup 5)))]
! "")
!
! (define_insn ""
! [(set (match_operand:HI 0 "register_operand" "=r,r,r")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(cc0) (const_int 0)])
! (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;
}")
(define_expand "movsfcc"
! [(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
(match_operand:SF 2 "register_operand" "")
(match_operand:SF 3 "register_operand" "")))]
! "TARGET_CMOVE"
"
{
! if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
! FAIL;
!
! operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
! GET_MODE (i386_compare_op0),
! i386_compare_op0, i386_compare_op1);
! }")
!
! (define_insn ""
! [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
! (if_then_else:SF (match_operator 1 "comparison_operator"
! [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
! (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
! (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
! (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
! "TARGET_CMOVE"
! "#")
!
! (define_insn ""
! [(set (match_operand:SF 0 "register_operand" "=f,f,f,f,f,f")
! (if_then_else:SF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
! (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
! (match_operand:SF 4 "register_operand" "f,f,0,0,f,f")
! (match_operand:SF 5 "register_operand" "0,0,f,f,f,f")))]
! "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
! "#")
!
! (define_split
! [(set (match_operand:SF 0 "register_operand" "=f,f,f")
! (if_then_else:SF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (const_int 0)])
! (match_operand:SF 3 "register_operand" "f,0,f")
! (match_operand:SF 4 "register_operand" "0,f,f")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0)
! (match_dup 2))
! (set (match_dup 0)
! (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 3) (match_dup 4)))]
! "")
!
! (define_split
! [(set (match_operand:SF 0 "register_operand" "=f,f,f")
! (if_then_else:SF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (match_operand 3 "general_operand" "")])
! (match_operand:SF 4 "register_operand" "f,0,f")
! (match_operand:SF 5 "register_operand" "0,f,f")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0) (compare (match_dup 2) (match_dup 3)))
! (set (match_dup 0)
! (if_then_else:SF (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 4) (match_dup 5)))]
! "")
!
! (define_insn ""
! [(set (match_operand:SF 0 "register_operand" "=f,f,f")
! (if_then_else:SF (match_operator 1 "comparison_operator"
! [(cc0) (const_int 0)])
! (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;
}")
(define_expand "movdfcc"
! [(set (match_operand:DF 0 "register_operand" "")
(if_then_else:DF (match_operand 1 "comparison_operator" "")
(match_operand:DF 2 "register_operand" "")
(match_operand:DF 3 "register_operand" "")))]
! "TARGET_CMOVE"
"
{
! if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
! FAIL;
!
! operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
! GET_MODE (i386_compare_op0),
! i386_compare_op0, i386_compare_op1);
! }")
!
! (define_insn ""
! [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
! (if_then_else:DF (match_operator 1 "comparison_operator"
! [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
! (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
! (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
! (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
! "TARGET_CMOVE"
! "#")
!
! (define_insn ""
! [(set (match_operand:DF 0 "register_operand" "=f,f,f,f,f,f")
! (if_then_else:DF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
! (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
! (match_operand:DF 4 "register_operand" "f,f,0,0,f,f")
! (match_operand:DF 5 "register_operand" "0,0,f,f,f,f")))]
! "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
! "#")
!
! (define_split
! [(set (match_operand:DF 0 "register_operand" "=f,f,f")
! (if_then_else:DF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (const_int 0)])
! (match_operand:DF 3 "register_operand" "f,0,f")
! (match_operand:DF 4 "register_operand" "0,f,f")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0)
! (match_dup 2))
! (set (match_dup 0)
! (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 3) (match_dup 4)))]
! "")
!
! (define_split
! [(set (match_operand:DF 0 "register_operand" "=f,f,f")
! (if_then_else:DF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (match_operand 3 "general_operand" "")])
! (match_operand:DF 4 "register_operand" "f,0,f")
! (match_operand:DF 5 "register_operand" "0,f,f")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0) (compare (match_dup 2) (match_dup 3)))
! (set (match_dup 0)
! (if_then_else:DF (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 4) (match_dup 5)))]
! "")
!
! (define_insn ""
! [(set (match_operand:DF 0 "register_operand" "=f,f,f")
! (if_then_else:DF (match_operator 1 "comparison_operator"
! [(cc0) (const_int 0)])
! (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;
}")
(define_expand "movxfcc"
! [(set (match_operand:XF 0 "register_operand" "")
(if_then_else:XF (match_operand 1 "comparison_operator" "")
(match_operand:XF 2 "register_operand" "")
(match_operand:XF 3 "register_operand" "")))]
! "TARGET_CMOVE"
"
{
! if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
! FAIL;
!
! operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
! GET_MODE (i386_compare_op0),
! i386_compare_op0, i386_compare_op1);
}")
! (define_insn ""
! [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
! (if_then_else:XF (match_operator 1 "comparison_operator"
! [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
! (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
! (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
! (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
! "TARGET_CMOVE"
! "#")
!
! (define_insn ""
! [(set (match_operand:XF 0 "register_operand" "=f,f,f,f,f,f")
! (if_then_else:XF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
! (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
! (match_operand:XF 4 "register_operand" "f,f,0,0,f,f")
! (match_operand:XF 5 "register_operand" "0,0,f,f,f,f")))]
! "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
! "#")
!
! (define_split
! [(set (match_operand:XF 0 "register_operand" "=f,f,f")
! (if_then_else:XF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (const_int 0)])
! (match_operand:XF 3 "register_operand" "f,0,f")
! (match_operand:XF 4 "register_operand" "0,f,f")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0)
! (match_dup 2))
! (set (match_dup 0)
! (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 3) (match_dup 4)))]
! "")
!
! (define_split
! [(set (match_operand:XF 0 "register_operand" "=f,f,f")
! (if_then_else:XF (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (match_operand 3 "general_operand" "")])
! (match_operand:XF 4 "register_operand" "f,0,f")
! (match_operand:XF 5 "register_operand" "0,f,f")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0) (compare (match_dup 2) (match_dup 3)))
! (set (match_dup 0)
! (if_then_else:XF (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 4) (match_dup 5)))]
! "")
!
! (define_insn ""
! [(set (match_operand:XF 0 "register_operand" "=f,f,f")
! (if_then_else:XF (match_operator 1 "comparison_operator"
! [(cc0) (const_int 0)])
! (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:
***************
*** 7448,7483 ****
output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
break;
}
RET;
}")
! (define_insn "movdfcc_1"
! [(set (match_operand:DF 0 "general_operand" "=f,f,&f")
! (if_then_else:DF (match_operator 1 "comparison_operator"
! [(cc0) (const_int 0)])
! (match_operand:DF 2 "register_operand" "0,f,f")
! (match_operand:DF 3 "register_operand" "f,0,f")))]
! "0 && TARGET_CMOVE"
"*
{
switch (which_alternative)
{
case 0:
/* r <- cond ? arg : r */
! output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
break;
case 1:
/* r <- cond ? r : arg */
! output_asm_insn (AS2 (fcmov%F1,%2,%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;
}
--- 7736,7861 ----
output_asm_insn (AS2 (fcmov%F1,%2,%0), operands);
output_asm_insn (AS2 (fcmov%f1,%3,%0), operands);
break;
+
+ default:
+ abort();
+ /* NOTREACHED */
+ break;
}
RET;
}")
! (define_expand "movdicc"
! [(set (match_operand:DI 0 "register_operand" "")
! (if_then_else:DI (match_operand 1 "comparison_operator" "")
! (match_operand:DI 2 "nonimmediate_operand" "")
! (match_operand:DI 3 "nonimmediate_operand" "")))]
! "TARGET_CMOVE"
! "
! {
! if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT)
! FAIL;
!
! operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
! GET_MODE (i386_compare_op0),
! i386_compare_op0, i386_compare_op1);
! }")
!
! (define_insn ""
! [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r,&r,&r")
! (if_then_else:DI (match_operator 1 "comparison_operator"
! [(match_operand:QI 2 "nonimmediate_operand" "q,m,q,m,q,m")
! (match_operand:QI 3 "general_operand" "qmn,qn,qmn,qn,qmn,qn")])
! (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0,ro,ro")
! (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro,ro,ro")))]
! "TARGET_CMOVE"
! "#")
!
! (define_insn ""
! [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r,&r,&r,&r")
! (if_then_else:DI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "r,m,r,m,r,m")
! (match_operand 3 "general_operand" "rmi,ri,rmi,ri,rmi,ri")])
! (match_operand:DI 4 "nonimmediate_operand" "ro,ro,0,0,ro,ro")
! (match_operand:DI 5 "nonimmediate_operand" "0,0,ro,ro,ro,ro")))]
! "TARGET_CMOVE && GET_MODE_CLASS (GET_MODE (operands[2])) == MODE_INT"
! "#")
!
! (define_split
! [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
! (if_then_else:DI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (const_int 0)])
! (match_operand:DI 3 "nonimmediate_operand" "ro,0,ro")
! (match_operand:DI 4 "nonimmediate_operand" "0,ro,ro")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0)
! (match_dup 2))
! (set (match_dup 0)
! (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 3) (match_dup 4)))]
! "")
!
! (define_split
! [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
! (if_then_else:DI (match_operator 1 "comparison_operator"
! [(match_operand 2 "nonimmediate_operand" "")
! (match_operand 3 "general_operand" "")])
! (match_operand:DI 4 "nonimmediate_operand" "ro,0,ro")
! (match_operand:DI 5 "nonimmediate_operand" "0,ro,ro")))]
! "TARGET_CMOVE && reload_completed"
! [(set (cc0) (compare (match_dup 2) (match_dup 3)))
! (set (match_dup 0)
! (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)])
! (match_dup 4) (match_dup 5)))]
! "")
!
! (define_insn ""
! [(set (match_operand:DI 0 "register_operand" "=&r,&r,&r")
! (if_then_else:DI (match_operator 1 "comparison_operator"
! [(cc0) (const_int 0)])
! (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;
}
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------