diff options
author | Michael Collison <michael.collison@linaro.org> | 2016-04-29 12:54:31 -0700 |
---|---|---|
committer | Michael Collison <michael.collison@linaro.org> | 2016-04-30 23:06:24 -0700 |
commit | e329d1a244dca54b1c86d8f0ed61a462679cd515 (patch) | |
tree | 76ae524644466e943c5c071a42f436f00e6f772d | |
parent | 608e1e3746f5242f0b0987ce64ca99969c33fb48 (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.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 22 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 46 |
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" |