OSDN Git Service

* arm/thumb2.md (thumb2_extendsidi2): Add a split sub-pattern.
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 31 May 2009 14:09:12 +0000 (14:09 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 31 May 2009 14:09:12 +0000 (14:09 +0000)
(thumb2_extendqidi2): New pattern.

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

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

index 400b535..69d0ea2 100644 (file)
@@ -1,3 +1,8 @@
+2009-05-31  Richard Earnshaw  <rearnsha@arm.com>
+
+       * arm/thumb2.md (thumb2_extendsidi2): Add a split sub-pattern.
+       (thumb2_extendqidi2): New pattern.
+
 2009-05-31  Ira Rosen  <irar@il.ibm.com>
 
        * tree-vect-loop-manip.c (slpeel_update_phi_nodes_for_guard1): Don't
index eada5ca..203001b 100644 (file)
    (set_attr "neg_pool_range" "*,250")]
 )
 
-(define_insn "*thumb2_extendsidi2"
+(define_insn_and_split "*thumb2_extendsidi2"
   [(set (match_operand:DI 0 "s_register_operand" "=r")
         (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
   "TARGET_THUMB2"
-  "*
-    /* ??? Output both instructions unconditionally, otherwise the conditional
-       execution insn counter gets confused.
-    if (REGNO (operands[1])
-        != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0)) */
-      output_asm_insn (\"mov%?\\t%Q0, %1\", operands);
-    return \"asr%?\\t%R0, %Q0, #31\";
-  "
+  "mov%?\\t%Q0, %1\;asr?\\t%R0, %1, #31"
+  "&& reload_completed"
+  [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
+  {
+    rtx lo_part = gen_lowpart (SImode, operands[0]);
+
+    if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
+      emit_move_insn (lo_part, operands[1]);
+    operands[0] = gen_highpart (SImode, operands[0]);
+  }
   [(set_attr "length" "8")
    (set_attr "ce_count" "2")
    (set_attr "shift" "1")
    (set_attr "predicable" "yes")]
 )
 
+(define_insn_and_split "*thumb2_extendqidi2"
+  [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
+       (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
+  "TARGET_THUMB2"
+  "@
+   sxtb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
+   ldrsb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
+  "&& reload_completed"
+  [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
+   (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
+  "
+  {
+    operands[2] = gen_highpart (SImode, operands[0]);
+    operands[0] = gen_lowpart (SImode, operands[0]);
+  }
+  "
+  [(set_attr "length" "8")
+   (set_attr "ce_count" "2")
+   (set_attr "predicable" "yes")
+   (set_attr "type" "*,load_byte")
+   (set_attr "pool_range" "*,4092")
+   (set_attr "neg_pool_range" "*,250")]
+)
+
 ;; All supported Thumb2 implementations are armv6, so only that case is
 ;; provided.
 (define_insn "*thumb2_extendqisi_v6"