TILE-Gx...
authorWalter Lee <walt@tilera.com>
Wed, 23 Nov 2016 04:33:43 +0000 (04:33 +0000)
committerWalter Lee <walt@gcc.gnu.org>
Wed, 23 Nov 2016 04:33:43 +0000 (04:33 +0000)
TILE-Gx: fixes the zero_extract/sign_extract patterns so that they
properly handle the case when pos + size > number of bits in a word.

* config/tilegx/tilegx.md (*zero_extract): Use
  define_insn_and_split instead of define_insn; Handle pos +
  size > 64.
  (*sign_extract): Likewise.

From-SVN: r242734

gcc/ChangeLog
gcc/config/tilegx/tilegx.md

index 8d11c29d1a6fae96b875cefefc35d604b6caa278..a7a776e70e17f852ea669397b9ac240bc719def7 100644 (file)
@@ -1,3 +1,10 @@
+2016-11-22  Walter Lee  <walt@tilera.com>
+
+       * config/tilegx/tilegx.md (*zero_extract): Use
+       define_insn_and_split instead of define_insn; Handle pos + size >
+       64.
+       (*sign_extract): Likewise.
+
 2016-11-22  Marek Polacek  <polacek@redhat.com>
 
        PR tree-optimization/78455
index 55c345c50d43233ae266a182c452c89b64fb36a4..3ad5a873b1f7d0abd3b1ef3c69ecffd139553453 100644 (file)
   "ld<four_s_if_si>_tls\t%0, %1, tls_ie_load(%2)"
   [(set_attr "type" "X1_2cycle")])
 
-(define_insn "*zero_extract<mode>"
+(define_insn_and_split "*zero_extract<mode>"
   [(set (match_operand:I48MODE 0 "register_operand" "=r")
        (zero_extract:I48MODE
          (match_operand:I48MODE 1 "reg_or_0_operand" "r")
          (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
   ""
   "bfextu\t%0, %r1, %3, %3+%2-1"
+  "&& reload_completed"
+  [(set (match_dup 0) (zero_extract:I48MODE
+                       (match_dup 1)
+                       (match_dup 2)
+                       (match_dup 3)))]
+{
+  HOST_WIDE_INT bit_width = INTVAL (operands[2]);
+  HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
+
+  if (bit_offset + bit_width > 64)
+    operands[2] = GEN_INT (64 - bit_offset);
+}
   [(set_attr "type" "X0")])
 
 (define_insn "*sign_extract_low32"
   "INTVAL (operands[3]) == 0 && INTVAL (operands[2]) == 32"
   "addxi\t%0, %r1, 0")
 
-(define_insn "*sign_extract"
+(define_insn_and_split "*sign_extract"
   [(set (match_operand:I48MODE 0 "register_operand" "=r")
        (sign_extract:I48MODE
          (match_operand:I48MODE 1 "reg_or_0_operand" "r")
          (match_operand:I48MODE 3 "u6bit_cint_operand" "n")))]
   ""
   "bfexts\t%0, %r1, %3, %3+%2-1"
+  "&& reload_completed"
+  [(set (match_dup 0) (sign_extract:I48MODE
+                       (match_dup 1)
+                       (match_dup 2)
+                       (match_dup 3)))]
+{
+  HOST_WIDE_INT bit_width = INTVAL (operands[2]);
+  HOST_WIDE_INT bit_offset = INTVAL (operands[3]);
+
+  if (bit_offset + bit_width > 64)
+    operands[2] = GEN_INT (64 - bit_offset);
+}
   [(set_attr "type" "X0")])
 
 \f