re PR target/14631 (common subexpression elimilation error with sse2 instrinsic _mm_i...
authorRichard Henderson <rth@redhat.com>
Mon, 3 Jan 2005 06:26:52 +0000 (22:26 -0800)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 3 Jan 2005 06:26:52 +0000 (07:26 +0100)
PR target/14631
* config/i386/i386.c (ix86_expand_builtin): [IX86_BUILTIN_PINSRW,
IX86_BUILTIN_PINSRW128]: Fix wrong selector range in error message.
* config/i386/i386.md (mmx_pinsrw, sse2_pinsrw): Fix selector
handling.
(*mmx_pinsrw, *sse2_pinsrw): New patterns.
* config/i386/i386/predicates.md (const_pow2_1_to_8_operand,
const_pow2_1_to_128_operand): New predicates.

Co-Authored-By: Uros Bizjak <uros@kss-loka.si>
From-SVN: r92823

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/i386/predicates.md

index 3d3408c..6999538 100644 (file)
@@ -1,3 +1,15 @@
+2005-01-03  Richard Henderson  <rth@redhat.com>
+           Uros Bizjak  <uros@kss-loka.si>
+
+       PR target/14631
+       * config/i386/i386.c (ix86_expand_builtin): [IX86_BUILTIN_PINSRW,
+       IX86_BUILTIN_PINSRW128]: Fix wrong selector range in error message.
+       * config/i386/i386.md (mmx_pinsrw, sse2_pinsrw): Fix selector
+       handling.
+       (*mmx_pinsrw, *sse2_pinsrw): New patterns.
+       * config/i386/i386/predicates.md (const_pow2_1_to_8_operand,
+       const_pow2_1_to_128_operand): New predicates.
+
 2005-01-02  Greg McGary  <greg@mcgary.org>
 
        * tree-mudflap.c (mf_varname_tree): decl_printable_name handles
index 6e65969..23129a0 100644 (file)
@@ -13437,7 +13437,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
       if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
        {
          error ("selector must be an integer constant in the range 0..%i",
-                 fcode == IX86_BUILTIN_PINSRW ? 15:255);
+                 fcode == IX86_BUILTIN_PINSRW ? 3:7);
          return const0_rtx;
        }
       if (target == 0
index 44549d4..9483218 100644 (file)
 
 ;; MMX insert/extract/shuffle
 
-(define_insn "mmx_pinsrw"
+(define_expand "mmx_pinsrw"
+  [(set (match_operand:V4HI 0 "register_operand" "")
+        (vec_merge:V4HI
+         (match_operand:V4HI 1 "register_operand" "")
+          (vec_duplicate:V4HI
+            (match_operand:SI 2 "nonimmediate_operand" ""))
+          (match_operand:SI 3 "const_0_to_3_operand" "")))]
+  "TARGET_SSE || TARGET_3DNOW_A"
+{
+  operands[2] = gen_lowpart (HImode, operands[2]);
+  operands[3] = GEN_INT (1 << INTVAL (operands[3]));
+})
+
+(define_insn "*mmx_pinsrw"
   [(set (match_operand:V4HI 0 "register_operand" "=y")
-        (vec_merge:V4HI (match_operand:V4HI 1 "register_operand" "0")
-                       (vec_duplicate:V4HI
-                        (truncate:HI (match_operand:SI 2 "nonimmediate_operand" "rm")))
-                       (match_operand:SI 3 "const_0_to_15_operand" "N")))]
+        (vec_merge:V4HI
+         (match_operand:V4HI 1 "register_operand" "0")
+          (vec_duplicate:V4HI
+            (match_operand:HI 2 "nonimmediate_operand" "rm"))
+          (match_operand:SI 3 "const_pow2_1_to_8_operand" "N")))]
   "TARGET_SSE || TARGET_3DNOW_A"
-  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
+{
+  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
+  return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
+}
   [(set_attr "type" "mmxcvt")
    (set_attr "mode" "DI")])
 
 
 ;; MMX insert/extract/shuffle
 
-(define_insn "sse2_pinsrw"
+(define_expand "sse2_pinsrw"
+  [(set (match_operand:V8HI 0 "register_operand" "")
+        (vec_merge:V8HI
+         (match_operand:V8HI 1 "register_operand" "")
+          (vec_duplicate:V8HI
+            (match_operand:SI 2 "nonimmediate_operand" ""))
+          (match_operand:SI 3 "const_0_to_7_operand" "")))]
+  "TARGET_SSE2"
+{
+  operands[2] = gen_lowpart (HImode, operands[2]);
+  operands[3] = GEN_INT (1 << INTVAL (operands[3]));
+})
+
+(define_insn "*sse2_pinsrw"
   [(set (match_operand:V8HI 0 "register_operand" "=x")
-        (vec_merge:V8HI (match_operand:V8HI 1 "register_operand" "0")
-                       (vec_duplicate:V8HI
-                        (truncate:HI
-                          (match_operand:SI 2 "nonimmediate_operand" "rm")))
-                       (match_operand:SI 3 "const_0_to_255_operand" "N")))]
+        (vec_merge:V8HI
+         (match_operand:V8HI 1 "register_operand" "0")
+          (vec_duplicate:V8HI
+            (match_operand:HI 2 "nonimmediate_operand" "rm"))
+          (match_operand:SI 3 "const_pow2_1_to_128_operand" "N")))]
   "TARGET_SSE2"
-  "pinsrw\t{%3, %2, %0|%0, %2, %3}"
+{
+  operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
+  return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
+}
   [(set_attr "type" "ssecvt")
    (set_attr "mode" "TI")])
 
index 5127162..5fa93fa 100644 (file)
   (and (match_code "const_int")
        (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 255")))
 
+;; Match exactly one bit in 4-bit mask.
+(define_predicate "const_pow2_1_to_8_operand"
+  (match_code "const_int")
+{
+  unsigned int log = exact_log2 (INTVAL (op));
+  return log <= 3;
+})
+
+;; Match exactly one bit in 8-bit mask.
+(define_predicate "const_pow2_1_to_128_operand"
+  (match_code "const_int")
+{
+  unsigned int log = exact_log2 (INTVAL (op));
+  return log <= 7;
+})
+
 ;; True if this is a constant appropriate for an increment or decrement.
 (define_predicate "incdec_operand"
   (match_code "const_int")