OSDN Git Service

Fix Thumb2 bic orn
authorramana <ramana@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 May 2009 05:40:17 +0000 (05:40 +0000)
committerramana <ramana@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 20 May 2009 05:40:17 +0000 (05:40 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147729 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/config/arm/thumb2.md

index 82f00eb..b64bdce 100644 (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
index 8579ce4..eda5cea 100644 (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;
index 2b2d703..de78d28 100644 (file)
   [(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))]
    (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))
index 14b52d0..935ca08 100644 (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")
    (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")]
+)