* config/i386/predicates/md (reg_not_xmm0_operand): New predicate.
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Jun 2007 05:35:39 +0000 (05:35 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 5 Jun 2007 05:35:39 +0000 (05:35 +0000)
(nonimm_not_xmm0_operand): Ditto.
* config/i386/sse.md ("sse4_1_blendvpd"): Use "reg_not_xmm0_operand"
as operand[0] and operand[1] predicate.  Use "nonimm_not_xmm0_operand"
as operand[2] predicate.  Require "z" class XMM register for
operand[3].  Adjust asm template.
("sse4_1_blendvpd"): Ditto.
("sse4_1_pblendvb"): Ditto.
  * config/i386/i386.c (ix86_expand_sse_4_operands_builtin): Do not
force op2 into xmm0 register for variable blend instructions.

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

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

index 98212c3..bcf11a2 100644 (file)
@@ -1,3 +1,16 @@
+2007-06-05  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/predicates/md (reg_not_xmm0_operand): New predicate.
+       (nonimm_not_xmm0_operand): Ditto.
+       * config/i386/sse.md ("sse4_1_blendvpd"): Use "reg_not_xmm0_operand"
+       as operand[0] and operand[1] predicate.  Use "nonimm_not_xmm0_operand"
+       as operand[2] predicate.  Require "z" class XMM register for
+       operand[3].  Adjust asm template.
+       ("sse4_1_blendvpd"): Ditto.
+       ("sse4_1_pblendvb"): Ditto.
+       * config/i386/i386.c (ix86_expand_sse_4_operands_builtin): Do not
+       force op2 into xmm0 register for variable blend instructions.
+
 2007-06-04  Tom Tromey  <tromey@redhat.com>
 
        * c-tree.h (start_enum): Update.
index a150c05..64fb97e 100644 (file)
@@ -18280,13 +18280,14 @@ ix86_expand_sse_4_operands_builtin (enum insn_code icode, tree exp,
   enum machine_mode tmode = insn_data[icode].operand[0].mode;
   enum machine_mode mode1 = insn_data[icode].operand[1].mode;
   enum machine_mode mode2 = insn_data[icode].operand[2].mode;
-  enum machine_mode mode3;
-  rtx xmm0;
+  enum machine_mode mode3 = insn_data[icode].operand[3].mode;
 
   if (VECTOR_MODE_P (mode1))
     op0 = safe_vector_operand (op0, mode1);
   if (VECTOR_MODE_P (mode2))
     op1 = safe_vector_operand (op1, mode2);
+  if (VECTOR_MODE_P (mode3))
+    op2 = safe_vector_operand (op2, mode3);
 
   if (optimize
       || target == 0
@@ -18300,42 +18301,24 @@ ix86_expand_sse_4_operands_builtin (enum insn_code icode, tree exp,
       || !(*insn_data[icode].operand[2].predicate) (op1, mode2))
     op1 = copy_to_mode_reg (mode2, op1);
 
-  switch (icode)
-    {
-    case CODE_FOR_sse4_1_blendvpd:
-    case CODE_FOR_sse4_1_blendvps:
-    case CODE_FOR_sse4_1_pblendvb:
-      mode3 = tmode;
-      op2 = safe_vector_operand (op2, mode3);
-
-      if (!register_operand (op2, mode3))
+  if (! (*insn_data[icode].operand[3].predicate) (op2, mode3))
+    switch (icode)
+      {
+      case CODE_FOR_sse4_1_blendvpd:
+      case CODE_FOR_sse4_1_blendvps:
+      case CODE_FOR_sse4_1_pblendvb:
        op2 = copy_to_mode_reg (mode3, op2);
+       break;
 
-      /* ??? The third argument of variable blends must be xmm0.  */
-      xmm0 = gen_rtx_REG (mode3, XMM0_REG);
+      case CODE_FOR_sse4_1_roundsd:
+      case CODE_FOR_sse4_1_roundss:
+       error ("the third argument must be a 4-bit immediate");
+       return const0_rtx;
 
-      emit_move_insn (xmm0, op2);
-      op2 = xmm0;
-      break;
-
-    default:
-      mode3 = insn_data[icode].operand[3].mode;
-      if (! (*insn_data[icode].operand[3].predicate) (op2, mode3))
-       {
-         switch (icode)
-           {
-           case CODE_FOR_sse4_1_roundsd:
-           case CODE_FOR_sse4_1_roundss:
-             error ("the third argument must be a 4-bit immediate");
-             break;
-           default:
-             error ("the third argument must be an 8-bit immediate");
-             break;
-           }
-         return const0_rtx;
-       }
-      break;
-    }
+      default:
+       error ("the third argument must be an 8-bit immediate");
+       return const0_rtx;
+      }
 
   pat = GEN_FCN (icode) (target, op0, op1, op2);
   if (! pat)
index 6d351f6..730f32b 100644 (file)
@@ -1315,7 +1315,7 @@ enum reg_class
    "GENERAL_REGS",                     \
    "FP_TOP_REG", "FP_SECOND_REG",      \
    "FLOAT_REGS",                       \
-   "FIRST_SSE_REG",                    \
+   "SSE_FIRST_REG",                    \
    "SSE_REGS",                         \
    "MMX_REGS",                         \
    "FP_TOP_SSE_REGS",                  \
@@ -1343,7 +1343,7 @@ enum reg_class
   { 0x1100ff,  0x1fe0 },               /* GENERAL_REGS */              \
      { 0x100,     0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */\
     { 0xff00,     0x0 },               /* FLOAT_REGS */                \
-  { 0x200000,     0x0 },               /* FIRST_SSE_REG */             \
+  { 0x200000,     0x0 },               /* SSE_FIRST_REG */             \
 { 0x1fe00000,0x1fe000 },               /* SSE_REGS */                  \
 { 0xe0000000,    0x1f },               /* MMX_REGS */                  \
 { 0x1fe00100,0x1fe000 },               /* FP_TOP_SSE_REG */            \
index ad8ad00..3d10177 100644 (file)
    (FLAGS_REG                  17)
    (FPSR_REG                   18)
    (FPCR_REG                   19)
-   (XMM0_REG                   21)
    (R10_REG                    39)
    (R11_REG                    40)
   ])
index 5dcc24b..c035287 100644 (file)
   (and (match_code "reg")
        (match_test "REGNO (op) == FLAGS_REG")))
 
+;; Return true if op is not xmm0 register.
+(define_predicate "reg_not_xmm0_operand"
+   (and (match_operand 0 "register_operand")
+       (match_test "GET_CODE (op) != REG
+                    || REGNO (op) != FIRST_SSE_REG")))
+
+;; As above, but allow nonimmediate operands.
+(define_predicate "nonimm_not_xmm0_operand"
+   (and (match_operand 0 "nonimmediate_operand")
+       (match_test "GET_CODE (op) != REG
+                    || REGNO (op) != FIRST_SSE_REG")))
+
 ;; Return 1 if VALUE can be stored in a sign extended immediate field.
 (define_predicate "x86_64_immediate_operand"
   (match_code "const_int,symbol_ref,label_ref,const")
index cd83717..8917dfc 100644 (file)
    (set_attr "mode" "V4SF")])
 
 (define_insn "sse4_1_blendvpd"
-  [(set (match_operand:V2DF 0 "register_operand" "=x")
-       (unspec:V2DF [(match_operand:V2DF 1 "register_operand"  "0")
-                     (match_operand:V2DF 2 "nonimmediate_operand" "xm")
-                     (reg:V2DF XMM0_REG)]
+  [(set (match_operand:V2DF 0 "reg_not_xmm0_operand" "=x")
+       (unspec:V2DF [(match_operand:V2DF 1 "reg_not_xmm0_operand"  "0")
+                     (match_operand:V2DF 2 "nonimm_not_xmm0_operand" "xm")
+                     (match_operand:V2DF 3 "register_operand" "z")]
                     UNSPEC_BLENDV))]
   "TARGET_SSE4_1"
-  "blendvpd\t{%%xmm0, %2, %0|%0, %2, %%xmm0}"
+  "blendvpd\t{%3, %2, %0|%0, %2, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2DF")])
 
 (define_insn "sse4_1_blendvps"
-  [(set (match_operand:V4SF 0 "register_operand" "=x")
-       (unspec:V4SF [(match_operand:V4SF 1 "register_operand" "0")
-                     (match_operand:V4SF 2 "nonimmediate_operand" "xm")
-                     (reg:V4SF XMM0_REG)]
+  [(set (match_operand:V4SF 0 "reg_not_xmm0_operand" "=x")
+       (unspec:V4SF [(match_operand:V4SF 1 "reg_not_xmm0_operand" "0")
+                     (match_operand:V4SF 2 "nonimm_not_xmm0_operand" "xm")
+                     (match_operand:V4SF 3 "register_operand" "z")]
                     UNSPEC_BLENDV))]
   "TARGET_SSE4_1"
-  "blendvps\t{%%xmm0, %2, %0|%0, %2, %%xmm0}"
+  "blendvps\t{%3, %2, %0|%0, %2, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "mode" "V4SF")])
    (set_attr "mode" "TI")])
 
 (define_insn "sse4_1_pblendvb"
-  [(set (match_operand:V16QI 0 "register_operand" "=x")
-       (unspec:V16QI [(match_operand:V16QI 1 "register_operand"  "0")
-                      (match_operand:V16QI 2 "nonimmediate_operand" "xm")
-                      (reg:V16QI XMM0_REG)]
+  [(set (match_operand:V16QI 0 "reg_not_xmm0_operand" "=x")
+       (unspec:V16QI [(match_operand:V16QI 1 "reg_not_xmm0_operand"  "0")
+                      (match_operand:V16QI 2 "nonimm_not_xmm0_operand" "xm")
+                      (match_operand:V16QI 3 "register_operand" "z")]
                      UNSPEC_BLENDV))]
   "TARGET_SSE4_1"
-  "pblendvb\t{%%xmm0, %2, %0|%0, %2, %%xmm0}"
+  "pblendvb\t{%3, %2, %0|%0, %2, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix_extra" "1")
    (set_attr "mode" "TI")])