+2016-09-25 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * config/sh/sh.c (sh_movt_set_dest, sh_movrt_set_dest): Add overloads.
+ (sh_rtx_costs): Handle SET of movt and movrt patterns.
+ * cnofig/sh/sh-protos.h (sh_movt_set_dest, sh_movrt_set_dest): Forward
+ declare new overloads.
+ * config/sh/sh.md (*cset_zero): Add variant that takes a treg_set_expr
+ operand.
+
2016-09-24 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
* config/rs6000/rs6000.c (expand_block_compare, do_load_for_compare):
extern bool sh_is_nott_insn (const rtx_insn* i);
extern rtx sh_movt_set_dest (const rtx_insn* i);
+extern rtx sh_movt_set_dest (const_rtx i);
extern rtx sh_movrt_set_dest (const rtx_insn* i);
+extern rtx sh_movrt_set_dest (const_rtx i);
inline bool sh_is_movt_insn (const rtx_insn* i)
{
/ mov_insn_size (mode, TARGET_SH2A));
return true;
}
+
+ if (sh_movt_set_dest (x) != NULL || sh_movrt_set_dest (x) != NULL)
+ return COSTS_N_INSNS (1);
+
return false;
/* The cost of a mem access is mainly the cost of the address mode. */
rtx
sh_movt_set_dest (const rtx_insn* i)
{
- if (i == NULL)
- return NULL;
+ return i == NULL ? NULL : sh_movt_set_dest (PATTERN (i));
+}
- const_rtx p = PATTERN (i);
- return GET_CODE (p) == SET
- && arith_reg_dest (XEXP (p, 0), SImode)
- && t_reg_operand (XEXP (p, 1), VOIDmode) ? XEXP (p, 0) : NULL;
+rtx
+sh_movt_set_dest (const_rtx pat)
+{
+ return GET_CODE (pat) == SET
+ && arith_reg_dest (XEXP (pat, 0), SImode)
+ && t_reg_operand (XEXP (pat, 1), VOIDmode) ? XEXP (pat, 0) : NULL;
}
/* Given an insn, check whether it's a 'movrt' kind of insn, i.e. an insn
rtx
sh_movrt_set_dest (const rtx_insn* i)
{
- if (i == NULL)
- return NULL;
-
- const_rtx p = PATTERN (i);
+ return i == NULL ? NULL : sh_movrt_set_dest (PATTERN (i));
+}
+rtx
+sh_movrt_set_dest (const_rtx pat)
+{
/* The negc movrt replacement is inside a parallel. */
- if (GET_CODE (p) == PARALLEL)
- p = XVECEXP (p, 0, 0);
+ if (GET_CODE (pat) == PARALLEL)
+ pat = XVECEXP (pat, 0, 0);
+
+ return GET_CODE (pat) == SET
+ && arith_reg_dest (XEXP (pat, 0), SImode)
+ && negt_reg_operand (XEXP (pat, 1), VOIDmode) ? XEXP (pat, 0) : NULL;
- return GET_CODE (p) == SET
- && arith_reg_dest (XEXP (p, 0), SImode)
- && negt_reg_operand (XEXP (p, 1), VOIDmode) ? XEXP (p, 0) : NULL;
}
/* Given an insn and a reg number, tell whether the reg dies or is unused
[(set_attr "type" "arith") ;; poor approximation
(set_attr "length" "4")])
+(define_insn_and_split "*cset_zero"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (if_then_else:SI (match_operand 1 "treg_set_expr_not_const01")
+ (match_dup 0) (const_int 0)))
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH1 && TARGET_ZDCBRANCH && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (if_then_else:SI (match_dup 1) (match_dup 0) (const_int 0)))]
+{
+ sh_treg_insns ti = sh_split_treg_set_expr (operands[1], curr_insn);
+ if (ti.remove_trailing_nott ())
+ operands[1] = gen_rtx_EQ (SImode, get_t_reg_rtx (), const0_rtx);
+ else
+ operands[1] = gen_rtx_EQ (SImode, get_t_reg_rtx (), const1_rtx);
+})
+
(define_expand "cstoresf4"
[(set (match_operand:SI 0 "register_operand")
(match_operator:SI 1 "ordered_comparison_operator"
+2016-09-25 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * gcc.target/sh/pr51244-11.c: Add more detailed expected insn matching.
+
2016-09-24 Dominique d'Humieres <dominiq@lps.ens.fr>
* gfortran.dg/coarray_lib_comm_1.f90: Really fix test
/* Check that zero-displacement branches are used instead of branch-free
- execution patterns. */
+ execution patterns.
+ This is usually handled by the *cset_zero patterns. */
/* { dg-do compile } */
-/* { dg-options "-O1 -mzdcbranch" } */
-/* { dg-final { scan-assembler-not "subc|and" } } */
+/* { dg-options "-O1 -mzdcbranch" } */
+/* { dg-final { scan-assembler-not "subc|and|bra" } } */
+/* { dg-final { scan-assembler-times "bf\t0f" 1 } } */
+/* { dg-final { scan-assembler-times "bt\t0f" 1 } } */
int*
test_00 (int* s)