mirror of git://gcc.gnu.org/git/gcc.git
sparc.opt (msubxc): New option.
* config/sparc/sparc.opt (msubxc): New option. * doc/invoke.texi (SPARC options): Document it and tidy up. * doc/tm.texi.in (Condition Codes): Adjust SPARC example. * doc/tm.texi: Regenerate. * config/sparc/sparc-modes.def (CC_NOOV): Rename into... (CCNZ): ...this. (CCX_NOOV): Rename into... (CCXNZ): ...this. (CCC): New. (CCXC): Likewise. * config/sparc/predicates.m (fcc_register_operand): Simplify. (fcc0_register_operand): Likewise. (icc_register_operand): New. (icc_or_fcc_register_operand): Simplify. (nz_comparison_operator): New. (c_comparison_operator): Likewise. (noov_compare_operator): Rename into... (icc_comparison_operator): ...this. Use above predicates. (noov_compare64_operator): Rename into... (v9_comparison_operator): ...this and tidy up. (fcc_comparison_operator): New. (icc_or_fcc_comparison_operator): Likewise. (v9_register_compare_operator): Rename info... (v9_register_comparison_operator): ...this. * config/sparc/sparc.c (TARGET_FIXED_CONDITION_CODE_REGS): Define. (sparc_option_override): Remove redundant VIS masks and add MASK_SUBXC for Niagara-7. (sparc_fixed_condition_code_regs): New function. (select_cc_mode): Remove ATTRIBUTE_UNUSED. Adjust for CCNZ/CCXNZ renaming and add support for CCC/CCXC. (output_cbranch): Likewise. (sparc_print_operand): Likewise. (gen_v9_scc): Remove obsolete assertion. (emit_scc_insn): Emit RTL directly for EQ and NE. Add direct support for EQ in DImode if TARGET_SUBXC. Remove test on TARGET_VIS3 for GEU. (output_cbcond): Remove bogus handling of CC modes. (sparc_register_move_cost): Return 100 for NO_REGS. * config/sparc/sparc.md (W): New mode iterator. (length): Adjust for noov_compare64_operator renaming. (cmpsi_sne): New instruction. (cmpdi_sne): Likewise. (seqdi_special): Delete. (seqdi_special): Likewise. (snesi<P:mode>_special): Likewise. (snedi_special): Likewise. (snedi_special_vis3): Likewise. (snesi patterns): Use W iterator. (snedi patterns): Likewise. Add TARGET_SUBXC patterns. (sltu patterns): Likewise. (sgeu patterns): Likewise. (scc splitter): Do not split GEU in DImode if TARGET_SUBXC. (normal_branch): Use icc_comparison_operator predicate. (inverted_branch): Likewise. (cbcond_sp32): Use comparison_operator predicate. (cbcond_sp64): Likewise. (normal_int_branch_sp64): Adjust for renaming (inverted_int_branch_sp64): Likewise. (mov<I:mode>_cc_reg_sp64): Likewise. (movsf_cc_reg_sp6): Likewise. (movdf_cc_reg_sp64): Likewise. (movtf_cc_reg_hq_sp64): Likewise. (movtf_cc_reg_sp64): Likewise. (mov<I:mode>_cc_v9): Use icc_or_fcc_comparison_operator predicate. (movsf_cc_v9): Likewise. (movdf_cc_v9): Likewise. (movtf_cc_hq_v9): Likewise. (movtf_cc_v9): Likewise. (adddi3): Call gen_adddi3_sp32. (adddi3_insn_sp32): Rename to... (adddi3_sp32): ...this. Accept only register_operand as operand #1 and use CCCmode for the carry. (addx_extend_sp32): Use CCCmode for the carry. (addx_extend_sp64): Delete. (adddi3_extend_sp32): Use CCCmode for the carry. (cmp_plus patterns): Use CCNZ/CCXNZ mode and add C variants. (subdi3): Call gen_subdi3_sp32. (subdi3_insn_sp32): Rename to... (subdi3_sp32): ...this and use CCmode for the carry. (subx_extend_sp32): Use CCCmode for the carry. (subx_extend_sp64): Delete. (subdi3_extend_sp32): Use CCmode for the carry. (cmp_minus patterns): Use CCNZ/CCXNZ mode and add C variants. (negdi3): Call gen_negdi3_sp32. (negdi3_sp32): Use CCCmode for the carry. (cmp_neg patterns): Use CCNZ/CCXNZ mode and add C variants. (cmp_nz_ashift_1): Use CCNZ mode. (cmp_nz_set_ashift_1): Likewise. (ctrapsi4): Use comparison_operator predicate. (ctrapdi4): Likewise. (trapsi_insn): Use icc_comparison_operator predicate. (trapdi_insn): Likewise. (edge8 patterns): Use CCNZmode. (edge16 patterns): Likewise. (edge32 patterns): Likewise. From-SVN: r240971
This commit is contained in:
parent
8d946ecc46
commit
ff7e7ee099
|
|
@ -1,3 +1,100 @@
|
||||||
|
2016-10-11 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
* config/sparc/sparc.opt (msubxc): New option.
|
||||||
|
* doc/invoke.texi (SPARC options): Document it and tidy up.
|
||||||
|
* doc/tm.texi.in (Condition Codes): Adjust SPARC example.
|
||||||
|
* doc/tm.texi: Regenerate.
|
||||||
|
* config/sparc/sparc-modes.def (CC_NOOV): Rename into...
|
||||||
|
(CCNZ): ...this.
|
||||||
|
(CCX_NOOV): Rename into...
|
||||||
|
(CCXNZ): ...this.
|
||||||
|
(CCC): New.
|
||||||
|
(CCXC): Likewise.
|
||||||
|
* config/sparc/predicates.m (fcc_register_operand): Simplify.
|
||||||
|
(fcc0_register_operand): Likewise.
|
||||||
|
(icc_register_operand): New.
|
||||||
|
(icc_or_fcc_register_operand): Simplify.
|
||||||
|
(nz_comparison_operator): New.
|
||||||
|
(c_comparison_operator): Likewise.
|
||||||
|
(noov_compare_operator): Rename into...
|
||||||
|
(icc_comparison_operator): ...this. Use above predicates.
|
||||||
|
(noov_compare64_operator): Rename into...
|
||||||
|
(v9_comparison_operator): ...this and tidy up.
|
||||||
|
(fcc_comparison_operator): New.
|
||||||
|
(icc_or_fcc_comparison_operator): Likewise.
|
||||||
|
(v9_register_compare_operator): Rename info...
|
||||||
|
(v9_register_comparison_operator): ...this.
|
||||||
|
* config/sparc/sparc.c (TARGET_FIXED_CONDITION_CODE_REGS): Define.
|
||||||
|
(sparc_option_override): Remove redundant VIS masks and add MASK_SUBXC
|
||||||
|
for Niagara-7.
|
||||||
|
(sparc_fixed_condition_code_regs): New function.
|
||||||
|
(select_cc_mode): Remove ATTRIBUTE_UNUSED. Adjust for CCNZ/CCXNZ
|
||||||
|
renaming and add support for CCC/CCXC.
|
||||||
|
(output_cbranch): Likewise.
|
||||||
|
(sparc_print_operand): Likewise.
|
||||||
|
(gen_v9_scc): Remove obsolete assertion.
|
||||||
|
(emit_scc_insn): Emit RTL directly for EQ and NE. Add direct support
|
||||||
|
for EQ in DImode if TARGET_SUBXC. Remove test on TARGET_VIS3 for GEU.
|
||||||
|
(output_cbcond): Remove bogus handling of CC modes.
|
||||||
|
(sparc_register_move_cost): Return 100 for NO_REGS.
|
||||||
|
* config/sparc/sparc.md (W): New mode iterator.
|
||||||
|
(length): Adjust for noov_compare64_operator renaming.
|
||||||
|
(cmpsi_sne): New instruction.
|
||||||
|
(cmpdi_sne): Likewise.
|
||||||
|
(seqdi_special): Delete.
|
||||||
|
(seqdi_special): Likewise.
|
||||||
|
(snesi<P:mode>_special): Likewise.
|
||||||
|
(snedi_special): Likewise.
|
||||||
|
(snedi_special_vis3): Likewise.
|
||||||
|
(snesi patterns): Use W iterator.
|
||||||
|
(snedi patterns): Likewise. Add TARGET_SUBXC patterns.
|
||||||
|
(sltu patterns): Likewise.
|
||||||
|
(sgeu patterns): Likewise.
|
||||||
|
(scc splitter): Do not split GEU in DImode if TARGET_SUBXC.
|
||||||
|
(normal_branch): Use icc_comparison_operator predicate.
|
||||||
|
(inverted_branch): Likewise.
|
||||||
|
(cbcond_sp32): Use comparison_operator predicate.
|
||||||
|
(cbcond_sp64): Likewise.
|
||||||
|
(normal_int_branch_sp64): Adjust for renaming
|
||||||
|
(inverted_int_branch_sp64): Likewise.
|
||||||
|
(mov<I:mode>_cc_reg_sp64): Likewise.
|
||||||
|
(movsf_cc_reg_sp6): Likewise.
|
||||||
|
(movdf_cc_reg_sp64): Likewise.
|
||||||
|
(movtf_cc_reg_hq_sp64): Likewise.
|
||||||
|
(movtf_cc_reg_sp64): Likewise.
|
||||||
|
(mov<I:mode>_cc_v9): Use icc_or_fcc_comparison_operator predicate.
|
||||||
|
(movsf_cc_v9): Likewise.
|
||||||
|
(movdf_cc_v9): Likewise.
|
||||||
|
(movtf_cc_hq_v9): Likewise.
|
||||||
|
(movtf_cc_v9): Likewise.
|
||||||
|
(adddi3): Call gen_adddi3_sp32.
|
||||||
|
(adddi3_insn_sp32): Rename to...
|
||||||
|
(adddi3_sp32): ...this. Accept only register_operand as operand #1
|
||||||
|
and use CCCmode for the carry.
|
||||||
|
(addx_extend_sp32): Use CCCmode for the carry.
|
||||||
|
(addx_extend_sp64): Delete.
|
||||||
|
(adddi3_extend_sp32): Use CCCmode for the carry.
|
||||||
|
(cmp_plus patterns): Use CCNZ/CCXNZ mode and add C variants.
|
||||||
|
(subdi3): Call gen_subdi3_sp32.
|
||||||
|
(subdi3_insn_sp32): Rename to...
|
||||||
|
(subdi3_sp32): ...this and use CCmode for the carry.
|
||||||
|
(subx_extend_sp32): Use CCCmode for the carry.
|
||||||
|
(subx_extend_sp64): Delete.
|
||||||
|
(subdi3_extend_sp32): Use CCmode for the carry.
|
||||||
|
(cmp_minus patterns): Use CCNZ/CCXNZ mode and add C variants.
|
||||||
|
(negdi3): Call gen_negdi3_sp32.
|
||||||
|
(negdi3_sp32): Use CCCmode for the carry.
|
||||||
|
(cmp_neg patterns): Use CCNZ/CCXNZ mode and add C variants.
|
||||||
|
(cmp_nz_ashift_1): Use CCNZ mode.
|
||||||
|
(cmp_nz_set_ashift_1): Likewise.
|
||||||
|
(ctrapsi4): Use comparison_operator predicate.
|
||||||
|
(ctrapdi4): Likewise.
|
||||||
|
(trapsi_insn): Use icc_comparison_operator predicate.
|
||||||
|
(trapdi_insn): Likewise.
|
||||||
|
(edge8 patterns): Use CCNZmode.
|
||||||
|
(edge16 patterns): Likewise.
|
||||||
|
(edge32 patterns): Likewise.
|
||||||
|
|
||||||
2016-10-11 Eric Botcazou <ebotcazou@adacore.com>
|
2016-10-11 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* config/visium/visium-modes.def (CC_NOOV): Rename into...
|
* config/visium/visium-modes.def (CC_NOOV): Rename into...
|
||||||
|
|
|
||||||
|
|
@ -234,53 +234,23 @@
|
||||||
|
|
||||||
;; Return true if OP is a floating point condition code register.
|
;; Return true if OP is a floating point condition code register.
|
||||||
(define_predicate "fcc_register_operand"
|
(define_predicate "fcc_register_operand"
|
||||||
(match_code "reg")
|
(and (match_code "reg")
|
||||||
{
|
(match_test "((unsigned) REGNO (op) - SPARC_FIRST_V9_FCC_REG) < 4")))
|
||||||
if (mode != VOIDmode && mode != GET_MODE (op))
|
|
||||||
return false;
|
|
||||||
if (mode == VOIDmode
|
|
||||||
&& (GET_MODE (op) != CCFPmode && GET_MODE (op) != CCFPEmode))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#if 0 /* ??? 1 when %fcc0-3 are pseudos first. See gen_compare_reg(). */
|
|
||||||
if (reg_renumber == 0)
|
|
||||||
return REGNO (op) >= FIRST_PSEUDO_REGISTER;
|
|
||||||
return REGNO_OK_FOR_CCFP_P (REGNO (op));
|
|
||||||
#else
|
|
||||||
return ((unsigned) REGNO (op) - SPARC_FIRST_V9_FCC_REG) < 4;
|
|
||||||
#endif
|
|
||||||
})
|
|
||||||
|
|
||||||
;; Return true if OP is the floating point condition code register fcc0.
|
;; Return true if OP is the floating point condition code register fcc0.
|
||||||
(define_predicate "fcc0_register_operand"
|
(define_predicate "fcc0_register_operand"
|
||||||
(match_code "reg")
|
(and (match_code "reg")
|
||||||
{
|
(match_test "REGNO (op) == SPARC_FCC_REG")))
|
||||||
if (mode != VOIDmode && mode != GET_MODE (op))
|
|
||||||
return false;
|
|
||||||
if (mode == VOIDmode
|
|
||||||
&& (GET_MODE (op) != CCFPmode && GET_MODE (op) != CCFPEmode))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return REGNO (op) == SPARC_FCC_REG;
|
;; Return true if OP is an integer condition code register.
|
||||||
})
|
(define_predicate "icc_register_operand"
|
||||||
|
(and (match_code "reg")
|
||||||
|
(match_test "REGNO (op) == SPARC_ICC_REG")))
|
||||||
|
|
||||||
;; Return true if OP is an integer or floating point condition code register.
|
;; Return true if OP is an integer or floating point condition code register.
|
||||||
(define_predicate "icc_or_fcc_register_operand"
|
(define_predicate "icc_or_fcc_register_operand"
|
||||||
(match_code "reg")
|
(ior (match_operand 0 "icc_register_operand")
|
||||||
{
|
(match_operand 0 "fcc_register_operand")))
|
||||||
if (REGNO (op) == SPARC_ICC_REG)
|
|
||||||
{
|
|
||||||
if (mode != VOIDmode && mode != GET_MODE (op))
|
|
||||||
return false;
|
|
||||||
if (mode == VOIDmode
|
|
||||||
&& GET_MODE (op) != CCmode && GET_MODE (op) != CCXmode)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return fcc_register_operand (op, mode);
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
;; Predicates for arithmetic instructions.
|
;; Predicates for arithmetic instructions.
|
||||||
|
|
@ -442,46 +412,74 @@
|
||||||
|
|
||||||
;; Predicates for operators.
|
;; Predicates for operators.
|
||||||
|
|
||||||
;; Return true if OP is a comparison operator. This allows the use of
|
;; Return true if OP is a valid comparison operator for CCNZmode.
|
||||||
;; MATCH_OPERATOR to recognize all the branch insns.
|
(define_predicate "nz_comparison_operator"
|
||||||
(define_predicate "noov_compare_operator"
|
(match_code "eq,ne,lt,ge"))
|
||||||
(match_code "ne,eq,ge,gt,le,lt,geu,gtu,leu,ltu")
|
|
||||||
|
;; Return true if OP is a valid comparison operator for CCCmode.
|
||||||
|
(define_predicate "c_comparison_operator"
|
||||||
|
(match_code "ltu,geu"))
|
||||||
|
|
||||||
|
;; Return true if OP is an integer comparison operator. This allows
|
||||||
|
;; the use of MATCH_OPERATOR to recognize all the branch insns.
|
||||||
|
(define_predicate "icc_comparison_operator"
|
||||||
|
(match_operand 0 "ordered_comparison_operator")
|
||||||
{
|
{
|
||||||
enum rtx_code code = GET_CODE (op);
|
switch (GET_MODE (XEXP (op, 0)))
|
||||||
if (GET_MODE (XEXP (op, 0)) == CC_NOOVmode
|
{
|
||||||
|| GET_MODE (XEXP (op, 0)) == CCX_NOOVmode)
|
case CCmode:
|
||||||
/* These are the only branches which work with CC_NOOVmode. */
|
case CCXmode:
|
||||||
return (code == EQ || code == NE || code == GE || code == LT);
|
|
||||||
return true;
|
return true;
|
||||||
|
case CCNZmode:
|
||||||
|
case CCXNZmode:
|
||||||
|
return nz_comparison_operator (op, mode);
|
||||||
|
case CCCmode:
|
||||||
|
case CCXCmode:
|
||||||
|
return c_comparison_operator (op, mode);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
;; Return true if OP is a 64-bit comparison operator. This allows the use of
|
;; Return true if OP is a FP comparison operator.
|
||||||
;; MATCH_OPERATOR to recognize all the branch insns.
|
(define_predicate "fcc_comparison_operator"
|
||||||
(define_predicate "noov_compare64_operator"
|
(match_operand 0 "comparison_operator")
|
||||||
(and (match_code "ne,eq,ge,gt,le,lt,geu,gtu,leu,ltu")
|
|
||||||
(match_test "TARGET_V9"))
|
|
||||||
{
|
{
|
||||||
enum rtx_code code = GET_CODE (op);
|
switch (GET_MODE (XEXP (op, 0)))
|
||||||
if (GET_MODE (XEXP (op, 0)) == CCX_NOOVmode)
|
{
|
||||||
/* These are the only branches which work with CCX_NOOVmode. */
|
case CCFPmode:
|
||||||
return (code == EQ || code == NE || code == GE || code == LT);
|
case CCFPEmode:
|
||||||
return (GET_MODE (XEXP (op, 0)) == CCXmode);
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
;; Return true if OP is an integer or FP comparison operator. This allows
|
||||||
|
;; the use of MATCH_OPERATOR to recognize all the conditional move insns.
|
||||||
|
(define_predicate "icc_or_fcc_comparison_operator"
|
||||||
|
(ior (match_operand 0 "icc_comparison_operator")
|
||||||
|
(match_operand 0 "fcc_comparison_operator")))
|
||||||
|
|
||||||
|
;; Return true if OP is an integer comparison operator for V9.
|
||||||
|
(define_predicate "v9_comparison_operator"
|
||||||
|
(and (match_operand 0 "ordered_comparison_operator")
|
||||||
|
(match_test "TARGET_V9")))
|
||||||
|
|
||||||
;; Return true if OP is a comparison operator suitable for use in V9
|
;; Return true if OP is a comparison operator suitable for use in V9
|
||||||
;; conditional move or branch on register contents instructions.
|
;; conditional move or branch on register contents instructions.
|
||||||
(define_predicate "v9_register_compare_operator"
|
(define_predicate "v9_register_comparison_operator"
|
||||||
(match_code "eq,ne,ge,lt,le,gt"))
|
(match_code "eq,ne,ge,lt,le,gt"))
|
||||||
|
|
||||||
;; Return true if OP is an operator which can set the condition codes
|
;; Return true if OP is an operator which can set the condition codes
|
||||||
;; explicitly. We do not include PLUS and MINUS because these
|
;; explicitly. We do not include PLUS/MINUS/NEG/ASHIFT because these
|
||||||
;; require CC_NOOVmode, which we handle explicitly.
|
;; require CCNZmode, which we handle explicitly.
|
||||||
(define_predicate "cc_arith_operator"
|
(define_predicate "cc_arith_operator"
|
||||||
(match_code "and,ior,xor"))
|
(match_code "and,ior,xor"))
|
||||||
|
|
||||||
;; Return true if OP is an operator which can bitwise complement its
|
;; Return true if OP is an operator which can bitwise complement its
|
||||||
;; second operand and set the condition codes explicitly.
|
;; second operand and set the condition codes explicitly.
|
||||||
;; XOR is not here because combine canonicalizes (xor (not ...) ...)
|
;; XOR is not here because combine canonicalizes (xor (not ...) ...)
|
||||||
;; and (xor ... (not ...)) to (not (xor ...)). */
|
;; and (xor ... (not ...)) to (not (xor ...)).
|
||||||
(define_predicate "cc_arith_not_operator"
|
(define_predicate "cc_arith_not_operator"
|
||||||
(match_code "and,ior"))
|
(match_code "and,ior"))
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/* Definitions of target machine for GCC, for Sun SPARC.
|
/* Definitions of target machine for GCC, for Sun SPARC.
|
||||||
Copyright (C) 2002-2016 Free Software Foundation, Inc.
|
Copyright (C) 2002-2016 Free Software Foundation, Inc.
|
||||||
Contributed by Michael Tiemann (tiemann@cygnus.com).
|
Contributed by Michael Tiemann (tiemann@cygnus.com).
|
||||||
64 bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
|
64-bit SPARC V9 support by Michael Tiemann, Jim Wilson, and Doug Evans,
|
||||||
at Cygnus Support.
|
at Cygnus Support.
|
||||||
|
|
||||||
This file is part of GCC.
|
This file is part of GCC.
|
||||||
|
|
@ -25,20 +25,27 @@ FLOAT_MODE (TF, 16, ieee_quad_format);
|
||||||
|
|
||||||
/* Add any extra modes needed to represent the condition code.
|
/* Add any extra modes needed to represent the condition code.
|
||||||
|
|
||||||
On the SPARC, we have a "no-overflow" mode which is used when an add or
|
We have a CCNZ mode which is used for implicit comparisons with zero when
|
||||||
subtract insn is used to set the condition code. Different branches are
|
arithmetic instructions set the condition code. Only the N and Z flags
|
||||||
used in this case for some operations.
|
are valid in this mode, which means that only the =,!= and <,>= operators
|
||||||
|
can be used in conjunction with it.
|
||||||
|
|
||||||
|
We also have a CCCmode which is used by the arithmetic instructions when
|
||||||
|
they explicitly set the C flag (unsigned overflow). Only the unsigned
|
||||||
|
<,>= 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
|
||||||
one for comparisons which will never trap (CCFPmode).
|
one for comparisons which will never trap (CCFPmode).
|
||||||
|
|
||||||
CCXmode and CCX_NOOVmode are only used by v9. */
|
CC modes are used for the 32-bit ICC, CCX modes for the 64-bit XCC. */
|
||||||
|
|
||||||
CC_MODE (CCX);
|
CC_MODE (CCX);
|
||||||
CC_MODE (CC_NOOV);
|
CC_MODE (CCNZ);
|
||||||
CC_MODE (CCX_NOOV);
|
CC_MODE (CCXNZ);
|
||||||
|
CC_MODE (CCC);
|
||||||
|
CC_MODE (CCXC);
|
||||||
CC_MODE (CCFP);
|
CC_MODE (CCFP);
|
||||||
CC_MODE (CCFPE);
|
CC_MODE (CCFPE);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -647,6 +647,7 @@ static reg_class_t sparc_secondary_reload (bool, rtx, reg_class_t,
|
||||||
secondary_reload_info *);
|
secondary_reload_info *);
|
||||||
static machine_mode sparc_cstore_mode (enum insn_code icode);
|
static machine_mode sparc_cstore_mode (enum insn_code icode);
|
||||||
static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *);
|
static void sparc_atomic_assign_expand_fenv (tree *, tree *, tree *);
|
||||||
|
static bool sparc_fixed_condition_code_regs (unsigned int *, unsigned int *);
|
||||||
|
|
||||||
#ifdef SUBTARGET_ATTRIBUTE_TABLE
|
#ifdef SUBTARGET_ATTRIBUTE_TABLE
|
||||||
/* Table of valid machine attributes. */
|
/* Table of valid machine attributes. */
|
||||||
|
|
@ -857,6 +858,9 @@ char sparc_hard_reg_printed[8];
|
||||||
#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
|
#undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
|
||||||
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV sparc_atomic_assign_expand_fenv
|
#define TARGET_ATOMIC_ASSIGN_EXPAND_FENV sparc_atomic_assign_expand_fenv
|
||||||
|
|
||||||
|
#undef TARGET_FIXED_CONDITION_CODE_REGS
|
||||||
|
#define TARGET_FIXED_CONDITION_CODE_REGS sparc_fixed_condition_code_regs
|
||||||
|
|
||||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||||
|
|
||||||
/* Return the memory reference contained in X if any, zero otherwise. */
|
/* Return the memory reference contained in X if any, zero otherwise. */
|
||||||
|
|
@ -1314,13 +1318,13 @@ sparc_option_override (void)
|
||||||
MASK_V9|MASK_POPC|MASK_VIS2 },
|
MASK_V9|MASK_POPC|MASK_VIS2 },
|
||||||
/* UltraSPARC T3 */
|
/* UltraSPARC T3 */
|
||||||
{ "niagara3", MASK_ISA,
|
{ "niagara3", MASK_ISA,
|
||||||
MASK_V9|MASK_POPC|MASK_VIS2|MASK_VIS3|MASK_FMAF },
|
MASK_V9|MASK_POPC|MASK_VIS3|MASK_FMAF },
|
||||||
/* UltraSPARC T4 */
|
/* UltraSPARC T4 */
|
||||||
{ "niagara4", MASK_ISA,
|
{ "niagara4", MASK_ISA,
|
||||||
MASK_V9|MASK_POPC|MASK_VIS2|MASK_VIS3|MASK_FMAF|MASK_CBCOND },
|
MASK_V9|MASK_POPC|MASK_VIS3|MASK_FMAF|MASK_CBCOND },
|
||||||
/* UltraSPARC M7 */
|
/* UltraSPARC M7 */
|
||||||
{ "niagara7", MASK_ISA,
|
{ "niagara7", MASK_ISA,
|
||||||
MASK_V9|MASK_POPC|MASK_VIS2|MASK_VIS3|MASK_VIS4|MASK_FMAF|MASK_CBCOND },
|
MASK_V9|MASK_POPC|MASK_VIS4|MASK_FMAF|MASK_CBCOND|MASK_SUBXC }
|
||||||
};
|
};
|
||||||
const struct cpu_table *cpu;
|
const struct cpu_table *cpu;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
@ -1451,7 +1455,7 @@ sparc_option_override (void)
|
||||||
& ~MASK_CBCOND
|
& ~MASK_CBCOND
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_AS_SPARC5_VIS4
|
#ifndef HAVE_AS_SPARC5_VIS4
|
||||||
& ~MASK_VIS4
|
& ~(MASK_VIS4 | MASK_SUBXC)
|
||||||
#endif
|
#endif
|
||||||
#ifndef HAVE_AS_LEON
|
#ifndef HAVE_AS_LEON
|
||||||
& ~(MASK_LEON | MASK_LEON3)
|
& ~(MASK_LEON | MASK_LEON3)
|
||||||
|
|
@ -2742,14 +2746,24 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
|
||||||
sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits);
|
sparc_emit_set_const64_longway (op0, temp, high_bits, low_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Implement TARGET_FIXED_CONDITION_CODE_REGS. */
|
||||||
|
|
||||||
|
static bool
|
||||||
|
sparc_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
|
||||||
|
{
|
||||||
|
*p1 = SPARC_ICC_REG;
|
||||||
|
*p2 = SPARC_FCC_REG;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
|
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
|
||||||
return the mode to be used for the comparison. For floating-point,
|
return the mode to be used for the comparison. For floating-point,
|
||||||
CCFP[E]mode is used. CC_NOOVmode should be used when the first operand
|
CCFP[E]mode is used. CCNZmode should be used when the first operand
|
||||||
is a PLUS, MINUS, NEG, or ASHIFT. CCmode should be used when no special
|
is a PLUS, MINUS, NEG, or ASHIFT. CCmode should be used when no special
|
||||||
processing is needed. */
|
processing is needed. */
|
||||||
|
|
||||||
machine_mode
|
machine_mode
|
||||||
select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
|
select_cc_mode (enum rtx_code op, rtx x, rtx y)
|
||||||
{
|
{
|
||||||
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
|
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
|
||||||
{
|
{
|
||||||
|
|
@ -2781,12 +2795,21 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y ATTRIBUTE_UNUSED)
|
||||||
|| GET_CODE (x) == NEG || GET_CODE (x) == ASHIFT)
|
|| GET_CODE (x) == NEG || GET_CODE (x) == ASHIFT)
|
||||||
{
|
{
|
||||||
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
||||||
return CCX_NOOVmode;
|
return CCXNZmode;
|
||||||
else
|
else
|
||||||
return CC_NOOVmode;
|
return CCNZmode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* This is for the cmp<mode>_sne pattern. */
|
||||||
|
if (GET_CODE (x) == NOT && y == constm1_rtx)
|
||||||
|
{
|
||||||
|
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
||||||
|
return CCXCmode;
|
||||||
|
else
|
||||||
|
return CCCmode;
|
||||||
|
}
|
||||||
|
|
||||||
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
|
||||||
return CCXmode;
|
return CCXmode;
|
||||||
else
|
else
|
||||||
|
|
@ -2951,9 +2974,6 @@ gen_v9_scc (rtx dest, enum rtx_code compare_code, rtx x, rtx y)
|
||||||
x = gen_compare_reg_1 (compare_code, x, y);
|
x = gen_compare_reg_1 (compare_code, x, y);
|
||||||
y = const0_rtx;
|
y = const0_rtx;
|
||||||
|
|
||||||
gcc_assert (GET_MODE (x) != CC_NOOVmode
|
|
||||||
&& GET_MODE (x) != CCX_NOOVmode);
|
|
||||||
|
|
||||||
emit_insn (gen_rtx_SET (dest, const0_rtx));
|
emit_insn (gen_rtx_SET (dest, const0_rtx));
|
||||||
emit_insn (gen_rtx_SET (dest,
|
emit_insn (gen_rtx_SET (dest,
|
||||||
gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
|
gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
|
||||||
|
|
@ -2971,10 +2991,9 @@ gen_v9_scc (rtx dest, enum rtx_code compare_code, rtx x, rtx y)
|
||||||
bool
|
bool
|
||||||
emit_scc_insn (rtx operands[])
|
emit_scc_insn (rtx operands[])
|
||||||
{
|
{
|
||||||
rtx tem;
|
rtx tem, x, y;
|
||||||
rtx x;
|
|
||||||
rtx y;
|
|
||||||
enum rtx_code code;
|
enum rtx_code code;
|
||||||
|
machine_mode mode;
|
||||||
|
|
||||||
/* The quad-word fp compare library routines all return nonzero to indicate
|
/* The quad-word fp compare library routines all return nonzero to indicate
|
||||||
true, which is different from the equivalent libgcc routines, so we must
|
true, which is different from the equivalent libgcc routines, so we must
|
||||||
|
|
@ -2990,59 +3009,42 @@ emit_scc_insn (rtx operands[])
|
||||||
code = GET_CODE (operands[1]);
|
code = GET_CODE (operands[1]);
|
||||||
x = operands[2];
|
x = operands[2];
|
||||||
y = operands[3];
|
y = operands[3];
|
||||||
|
mode = GET_MODE (x);
|
||||||
|
|
||||||
/* For seq/sne on v9 we use the same code as v8 (the addx/subx method has
|
/* For seq/sne on v9 we use the same code as v8 (the addx/subx method has
|
||||||
more applications). The exception to this is "reg != 0" which can
|
more applications). The exception to this is "reg != 0" which can
|
||||||
be done in one instruction on v9 (so we do it). */
|
be done in one instruction on v9 (so we do it). */
|
||||||
if (code == EQ)
|
if ((code == EQ || code == NE) && (mode == SImode || mode == DImode))
|
||||||
{
|
{
|
||||||
if (GET_MODE (x) == SImode)
|
if (y != const0_rtx)
|
||||||
|
x = force_reg (mode, gen_rtx_XOR (mode, x, y));
|
||||||
|
|
||||||
|
rtx pat = gen_rtx_SET (operands[0],
|
||||||
|
gen_rtx_fmt_ee (code, GET_MODE (operands[0]),
|
||||||
|
x, const0_rtx));
|
||||||
|
|
||||||
|
/* If we can use addx/subx or addxc/subxc, add a clobber for CC. */
|
||||||
|
if (mode == SImode
|
||||||
|
|| (code == NE && TARGET_VIS3)
|
||||||
|
|| (code == EQ && TARGET_SUBXC))
|
||||||
{
|
{
|
||||||
rtx pat;
|
rtx clobber
|
||||||
if (TARGET_ARCH64)
|
= gen_rtx_CLOBBER (VOIDmode,
|
||||||
pat = gen_seqsidi_special (operands[0], x, y);
|
gen_rtx_REG (mode == SImode ? CCmode : CCXmode,
|
||||||
else
|
SPARC_ICC_REG));
|
||||||
pat = gen_seqsisi_special (operands[0], x, y);
|
pat = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clobber));
|
||||||
emit_insn (pat);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (GET_MODE (x) == DImode)
|
|
||||||
{
|
|
||||||
rtx pat = gen_seqdi_special (operands[0], x, y);
|
|
||||||
emit_insn (pat);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == NE)
|
|
||||||
{
|
|
||||||
if (GET_MODE (x) == SImode)
|
|
||||||
{
|
|
||||||
rtx pat;
|
|
||||||
if (TARGET_ARCH64)
|
|
||||||
pat = gen_snesidi_special (operands[0], x, y);
|
|
||||||
else
|
|
||||||
pat = gen_snesisi_special (operands[0], x, y);
|
|
||||||
emit_insn (pat);
|
emit_insn (pat);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (GET_MODE (x) == DImode)
|
|
||||||
{
|
|
||||||
rtx pat;
|
|
||||||
if (TARGET_VIS3)
|
|
||||||
pat = gen_snedi_special_vis3 (operands[0], x, y);
|
|
||||||
else
|
|
||||||
pat = gen_snedi_special (operands[0], x, y);
|
|
||||||
emit_insn (pat);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TARGET_V9
|
/* We can do LTU in DImode using the addxc instruction with VIS3
|
||||||
&& TARGET_ARCH64
|
and GEU in DImode using the subxc instruction with SUBXC. */
|
||||||
&& GET_MODE (x) == DImode
|
if (TARGET_ARCH64
|
||||||
&& !(TARGET_VIS3
|
&& mode == DImode
|
||||||
&& (code == GTU || code == LTU))
|
&& !((code == LTU || code == GTU) && TARGET_VIS3)
|
||||||
|
&& !((code == GEU || code == LEU) && TARGET_SUBXC)
|
||||||
&& gen_v9_scc (operands[0], code, x, y))
|
&& gen_v9_scc (operands[0], code, x, y))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -3061,8 +3063,7 @@ emit_scc_insn (rtx operands[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (code == LTU
|
if (code == LTU || code == GEU)
|
||||||
|| (!TARGET_VIS3 && code == GEU))
|
|
||||||
{
|
{
|
||||||
emit_insn (gen_rtx_SET (operands[0],
|
emit_insn (gen_rtx_SET (operands[0],
|
||||||
gen_rtx_fmt_ee (code, GET_MODE (operands[0]),
|
gen_rtx_fmt_ee (code, GET_MODE (operands[0]),
|
||||||
|
|
@ -7715,7 +7716,6 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
case LTGT:
|
case LTGT:
|
||||||
branch = "fblg";
|
branch = "fblg";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
|
|
@ -7741,7 +7741,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
branch = "be";
|
branch = "be";
|
||||||
break;
|
break;
|
||||||
case GE:
|
case GE:
|
||||||
if (mode == CC_NOOVmode || mode == CCX_NOOVmode)
|
if (mode == CCNZmode || mode == CCXNZmode)
|
||||||
branch = "bpos";
|
branch = "bpos";
|
||||||
else
|
else
|
||||||
branch = "bge";
|
branch = "bge";
|
||||||
|
|
@ -7753,7 +7753,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
branch = "ble";
|
branch = "ble";
|
||||||
break;
|
break;
|
||||||
case LT:
|
case LT:
|
||||||
if (mode == CC_NOOVmode || mode == CCX_NOOVmode)
|
if (mode == CCNZmode || mode == CCXNZmode)
|
||||||
branch = "bneg";
|
branch = "bneg";
|
||||||
else
|
else
|
||||||
branch = "bl";
|
branch = "bl";
|
||||||
|
|
@ -7770,7 +7770,6 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
case LTU:
|
case LTU:
|
||||||
branch = "blu";
|
branch = "blu";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
|
|
@ -7801,7 +7800,23 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
v8 = 1;
|
v8 = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == CCFPmode || mode == CCFPEmode)
|
switch (mode)
|
||||||
|
{
|
||||||
|
case CCmode:
|
||||||
|
case CCNZmode:
|
||||||
|
case CCCmode:
|
||||||
|
labelno = "%%icc, ";
|
||||||
|
if (v8)
|
||||||
|
labelno = "";
|
||||||
|
break;
|
||||||
|
case CCXmode:
|
||||||
|
case CCXNZmode:
|
||||||
|
case CCXCmode:
|
||||||
|
labelno = "%%xcc, ";
|
||||||
|
gcc_assert (!v8);
|
||||||
|
break;
|
||||||
|
case CCFPmode:
|
||||||
|
case CCFPEmode:
|
||||||
{
|
{
|
||||||
static char v9_fcc_labelno[] = "%%fccX, ";
|
static char v9_fcc_labelno[] = "%%fccX, ";
|
||||||
/* Set the char indicating the number of the fcc reg to use. */
|
/* Set the char indicating the number of the fcc reg to use. */
|
||||||
|
|
@ -7813,16 +7828,9 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
|
||||||
labelno = "";
|
labelno = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mode == CCXmode || mode == CCX_NOOVmode)
|
break;
|
||||||
{
|
default:
|
||||||
labelno = "%%xcc, ";
|
gcc_unreachable ();
|
||||||
gcc_assert (! v8);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
labelno = "%%icc, ";
|
|
||||||
if (v8)
|
|
||||||
labelno = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*labelno && insn && (note = find_reg_note (insn, REG_BR_PROB, NULL_RTX)))
|
if (*labelno && insn && (note = find_reg_note (insn, REG_BR_PROB, NULL_RTX)))
|
||||||
|
|
@ -8129,9 +8137,6 @@ output_cbcond (rtx op, rtx dest, rtx_insn *insn)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GE:
|
case GE:
|
||||||
if (mode == CC_NOOVmode || mode == CCX_NOOVmode)
|
|
||||||
cond_str = "pos";
|
|
||||||
else
|
|
||||||
cond_str = "ge";
|
cond_str = "ge";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -8144,9 +8149,6 @@ output_cbcond (rtx op, rtx dest, rtx_insn *insn)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LT:
|
case LT:
|
||||||
if (mode == CC_NOOVmode || mode == CCX_NOOVmode)
|
|
||||||
cond_str = "neg";
|
|
||||||
else
|
|
||||||
cond_str = "l";
|
cond_str = "l";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -8699,6 +8701,8 @@ sparc_print_operand_punct_valid_p (unsigned char code)
|
||||||
static void
|
static void
|
||||||
sparc_print_operand (FILE *file, rtx x, int code)
|
sparc_print_operand (FILE *file, rtx x, int code)
|
||||||
{
|
{
|
||||||
|
const char *s;
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case '#':
|
case '#':
|
||||||
|
|
@ -8806,15 +8810,23 @@ sparc_print_operand (FILE *file, rtx x, int code)
|
||||||
/* Print a condition code register. */
|
/* Print a condition code register. */
|
||||||
if (REGNO (x) == SPARC_ICC_REG)
|
if (REGNO (x) == SPARC_ICC_REG)
|
||||||
{
|
{
|
||||||
/* We don't handle CC[X]_NOOVmode because they're not supposed
|
switch (GET_MODE (x))
|
||||||
to occur here. */
|
{
|
||||||
if (GET_MODE (x) == CCmode)
|
case CCmode:
|
||||||
fputs ("%icc", file);
|
case CCNZmode:
|
||||||
else if (GET_MODE (x) == CCXmode)
|
case CCCmode:
|
||||||
fputs ("%xcc", file);
|
s = "%icc";
|
||||||
else
|
break;
|
||||||
|
case CCXmode:
|
||||||
|
case CCXNZmode:
|
||||||
|
case CCXCmode:
|
||||||
|
s = "%xcc";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
gcc_unreachable ();
|
gcc_unreachable ();
|
||||||
}
|
}
|
||||||
|
fputs (s, file);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
/* %fccN register */
|
/* %fccN register */
|
||||||
fputs (reg_names[REGNO (x)], file);
|
fputs (reg_names[REGNO (x)], file);
|
||||||
|
|
@ -8838,67 +8850,147 @@ sparc_print_operand (FILE *file, rtx x, int code)
|
||||||
case 'A':
|
case 'A':
|
||||||
switch (GET_CODE (x))
|
switch (GET_CODE (x))
|
||||||
{
|
{
|
||||||
case IOR: fputs ("or", file); break;
|
case IOR:
|
||||||
case AND: fputs ("and", file); break;
|
s = "or";
|
||||||
case XOR: fputs ("xor", file); break;
|
break;
|
||||||
default: output_operand_lossage ("invalid %%A operand");
|
case AND:
|
||||||
|
s = "and";
|
||||||
|
break;
|
||||||
|
case XOR:
|
||||||
|
s = "xor";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output_operand_lossage ("invalid %%A operand");
|
||||||
|
s = "";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
fputs (s, file);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 'B':
|
case 'B':
|
||||||
switch (GET_CODE (x))
|
switch (GET_CODE (x))
|
||||||
{
|
{
|
||||||
case IOR: fputs ("orn", file); break;
|
case IOR:
|
||||||
case AND: fputs ("andn", file); break;
|
s = "orn";
|
||||||
case XOR: fputs ("xnor", file); break;
|
break;
|
||||||
default: output_operand_lossage ("invalid %%B operand");
|
case AND:
|
||||||
|
s = "andn";
|
||||||
|
break;
|
||||||
|
case XOR:
|
||||||
|
s = "xnor";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output_operand_lossage ("invalid %%B operand");
|
||||||
|
s = "";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
fputs (s, file);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* This is used by the conditional move instructions. */
|
/* This is used by the conditional move instructions. */
|
||||||
case 'C':
|
case 'C':
|
||||||
{
|
{
|
||||||
enum rtx_code rc = GET_CODE (x);
|
machine_mode mode = GET_MODE (XEXP (x, 0));
|
||||||
|
switch (GET_CODE (x))
|
||||||
switch (rc)
|
|
||||||
{
|
{
|
||||||
case NE: fputs ("ne", file); break;
|
case NE:
|
||||||
case EQ: fputs ("e", file); break;
|
s = "ne";
|
||||||
case GE: fputs ("ge", file); break;
|
break;
|
||||||
case GT: fputs ("g", file); break;
|
case EQ:
|
||||||
case LE: fputs ("le", file); break;
|
s = "e";
|
||||||
case LT: fputs ("l", file); break;
|
break;
|
||||||
case GEU: fputs ("geu", file); break;
|
case GE:
|
||||||
case GTU: fputs ("gu", file); break;
|
if (mode == CCNZmode || mode == CCXNZmode)
|
||||||
case LEU: fputs ("leu", file); break;
|
s = "pos";
|
||||||
case LTU: fputs ("lu", file); break;
|
else
|
||||||
case LTGT: fputs ("lg", file); break;
|
s = "ge";
|
||||||
case UNORDERED: fputs ("u", file); break;
|
break;
|
||||||
case ORDERED: fputs ("o", file); break;
|
case GT:
|
||||||
case UNLT: fputs ("ul", file); break;
|
s = "g";
|
||||||
case UNLE: fputs ("ule", file); break;
|
break;
|
||||||
case UNGT: fputs ("ug", file); break;
|
case LE:
|
||||||
case UNGE: fputs ("uge", file); break;
|
s = "le";
|
||||||
case UNEQ: fputs ("ue", file); break;
|
break;
|
||||||
default: output_operand_lossage ("invalid %%C operand");
|
case LT:
|
||||||
|
if (mode == CCNZmode || mode == CCXNZmode)
|
||||||
|
s = "neg";
|
||||||
|
else
|
||||||
|
s = "l";
|
||||||
|
break;
|
||||||
|
case GEU:
|
||||||
|
s = "geu";
|
||||||
|
break;
|
||||||
|
case GTU:
|
||||||
|
s = "gu";
|
||||||
|
break;
|
||||||
|
case LEU:
|
||||||
|
s = "leu";
|
||||||
|
break;
|
||||||
|
case LTU:
|
||||||
|
s = "lu";
|
||||||
|
break;
|
||||||
|
case LTGT:
|
||||||
|
s = "lg";
|
||||||
|
break;
|
||||||
|
case UNORDERED:
|
||||||
|
s = "u";
|
||||||
|
break;
|
||||||
|
case ORDERED:
|
||||||
|
s = "o";
|
||||||
|
break;
|
||||||
|
case UNLT:
|
||||||
|
s = "ul";
|
||||||
|
break;
|
||||||
|
case UNLE:
|
||||||
|
s = "ule";
|
||||||
|
break;
|
||||||
|
case UNGT:
|
||||||
|
s = "ug";
|
||||||
|
break;
|
||||||
|
case UNGE:
|
||||||
|
s = "uge"
|
||||||
|
; break;
|
||||||
|
case UNEQ:
|
||||||
|
s = "ue";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output_operand_lossage ("invalid %%C operand");
|
||||||
|
s = "";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
fputs (s, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This are used by the movr instruction pattern. */
|
/* This are used by the movr instruction pattern. */
|
||||||
case 'D':
|
case 'D':
|
||||||
{
|
{
|
||||||
enum rtx_code rc = GET_CODE (x);
|
switch (GET_CODE (x))
|
||||||
switch (rc)
|
|
||||||
{
|
{
|
||||||
case NE: fputs ("ne", file); break;
|
case NE:
|
||||||
case EQ: fputs ("e", file); break;
|
s = "ne";
|
||||||
case GE: fputs ("gez", file); break;
|
break;
|
||||||
case LT: fputs ("lz", file); break;
|
case EQ:
|
||||||
case LE: fputs ("lez", file); break;
|
s = "e";
|
||||||
case GT: fputs ("gz", file); break;
|
break;
|
||||||
default: output_operand_lossage ("invalid %%D operand");
|
case GE:
|
||||||
|
s = "gez";
|
||||||
|
break;
|
||||||
|
case LT:
|
||||||
|
s = "lz";
|
||||||
|
break;
|
||||||
|
case LE:
|
||||||
|
s = "lez";
|
||||||
|
break;
|
||||||
|
case GT:
|
||||||
|
s = "gz";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
output_operand_lossage ("invalid %%D operand");
|
||||||
|
s = "";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
fputs (s, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -11238,6 +11330,10 @@ sparc_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
|
||||||
{
|
{
|
||||||
bool need_memory = false;
|
bool need_memory = false;
|
||||||
|
|
||||||
|
/* This helps postreload CSE to eliminate redundant comparisons. */
|
||||||
|
if (from == NO_REGS || to == NO_REGS)
|
||||||
|
return 100;
|
||||||
|
|
||||||
if (from == FPCC_REGS || to == FPCC_REGS)
|
if (from == FPCC_REGS || to == FPCC_REGS)
|
||||||
need_memory = true;
|
need_memory = true;
|
||||||
else if ((FP_REG_CLASS_P (from) && general_or_i64_p (to))
|
else if ((FP_REG_CLASS_P (from) && general_or_i64_p (to))
|
||||||
|
|
|
||||||
|
|
@ -1517,7 +1517,7 @@ do { \
|
||||||
|
|
||||||
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
|
/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
|
||||||
return the mode to be used for the comparison. For floating-point,
|
return the mode to be used for the comparison. For floating-point,
|
||||||
CCFP[E]mode is used. CC_NOOVmode should be used when the first operand
|
CCFP[E]mode is used. CCNZmode should be used when the first operand
|
||||||
is a PLUS, MINUS, NEG, or ASHIFT. CCmode should be used when no special
|
is a PLUS, MINUS, NEG, or ASHIFT. CCmode should be used when no special
|
||||||
processing is needed. */
|
processing is needed. */
|
||||||
#define SELECT_CC_MODE(OP,X,Y) select_cc_mode ((OP), (X), (Y))
|
#define SELECT_CC_MODE(OP,X,Y) select_cc_mode ((OP), (X), (Y))
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -89,6 +89,10 @@ mpopc
|
||||||
Target Report Mask(POPC)
|
Target Report Mask(POPC)
|
||||||
Use UltraSPARC Population-Count instruction.
|
Use UltraSPARC Population-Count instruction.
|
||||||
|
|
||||||
|
msubxc
|
||||||
|
Target Report Mask(SUBXC)
|
||||||
|
Use UltraSPARC Subtract-Extended-with-Carry instruction.
|
||||||
|
|
||||||
mptr64
|
mptr64
|
||||||
Target Report RejectNegative Mask(PTR64)
|
Target Report RejectNegative Mask(PTR64)
|
||||||
Pointers are 64-bit.
|
Pointers are 64-bit.
|
||||||
|
|
|
||||||
|
|
@ -1092,8 +1092,8 @@ See RS/6000 and PowerPC Options.
|
||||||
-muser-mode -mno-user-mode @gol
|
-muser-mode -mno-user-mode @gol
|
||||||
-mv8plus -mno-v8plus -mvis -mno-vis @gol
|
-mv8plus -mno-v8plus -mvis -mno-vis @gol
|
||||||
-mvis2 -mno-vis2 -mvis3 -mno-vis3 @gol
|
-mvis2 -mno-vis2 -mvis3 -mno-vis3 @gol
|
||||||
-mcbcond -mno-cbcond @gol
|
-mcbcond -mno-cbcond -mfmaf -mno-fmaf @gol
|
||||||
-mfmaf -mno-fmaf -mpopc -mno-popc @gol
|
-mpopc -mno-popc -msubxc -mno-subxc@gol
|
||||||
-mfix-at697f -mfix-ut699}
|
-mfix-at697f -mfix-ut699}
|
||||||
|
|
||||||
@emph{SPU Options}
|
@emph{SPU Options}
|
||||||
|
|
@ -22941,18 +22941,9 @@ also sets @option{-mvis3}, @option{-mvis2} and @option{-mvis}.
|
||||||
@itemx -mno-cbcond
|
@itemx -mno-cbcond
|
||||||
@opindex mcbcond
|
@opindex mcbcond
|
||||||
@opindex mno-cbcond
|
@opindex mno-cbcond
|
||||||
With @option{-mcbcond}, GCC generates code that takes advantage of
|
With @option{-mcbcond}, GCC generates code that takes advantage of the UltraSPARC
|
||||||
compare-and-branch instructions, as defined in the Sparc Architecture 2011.
|
Compare-and-Branch-on-Condition instructions. The default is @option{-mcbcond}
|
||||||
The default is @option{-mcbcond} when targeting a cpu that supports such
|
when targeting a CPU that supports such instructions, such as Niagara-4 and
|
||||||
instructions, such as niagara-4 and later.
|
|
||||||
|
|
||||||
@item -mpopc
|
|
||||||
@itemx -mno-popc
|
|
||||||
@opindex mpopc
|
|
||||||
@opindex mno-popc
|
|
||||||
With @option{-mpopc}, GCC generates code that takes advantage of the UltraSPARC
|
|
||||||
population count instruction. The default is @option{-mpopc}
|
|
||||||
when targeting a cpu that supports such instructions, such as Niagara-2 and
|
|
||||||
later.
|
later.
|
||||||
|
|
||||||
@item -mfmaf
|
@item -mfmaf
|
||||||
|
|
@ -22960,8 +22951,26 @@ later.
|
||||||
@opindex mfmaf
|
@opindex mfmaf
|
||||||
@opindex mno-fmaf
|
@opindex mno-fmaf
|
||||||
With @option{-mfmaf}, GCC generates code that takes advantage of the UltraSPARC
|
With @option{-mfmaf}, GCC generates code that takes advantage of the UltraSPARC
|
||||||
Fused Multiply-Add Floating-point extensions. The default is @option{-mfmaf}
|
Fused Multiply-Add Floating-point instructions. The default is @option{-mfmaf}
|
||||||
when targeting a cpu that supports such instructions, such as Niagara-3 and
|
when targeting a CPU that supports such instructions, such as Niagara-3 and
|
||||||
|
later.
|
||||||
|
|
||||||
|
@item -mpopc
|
||||||
|
@itemx -mno-popc
|
||||||
|
@opindex mpopc
|
||||||
|
@opindex mno-popc
|
||||||
|
With @option{-mpopc}, GCC generates code that takes advantage of the UltraSPARC
|
||||||
|
Population Count instruction. The default is @option{-mpopc}
|
||||||
|
when targeting a CPU that supports such an instruction, such as Niagara-2 and
|
||||||
|
later.
|
||||||
|
|
||||||
|
@item -msubxc
|
||||||
|
@itemx -mno-subxc
|
||||||
|
@opindex msubxc
|
||||||
|
@opindex mno-subxc
|
||||||
|
With @option{-msubxc}, GCC generates code that takes advantage of the UltraSPARC
|
||||||
|
Subtract-Extended-with-Carry instruction. The default is @option{-msubxc}
|
||||||
|
when targeting a CPU that supports such an instruction, such as Niagara-7 and
|
||||||
later.
|
later.
|
||||||
|
|
||||||
@item -mfix-at697f
|
@item -mfix-at697f
|
||||||
|
|
|
||||||
|
|
@ -6021,8 +6021,8 @@ the case of the add on the SPARC discussed above, we have the pattern
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
(define_insn ""
|
(define_insn ""
|
||||||
[(set (reg:CC_NOOV 0)
|
[(set (reg:CCNZ 0)
|
||||||
(compare:CC_NOOV
|
(compare:CCNZ
|
||||||
(plus:SI (match_operand:SI 0 "register_operand" "%r")
|
(plus:SI (match_operand:SI 0 "register_operand" "%r")
|
||||||
(match_operand:SI 1 "arith_operand" "rI"))
|
(match_operand:SI 1 "arith_operand" "rI"))
|
||||||
(const_int 0)))]
|
(const_int 0)))]
|
||||||
|
|
@ -6031,7 +6031,7 @@ the case of the add on the SPARC discussed above, we have the pattern
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
together with a @code{SELECT_CC_MODE} that returns @code{CC_NOOVmode}
|
together with a @code{SELECT_CC_MODE} that returns @code{CCNZmode}
|
||||||
for comparisons whose argument is a @code{plus}:
|
for comparisons whose argument is a @code{plus}:
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
|
|
@ -6041,7 +6041,7 @@ for comparisons whose argument is a @code{plus}:
|
||||||
? CCFPEmode : CCFPmode) \
|
? CCFPEmode : CCFPmode) \
|
||||||
: ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \
|
: ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \
|
||||||
|| GET_CODE (X) == NEG || GET_CODE (x) == ASHIFT) \
|
|| GET_CODE (X) == NEG || GET_CODE (x) == ASHIFT) \
|
||||||
? CC_NOOVmode : CCmode))
|
? CCNZmode : CCmode))
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
Another reason to use modes is to retain information on which operands
|
Another reason to use modes is to retain information on which operands
|
||||||
|
|
|
||||||
|
|
@ -4443,8 +4443,8 @@ the case of the add on the SPARC discussed above, we have the pattern
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
(define_insn ""
|
(define_insn ""
|
||||||
[(set (reg:CC_NOOV 0)
|
[(set (reg:CCNZ 0)
|
||||||
(compare:CC_NOOV
|
(compare:CCNZ
|
||||||
(plus:SI (match_operand:SI 0 "register_operand" "%r")
|
(plus:SI (match_operand:SI 0 "register_operand" "%r")
|
||||||
(match_operand:SI 1 "arith_operand" "rI"))
|
(match_operand:SI 1 "arith_operand" "rI"))
|
||||||
(const_int 0)))]
|
(const_int 0)))]
|
||||||
|
|
@ -4453,7 +4453,7 @@ the case of the add on the SPARC discussed above, we have the pattern
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
together with a @code{SELECT_CC_MODE} that returns @code{CC_NOOVmode}
|
together with a @code{SELECT_CC_MODE} that returns @code{CCNZmode}
|
||||||
for comparisons whose argument is a @code{plus}:
|
for comparisons whose argument is a @code{plus}:
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
|
|
@ -4463,7 +4463,7 @@ for comparisons whose argument is a @code{plus}:
|
||||||
? CCFPEmode : CCFPmode) \
|
? CCFPEmode : CCFPmode) \
|
||||||
: ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \
|
: ((GET_CODE (X) == PLUS || GET_CODE (X) == MINUS \
|
||||||
|| GET_CODE (X) == NEG || GET_CODE (x) == ASHIFT) \
|
|| GET_CODE (X) == NEG || GET_CODE (x) == ASHIFT) \
|
||||||
? CC_NOOVmode : CCmode))
|
? CCNZmode : CCmode))
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
Another reason to use modes is to retain information on which operands
|
Another reason to use modes is to retain information on which operands
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,20 @@
|
||||||
|
2016-10-11 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
|
* gcc.target/sparc/cbcond-1.c: New test.
|
||||||
|
* gcc.target/sparc/cbcond-2.c: Likewise.
|
||||||
|
* gcc.target/sparc/movcc-1.c: Likewise.
|
||||||
|
* gcc.target/sparc/movcc-2.c: Likewise.
|
||||||
|
* gcc.target/sparc/setcc-1.c: Adjust.
|
||||||
|
* gcc.target/sparc/setcc-2.c: Likewise.
|
||||||
|
* gcc.target/sparc/setcc-3.c: Likewise.
|
||||||
|
* gcc.target/sparc/setcc-4.c: Likewise.
|
||||||
|
* gcc.target/sparc/setcc-5.c: Likewise.
|
||||||
|
* gcc.target/sparc/setcc-6.c: New test.
|
||||||
|
* gcc.target/sparc/setcc-7.c: Likewise.
|
||||||
|
* gcc.target/sparc/setcc-8.c: Likewise.
|
||||||
|
* gcc.target/sparc/setcc-9.c: Likewise.
|
||||||
|
* gcc.target/sparc/setcc-10.c: Likewise.
|
||||||
|
|
||||||
2016-10-10 Jeff Law <law@redhat.com>
|
2016-10-10 Jeff Law <law@redhat.com>
|
||||||
|
|
||||||
PR tree-optimization/71947
|
PR tree-optimization/71947
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O -mcbcond" } */
|
||||||
|
|
||||||
|
extern void foo (void);
|
||||||
|
extern void bar (void);
|
||||||
|
|
||||||
|
void cbcondne (int a)
|
||||||
|
{
|
||||||
|
if (a != 0)
|
||||||
|
foo ();
|
||||||
|
bar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cbconde (int a)
|
||||||
|
{
|
||||||
|
if (a == 0)
|
||||||
|
foo ();
|
||||||
|
bar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cbcondl (int a)
|
||||||
|
{
|
||||||
|
if (a < 0)
|
||||||
|
foo ();
|
||||||
|
bar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cbcondle (int a)
|
||||||
|
{
|
||||||
|
if (a <= 0)
|
||||||
|
foo ();
|
||||||
|
bar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "cwbe\t%" { target ilp32 } } } */
|
||||||
|
/* { dg-final { scan-assembler "cwbne\t%" { target ilp32 } } } */
|
||||||
|
/* { dg-final { scan-assembler "cwbl\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler "cwble\t%" } } */
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O -mcbcond" } */
|
||||||
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
|
||||||
|
extern void foo (void);
|
||||||
|
extern void bar (void);
|
||||||
|
|
||||||
|
void cbcondne (long a)
|
||||||
|
{
|
||||||
|
if (a != 0)
|
||||||
|
foo ();
|
||||||
|
bar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cbconde (long a)
|
||||||
|
{
|
||||||
|
if (a == 0)
|
||||||
|
foo ();
|
||||||
|
bar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cbcondl (long a)
|
||||||
|
{
|
||||||
|
if (a < 0)
|
||||||
|
foo ();
|
||||||
|
bar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cbcondle (long a)
|
||||||
|
{
|
||||||
|
if (a <= 0)
|
||||||
|
foo ();
|
||||||
|
bar ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "cxbe\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler "cxbne\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler "cxbl\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler "cxble\t%" } } */
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2" } */
|
||||||
|
|
||||||
|
int foo1 (int a)
|
||||||
|
{
|
||||||
|
int b = a + 1;
|
||||||
|
if (b != 0)
|
||||||
|
return b;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo2 (int a)
|
||||||
|
{
|
||||||
|
int b = a + 1;
|
||||||
|
if (b < 0)
|
||||||
|
return b;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo3 (int a)
|
||||||
|
{
|
||||||
|
int b = a + 1;
|
||||||
|
if (b >= 0)
|
||||||
|
return b;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "move\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler "movpos\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler "movneg\t%" } } */
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2" } */
|
||||||
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
|
||||||
|
long foo1 (long a)
|
||||||
|
{
|
||||||
|
long b = a + 1;
|
||||||
|
if (b != 0)
|
||||||
|
return b;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo2 (long a)
|
||||||
|
{
|
||||||
|
long b = a + 1;
|
||||||
|
if (b < 0)
|
||||||
|
return b;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo3 (long a)
|
||||||
|
{
|
||||||
|
long b = a + 1;
|
||||||
|
if (b >= 0)
|
||||||
|
return b;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler "movre\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler "movrgez\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler "movrlz\t%" } } */
|
||||||
|
|
@ -32,8 +32,7 @@ int gt (unsigned int a, unsigned int b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
|
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
|
||||||
/* { dg-final { scan-assembler-times "subcc\t%" 2 } } */
|
|
||||||
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
|
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
|
||||||
/* { dg-final { scan-assembler-times "subx\t%" 3 } } */
|
/* { dg-final { scan-assembler-times "subx\t%" 3 } } */
|
||||||
/* { dg-final { scan-assembler-times "cmp\t%" 4 } } */
|
/* { dg-final { scan-assembler-times "cmp\t%" 6 } } */
|
||||||
/* { dg-final { scan-assembler-not "sra\t%" { target lp64 } } } */
|
/* { dg-final { scan-assembler-not "sra\t%" { target lp64 } } } */
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,7 @@ int gt (unsigned int a, unsigned int b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
|
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
|
||||||
/* { dg-final { scan-assembler-times "subcc\t%" 2 } } */
|
|
||||||
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
|
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
|
||||||
/* { dg-final { scan-assembler-times "subx\t%" 3 } } */
|
/* { dg-final { scan-assembler-times "subx\t%" 3 } } */
|
||||||
/* { dg-final { scan-assembler-times "cmp\t%" 4 } } */
|
/* { dg-final { scan-assembler-times "cmp\t%" 6 } } */
|
||||||
/* { dg-final { scan-assembler-not "sra\t%" { target lp64 } } } */
|
/* { dg-final { scan-assembler-not "sra\t%" { target lp64 } } } */
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ int gt (unsigned long a, unsigned long b)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* { dg-final { scan-assembler "xor\t%" } } */
|
/* { dg-final { scan-assembler "xor\t%" } } */
|
||||||
/* { dg-final { scan-assembler "subcc\t%" } } */
|
|
||||||
/* { dg-final { scan-assembler-times "addxc\t%" 3 } } */
|
/* { dg-final { scan-assembler-times "addxc\t%" 3 } } */
|
||||||
/* { dg-final { scan-assembler-times "cmp\t%" 2 } } */
|
/* { dg-final { scan-assembler-times "cmp\t%" 3 } } */
|
||||||
/* { dg-final { scan-assembler-not "sra\t%" } } */
|
/* { dg-final { scan-assembler-not "sra\t%" } } */
|
||||||
|
|
|
||||||
|
|
@ -1,44 +1,23 @@
|
||||||
/* { dg-do compile } */
|
/* { dg-do compile } */
|
||||||
/* { dg-require-effective-target lp64 } */
|
/* { dg-require-effective-target lp64 } */
|
||||||
/* { dg-options "-O1 -mno-vis3" } */
|
/* { dg-options "-O1 -msubxc" } */
|
||||||
|
|
||||||
long neq (long a, long b)
|
int eq (long a, long b)
|
||||||
{
|
|
||||||
return a != b;
|
|
||||||
}
|
|
||||||
|
|
||||||
long eq (long a, long b)
|
|
||||||
{
|
{
|
||||||
return a == b;
|
return a == b;
|
||||||
}
|
}
|
||||||
|
|
||||||
long lt (unsigned long a, unsigned long b)
|
int ge (unsigned long a, unsigned long b)
|
||||||
{
|
|
||||||
return a < b;
|
|
||||||
}
|
|
||||||
|
|
||||||
long leq (unsigned long a, unsigned long b)
|
|
||||||
{
|
|
||||||
return a <= b;
|
|
||||||
}
|
|
||||||
|
|
||||||
long geq (unsigned long a, unsigned long b)
|
|
||||||
{
|
{
|
||||||
return a >= b;
|
return a >= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
long gt (unsigned long a, unsigned long b)
|
int le (unsigned long a, unsigned long b)
|
||||||
{
|
{
|
||||||
return a > b;
|
return a <= b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
|
/* { dg-final { scan-assembler "xor\t%" } } */
|
||||||
/* { dg-final { scan-assembler-times "cmp\t%" 4 } } */
|
/* { dg-final { scan-assembler-times "subxc\t%" 3 } } */
|
||||||
/* { dg-final { scan-assembler-times "movrne\t%" 1 } } */
|
/* { dg-final { scan-assembler-times "cmp\t%" 3 } } */
|
||||||
/* { dg-final { scan-assembler-times "movre\t%" 1 } } */
|
|
||||||
/* { dg-final { scan-assembler-times "movlu\t%" 1 } } */
|
|
||||||
/* { dg-final { scan-assembler-times "movleu\t%" 1 } } */
|
|
||||||
/* { dg-final { scan-assembler-times "movgeu\t%" 1 } } */
|
|
||||||
/* { dg-final { scan-assembler-times "movgu\t%" 1 } } */
|
|
||||||
/* { dg-final { scan-assembler-not "sra\t%" } } */
|
/* { dg-final { scan-assembler-not "sra\t%" } } */
|
||||||
/* { dg-final { scan-assembler-not "and\t%" } } */
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* { dg-do compile } */
|
/* { dg-do compile } */
|
||||||
/* { dg-require-effective-target lp64 } */
|
/* { dg-require-effective-target lp64 } */
|
||||||
/* { dg-options "-O1 -mvis3" } */
|
/* { dg-options "-O1 -mno-vis3 -mno-subxc" } */
|
||||||
|
|
||||||
long neq (long a, long b)
|
long neq (long a, long b)
|
||||||
{
|
{
|
||||||
|
|
@ -34,9 +34,11 @@ long gt (unsigned long a, unsigned long b)
|
||||||
|
|
||||||
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
|
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
|
||||||
/* { dg-final { scan-assembler-times "cmp\t%" 4 } } */
|
/* { dg-final { scan-assembler-times "cmp\t%" 4 } } */
|
||||||
/* { dg-final { scan-assembler-times "addxc\t%" 3 } } */
|
/* { dg-final { scan-assembler-times "movrne\t%" 1 } } */
|
||||||
/* { dg-final { scan-assembler-times "movre\t%" 1 } } */
|
/* { dg-final { scan-assembler-times "movre\t%" 1 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "movlu\t%" 1 } } */
|
||||||
/* { dg-final { scan-assembler-times "movleu\t%" 1 } } */
|
/* { dg-final { scan-assembler-times "movleu\t%" 1 } } */
|
||||||
/* { dg-final { scan-assembler-times "movgeu\t%" 1 } } */
|
/* { dg-final { scan-assembler-times "movgeu\t%" 1 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "movgu\t%" 1 } } */
|
||||||
/* { dg-final { scan-assembler-not "sra\t%" } } */
|
/* { dg-final { scan-assembler-not "sra\t%" } } */
|
||||||
/* { dg-final { scan-assembler-not "and\t%" } } */
|
/* { dg-final { scan-assembler-not "and\t%" } } */
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
/* { dg-options "-O1 -mvis3 -msubxc" } */
|
||||||
|
|
||||||
|
long neq (long a, long b)
|
||||||
|
{
|
||||||
|
return a != b;
|
||||||
|
}
|
||||||
|
|
||||||
|
long eq (long a, long b)
|
||||||
|
{
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
|
||||||
|
long lt (unsigned long a, unsigned long b)
|
||||||
|
{
|
||||||
|
return a < b;
|
||||||
|
}
|
||||||
|
|
||||||
|
long leq (unsigned long a, unsigned long b)
|
||||||
|
{
|
||||||
|
return a <= b;
|
||||||
|
}
|
||||||
|
|
||||||
|
long geq (unsigned long a, unsigned long b)
|
||||||
|
{
|
||||||
|
return a >= b;
|
||||||
|
}
|
||||||
|
|
||||||
|
long gt (unsigned long a, unsigned long b)
|
||||||
|
{
|
||||||
|
return a > b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "xor\t%" 2 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "cmp\t%" 6 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "addxc\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "subxc\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-not "sra\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "and\t%" } } */
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O1" } */
|
||||||
|
|
||||||
|
int foo1 (int a, int i)
|
||||||
|
{
|
||||||
|
return a + (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo2 (int a, int i)
|
||||||
|
{
|
||||||
|
return a - (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo3 (int a, int b, int i)
|
||||||
|
{
|
||||||
|
return a + b + (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo4 (int a, int b, int i)
|
||||||
|
{
|
||||||
|
return a - b - (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo5 (int a, int i)
|
||||||
|
{
|
||||||
|
return a + (i == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int foo6 (int a, int i)
|
||||||
|
{
|
||||||
|
return a - (i == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "subx\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "cmp\t%" 6 } } */
|
||||||
|
/* { dg-final { scan-assembler-not "add\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "sub\t%" } } */
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
/* { dg-options "-O1 -mno-vis3 -mno-subxc" } */
|
||||||
|
|
||||||
|
long foo1 (long a, int i)
|
||||||
|
{
|
||||||
|
return a + (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo2 (long a, int i)
|
||||||
|
{
|
||||||
|
return a - (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo3 (long a, long b, int i)
|
||||||
|
{
|
||||||
|
return a + b + (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo4 (long a, long b, int i)
|
||||||
|
{
|
||||||
|
return a - b - (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo5 (long a, int i)
|
||||||
|
{
|
||||||
|
return a + (i == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo6 (long a, int i)
|
||||||
|
{
|
||||||
|
return a - (i == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "subx\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "cmp\t%" 6 } } */
|
||||||
|
/* { dg-final { scan-assembler-not "add\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "sub\t%" } } */
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-require-effective-target lp64 } */
|
||||||
|
/* { dg-options "-O1 -mvis3" } */
|
||||||
|
|
||||||
|
long foo1 (long a, long i)
|
||||||
|
{
|
||||||
|
return a + (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo3 (long a, long b, long i)
|
||||||
|
{
|
||||||
|
return a + b + (i != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
long foo6 (long a, long i)
|
||||||
|
{
|
||||||
|
return a - (i == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-times "addxc\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-times "cmp\t%" 3 } } */
|
||||||
|
/* { dg-final { scan-assembler-not "add\t%" } } */
|
||||||
|
/* { dg-final { scan-assembler-not "sub\t%" } } */
|
||||||
Loading…
Reference in New Issue