mirror of git://gcc.gnu.org/git/gcc.git
sparc-modes.def (CCV): New.
* config/sparc/sparc-modes.def (CCV): New.
(CCXV): Likewise.
* config/sparc/predicates.md (v_comparison_operator): New.
(icc_comparison_operator): Add support for CCV/CCXV.
(xcc_comparison_operator): Likewise.
* config/sparc/sparc.c (output_cbranch): Likewise.
(sparc_print_operand): Likewise.
* config/sparc/sparc.md (UNSPEC_{ADD,SUB,NEG}V): New constants.
(uaddvdi4): New expander.
(addvdi4): Likewise.
(uaddvdi4_sp32): New instruction.
(addvdi4_sp32): Likewise.
(uaddvsi4): New expander.
(addvsi4): Likewise.
(cmp_ccc_plus_sltu_set): New instruction.
(cmp_ccv_plus): Likewise.
(cmp_ccxv_plus): Likewise.
(cmp_ccv_plus_set): Likewise.
(cmp_ccxv_plus_set): Likewise.
(cmp_ccv_plus_sltu_set): Likewise.
(uaddvdi4): New expander.
(subvdi4): Likewise.
(usubdi4_sp32): New instruction.
(subvdi4_sp32): Likewise.
(usubvsi4): New expander.
(subvsi4): Likewise.
(cmpsi_minus_sltu_set): New instruction.
(cmp_ccv_minus): Likewise.
(cmp_ccxv_minus): Likewise.
(cmp_ccv_minus_set): Likewise.
(cmp_ccxv_minus_set): Likewise.
(cmp_ccv_minus_sltu_set): Likewise.
(unegvdi3): New expander.
(negvdi3): Likewise.
(unegdi3_sp32): New instruction.
(negvdi3_sp32): Likewise.
(unegvsi3): New expander.
(negvsi3): Likewise.
(cmp_ccc_neg_sltu_set): New instruction.
(cmp_ccv_neg): Likewise.
(cmp_ccxv_neg): Likewise.
(cmp_ccv_neg_set): Likewise.
(cmp_ccxv_neg_set): Likewise.
(cmp_ccv_neg_sltu_set): Likewise.
From-SVN: r241397
This commit is contained in:
parent
d17f2c3b49
commit
8572922996
|
|
@ -1,3 +1,50 @@
|
||||||
|
2016-10-21 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
* config/sparc/sparc-modes.def (CCV): New.
|
||||||
|
(CCXV): Likewise.
|
||||||
|
* config/sparc/predicates.md (v_comparison_operator): New.
|
||||||
|
(icc_comparison_operator): Add support for CCV/CCXV.
|
||||||
|
(xcc_comparison_operator): Likewise.
|
||||||
|
* config/sparc/sparc.c (output_cbranch): Likewise.
|
||||||
|
(sparc_print_operand): Likewise.
|
||||||
|
* config/sparc/sparc.md (UNSPEC_{ADD,SUB,NEG}V): New constants.
|
||||||
|
(uaddvdi4): New expander.
|
||||||
|
(addvdi4): Likewise.
|
||||||
|
(uaddvdi4_sp32): New instruction.
|
||||||
|
(addvdi4_sp32): Likewise.
|
||||||
|
(uaddvsi4): New expander.
|
||||||
|
(addvsi4): Likewise.
|
||||||
|
(cmp_ccc_plus_sltu_set): New instruction.
|
||||||
|
(cmp_ccv_plus): Likewise.
|
||||||
|
(cmp_ccxv_plus): Likewise.
|
||||||
|
(cmp_ccv_plus_set): Likewise.
|
||||||
|
(cmp_ccxv_plus_set): Likewise.
|
||||||
|
(cmp_ccv_plus_sltu_set): Likewise.
|
||||||
|
(uaddvdi4): New expander.
|
||||||
|
(subvdi4): Likewise.
|
||||||
|
(usubdi4_sp32): New instruction.
|
||||||
|
(subvdi4_sp32): Likewise.
|
||||||
|
(usubvsi4): New expander.
|
||||||
|
(subvsi4): Likewise.
|
||||||
|
(cmpsi_minus_sltu_set): New instruction.
|
||||||
|
(cmp_ccv_minus): Likewise.
|
||||||
|
(cmp_ccxv_minus): Likewise.
|
||||||
|
(cmp_ccv_minus_set): Likewise.
|
||||||
|
(cmp_ccxv_minus_set): Likewise.
|
||||||
|
(cmp_ccv_minus_sltu_set): Likewise.
|
||||||
|
(unegvdi3): New expander.
|
||||||
|
(negvdi3): Likewise.
|
||||||
|
(unegdi3_sp32): New instruction.
|
||||||
|
(negvdi3_sp32): Likewise.
|
||||||
|
(unegvsi3): New expander.
|
||||||
|
(negvsi3): Likewise.
|
||||||
|
(cmp_ccc_neg_sltu_set): New instruction.
|
||||||
|
(cmp_ccv_neg): Likewise.
|
||||||
|
(cmp_ccxv_neg): Likewise.
|
||||||
|
(cmp_ccv_neg_set): Likewise.
|
||||||
|
(cmp_ccxv_neg_set): Likewise.
|
||||||
|
(cmp_ccv_neg_sltu_set): Likewise.
|
||||||
|
|
||||||
2016-10-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
2016-10-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||||
|
|
||||||
PR rtl-optimization/78038
|
PR rtl-optimization/78038
|
||||||
|
|
|
||||||
|
|
@ -420,6 +420,10 @@
|
||||||
(define_predicate "c_comparison_operator"
|
(define_predicate "c_comparison_operator"
|
||||||
(match_code "ltu,geu"))
|
(match_code "ltu,geu"))
|
||||||
|
|
||||||
|
;; Return true if OP is a valid comparison operator for CCVmode.
|
||||||
|
(define_predicate "v_comparison_operator"
|
||||||
|
(match_code "eq,ne"))
|
||||||
|
|
||||||
;; Return true if OP is an integer comparison operator. This allows
|
;; Return true if OP is an integer comparison operator. This allows
|
||||||
;; the use of MATCH_OPERATOR to recognize all the branch insns.
|
;; the use of MATCH_OPERATOR to recognize all the branch insns.
|
||||||
(define_predicate "icc_comparison_operator"
|
(define_predicate "icc_comparison_operator"
|
||||||
|
|
@ -436,6 +440,9 @@
|
||||||
case CCCmode:
|
case CCCmode:
|
||||||
case CCXCmode:
|
case CCXCmode:
|
||||||
return c_comparison_operator (op, mode);
|
return c_comparison_operator (op, mode);
|
||||||
|
case CCVmode:
|
||||||
|
case CCXVmode:
|
||||||
|
return v_comparison_operator (op, mode);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,10 @@ FLOAT_MODE (TF, 16, ieee_quad_format);
|
||||||
they explicitly set the C flag (unsigned overflow). Only the unsigned
|
they explicitly set the C flag (unsigned overflow). Only the unsigned
|
||||||
<,>= operators can be used in conjunction with it.
|
<,>= operators can be used in conjunction with it.
|
||||||
|
|
||||||
|
We also have a CCVmode which is used by the arithmetic instructions when
|
||||||
|
they explicitly set the V flag (signed overflow). Only the =,!= operators
|
||||||
|
can be used in conjunction with it.
|
||||||
|
|
||||||
We also have two modes to indicate that the relevant condition code is
|
We also have two modes to indicate that the relevant condition code is
|
||||||
in the floating-point condition code register. One for comparisons which
|
in the floating-point condition code register. One for comparisons which
|
||||||
will generate an exception if the result is unordered (CCFPEmode) and
|
will generate an exception if the result is unordered (CCFPEmode) and
|
||||||
|
|
@ -46,6 +50,8 @@ CC_MODE (CCNZ);
|
||||||
CC_MODE (CCXNZ);
|
CC_MODE (CCXNZ);
|
||||||
CC_MODE (CCC);
|
CC_MODE (CCC);
|
||||||
CC_MODE (CCXC);
|
CC_MODE (CCXC);
|
||||||
|
CC_MODE (CCV);
|
||||||
|
CC_MODE (CCXV);
|
||||||
CC_MODE (CCFP);
|
CC_MODE (CCFP);
|
||||||
CC_MODE (CCFPE);
|
CC_MODE (CCFPE);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2784,8 +2784,9 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y)
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
|
else if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
|
||||||
|| GET_CODE (x) == NEG || GET_CODE (x) == ASHIFT)
|
|| GET_CODE (x) == NEG || GET_CODE (x) == ASHIFT)
|
||||||
|
&& y == const0_rtx)
|
||||||
{
|
{
|
||||||
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
||||||
return CCXNZmode;
|
return CCXNZmode;
|
||||||
|
|
@ -2803,6 +2804,18 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y)
|
||||||
return CCCmode;
|
return CCCmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is for the [u]addvdi4_sp32 and [u]subvdi4_sp32 patterns. */
|
||||||
|
if (!TARGET_ARCH64 && GET_MODE (x) == DImode)
|
||||||
|
{
|
||||||
|
if (GET_CODE (y) == UNSPEC
|
||||||
|
&& (XINT (y, 1) == UNSPEC_ADDV
|
||||||
|
|| XINT (y, 1) == UNSPEC_SUBV
|
||||||
|
|| XINT (y, 1) == UNSPEC_NEGV))
|
||||||
|
return CCVmode;
|
||||||
|
else
|
||||||
|
return CCCmode;
|
||||||
|
}
|
||||||
|
|
||||||
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
||||||
return CCXmode;
|
return CCXmode;
|
||||||
else
|
else
|
||||||
|
|
@ -7724,9 +7737,15 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case NE:
|
case NE:
|
||||||
|
if (mode == CCVmode || mode == CCXVmode)
|
||||||
|
branch = "bvs";
|
||||||
|
else
|
||||||
branch = "bne";
|
branch = "bne";
|
||||||
break;
|
break;
|
||||||
case EQ:
|
case EQ:
|
||||||
|
if (mode == CCVmode || mode == CCXVmode)
|
||||||
|
branch = "bvc";
|
||||||
|
else
|
||||||
branch = "be";
|
branch = "be";
|
||||||
break;
|
break;
|
||||||
case GE:
|
case GE:
|
||||||
|
|
@ -7794,6 +7813,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
case CCmode:
|
case CCmode:
|
||||||
case CCNZmode:
|
case CCNZmode:
|
||||||
case CCCmode:
|
case CCCmode:
|
||||||
|
case CCVmode:
|
||||||
labelno = "%%icc, ";
|
labelno = "%%icc, ";
|
||||||
if (v8)
|
if (v8)
|
||||||
labelno = "";
|
labelno = "";
|
||||||
|
|
@ -7801,6 +7821,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
case CCXmode:
|
case CCXmode:
|
||||||
case CCXNZmode:
|
case CCXNZmode:
|
||||||
case CCXCmode:
|
case CCXCmode:
|
||||||
|
case CCXVmode:
|
||||||
labelno = "%%xcc, ";
|
labelno = "%%xcc, ";
|
||||||
gcc_assert (!v8);
|
gcc_assert (!v8);
|
||||||
break;
|
break;
|
||||||
|
|
@ -8804,11 +8825,13 @@ sparc_print_operand (FILE *file, rtx x, int code)
|
||||||
case CCmode:
|
case CCmode:
|
||||||
case CCNZmode:
|
case CCNZmode:
|
||||||
case CCCmode:
|
case CCCmode:
|
||||||
|
case CCVmode:
|
||||||
s = "%icc";
|
s = "%icc";
|
||||||
break;
|
break;
|
||||||
case CCXmode:
|
case CCXmode:
|
||||||
case CCXNZmode:
|
case CCXNZmode:
|
||||||
case CCXCmode:
|
case CCXCmode:
|
||||||
|
case CCXVmode:
|
||||||
s = "%xcc";
|
s = "%xcc";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -8883,9 +8906,15 @@ sparc_print_operand (FILE *file, rtx x, int code)
|
||||||
switch (GET_CODE (x))
|
switch (GET_CODE (x))
|
||||||
{
|
{
|
||||||
case NE:
|
case NE:
|
||||||
|
if (mode == CCVmode || mode == CCXVmode)
|
||||||
|
s = "vs";
|
||||||
|
else
|
||||||
s = "ne";
|
s = "ne";
|
||||||
break;
|
break;
|
||||||
case EQ:
|
case EQ:
|
||||||
|
if (mode == CCVmode || mode == CCXVmode)
|
||||||
|
s = "vc";
|
||||||
|
else
|
||||||
s = "e";
|
s = "e";
|
||||||
break;
|
break;
|
||||||
case GE:
|
case GE:
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,10 @@
|
||||||
UNSPEC_MUL8
|
UNSPEC_MUL8
|
||||||
UNSPEC_MUL8SU
|
UNSPEC_MUL8SU
|
||||||
UNSPEC_MULDSU
|
UNSPEC_MULDSU
|
||||||
|
|
||||||
|
UNSPEC_ADDV
|
||||||
|
UNSPEC_SUBV
|
||||||
|
UNSPEC_NEGV
|
||||||
])
|
])
|
||||||
|
|
||||||
(define_c_enum "unspecv" [
|
(define_c_enum "unspecv" [
|
||||||
|
|
@ -3714,6 +3718,51 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
(define_expand "uaddvdi4"
|
||||||
|
[(parallel [(set (reg:CCXC CC_REG)
|
||||||
|
(compare:CCXC (plus:DI (match_operand:DI 1 "register_operand")
|
||||||
|
(match_operand:DI 2 "arith_add_operand"))
|
||||||
|
(match_dup 1)))
|
||||||
|
(set (match_operand:DI 0 "register_operand")
|
||||||
|
(plus:DI (match_dup 1) (match_dup 2)))])
|
||||||
|
(set (pc) (if_then_else (ltu (reg:CCXC CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (!TARGET_64BIT)
|
||||||
|
{
|
||||||
|
emit_insn (gen_uaddvdi4_sp32 (operands[0], operands[1], operands[2]));
|
||||||
|
rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
|
||||||
|
const0_rtx);
|
||||||
|
emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_expand "addvdi4"
|
||||||
|
[(parallel [(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (plus:DI (match_operand:DI 1 "register_operand")
|
||||||
|
(match_operand:DI 2 "arith_add_operand"))
|
||||||
|
(unspec:DI [(match_dup 1) (match_dup 2)]
|
||||||
|
UNSPEC_ADDV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand")
|
||||||
|
(plus:DI (match_dup 1) (match_dup 2)))])
|
||||||
|
(set (pc) (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (!TARGET_64BIT)
|
||||||
|
{
|
||||||
|
emit_insn (gen_addvdi4_sp32 (operands[0], operands[1], operands[2]));
|
||||||
|
rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
|
||||||
|
const0_rtx);
|
||||||
|
emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
(define_insn_and_split "adddi3_sp32"
|
(define_insn_and_split "adddi3_sp32"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=&r")
|
[(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
(plus:DI (match_operand:DI 1 "register_operand" "%r")
|
(plus:DI (match_operand:DI 1 "register_operand" "%r")
|
||||||
|
|
@ -3740,6 +3789,80 @@
|
||||||
}
|
}
|
||||||
[(set_attr "length" "2")])
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
|
(define_insn_and_split "uaddvdi4_sp32"
|
||||||
|
[(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (plus:DI (match_operand:DI 1 "register_operand" "%r")
|
||||||
|
(match_operand:DI 2 "arith_double_operand" "rHI"))
|
||||||
|
(match_dup 1)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
||||||
|
"!TARGET_ARCH64"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (plus:SI (match_dup 4) (match_dup 5))
|
||||||
|
(match_dup 4)))
|
||||||
|
(set (match_dup 3)
|
||||||
|
(plus:SI (match_dup 4) (match_dup 5)))])
|
||||||
|
(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (zero_extend:DI
|
||||||
|
(plus:SI (plus:SI (match_dup 7) (match_dup 8))
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0))))
|
||||||
|
(plus:DI (plus:DI (zero_extend:DI (match_dup 7))
|
||||||
|
(zero_extend:DI (match_dup 8)))
|
||||||
|
(ltu:DI (reg:CCC CC_REG)
|
||||||
|
(const_int 0)))))
|
||||||
|
(set (match_dup 6)
|
||||||
|
(plus:SI (plus:SI (match_dup 7) (match_dup 8))
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0))))])]
|
||||||
|
{
|
||||||
|
operands[3] = gen_lowpart (SImode, operands[0]);
|
||||||
|
operands[4] = gen_lowpart (SImode, operands[1]);
|
||||||
|
operands[5] = gen_lowpart (SImode, operands[2]);
|
||||||
|
operands[6] = gen_highpart (SImode, operands[0]);
|
||||||
|
operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
|
||||||
|
operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
|
||||||
|
}
|
||||||
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
|
(define_insn_and_split "addvdi4_sp32"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (plus:DI (match_operand:DI 1 "register_operand" "%r")
|
||||||
|
(match_operand:DI 2 "arith_double_operand" "rHI"))
|
||||||
|
(unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
||||||
|
"!TARGET_ARCH64"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (plus:SI (match_dup 4) (match_dup 5))
|
||||||
|
(match_dup 4)))
|
||||||
|
(set (match_dup 3)
|
||||||
|
(plus:SI (match_dup 4) (match_dup 5)))])
|
||||||
|
(parallel [(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (plus:SI (plus:SI (match_dup 7) (match_dup 8))
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0)))
|
||||||
|
(unspec:SI [(plus:SI (match_dup 7) (match_dup 8))
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0))]
|
||||||
|
UNSPEC_ADDV)))
|
||||||
|
(set (match_dup 6)
|
||||||
|
(plus:SI (plus:SI (match_dup 7) (match_dup 8))
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0))))])]
|
||||||
|
{
|
||||||
|
operands[3] = gen_lowpart (SImode, operands[0]);
|
||||||
|
operands[4] = gen_lowpart (SImode, operands[1]);
|
||||||
|
operands[5] = gen_lowpart (SImode, operands[2]);
|
||||||
|
operands[6] = gen_highpart (SImode, operands[0]);
|
||||||
|
operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
|
||||||
|
operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
|
||||||
|
}
|
||||||
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
(define_insn_and_split "*addx_extend_sp32"
|
(define_insn_and_split "*addx_extend_sp32"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
(zero_extend:DI (plus:SI (plus:SI
|
(zero_extend:DI (plus:SI (plus:SI
|
||||||
|
|
@ -3797,6 +3920,31 @@
|
||||||
[(set_attr "type" "*,*")
|
[(set_attr "type" "*,*")
|
||||||
(set_attr "fptype" "*,*")])
|
(set_attr "fptype" "*,*")])
|
||||||
|
|
||||||
|
(define_expand "uaddvsi4"
|
||||||
|
[(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (plus:SI (match_operand:SI 1 "register_operand")
|
||||||
|
(match_operand:SI 2 "arith_operand"))
|
||||||
|
(match_dup 1)))
|
||||||
|
(set (match_operand:SI 0 "register_operand")
|
||||||
|
(plus:SI (match_dup 1) (match_dup 2)))])
|
||||||
|
(set (pc) (if_then_else (ltu (reg:CCC CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))]
|
||||||
|
"")
|
||||||
|
|
||||||
|
(define_expand "addvsi4"
|
||||||
|
[(parallel [(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (plus:SI (match_operand:SI 1 "register_operand")
|
||||||
|
(match_operand:SI 2 "arith_operand"))
|
||||||
|
(unspec:SI [(match_dup 1) (match_dup 2)]
|
||||||
|
UNSPEC_ADDV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand")
|
||||||
|
(plus:SI (match_dup 1) (match_dup 2)))])
|
||||||
|
(set (pc) (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))]
|
||||||
|
"")
|
||||||
|
|
||||||
(define_insn "*cmp_ccnz_plus"
|
(define_insn "*cmp_ccnz_plus"
|
||||||
[(set (reg:CCNZ CC_REG)
|
[(set (reg:CCNZ CC_REG)
|
||||||
(compare:CCNZ (plus:SI (match_operand:SI 0 "register_operand" "%r")
|
(compare:CCNZ (plus:SI (match_operand:SI 0 "register_operand" "%r")
|
||||||
|
|
@ -3877,6 +4025,79 @@
|
||||||
"addcc\t%1, %2, %0"
|
"addcc\t%1, %2, %0"
|
||||||
[(set_attr "type" "compare")])
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccc_plus_sltu_set"
|
||||||
|
[(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (zero_extend:DI
|
||||||
|
(plus:SI
|
||||||
|
(plus:SI (match_operand:SI 1 "register_operand" "%r")
|
||||||
|
(match_operand:SI 2 "arith_operand" "rI"))
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0))))
|
||||||
|
(plus:DI (plus:DI (zero_extend:DI (match_dup 1))
|
||||||
|
(zero_extend:DI (match_dup 2)))
|
||||||
|
(ltu:DI (reg:CCC CC_REG) (const_int 0)))))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(plus:SI (plus:SI (match_dup 1) (match_dup 2))
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0))))]
|
||||||
|
""
|
||||||
|
"addxcc\t%1, %2, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_plus"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (plus:SI (match_operand:SI 0 "register_operand" "%r")
|
||||||
|
(match_operand:SI 1 "arith_operand" "rI"))
|
||||||
|
(unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))]
|
||||||
|
""
|
||||||
|
"addcc\t%0, %1, %%g0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccxv_plus"
|
||||||
|
[(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (plus:DI (match_operand:DI 0 "register_operand" "%r")
|
||||||
|
(match_operand:DI 1 "arith_operand" "rI"))
|
||||||
|
(unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_ADDV)))]
|
||||||
|
"TARGET_ARCH64"
|
||||||
|
"addcc\t%0, %1, %%g0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_plus_set"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (plus:SI (match_operand:SI 1 "register_operand" "%r")
|
||||||
|
(match_operand:SI 2 "arith_operand" "rI"))
|
||||||
|
(unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||||
|
""
|
||||||
|
"addcc\t%1, %2, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccxv_plus_set"
|
||||||
|
[(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (plus:DI (match_operand:DI 1 "register_operand" "%r")
|
||||||
|
(match_operand:DI 2 "arith_operand" "rI"))
|
||||||
|
(unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_ADDV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
|
(plus:DI (match_dup 1) (match_dup 2)))]
|
||||||
|
"TARGET_ARCH64"
|
||||||
|
"addcc\t%1, %2, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_plus_sltu_set"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "%r")
|
||||||
|
(match_operand:SI 2 "arith_operand" "rI"))
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0)))
|
||||||
|
(unspec:SI [(plus:SI (match_dup 1) (match_dup 2))
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0))]
|
||||||
|
UNSPEC_ADDV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(plus:SI (plus:SI (match_dup 1) (match_dup 2))
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0))))]
|
||||||
|
""
|
||||||
|
"addxcc\t%1, %2, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
|
||||||
(define_expand "subdi3"
|
(define_expand "subdi3"
|
||||||
[(set (match_operand:DI 0 "register_operand" "")
|
[(set (match_operand:DI 0 "register_operand" "")
|
||||||
(minus:DI (match_operand:DI 1 "register_operand" "")
|
(minus:DI (match_operand:DI 1 "register_operand" "")
|
||||||
|
|
@ -3890,6 +4111,56 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
(define_expand "usubvdi4"
|
||||||
|
[(parallel [(set (reg:CCX CC_REG)
|
||||||
|
(compare:CCX (match_operand:DI 1 "register_or_zero_operand")
|
||||||
|
(match_operand:DI 2 "arith_add_operand")))
|
||||||
|
(set (match_operand:DI 0 "register_operand")
|
||||||
|
(minus:DI (match_dup 1) (match_dup 2)))])
|
||||||
|
(set (pc) (if_then_else (ltu (reg:CCX CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (operands[1] == const0_rtx)
|
||||||
|
{
|
||||||
|
emit_insn (gen_unegvdi3 (operands[0], operands[2], operands[3]));
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!TARGET_64BIT)
|
||||||
|
{
|
||||||
|
emit_insn (gen_usubvdi4_sp32 (operands[0], operands[1], operands[2]));
|
||||||
|
rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
|
||||||
|
const0_rtx);
|
||||||
|
emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_expand "subvdi4"
|
||||||
|
[(parallel [(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (minus:DI (match_operand:DI 1 "register_operand")
|
||||||
|
(match_operand:DI 2 "arith_add_operand"))
|
||||||
|
(unspec:DI [(match_dup 1) (match_dup 2)]
|
||||||
|
UNSPEC_SUBV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand")
|
||||||
|
(minus:DI (match_dup 1) (match_dup 2)))])
|
||||||
|
(set (pc) (if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (!TARGET_64BIT)
|
||||||
|
{
|
||||||
|
emit_insn (gen_subvdi4_sp32 (operands[0], operands[1], operands[2]));
|
||||||
|
rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
|
||||||
|
const0_rtx);
|
||||||
|
emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[3]));
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
(define_insn_and_split "subdi3_sp32"
|
(define_insn_and_split "subdi3_sp32"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=&r")
|
[(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
(minus:DI (match_operand:DI 1 "register_operand" "r")
|
(minus:DI (match_operand:DI 1 "register_operand" "r")
|
||||||
|
|
@ -3915,6 +4186,80 @@
|
||||||
}
|
}
|
||||||
[(set_attr "length" "2")])
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
|
(define_insn_and_split "usubvdi4_sp32"
|
||||||
|
[(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (match_operand:DI 1 "register_operand" "r")
|
||||||
|
(match_operand:DI 2 "arith_double_operand" "rHI")))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
|
(minus:DI (match_dup 1) (match_dup 2)))]
|
||||||
|
"!TARGET_ARCH64"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(parallel [(set (reg:CC CC_REG)
|
||||||
|
(compare:CC (match_dup 4) (match_dup 5)))
|
||||||
|
(set (match_dup 3)
|
||||||
|
(minus:SI (match_dup 4) (match_dup 5)))])
|
||||||
|
(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (zero_extend:DI
|
||||||
|
(minus:SI (minus:SI (match_dup 7)
|
||||||
|
(ltu:SI (reg:CC CC_REG)
|
||||||
|
(const_int 0)))
|
||||||
|
(match_dup 8)))
|
||||||
|
(minus:DI
|
||||||
|
(minus:DI (zero_extend:DI (match_dup 7))
|
||||||
|
(ltu:DI (reg:CC CC_REG)
|
||||||
|
(const_int 0)))
|
||||||
|
(zero_extend:DI (match_dup 8)))))
|
||||||
|
(set (match_dup 6)
|
||||||
|
(minus:SI (minus:SI (match_dup 7)
|
||||||
|
(ltu:SI (reg:CC CC_REG)
|
||||||
|
(const_int 0)))
|
||||||
|
(match_dup 8)))])]
|
||||||
|
{
|
||||||
|
operands[3] = gen_lowpart (SImode, operands[0]);
|
||||||
|
operands[4] = gen_lowpart (SImode, operands[1]);
|
||||||
|
operands[5] = gen_lowpart (SImode, operands[2]);
|
||||||
|
operands[6] = gen_highpart (SImode, operands[0]);
|
||||||
|
operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
|
||||||
|
operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
|
||||||
|
}
|
||||||
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
|
(define_insn_and_split "subvdi4_sp32"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (minus:DI (match_operand:DI 1 "register_operand" "%r")
|
||||||
|
(match_operand:DI 2 "arith_double_operand" "rHI"))
|
||||||
|
(unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
|
(minus:DI (match_dup 1) (match_dup 2)))]
|
||||||
|
"!TARGET_ARCH64"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(parallel [(set (reg:CC CC_REG)
|
||||||
|
(compare:CC (match_dup 4) (match_dup 5)))
|
||||||
|
(set (match_dup 3)
|
||||||
|
(minus:SI (match_dup 4) (match_dup 5)))])
|
||||||
|
(parallel [(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (minus:SI (minus:SI (match_dup 7) (match_dup 8))
|
||||||
|
(ltu:SI (reg:CC CC_REG)
|
||||||
|
(const_int 0)))
|
||||||
|
(unspec:SI [(minus:SI (match_dup 7) (match_dup 8))
|
||||||
|
(ltu:SI (reg:CC CC_REG)
|
||||||
|
(const_int 0))]
|
||||||
|
UNSPEC_SUBV)))
|
||||||
|
(set (match_dup 6)
|
||||||
|
(minus:SI (minus:SI (match_dup 7) (match_dup 8))
|
||||||
|
(ltu:SI (reg:CC CC_REG) (const_int 0))))])]
|
||||||
|
{
|
||||||
|
operands[3] = gen_lowpart (SImode, operands[0]);
|
||||||
|
operands[4] = gen_lowpart (SImode, operands[1]);
|
||||||
|
operands[5] = gen_lowpart (SImode, operands[2]);
|
||||||
|
operands[6] = gen_highpart (SImode, operands[0]);
|
||||||
|
operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
|
||||||
|
operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
|
||||||
|
}
|
||||||
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
(define_insn_and_split "*subx_extend_sp32"
|
(define_insn_and_split "*subx_extend_sp32"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
(zero_extend:DI (minus:SI (minus:SI
|
(zero_extend:DI (minus:SI (minus:SI
|
||||||
|
|
@ -3971,6 +4316,37 @@
|
||||||
[(set_attr "type" "*,*")
|
[(set_attr "type" "*,*")
|
||||||
(set_attr "fptype" "*,*")])
|
(set_attr "fptype" "*,*")])
|
||||||
|
|
||||||
|
(define_expand "usubvsi4"
|
||||||
|
[(parallel [(set (reg:CC CC_REG)
|
||||||
|
(compare:CC (match_operand:SI 1 "register_or_zero_operand")
|
||||||
|
(match_operand:SI 2 "arith_operand")))
|
||||||
|
(set (match_operand:SI 0 "register_operand")
|
||||||
|
(minus:SI (match_dup 1) (match_dup 2)))])
|
||||||
|
(set (pc) (if_then_else (ltu (reg:CC CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (operands[1] == const0_rtx)
|
||||||
|
{
|
||||||
|
emit_insn (gen_unegvsi3 (operands[0], operands[2], operands[3]));
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_expand "subvsi4"
|
||||||
|
[(parallel [(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (minus:SI (match_operand:SI 1 "register_operand")
|
||||||
|
(match_operand:SI 2 "arith_operand"))
|
||||||
|
(unspec:SI [(match_dup 1) (match_dup 2)]
|
||||||
|
UNSPEC_SUBV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand")
|
||||||
|
(minus:SI (match_dup 1) (match_dup 2)))])
|
||||||
|
(set (pc) (if_then_else (ne (reg:CCV CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 3))
|
||||||
|
(pc)))]
|
||||||
|
"")
|
||||||
|
|
||||||
(define_insn "*cmp_ccnz_minus"
|
(define_insn "*cmp_ccnz_minus"
|
||||||
[(set (reg:CCNZ CC_REG)
|
[(set (reg:CCNZ CC_REG)
|
||||||
(compare:CCNZ (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
|
(compare:CCNZ (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
|
||||||
|
|
@ -4031,6 +4407,82 @@
|
||||||
"subcc\t%r1, %2, %0"
|
"subcc\t%r1, %2, %0"
|
||||||
[(set_attr "type" "compare")])
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccc_minus_sltu_set"
|
||||||
|
[(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (zero_extend:DI
|
||||||
|
(minus:SI
|
||||||
|
(minus:SI
|
||||||
|
(match_operand:SI 1 "register_or_zero_operand" "rJ")
|
||||||
|
(ltu:SI (reg:CC CC_REG) (const_int 0)))
|
||||||
|
(match_operand:SI 2 "arith_operand" "rI")))
|
||||||
|
(minus:DI
|
||||||
|
(minus:DI
|
||||||
|
(zero_extend:DI (match_dup 1))
|
||||||
|
(ltu:DI (reg:CC CC_REG) (const_int 0)))
|
||||||
|
(zero_extend:DI (match_dup 2)))))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(minus:SI (minus:SI (match_dup 1)
|
||||||
|
(ltu:SI (reg:CC CC_REG) (const_int 0)))
|
||||||
|
(match_dup 2)))]
|
||||||
|
""
|
||||||
|
"subxcc\t%r1, %2, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_minus"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (minus:SI (match_operand:SI 0 "register_or_zero_operand" "rJ")
|
||||||
|
(match_operand:SI 1 "arith_operand" "rI"))
|
||||||
|
(unspec:SI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))]
|
||||||
|
""
|
||||||
|
"subcc\t%r0, %1, %%g0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccxv_minus"
|
||||||
|
[(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (minus:DI (match_operand:DI 0 "register_or_zero_operand" "rJ")
|
||||||
|
(match_operand:DI 1 "arith_operand" "rI"))
|
||||||
|
(unspec:DI [(match_dup 0) (match_dup 1)] UNSPEC_SUBV)))]
|
||||||
|
"TARGET_ARCH64"
|
||||||
|
"subcc\t%r0, %1, %%g0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_minus_set"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
|
||||||
|
(match_operand:SI 2 "arith_operand" "rI"))
|
||||||
|
(unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(minus:SI (match_dup 1) (match_dup 2)))]
|
||||||
|
""
|
||||||
|
"subcc\t%r1, %2, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccxv_minus_set"
|
||||||
|
[(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (minus:DI (match_operand:DI 1 "register_or_zero_operand" "rJ")
|
||||||
|
(match_operand:DI 2 "arith_operand" "rI"))
|
||||||
|
(unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SUBV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
|
(minus:DI (match_dup 1) (match_dup 2)))]
|
||||||
|
"TARGET_ARCH64"
|
||||||
|
"subcc\t%r1, %2, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_minus_sltu_set"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (minus:SI (minus:SI (match_operand:SI 1 "register_or_zero_operand" "rJ")
|
||||||
|
(match_operand:SI 2 "arith_operand" "rI"))
|
||||||
|
(ltu:SI (reg:CC CC_REG) (const_int 0)))
|
||||||
|
(unspec:SI [(minus:SI (match_dup 1) (match_dup 2))
|
||||||
|
(ltu:SI (reg:CC CC_REG) (const_int 0))]
|
||||||
|
UNSPEC_SUBV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(minus:SI (minus:SI (match_dup 1) (match_dup 2))
|
||||||
|
(ltu:SI (reg:CC CC_REG) (const_int 0))))]
|
||||||
|
""
|
||||||
|
"subxcc\t%1, %2, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
|
||||||
;; Integer multiply/divide instructions.
|
;; Integer multiply/divide instructions.
|
||||||
|
|
||||||
|
|
@ -5127,6 +5579,50 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
(define_expand "unegvdi3"
|
||||||
|
[(parallel [(set (reg:CCXC CC_REG)
|
||||||
|
(compare:CCXC (not:DI (match_operand:DI 1 "register_operand" ""))
|
||||||
|
(const_int -1)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "")
|
||||||
|
(neg:DI (match_dup 1)))])
|
||||||
|
(set (pc)
|
||||||
|
(if_then_else (ltu (reg:CCXC CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 2 ""))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (!TARGET_64BIT)
|
||||||
|
{
|
||||||
|
emit_insn (gen_unegvdi3_sp32 (operands[0], operands[1]));
|
||||||
|
rtx x = gen_rtx_LTU (VOIDmode, gen_rtx_REG (CCCmode, SPARC_ICC_REG),
|
||||||
|
const0_rtx);
|
||||||
|
emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2]));
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
(define_expand "negvdi3"
|
||||||
|
[(parallel [(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (neg:DI (match_operand:DI 1 "register_operand" ""))
|
||||||
|
(unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "")
|
||||||
|
(neg:DI (match_dup 1)))])
|
||||||
|
(set (pc)
|
||||||
|
(if_then_else (ne (reg:CCXV CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 2 ""))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
{
|
||||||
|
if (!TARGET_64BIT)
|
||||||
|
{
|
||||||
|
emit_insn (gen_negvdi3_sp32 (operands[0], operands[1]));
|
||||||
|
rtx x = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCVmode, SPARC_ICC_REG),
|
||||||
|
const0_rtx);
|
||||||
|
emit_jump_insn (gen_cbranchcc4 (x, XEXP (x, 0), XEXP (x, 1), operands[2]));
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
(define_insn_and_split "negdi2_sp32"
|
(define_insn_and_split "negdi2_sp32"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=&r")
|
[(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
(neg:DI (match_operand:DI 1 "register_operand" "r")))
|
(neg:DI (match_operand:DI 1 "register_operand" "r")))
|
||||||
|
|
@ -5145,6 +5641,64 @@
|
||||||
operands[5] = gen_lowpart (SImode, operands[1]);"
|
operands[5] = gen_lowpart (SImode, operands[1]);"
|
||||||
[(set_attr "length" "2")])
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
|
(define_insn_and_split "unegvdi3_sp32"
|
||||||
|
[(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (not:DI (match_operand:DI 1 "register_operand" "r"))
|
||||||
|
(const_int -1)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
|
(neg:DI (match_dup 1)))]
|
||||||
|
"!TARGET_ARCH64"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (not:SI (match_dup 5)) (const_int -1)))
|
||||||
|
(set (match_dup 4) (neg:SI (match_dup 5)))])
|
||||||
|
(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (zero_extend:DI
|
||||||
|
(neg:SI (plus:SI (match_dup 3)
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0)))))
|
||||||
|
(neg:DI (plus:DI (zero_extend:DI (match_dup 3))
|
||||||
|
(ltu:DI (reg:CCC CC_REG)
|
||||||
|
(const_int 0))))))
|
||||||
|
(set (match_dup 2) (neg:SI (plus:SI (match_dup 3)
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0)))))])]
|
||||||
|
"operands[2] = gen_highpart (SImode, operands[0]);
|
||||||
|
operands[3] = gen_highpart (SImode, operands[1]);
|
||||||
|
operands[4] = gen_lowpart (SImode, operands[0]);
|
||||||
|
operands[5] = gen_lowpart (SImode, operands[1]);"
|
||||||
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
|
(define_insn_and_split "negvdi3_sp32"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (neg:DI (match_operand:DI 1 "register_operand" "r"))
|
||||||
|
(unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=&r")
|
||||||
|
(neg:DI (match_dup 1)))]
|
||||||
|
"!TARGET_ARCH64"
|
||||||
|
"#"
|
||||||
|
"&& reload_completed"
|
||||||
|
[(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (not:SI (match_dup 5)) (const_int -1)))
|
||||||
|
(set (match_dup 4) (neg:SI (match_dup 5)))])
|
||||||
|
(parallel [(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (neg:SI (plus:SI (match_dup 3)
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0))))
|
||||||
|
(unspec:SI [(plus:SI (match_dup 3)
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0)))]
|
||||||
|
UNSPEC_NEGV)))
|
||||||
|
(set (match_dup 2) (neg:SI (plus:SI (match_dup 3)
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0)))))])]
|
||||||
|
"operands[2] = gen_highpart (SImode, operands[0]);
|
||||||
|
operands[3] = gen_highpart (SImode, operands[1]);
|
||||||
|
operands[4] = gen_lowpart (SImode, operands[0]);
|
||||||
|
operands[5] = gen_lowpart (SImode, operands[1]);"
|
||||||
|
[(set_attr "length" "2")])
|
||||||
|
|
||||||
(define_insn "*negdi2_sp64"
|
(define_insn "*negdi2_sp64"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
(neg:DI (match_operand:DI 1 "register_operand" "r")))]
|
(neg:DI (match_operand:DI 1 "register_operand" "r")))]
|
||||||
|
|
@ -5157,6 +5711,30 @@
|
||||||
""
|
""
|
||||||
"sub\t%%g0, %1, %0")
|
"sub\t%%g0, %1, %0")
|
||||||
|
|
||||||
|
(define_expand "unegvsi3"
|
||||||
|
[(parallel [(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (not:SI (match_operand:SI 1 "arith_operand" ""))
|
||||||
|
(const_int -1)))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "")
|
||||||
|
(neg:SI (match_dup 1)))])
|
||||||
|
(set (pc)
|
||||||
|
(if_then_else (ltu (reg:CCC CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 2 ""))
|
||||||
|
(pc)))]
|
||||||
|
"")
|
||||||
|
|
||||||
|
(define_expand "negvsi3"
|
||||||
|
[(parallel [(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" ""))
|
||||||
|
(unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "")
|
||||||
|
(neg:SI (match_dup 1)))])
|
||||||
|
(set (pc)
|
||||||
|
(if_then_else (ne (reg:CCV CC_REG) (const_int 0))
|
||||||
|
(label_ref (match_operand 2 ""))
|
||||||
|
(pc)))]
|
||||||
|
"")
|
||||||
|
|
||||||
(define_insn "*cmp_ccnz_neg"
|
(define_insn "*cmp_ccnz_neg"
|
||||||
[(set (reg:CCNZ CC_REG)
|
[(set (reg:CCNZ CC_REG)
|
||||||
(compare:CCNZ (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
|
(compare:CCNZ (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
|
||||||
|
|
@ -5213,6 +5791,73 @@
|
||||||
"subcc\t%%g0, %1, %0"
|
"subcc\t%%g0, %1, %0"
|
||||||
[(set_attr "type" "compare")])
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccc_neg_sltu_set"
|
||||||
|
[(set (reg:CCC CC_REG)
|
||||||
|
(compare:CCC (zero_extend:DI
|
||||||
|
(neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0)))))
|
||||||
|
(neg:DI (plus:DI (zero_extend:DI (match_dup 1))
|
||||||
|
(ltu:DI (reg:CCC CC_REG)
|
||||||
|
(const_int 0))))))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(neg:SI (plus:SI (match_dup 1)
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
|
||||||
|
""
|
||||||
|
"subxcc\t%%g0, %1, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_neg"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (neg:SI (match_operand:SI 0 "arith_operand" "rI"))
|
||||||
|
(unspec:SI [(match_dup 0)] UNSPEC_NEGV)))]
|
||||||
|
""
|
||||||
|
"subcc\t%%g0, %0, %%g0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccxv_neg"
|
||||||
|
[(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (neg:DI (match_operand:DI 0 "arith_operand" "rI"))
|
||||||
|
(unspec:DI [(match_dup 0)] UNSPEC_NEGV)))]
|
||||||
|
"TARGET_ARCH64"
|
||||||
|
"subcc\t%%g0, %0, %%g0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_neg_set"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (neg:SI (match_operand:SI 1 "arith_operand" "rI"))
|
||||||
|
(unspec:SI [(match_dup 1)] UNSPEC_NEGV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(neg:SI (match_dup 1)))]
|
||||||
|
""
|
||||||
|
"subcc\t%%g0, %1, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccxv_neg_set"
|
||||||
|
[(set (reg:CCXV CC_REG)
|
||||||
|
(compare:CCXV (neg:DI (match_operand:DI 1 "arith_operand" "rI"))
|
||||||
|
(unspec:DI [(match_dup 1)] UNSPEC_NEGV)))
|
||||||
|
(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
|
(neg:DI (match_dup 1)))]
|
||||||
|
"TARGET_ARCH64"
|
||||||
|
"subcc\t%%g0, %1, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
(define_insn "*cmp_ccv_neg_sltu_set"
|
||||||
|
[(set (reg:CCV CC_REG)
|
||||||
|
(compare:CCV (neg:SI (plus:SI (match_operand:SI 1 "arith_operand" "rI")
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0))))
|
||||||
|
(unspec:SI [(plus:SI (match_dup 1)
|
||||||
|
(ltu:SI (reg:CCC CC_REG)
|
||||||
|
(const_int 0)))]
|
||||||
|
UNSPEC_NEGV)))
|
||||||
|
(set (match_operand:SI 0 "register_operand" "=r")
|
||||||
|
(neg:SI (plus:SI (match_dup 1)
|
||||||
|
(ltu:SI (reg:CCC CC_REG) (const_int 0)))))]
|
||||||
|
""
|
||||||
|
"subxcc\t%%g0, %1, %0"
|
||||||
|
[(set_attr "type" "compare")])
|
||||||
|
|
||||||
|
|
||||||
(define_insn "one_cmpldi2"
|
(define_insn "one_cmpldi2"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2016-10-21 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
* gcc.target/sparc/overflow-1.c: New test.
|
||||||
|
* gcc.target/sparc/overflow-2.c: Likewise.
|
||||||
|
* gcc.target/sparc/overflow-3.c: Likewise.
|
||||||
|
|
||||||
2016-10-21 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
2016-10-21 Andre Vieira <andre.simoesdiasvieira@arm.com>
|
||||||
|
|
||||||
* gcc.target/arm/pure-code/pure-code.exp: Require arm_cortex_m
|
* gcc.target/arm/pure-code/pure-code.exp: Require arm_cortex_m
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O -mcpu=v8" } */
|
||||||
|
/* { dg-require-effective-target ilp32 } */
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
bool my_uadd_overflow (uint32_t a, uint32_t b, uint32_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_add_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_usub_overflow (uint32_t a, uint32_t b, uint32_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_uneg_overflow (uint32_t a, uint32_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (0, a, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_add_overflow (int32_t a, int32_t b, int32_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_add_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_sub_overflow (int32_t a, int32_t b, int32_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_neg_overflow (int32_t a, int32_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (0, a, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "bvs" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-not "cmp\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "save\t%" } } */
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O -mcpu=v8" } */
|
||||||
|
/* { dg-require-effective-target ilp32 } */
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
bool my_uadd_overflow (uint64_t a, uint64_t b, uint64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_add_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_usub_overflow (uint64_t a, uint64_t b, uint64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_uneg_overflow (uint64_t a, uint64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (0, a, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_add_overflow (int64_t a, int64_t b, int64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_add_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_sub_overflow (int64_t a, int64_t b, int64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_neg_overflow (int64_t a, int64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (0, a, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "addxcc\t%" 2 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "subxcc\t%" 4 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "addx\t%" 2 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "blu" 1 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "bvs" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-not "cmp\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "save\t%" } } */
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O" } */
|
||||||
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
bool my_uadd_overflow (uint64_t a, uint64_t b, uint64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_add_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_usub_overflow (uint64_t a, uint64_t b, uint64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_uneg_overflow (uint64_t a, uint64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (0, a, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_add_overflow (int64_t a, int64_t b, int64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_add_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_sub_overflow (int64_t a, int64_t b, int64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (a, b, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool my_neg_overflow (int64_t a, int64_t *res)
|
||||||
|
{
|
||||||
|
return __builtin_sub_overflow (0, a, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "movlu\t%" 1 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "blu" 2 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "bvs" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-not "cmp\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "save\t%" } } */
|
||||||
Loading…
Reference in New Issue