===================================================================
@@ -11568,34 +11568,34 @@
;; Store inverted T bit as MSB in a reg.
;; T = 0: 0x80000000 -> reg
;; T = 1: 0x00000000 -> reg
-;; On SH2A we can get away without clobbering the T_REG.
+;; On SH2A we can get away without clobbering the T_REG using the movrt insn.
+;; On non SH2A we resort to the following sequence:
+;; movt Rn
+;; tst Rn,Rn
+;; rotcr Rn
+;; The T bit value will be modified during the sequence, but the rotcr insn
+;; will restore its original value.
(define_insn_and_split "*negt_msb"
[(set (match_operand:SI 0 "arith_reg_dest")
(match_operand:SI 1 "negt_reg_shl31_operand"))]
- "TARGET_SH2A"
+ "TARGET_SH1"
"#"
"&& can_create_pseudo_p ()"
[(const_int 0)]
{
rtx tmp = gen_reg_rtx (SImode);
- emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
- emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
- DONE;
-})
-(define_insn_and_split "*negt_msb"
- [(set (match_operand:SI 0 "arith_reg_dest")
- (match_operand:SI 1 "negt_reg_shl31_operand"))
- (clobber (reg:SI T_REG))]
- "TARGET_SH1 && !TARGET_SH2A"
- "#"
- "&& can_create_pseudo_p ()"
- [(const_int 0)]
-{
- rtx tmp = gen_reg_rtx (SImode);
- emit_move_insn (tmp, get_t_reg_rtx ());
- emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
- emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
+ if (TARGET_SH2A)
+ {
+ emit_insn (gen_movrt (tmp, get_t_reg_rtx ()));
+ emit_insn (gen_rotrsi3 (operands[0], tmp, const1_rtx));
+ }
+ else
+ {
+ emit_move_insn (tmp, get_t_reg_rtx ());
+ emit_insn (gen_cmpeqsi_t (tmp, const0_rtx));
+ emit_insn (gen_rotcr (operands[0], tmp, get_t_reg_rtx ()));
+ }
DONE;
})
===================================================================
@@ -1134,6 +1132,28 @@
(define_predicate "negt_reg_shl31_operand"
(match_code "plus,minus,if_then_else")
{
+ /* (minus:SI (const_int -2147483648) ;; 0xffffffff80000000
+ (ashift:SI (match_operand:SI 1 "t_reg_operand")
+ (const_int 31)))
+ */
+ if (GET_CODE (op) == MINUS && satisfies_constraint_Jhb (XEXP (op, 0))
+ && GET_CODE (XEXP (op, 1)) == ASHIFT
+ && t_reg_operand (XEXP (XEXP (op, 1), 0), SImode)
+ && CONST_INT_P (XEXP (XEXP (op, 1), 1))
+ && INTVAL (XEXP (XEXP (op, 1), 1)) == 31)
+ return true;
+
+ /* (plus:SI (ashift:SI (match_operand:SI 1 "t_reg_operand")
+ (const_int 31))
+ (const_int -2147483648)) ;; 0xffffffff80000000
+ */
+ if (GET_CODE (op) == PLUS && satisfies_constraint_Jhb (XEXP (op, 1))
+ && GET_CODE (XEXP (op, 0)) == ASHIFT
+ && t_reg_operand (XEXP (XEXP (op, 0), 0), SImode)
+ && CONST_INT_P (XEXP (XEXP (op, 0), 1))
+ && INTVAL (XEXP (XEXP (op, 0), 1)) == 31)
+ return true;
+
/* (plus:SI (mult:SI (match_operand:SI 1 "t_reg_operand")
(const_int -2147483648)) ;; 0xffffffff80000000
(const_int -2147483648))