From: John Wehle Date: Sun, 31 May 1998 15:13:36 +0000 (+0000) Subject: reload.c (find_reloads): Record the existing mode if operand_mode == VOIDmode before... X-Git-Tag: prereleases/egcs-1.1-prerelease~1006 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=726e2d544cdcb3e91ac2e0ced52bf7ef592b18f3;p=thirdparty%2Fgcc.git reload.c (find_reloads): Record the existing mode if operand_mode == VOIDmode before replacing a... * 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. From-SVN: r20151 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fd7898a0ca48..87f05f9e3b7f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Sun May 31 16:11:41 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. + Sun May 31 00:44:02 PDT 1998 Jeff Law (law@cygnus.com) * version.c: Bump for snapshot. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 70687094b2f1..f060c05aee14 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -164,6 +164,7 @@ { i386_compare_gen = gen_tstsi_1; i386_compare_op0 = operands[0]; + i386_compare_op1 = const0_rtx; DONE; }") @@ -188,6 +189,7 @@ { i386_compare_gen = gen_tsthi_1; i386_compare_op0 = operands[0]; + i386_compare_op1 = const0_rtx; DONE; }") @@ -212,6 +214,7 @@ { i386_compare_gen = gen_tstqi_1; i386_compare_op0 = operands[0]; + i386_compare_op1 = const0_rtx; DONE; }") @@ -245,6 +248,7 @@ { i386_compare_gen = gen_tstsf_cc; i386_compare_op0 = operands[0]; + i386_compare_op1 = const0_rtx; DONE; }") @@ -278,6 +282,7 @@ { i386_compare_gen = gen_tstdf_cc; i386_compare_op0 = operands[0]; + i386_compare_op1 = const0_rtx; DONE; }") @@ -311,6 +316,7 @@ { i386_compare_gen = gen_tstxf_cc; i386_compare_op0 = operands[0]; + i386_compare_op1 = const0_rtx; DONE; }") @@ -7229,218 +7235,500 @@ byte_xor_operation: /* 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" "") + [(set (match_operand:SI 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" + (match_operand:SI 2 "nonimmediate_operand" "") + (match_operand:SI 3 "nonimmediate_operand" "")))] + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); -}") + if (GET_MODE_CLASS (GET_MODE (i386_compare_op0)) != MODE_INT) + FAIL; -(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); + operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), + GET_MODE (i386_compare_op0), + i386_compare_op0, i386_compare_op1); }") -(define_insn "movsicc_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,&r,rm") +(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 "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" + (match_operand:SI 2 "nonimmediate_operand" "rm,0,rm") + (match_operand:SI 3 "nonimmediate_operand" "0,rm,rm")))] + "TARGET_CMOVE && reload_completed" "* { - if (which_alternative == 0) + + switch (which_alternative) { + case 0: /* r <- cond ? arg : r */ output_asm_insn (AS2 (cmov%C1,%2,%0), operands); - } - else if (which_alternative == 1) - { + break; + + case 1: /* r <- cond ? r : arg */ output_asm_insn (AS2 (cmov%c1,%3,%0), operands); - } - else if (which_alternative == 2) - { + 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; } - 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") +(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 "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" + (match_operand:HI 2 "nonimmediate_operand" "rm,0,rm") + (match_operand:HI 3 "nonimmediate_operand" "0,rm,rm")))] + "TARGET_CMOVE && reload_completed" "* { - if (which_alternative == 0) + + switch (which_alternative) { + case 0: /* r <- cond ? arg : r */ output_asm_insn (AS2 (cmov%C1,%2,%0), operands); - } - else if (which_alternative == 1) - { + break; + + case 1: /* r <- cond ? r : arg */ output_asm_insn (AS2 (cmov%c1,%3,%0), operands); - } - else if (which_alternative == 2) - { + 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; } - 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" "") + [(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" "")))] - "0 && TARGET_CMOVE" + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); + 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" - [(match_dup 4) - (set (match_operand 0 "register_operand" "t") + [(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" "")))] - "0 && TARGET_CMOVE" + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); + 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" - [(match_dup 4) - (set (match_operand 0 "register_operand" "") + [(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" "")))] - "0 && TARGET_CMOVE" + "TARGET_CMOVE" " { - operands[4] = i386_compare_gen (i386_compare_op0, i386_compare_op1); + 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 "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" +(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,%3,%0), operands); + output_asm_insn (AS2 (fcmov%F1,%2,%0), operands); break; case 1: /* r <- cond ? r : arg */ - output_asm_insn (AS2 (fcmov%F1,%2,%0), operands); + output_asm_insn (AS2 (fcmov%f1,%3,%0), operands); break; case 2: @@ -7448,36 +7736,126 @@ byte_xor_operation: 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_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" +(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 (fcmov%f1,%3,%0), operands); + 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 (fcmov%F1,%2,%0), operands); + output_asm_insn (AS2 (cmov%c1,%3,%0), operands); + output_asm_insn (AS2 (cmov%c1,%3,%0), xops); 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); + /* 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; } diff --git a/gcc/reload.c b/gcc/reload.c index 694c23601b62..1604a7b0ba0e 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -2641,8 +2641,16 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) 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]; + { + /* 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)