Fix Thumb2 bic orn

2009-05-20  Ramana Radhakrishnan  <ramana.radhakrishnan@arm.com>
    
	* config/arm/arm.md (*arm_iorsi3): Refactored for only ARM.
        (peephole ior (reg, int) -> mov, ior): Refactored for only ARM.
        * config/arm/thumb2.md (*thumb_andsi_not_shiftsi_si): Allow bic
        with shifts for Thumb2.
        (orsi_notsi): New for orn.
        (*thumb_orsi_notshiftsi_si): Allow orn with shifts.
        (*thumb2_iorsi3): Rewrite support for iorsi for Thumb2.
        * config/arm/arm.c (const_ok_for_op): Split case for IOR for
        Thumb2.
        (arm_gen_constant): Set can_invert for IOR and Thumb2, Add
        comments. Don't invert remainder for IOR.

From-SVN: r147729
This commit is contained in:
Ramana Radhakrishnan 2009-05-20 05:40:17 +00:00 committed by Ramana Radhakrishnan
parent 875d0f10a6
commit a7994a57b9
4 changed files with 105 additions and 5 deletions

View File

@ -1,3 +1,17 @@
2009-05-20 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/arm/arm.md (*arm_iorsi3): Refactored for only ARM.
(peephole ior (reg, int) -> mov, ior): Refactored for only ARM.
* config/arm/thumb2.md (*thumb_andsi_not_shiftsi_si): Allow bic
with shifts for Thumb2.
(orsi_notsi): New for orn.
(*thumb_orsi_notshiftsi_si): Allow orn with shifts.
(*thumb2_iorsi3): Rewrite support for iorsi for Thumb2.
* config/arm/arm.c (const_ok_for_op): Split case for IOR for
Thumb2.
(arm_gen_constant): Set can_invert for IOR and Thumb2, Add
comments. Don't invert remainder for IOR.
2009-05-19 Zdenek Dvorak <ook@ucw.cz>
PR tree-optimization/40087

View File

