OSDN Git Service

gcc:
[pf3gnuchains/gcc-fork.git] / gcc / config / i386 / mmx.md
index 5184b1d..5551bcb 100644 (file)
@@ -1,5 +1,5 @@
 ;; GCC machine description for MMX and 3dNOW! instructions
-;; Copyright (C) 2005, 2007, 2008
+;; Copyright (C) 2005, 2007, 2008, 2009
 ;; Free Software Foundation, Inc.
 ;;
 ;; This file is part of GCC.
     %vmovq\t{%1, %0|%0, %1}"
   [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov")
    (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*")
+   (set_attr "prefix_rep" "*,*,*,*,*,1,1,*,1,*,*,*")
+   (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,1,1,1")
+   (set (attr "prefix_rex")
+     (if_then_else (eq_attr "alternative" "8,9")
+       (symbol_ref "x86_extended_reg_mentioned_p (insn)")
+       (const_string "*")))
    (set (attr "prefix")
      (if_then_else (eq_attr "alternative" "7,8,9,10,11")
        (const_string "maybe_vex")
     #"
   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,*,*")
    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*")
+   (set_attr "prefix_rep" "*,*,*,1,1,*,*,*,*,*")
    (set (attr "prefix")
      (if_then_else (eq_attr "alternative" "5,6,7")
        (const_string "vex")
     #"
   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*")
    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*")
+   (set_attr "prefix_rep" "*,*,*,1,1,*,1,*,*,*,*,*,*,*")
+   (set_attr "prefix_data16" "*,*,*,*,*,*,*,1,*,*,*,*,*,*")
    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
 
 (define_expand "movv2sf"
     vmovq\t{%1, %0|%0, %1}"
   [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
    (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
+   (set_attr "prefix_rep" "*,*,*,*,*,1,1,*,*,*,*,*,*")
+   (set_attr "length_vex" "*,*,*,*,*,*,*,*,*,*,*,4,4")
    (set (attr "prefix")
      (if_then_else (eq_attr "alternative" "7,8,9,10,11,12")
        (const_string "vex")
     movd\t{%1, %0|%0, %1}"
   [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov")
    (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*")
+   (set_attr "prefix_rep" "*,*,*,*,*,1,1,*,*,*,*,*,*")
    (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
 
 (define_insn "*movv2sf_internal_avx"
     #"
   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
+   (set_attr "prefix_rep" "*,*,*,1,1,*,*,*,*,*,*")
    (set (attr "prefix")
      (if_then_else (eq_attr "alternative" "5,6,7,8")
        (const_string "vex")
     #"
   [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*")
    (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*")
+   (set_attr "prefix_rep" "*,*,*,1,1,*,*,*,*,*,*")
    (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")])
 
 ;; %%% This multiword shite has got to go.
   "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)"
   "pfadd\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_expand "mmx_subv2sf3"
   "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
   "@
    pfsub\t{%2, %0|%0, %2}
-   pfsubr\t{%2, %0|%0, %2}"
+   pfsubr\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxadd")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_expand "mmx_mulv2sf3"
   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)"
   "pfmul\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxmul")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 ;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX
    && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)"
   "pf<maxminfprefix>\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "*mmx_<code>v2sf3"
   "TARGET_3DNOW"
   "pf<maxminfprefix>\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_rcpv2sf2"
   "TARGET_3DNOW"
   "pfrcp\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmx")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_rcpit1v2sf3"
   "TARGET_3DNOW"
   "pfrcpit1\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmx")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_rcpit2v2sf3"
   "TARGET_3DNOW"
   "pfrcpit2\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmx")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_rsqrtv2sf2"
   "TARGET_3DNOW"
   "pfrsqrt\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmx")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_rsqit1v2sf3"
   "TARGET_3DNOW"
   "pfrsqit1\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmx")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_haddv2sf3"
   "TARGET_3DNOW"
   "pfacc\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_hsubv2sf3"
   "TARGET_3DNOW_A"
   "pfnacc\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_addsubv2sf3"
   "TARGET_3DNOW_A"
   "pfpnacc\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)"
   "pfcmpeq\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxcmp")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_gtv2sf3"
   "TARGET_3DNOW"
   "pfcmpgt\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxcmp")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_gev2sf3"
   "TARGET_3DNOW"
   "pfcmpge\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxcmp")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   "TARGET_3DNOW"
   "pf2id\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxcvt")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_pf2iw"
   "TARGET_3DNOW_A"
   "pf2iw\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxcvt")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_pi2fw"
   "TARGET_3DNOW_A"
   "pi2fw\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxcvt")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "mmx_floatv2si2"
   "TARGET_3DNOW"
   "pi2fd\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxcvt")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   "TARGET_3DNOW_A"
   "pswapd\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxcvt")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "V2SF")])
 
 (define_insn "*vec_dupv2sf"
   "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)"
   "pmulhrw\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxmul")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "DI")])
 
 (define_expand "sse2_umulv1siv1di3"
   "TARGET_MMX"
   "psra<mmxvecsize>\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxshft")
