;; Same as treg_set_expr but disallow constants 0 and 1 which can be loaded
;; into the T bit.
(define_predicate "treg_set_expr_not_const01"
- (and (match_test "op != const0_rtx")
- (match_test "op != const1_rtx")
- (match_operand 0 "treg_set_expr")))
+ (match_test "sh_recog_treg_set_expr_not_01 (op, mode)"))
;; A predicate describing the T bit register in any form.
(define_predicate "t_reg_operand"
extern bool sh_in_recog_treg_set_expr (void);
extern bool sh_recog_treg_set_expr (rtx op, machine_mode mode);
+extern bool sh_recog_treg_set_expr_not_01 (rtx op, machine_mode mode);
/* Result value of sh_split_treg_set_expr. Contains the first insn emitted
and the optional trailing nott insn. */
return result >= 0;
}
+/* Return TRUE if OP is an expression for which there is a pattern to
+ set the T bit unless the expression is trivially loadable into
+ the T bit, FALSE otherwise. */
+bool
+sh_recog_treg_set_expr_not_01 (rtx op, machine_mode mode)
+{
+ if (op == const0_rtx || op == const1_rtx)
+ return false;
+
+ /* A right shift of 31 will return 0 or 1. */
+ if ((GET_CODE (op) == LSHIFTRT || GET_CODE (op) == ASHIFTRT)
+ && INTVAL (XEXP (op, 1)) == 31)
+ return false;
+
+ return sh_recog_treg_set_expr (op, mode);
+}
+
/* Returns true when recog of a 'treg_set_expr' is currently in progress.
This can be used as a condition for insn/split patterns to allow certain
T bit setting patters only to be matched as sub expressions of other
/* { dg-do compile } */
/* { dg-options "-O1" } */
-/* { dg-final { scan-assembler-times "addc" 36 } } */
+/* { dg-final { scan-assembler-times "addc" 32 } } */
/* { dg-final { scan-assembler-times "shll" 14 } } */
-/* { dg-final { scan-assembler-times "add\tr" 12 } } */
-/* { dg-final { scan-assembler-not "movt" } } */
+/* { dg-final { scan-assembler-times "add\tr" 16 } } */
+/* { dg-final { scan-assembler-times "movt" 4 } } */
/* { dg-final { scan-assembler-times "add\t#1" 1 } } */
int
test_023 (int a, int b, int c, int d)
{
- // 1x shll, 1x addc
+ // 1x shll, 1x add
return a + ((b >> 31) & 1);
}
int
test_024 (int a, int b, int c, int d)
{
- // 1x shll, 1x addc
+ // 1x shll, 1x add
return ((b >> 31) & 1) + a;
}
int
test_025 (int a, int b, int c, int d)
{
- // 1x shll, 1x addc
+ // 1x shll, 1x add
return ((a >> 31) & 1) + a;
}
int
test_026 (int a, int b, int c, int d)
{
- // 1x shll, 1x addc
+ // 1x shll, 1x add
return a + ((a >> 31) & 1);
}