@ -2008,7 +2008,11 @@ const_ok_for_op (HOST_WIDE_INT i, enum rtx_code code)
case MINUS: /* Should only occur with (MINUS I reg) => rsb */
case XOR:
return 0;
case IOR:
if (TARGET_THUMB2)
return const_ok_for_arm (ARM_SIGN_EXTEND (~i));
return 0;
case AND:
@ -2185,15 +2189,20 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
GEN_INT (ARM_SIGN_EXTEND (val))));
return 1;
}
if (remainder == 0)
{
if (reload_completed && rtx_equal_p (target, source))
return 0;
if (generate)
emit_constant_insn (cond,
gen_rtx_SET (VOIDmode, target, source));
return 1;
}
if (TARGET_THUMB2)
can_invert = 1;
break;
case AND:
@ -2281,6 +2290,7 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
/* Calculate a few attributes that may be useful for specific
optimizations. */
/* Count number of leading zeros. */
for (i = 31; i >= 0; i--)
{
if ((remainder & (1 << i)) == 0)
@ -2289,6 +2299,7 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
break;
}
/* Count number of leading 1's. */
for (i = 31; i >= 0; i--)
{
if ((remainder & (1 << i)) != 0)
@ -2297,6 +2308,7 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
break;
}
/* Count number of trailing zero's. */
for (i = 0; i <= 31; i++)
{
if ((remainder & (1 << i)) == 0)
@ -2305,6 +2317,7 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
break;
}
/* Count number of trailing 1's. */
for (i = 0; i <= 31; i++)
{
if ((remainder & (1 << i)) != 0)
@ -2492,6 +2505,17 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
if (code == XOR)
break;
/* Convert.
x = y | constant ( which is composed of set_sign_bit_copies of leading 1s
and the remainder 0s for e.g. 0xfff00000)
x = ~(~(y ashift set_sign_bit_copies) lshiftrt set_sign_bit_copies)
This can be done in 2 instructions by using shifts with mov or mvn.
e.g. for
x = x | 0xfff00000;
we generate.
mvn r0, r0, asl #12
mvn r0, r0, lsr #12 */
if (set_sign_bit_copies > 8
&& (val & (-1 << (32 - set_sign_bit_copies))) == val)
{
@ -2517,6 +2541,16 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
return 2;
}
/* Convert
x = y | constant (which has set_zero_bit_copies number of trailing ones).
to
x = ~((~y lshiftrt set_zero_bit_copies) ashift set_zero_bit_copies).
For eg. r0 = r0 | 0xfff
mvn r0, r0, lsr #12
mvn r0, r0, asl #12
*/
if (set_zero_bit_copies > 8
&& (remainder & ((1 << set_zero_bit_copies) - 1)) == remainder)
{
@ -2542,6 +2576,13 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
return 2;
}
/* This will never be reached for Thumb2 because orn is a valid
instruction. This is for Thumb1 and the ARM 32 bit cases.
x = y | constant (such that ~constant is a valid constant)
Transform this to
x = ~(~y & ~constant).
*/
if (const_ok_for_arm (temp1 = ARM_SIGN_EXTEND (~val)))
{
if (generate)
@ -2651,7 +2692,8 @@ arm_gen_constant (enum rtx_code code, enum machine_mode mode, rtx cond,
if (remainder & (1 << i))
num_bits_set++;
if (code == AND || (can_invert && num_bits_set > 16))
if ((code == AND)
|| (code != IOR && can_invert && num_bits_set > 16))
remainder = (~remainder) & 0xffffffff;
else if (code == PLUS && num_bits_set > 16)
remainder = (-remainder) & 0xffffffff;

View File

@ -2615,11 +2615,11 @@
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
(ior:SI (match_operand:SI 1 "s_register_operand" "r,r")
(match_operand:SI 2 "reg_or_int_operand" "rI,?n")))]
"TARGET_32BIT"
"TARGET_ARM"
"@
orr%?\\t%0, %1, %2
#"
"TARGET_32BIT
"TARGET_ARM
&& GET_CODE (operands[2]) == CONST_INT
&& !const_ok_for_arm (INTVAL (operands[2]))"
[(clobber (const_int 0))]
@ -2646,7 +2646,7 @@
(set (match_operand:SI 0 "arm_general_register_operand" "")
(ior:SI (match_operand:SI 1 "arm_general_register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))]
"TARGET_32BIT
"TARGET_ARM
&& !const_ok_for_arm (INTVAL (operands[2]))
&& const_ok_for_arm (~INTVAL (operands[2]))"
[(set (match_dup 3) (match_dup 2))

View File

@ -57,7 +57,7 @@
[(match_operand:SI 2 "s_register_operand" "r")
(match_operand:SI 3 "const_int_operand" "M")]))
(match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_ARM"
"TARGET_THUMB2"
"bic%?\\t%0, %1, %2%S4"
[(set_attr "predicable" "yes")
(set_attr "shift" "2")
@ -1252,3 +1252,47 @@
(set_attr "length" "2")]
)
(define_insn "orsi_notsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
(match_operand:SI 1 "reg_or_int_operand" "rK")))]
"TARGET_THUMB2"
"orn%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")]
)
(define_insn "*thumb_orsi_not_shiftsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(ior:SI (not:SI (match_operator:SI 4 "shift_operator"
[(match_operand:SI 2 "s_register_operand" "r")
(match_operand:SI 3 "const_int_operand" "M")]))
(match_operand:SI 1 "s_register_operand" "r")))]
"TARGET_THUMB2"
"orn%?\\t%0, %1, %2%S4"
[(set_attr "predicable" "yes")
(set_attr "shift" "2")
(set_attr "type" "alu_shift")]
)
(define_insn_and_split "*thumb2_iorsi3"
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
(ior:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
(match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
"TARGET_THUMB2"
"@
orr%?\\t%0, %1, %2
orn%?\\t%0, %1, #%B2
#"
"TARGET_THUMB2
&& GET_CODE (operands[2]) == CONST_INT
&& !(const_ok_for_arm (INTVAL (operands[2]))
|| const_ok_for_arm (~INTVAL (operands[2])))"
[(clobber (const_int 0))]
"
arm_split_constant (IOR, SImode, curr_insn,
INTVAL (operands[2]), operands[0], operands[1], 0);
DONE;
"
[(set_attr "length" "4,4,16")
(set_attr "predicable" "yes")]
)