aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Collison <michael.collison@linaro.org>2016-04-29 12:54:31 -0700
committerMichael Collison <michael.collison@linaro.org>2016-04-30 23:06:24 -0700
commite329d1a244dca54b1c86d8f0ed61a462679cd515 (patch)
tree76ae524644466e943c5c071a42f436f00e6f772d
parent608e1e3746f5242f0b0987ce64ca99969c33fb48 (diff)
Patch for bugzilla 70089linaro-local/bugzilla-70089
Add missing calls to neg_const_ok_for_arm Add assembly alternatives for negated constants Fix constraint on arm iorsi3 insn
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c22
-rw-r--r--gcc/config/arm/arm.md46
3 files changed, 49 insertions, 20 deletions
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index d8179c441bb..ee7d80df1d2 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -59,6 +59,7 @@ extern bool arm_small_register_classes_for_mode_p (machine_mode);
extern int arm_hard_regno_mode_ok (unsigned int, machine_mode);
extern bool arm_modes_tieable_p (machine_mode, machine_mode);
extern int const_ok_for_arm (HOST_WIDE_INT);
+extern int neg_const_ok_for_arm (HOST_WIDE_INT);
extern int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
extern int const_ok_for_dimode_op (HOST_WIDE_INT, enum rtx_code);
extern int arm_split_constant (RTX_CODE, machine_mode, rtx,
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 71b51439dc7..59927e4a0a5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -3888,6 +3888,28 @@ const_ok_for_arm (HOST_WIDE_INT i)
return FALSE;
}
+/* Return TRUE if int I is a valid negative immediate ARM constant. */
+
+int
+neg_const_ok_for_arm (HOST_WIDE_INT i)
+{
+ if (i >= 0)
+ return FALSE;
+
+ if (TARGET_32BIT)
+ {
+ HOST_WIDE_INT neg = -i;
+
+ if (IN_RANGE (i, -0x8000, 0x7fff))
+ {
+ if ((i & 0xffff) == (neg & 0xffff))
+ return const_ok_for_arm (neg);
+ }
+ }
+
+ return FALSE;
+}
+
/* Return true if I is a valid constant for the operation CODE. */
int
const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 47171b99682..603df8624a9 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -2163,19 +2163,21 @@
; ??? Check split length for Thumb-2
(define_insn_and_split "*arm_andsi3_insn"
- [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
- (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
- (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r,r")
+ (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r,r")
+ (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,L,?n")))]
"TARGET_32BIT"
"@
and%?\\t%0, %1, %2
and%?\\t%0, %1, %2
bic%?\\t%0, %1, #%B2
and%?\\t%0, %1, %2
+ and%?\\t%0, %1, #%n2
#"
"TARGET_32BIT
&& CONST_INT_P (operands[2])
&& !(const_ok_for_arm (INTVAL (operands[2]))
+ || neg_const_ok_for_arm (INTVAL (operands[2]))
|| const_ok_for_arm (~INTVAL (operands[2])))"
[(clobber (const_int 0))]
"
@@ -2183,10 +2185,10 @@
INTVAL (operands[2]), operands[0], operands[1], 0);
DONE;
"
- [(set_attr "length" "4,4,4,4,16")
+ [(set_attr "length" "4,4,4,4,4,16")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no,yes,no,no,no")
- (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
+ (set_attr "predicable_short_it" "no,yes,no,no,no,no")
+ (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm,logic_imm")]
)
(define_insn "*andsi3_compare0"
@@ -2979,19 +2981,21 @@
)
(define_insn_and_split "*iorsi3_insn"
- [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
- (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
- (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))]
+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r,r")
+ (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r,r")
+ (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,L,?n")))]
"TARGET_32BIT"
"@
orr%?\\t%0, %1, %2
orr%?\\t%0, %1, %2
orn%?\\t%0, %1, #%B2
orr%?\\t%0, %1, %2
+ orr%?\\t%0, %1, #%n2
#"
"TARGET_32BIT
&& CONST_INT_P (operands[2])
&& !(const_ok_for_arm (INTVAL (operands[2]))
+ || neg_const_ok_for_arm (INTVAL (operands[2]))
|| (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))"
[(clobber (const_int 0))]
{
@@ -2999,11 +3003,11 @@
INTVAL (operands[2]), operands[0], operands[1], 0);
DONE;
}
- [(set_attr "length" "4,4,4,4,16")
- (set_attr "arch" "32,t2,t2,32,32")
+ [(set_attr "length" "4,4,4,4,4,16")
+ (set_attr "arch" "32,t2,t2,32,32,32")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no,yes,no,no,no")
- (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
+ (set_attr "predicable_short_it" "no,yes,no,no,no,no")
+ (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_imm,logic_reg")]
)
(define_peephole2
@@ -3154,28 +3158,30 @@
)
(define_insn_and_split "*arm_xorsi3"
- [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r")
- (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r")
- (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))]
+ [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r")
+ (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r")
+ (match_operand:SI 2 "reg_or_int_operand" "I,l,r,L,?n")))]
"TARGET_32BIT"
"@
eor%?\\t%0, %1, %2
eor%?\\t%0, %1, %2
eor%?\\t%0, %1, %2
+ eor%?\\t%0, %1, #%n2
#"
"TARGET_32BIT
&& CONST_INT_P (operands[2])
- && !const_ok_for_arm (INTVAL (operands[2]))"
+ && !const_ok_for_arm (INTVAL (operands[2]))
+ && !neg_const_ok_for_arm (INTVAL (operands[2]))"
[(clobber (const_int 0))]
{
arm_split_constant (XOR, SImode, curr_insn,
INTVAL (operands[2]), operands[0], operands[1], 0);
DONE;
}
- [(set_attr "length" "4,4,4,16")
+ [(set_attr "length" "4,4,4,4,16")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no,yes,no,no")
- (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
+ (set_attr "predicable_short_it" "no,yes,no,no,no")
+ (set_attr "type" "logic_imm,logic_reg,logic_reg,logic_imm,multiple")]
)
(define_insn "*xorsi3_compare0"