aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJohn Wehle <john@feith.com>1998-05-31 15:13:36 +0000
committerJeff Law <law@gcc.gnu.org>1998-05-31 09:13:36 -0600
commit726e2d544cdcb3e91ac2e0ced52bf7ef592b18f3 (patch)
tree0c1c29104eec694d1022f9b5a1440651674fc445 /gcc
parent7e5df0048fe26c97b06e9f7d8d4a2ea66e6d1ad6 (diff)
downloadgcc-726e2d544cdcb3e91ac2e0ced52bf7ef592b18f3.zip
gcc-726e2d544cdcb3e91ac2e0ced52bf7ef592b18f3.tar.gz
gcc-726e2d544cdcb3e91ac2e0ced52bf7ef592b18f3.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/config/i386/i386.md680
-rw-r--r--gcc/reload.c12
3 files changed, 550 insertions, 153 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fd7898a..87f05f9 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 7068709..f060c05 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 694c236..1604a7b 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)