}
}
+/* Return nonzero if OP is a valid comparison operator
+ for an ALC condition in mode MODE. */
+
+int
+s390_alc_comparison (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+ return 0;
+
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != CC_REGNUM
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ switch (GET_MODE (XEXP (op, 0)))
+ {
+ case CCL1mode:
+ return GET_CODE (op) == LTU;
+
+ case CCL2mode:
+ return GET_CODE (op) == LEU;
+
+ case CCUmode:
+ return GET_CODE (op) == GTU;
+
+ case CCURmode:
+ return GET_CODE (op) == LTU;
+
+ case CCSmode:
+ return GET_CODE (op) == UNGT;
+
+ case CCSRmode:
+ return GET_CODE (op) == UNLT;
+
+ default:
+ return 0;
+ }
+}
+
+/* Return nonzero if OP is a valid comparison operator
+ for an SLB condition in mode MODE. */
+
+int
+s390_slb_comparison (rtx op, enum machine_mode mode)
+{
+ if (mode != VOIDmode && mode != GET_MODE (op))
+ return 0;
+
+ if (GET_RTX_CLASS (GET_CODE (op)) != '<')
+ return 0;
+
+ if (GET_CODE (XEXP (op, 0)) != REG
+ || REGNO (XEXP (op, 0)) != CC_REGNUM
+ || XEXP (op, 1) != const0_rtx)
+ return 0;
+
+ switch (GET_MODE (XEXP (op, 0)))
+ {
+ case CCL1mode:
+ return GET_CODE (op) == GEU;
+
+ case CCL2mode:
+ return GET_CODE (op) == GTU;
+
+ case CCUmode:
+ return GET_CODE (op) == LEU;
+
+ case CCURmode:
+ return GET_CODE (op) == GEU;
+
+ case CCSmode:
+ return GET_CODE (op) == LE;
+
+ case CCSRmode:
+ return GET_CODE (op) == GE;
+
+ default:
+ return 0;
+ }
+}
+
/* Return branch condition mask to implement a branch
specified by CODE. */
ag\t%0,%2"
[(set_attr "op_type" "RRE,RI,RXY")])
+(define_insn_and_split "*adddi3_31z"
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
+ (match_operand:DI 2 "general_operand" "do") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCL1 33)
+ (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
+ (match_dup 7)))
+ (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
+ (parallel
+ [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
+ (ltu:SI (reg:CCL1 33) (const_int 0))))
+ (clobber (reg:CC 33))])]
+ "operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[2], 0, 0, DImode);
+ operands[6] = operand_subword (operands[0], 1, 0, DImode);
+ operands[7] = operand_subword (operands[1], 1, 0, DImode);
+ operands[8] = operand_subword (operands[2], 1, 0, DImode);"
+ [(set_attr "op_type" "NN")])
+
(define_insn_and_split "*adddi3_31"
[(set (match_operand:DI 0 "register_operand" "=&d")
(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
(match_operand:DI 2 "general_operand" "do") ) )
(clobber (reg:CC 33))]
- "!TARGET_64BIT"
+ "!TARGET_CPU_ZARCH"
"#"
"&& reload_completed"
[(parallel
sg\t%0,%2"
[(set_attr "op_type" "RRE,RRE")])
+(define_insn_and_split "*subdi3_31z"
+ [(set (match_operand:DI 0 "register_operand" "=&d")
+ (minus:DI (match_operand:DI 1 "register_operand" "0")
+ (match_operand:DI 2 "general_operand" "do") ) )
+ (clobber (reg:CC 33))]
+ "!TARGET_64BIT && TARGET_CPU_ZARCH"
+ "#"
+ "&& reload_completed"
+ [(parallel
+ [(set (reg:CCL2 33)
+ (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
+ (match_dup 7)))
+ (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
+ (parallel
+ [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5))
+ (gtu:SI (reg:CCL2 33) (const_int 0))))
+ (clobber (reg:CC 33))])]
+ "operands[3] = operand_subword (operands[0], 0, 0, DImode);
+ operands[4] = operand_subword (operands[1], 0, 0, DImode);
+ operands[5] = operand_subword (operands[2], 0, 0, DImode);
+ operands[6] = operand_subword (operands[0], 1, 0, DImode);
+ operands[7] = operand_subword (operands[1], 1, 0, DImode);
+ operands[8] = operand_subword (operands[2], 1, 0, DImode);"
+ [(set_attr "op_type" "NN")])
+
(define_insn_and_split "*subdi3_31"
[(set (match_operand:DI 0 "register_operand" "=&d")
(minus:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:DI 2 "general_operand" "do") ) )
(clobber (reg:CC 33))]
- "!TARGET_64BIT"
+ "!TARGET_CPU_ZARCH"
"#"
"&& reload_completed"
[(parallel
(set_attr "type" "fsimps,fsimps")])
+;;
+;;- Conditional add/subtract instructions.
+;;
+
+;
+; adddicc instruction pattern(s).
+;
+
+(define_insn "*adddi3_alc_cc"
+ [(set (reg 33)
+ (compare
+ (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_alc_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (plus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "@
+ alcgr\\t%0,%2
+ alcg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*adddi3_alc"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_alc_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ alcgr\\t%0,%2
+ alcg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_slb_cc"
+ [(set (reg 33)
+ (compare
+ (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_slb_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (minus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+ "@
+ slbgr\\t%0,%2
+ slbg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subdi3_slb"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
+ (match_operand:DI 2 "general_operand" "d,m"))
+ (match_operand:DI 3 "s390_slb_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_64BIT"
+ "@
+ slbgr\\t%0,%2
+ slbg\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+;
+; addsicc instruction pattern(s).
+;
+
+(define_insn "*addsi3_alc_cc"
+ [(set (reg 33)
+ (compare
+ (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_alc_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "@
+ alcr\\t%0,%2
+ alc\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*addsi3_alc"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_alc_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
+ "@
+ alcr\\t%0,%2
+ alc\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subsi3_slb_cc"
+ [(set (reg 33)
+ (compare
+ (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_slb_comparison" ""))
+ (const_int 0)))
+ (set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))]
+ "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
+ "@
+ slbr\\t%0,%2
+ slb\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+(define_insn "*subsi3_slb"
+ [(set (match_operand:SI 0 "register_operand" "=d,d")
+ (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
+ (match_operand:SI 2 "general_operand" "d,m"))
+ (match_operand:SI 3 "s390_slb_comparison" "")))
+ (clobber (reg:CC 33))]
+ "TARGET_CPU_ZARCH"
+ "@
+ slbr\\t%0,%2
+ slb\\t%0,%2"
+ [(set_attr "op_type" "RRE,RXY")])
+
+
;;
;;- Multiply instructions.
;;