summaryrefslogtreecommitdiffstats
path: root/gcc/config/i386/i386.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r--gcc/config/i386/i386.md318
1 files changed, 227 insertions, 91 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 1bb96fd07db..198b59d2e47 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -759,77 +759,183 @@
(include "constraints.md")
-;; Compare instructions.
+;; Compare and branch/compare and store instructions.
-;; All compare insns have expanders that save the operands away without
-;; actually generating RTL. The bCOND or sCOND (emitted immediately
-;; after the cmp) will actually emit the cmpM.
+(define_expand "cbranchti4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
+ (match_operand:TI 2 "x86_64_general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_64BIT"
+{
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (TImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
-(define_expand "cmpti"
+(define_expand "cbranchdi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
- (match_operand:TI 1 "x86_64_general_operand" "")))]
+ (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
+ (match_operand:DI 2 "x86_64_general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+{
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (DImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
+
+(define_expand "cstoredi4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
+ (match_operand:DI 3 "x86_64_general_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
"TARGET_64BIT"
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (TImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[2]) && MEM_P (operands[3]))
+ operands[2] = force_reg (DImode, operands[2]);
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
-(define_expand "cmpdi"
+(define_expand "cbranchsi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
- (match_operand:DI 1 "x86_64_general_operand" "")))]
+ (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
+ (match_operand:SI 2 "general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (DImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (SImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
DONE;
})
-(define_expand "cmpsi"
+(define_expand "cstoresi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
- (match_operand:SI 1 "general_operand" "")))]
+ (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
+ (match_operand:SI 3 "general_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
""
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (SImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[2]) && MEM_P (operands[3]))
+ operands[2] = force_reg (SImode, operands[2]);
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
-(define_expand "cmphi"
+(define_expand "cbranchhi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
- (match_operand:HI 1 "general_operand" "")))]
+ (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
+ (match_operand:HI 2 "general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
""
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (HImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (HImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
DONE;
})
-(define_expand "cmpqi"
+(define_expand "cstorehi4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
- (match_operand:QI 1 "general_operand" "")))]
- "TARGET_QIMODE_MATH"
+ (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
+ (match_operand:HI 3 "general_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
+ ""
{
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[0] = force_reg (QImode, operands[0]);
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ if (MEM_P (operands[2]) && MEM_P (operands[3]))
+ operands[2] = force_reg (HImode, operands[2]);
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ DONE;
+})
+
+
+(define_expand "cbranchqi4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
+ (match_operand:QI 2 "general_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+{
+ if (MEM_P (operands[1]) && MEM_P (operands[2]))
+ operands[1] = force_reg (QImode, operands[1]);
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
+
+
+(define_expand "cstoreqi4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
+ (match_operand:QI 3 "general_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
+ ""
+{
+ if (MEM_P (operands[2]) && MEM_P (operands[3]))
+ operands[2] = force_reg (QImode, operands[2]);
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
+
(define_insn "cmpdi_ccno_1_rex64"
[(set (reg FLAGS_REG)
(compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
@@ -1078,39 +1184,103 @@
;; which would allow mix and match FP modes on the compares. Which is what
;; the old patterns did, but with many more of them.
-(define_expand "cmpxf"
+(define_expand "cbranchxf4"
+ [(set (reg:CC FLAGS_REG)
+ (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
+ (match_operand:XF 2 "nonmemory_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_80387"
+{
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
+
+(define_expand "cstorexf4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
- (match_operand:XF 1 "nonmemory_operand" "")))]
+ (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
+ (match_operand:XF 3 "nonmemory_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
"TARGET_80387"
{
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
-(define_expand "cmp<mode>"
+(define_expand "cbranch<mode>4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
- (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
+ (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
+ (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
+ (set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
"TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
{
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
DONE;
})
-(define_expand "cmpcc"
+(define_expand "cstore<mode>4"
[(set (reg:CC FLAGS_REG)
- (compare:CC (match_operand 0 "flags_reg_operand" "")
- (match_operand 1 "general_operand" "")))]
+ (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
+ (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
+ (set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(reg:CC FLAGS_REG)
+ (const_int 0)]))]
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+{
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
+ DONE;
+})
+
+(define_expand "cbranchcc4"
+ [(set (pc) (if_then_else
+ (match_operator 0 "comparison_operator"
+ [(match_operand 1 "flags_reg_operand" "")
+ (match_operand 2 "const0_operand" "")])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ ""
+{
+ ix86_compare_op0 = operands[1];
+ ix86_compare_op1 = operands[2];
+ ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
+ DONE;
+})
+
+(define_expand "cstorecc4"
+ [(set (match_operand:QI 0 "register_operand" "")
+ (match_operator 1 "comparison_operator"
+ [(match_operand 2 "flags_reg_operand" "")
+ (match_operand 3 "const0_operand" "")]))]
""
{
- ix86_compare_op0 = operands[0];
- ix86_compare_op1 = operands[1];
+ ix86_compare_op0 = operands[2];
+ ix86_compare_op1 = operands[3];
+ ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
DONE;
})
+
;; FP compares, step 1:
;; Set the FP condition codes.
;;
@@ -14182,18 +14352,6 @@
;; to avoid partial register stalls. Otherwise do things the setcc+movzx
;; way, which can later delete the movzx if only QImode is needed.
-(define_expand "s<code>"
- [(set (match_operand:QI 0 "register_operand" "")
- (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
- ""
- "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
-
-(define_expand "s<code>"
- [(set (match_operand:QI 0 "register_operand" "")
- (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
- "TARGET_80387 || TARGET_SSE"
- "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
-
(define_insn "*setcc_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(match_operator:QI 1 "ix86_comparison_operator"
@@ -14322,27 +14480,6 @@
;; Basic conditional jump instructions.
;; We ignore the overflow flag for signed branch instructions.
-;; For all bCOND expanders, also expand the compare or test insn that
-;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
-
-(define_expand "b<code>"
- [(set (pc)
- (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
- (const_int 0))
- (label_ref (match_operand 0 ""))
- (pc)))]
- ""
- "ix86_expand_branch (<CODE>, operands[0]); DONE;")
-
-(define_expand "b<code>"
- [(set (pc)
- (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
- (const_int 0))
- (label_ref (match_operand 0 ""))
- (pc)))]
- "TARGET_80387 || TARGET_SSE_MATH"
- "ix86_expand_branch (<CODE>, operands[0]); DONE;")
-
(define_insn "*jcc_1"
[(set (pc)
(if_then_else (match_operator 1 "ix86_comparison_operator"
@@ -22004,9 +22141,8 @@
emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
#endif
- ix86_compare_op0 = flags;
- ix86_compare_op1 = const0_rtx;
- emit_jump_insn (gen_beq (operands[2]));
+ emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
+ flags, const0_rtx, operands[2]));
DONE;
})
OpenPOWER on IntegriCloud