+   (set (attr "length_immediate")
+     (if_then_else (match_operand 2 "const_int_operand" "")
+       (const_string "1")
+       (const_string "0")))
    (set_attr "mode" "DI")])
 
 (define_insn "mmx_lshr<mode>3"
   "TARGET_MMX"
   "psrl<mmxvecsize>\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxshft")
+   (set (attr "length_immediate")
+     (if_then_else (match_operand 2 "const_int_operand" "")
+       (const_string "1")
+       (const_string "0")))
    (set_attr "mode" "DI")])
 
 (define_insn "mmx_ashl<mode>3"
   "TARGET_MMX"
   "psll<mmxvecsize>\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxshft")
+   (set (attr "length_immediate")
+     (if_then_else (match_operand 2 "const_int_operand" "")
+       (const_string "1")
+       (const_string "0")))
    (set_attr "mode" "DI")])
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
 (define_expand "mmx_<code><mode>3"
   [(set (match_operand:MMXMODEI 0 "register_operand" "")
-       (plogic:MMXMODEI
+       (any_logic:MMXMODEI
          (match_operand:MMXMODEI 1 "nonimmediate_operand" "")
          (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))]
   "TARGET_MMX"
 
 (define_insn "*mmx_<code><mode>3"
   [(set (match_operand:MMXMODEI 0 "register_operand" "=y")
-        (plogic:MMXMODEI
+        (any_logic:MMXMODEI
          (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
          (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))]
   "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
-  "p<plogicprefix>\t{%2, %0|%0, %2}"
+  "p<logicprefix>\t{%2, %0|%0, %2}"
   [(set_attr "type" "mmxadd")
    (set_attr "mode" "DI")])
 
   "TARGET_SSE || TARGET_3DNOW_A"
 {
   operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
-  return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
+  if (MEM_P (operands[2]))
+    return "pinsrw\t{%3, %2, %0|%0, %2, %3}";
+  else
+    return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}";
 }
   [(set_attr "type" "mmxcvt")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "DI")])
 
 (define_insn "mmx_pextrw"
   "TARGET_SSE || TARGET_3DNOW_A"
   "pextrw\t{%2, %1, %0|%0, %1, %2}"
   [(set_attr "type" "mmxcvt")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "DI")])
 
 (define_expand "mmx_pshufw"
   return "pshufw\t{%2, %1, %0|%0, %1, %2}";
 }
   [(set_attr "type" "mmxcvt")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "DI")])
 
 (define_insn "mmx_pswapdv2si2"
   "TARGET_3DNOW_A"
   "pswapd\t{%1, %0|%0, %1}"
   [(set_attr "type" "mmxcvt")
+   (set_attr "prefix_extra" "1")
    (set_attr "mode" "DI")])
 
 (define_insn "*vec_dupv4hi"
   "TARGET_SSE || TARGET_3DNOW_A"
   "pshufw\t{$0, %0, %0|%0, %0, 0}"
   [(set_attr "type" "mmxcvt")
+   (set_attr "length_immediate" "1")
    (set_attr "mode" "DI")])
 
 (define_insn "*vec_dupv2si"
    #
    #"
   [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov")
+   (set_attr "length_immediate" "*,*,1,*,*,*,*")
    (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
 
 (define_split
     return "pavgusb\t{%2, %0|%0, %2}";
 }
   [(set_attr "type" "mmxshft")
+   (set (attr "prefix_extra")
+     (if_then_else
+       (eq (symbol_ref "(TARGET_SSE || TARGET_3DNOW_A)") (const_int 0))
+       (const_string "1")
+       (const_string "*")))
    (set_attr "mode" "DI")])
 
 (define_expand "mmx_uavgv4hi3"
   [(set_attr "type" "mmxcvt")
    (set_attr "mode" "DI")])
 
-(define_insn "mmx_emms"
-  [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)
-   (clobber (reg:XF ST0_REG))
-   (clobber (reg:XF ST1_REG))
-   (clobber (reg:XF ST2_REG))
-   (clobber (reg:XF ST3_REG))
-   (clobber (reg:XF ST4_REG))
-   (clobber (reg:XF ST5_REG))
-   (clobber (reg:XF ST6_REG))
-   (clobber (reg:XF ST7_REG))
-   (clobber (reg:DI MM0_REG))
-   (clobber (reg:DI MM1_REG))
-   (clobber (reg:DI MM2_REG))
-   (clobber (reg:DI MM3_REG))
-   (clobber (reg:DI MM4_REG))
-   (clobber (reg:DI MM5_REG))
-   (clobber (reg:DI MM6_REG))
-   (clobber (reg:DI MM7_REG))]
+(define_expand "mmx_emms"
+  [(match_par_dup 0 [(const_int 0)])]
+  "TARGET_MMX"
+{
+  int regno;
+
+  operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
+
+  XVECEXP (operands[0], 0, 0)
+    = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
+                              UNSPECV_EMMS);
+
+  for (regno = 0; regno < 8; regno++)
+    {
+      XVECEXP (operands[0], 0, regno + 1)
+       = gen_rtx_CLOBBER (VOIDmode,
+                          gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
+
+      XVECEXP (operands[0], 0, regno + 9)
+       = gen_rtx_CLOBBER (VOIDmode,
+                          gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
+    }
+})
+
+(define_insn "*mmx_emms"
+  [(match_parallel 0 "emms_operation"
+    [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])]
   "TARGET_MMX"
   "emms"
   [(set_attr "type" "mmx")
-   (set_attr "memory" "unknown")])
-
-(define_insn "mmx_femms"
-  [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)
-   (clobber (reg:XF ST0_REG))
-   (clobber (reg:XF ST1_REG))
-   (clobber (reg:XF ST2_REG))
-   (clobber (reg:XF ST3_REG))
-   (clobber (reg:XF ST4_REG))
-   (clobber (reg:XF ST5_REG))
-   (clobber (reg:XF ST6_REG))
-   (clobber (reg:XF ST7_REG))
-   (clobber (reg:DI MM0_REG))
-   (clobber (reg:DI MM1_REG))
-   (clobber (reg:DI MM2_REG))
-   (clobber (reg:DI MM3_REG))
-   (clobber (reg:DI MM4_REG))
-   (clobber (reg:DI MM5_REG))
-   (clobber (reg:DI MM6_REG))
-   (clobber (reg:DI MM7_REG))]
+   (set_attr "modrm" "0")
+   (set_attr "memory" "none")])
+
+(define_expand "mmx_femms"
+  [(match_par_dup 0 [(const_int 0)])]
+  "TARGET_3DNOW"
+{
+  int regno;
+
+  operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17));
+
+  XVECEXP (operands[0], 0, 0)
+    = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx),
+                              UNSPECV_FEMMS);
+
+  for (regno = 0; regno < 8; regno++)
+    {
+      XVECEXP (operands[0], 0, regno + 1)
+       = gen_rtx_CLOBBER (VOIDmode,
+                          gen_rtx_REG (XFmode, FIRST_STACK_REG + regno));
+
+      XVECEXP (operands[0], 0, regno + 9)
+       = gen_rtx_CLOBBER (VOIDmode,
+                          gen_rtx_REG (DImode, FIRST_MMX_REG + regno));
+    }
+})
+
+(define_insn "*mmx_femms"
+  [(match_parallel 0 "emms_operation"
+    [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])]
   "TARGET_3DNOW"
   "femms"
   [(set_attr "type" "mmx")
+   (set_attr "modrm" "0")
    (set_attr "memory" "none")])