X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fi386%2Fmmx.md;h=5551bcb48f3671b0656f3df6e394cb917c51e6d9;hb=4dcd7ab324cb52d2d0ef482173ea8284300944eb;hp=4f0ab2ca3ee129ae20a631e0a220c0d420d3d94e;hpb=0a9ae7b110c0ea3fdc257500aa4058ce50e88318;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 4f0ab2ca3ee..5551bcb48f3 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -1,12 +1,12 @@ ;; GCC machine description for MMX and 3dNOW! instructions -;; Copyright (C) 2005 +;; Copyright (C) 2005, 2007, 2008, 2009 ;; Free Software Foundation, Inc. ;; ;; This file is part of GCC. ;; ;; GCC is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 2, or (at your option) +;; the Free Software Foundation; either version 3, or (at your option) ;; any later version. ;; ;; GCC is distributed in the hope that it will be useful, @@ -15,15 +15,14 @@ ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING. If not, write to -;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GCC; see the file COPYING3. If not see +;; . ;; The MMX and 3dNOW! patterns are in the same file because they use ;; the same register file, and 3dNOW! adds a number of extensions to ;; the base integer MMX isa. -;; Note! Except for the basic move instructions, *all* of these +;; Note! Except for the basic move instructions, *all* of these ;; patterns are outside the normal optabs namespace. This is because ;; use of these registers requires the insertion of emms or femms ;; instructions to return to normal fpu mode. The compiler doesn't @@ -32,17 +31,19 @@ ;; direction of the user via a builtin. ;; 8 byte integral modes handled by MMX (and by extension, SSE) -(define_mode_macro MMXMODEI [V8QI V4HI V2SI]) +(define_mode_iterator MMXMODEI [V8QI V4HI V2SI]) +(define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI V1DI]) ;; All 8-byte vector modes handled by MMX -(define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF]) +(define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF]) ;; Mix-n-match -(define_mode_macro MMXMODE12 [V8QI V4HI]) -(define_mode_macro MMXMODE24 [V4HI V2SI]) +(define_mode_iterator MMXMODE12 [V8QI V4HI]) +(define_mode_iterator MMXMODE24 [V4HI V2SI]) +(define_mode_iterator MMXMODE248 [V4HI V2SI V1DI]) ;; Mapping from integer vector mode to mnemonic suffix -(define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (DI "q")]) +(define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -54,8 +55,8 @@ ;; This is essential for maintaining stable calling conventions. (define_expand "mov" - [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "") - (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))] + [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" "") + (match_operand:MMXMODEI8 1 "nonimmediate_operand" ""))] "TARGET_MMX" { ix86_expand_vector_move (mode, operands); @@ -63,36 +64,73 @@ }) (define_insn "*mov_internal_rex64" - [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" - "=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x") - (match_operand:MMXMODEI 1 "vector_move_operand" - "Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))] + [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" + "=rm,r,!?y,!?y ,m ,!y,*Y2,x,x ,m,r,Yi") + (match_operand:MMXMODEI8 1 "vector_move_operand" + "Cr ,m,C ,!?ym,!?y,*Y2,!y,C,xm,x,Yi,r"))] "TARGET_64BIT && TARGET_MMX - && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ - movq\t{%1, %0|%0, %1} - movq\t{%1, %0|%0, %1} + mov{q}\t{%1, %0|%0, %1} + mov{q}\t{%1, %0|%0, %1} pxor\t%0, %0 movq\t{%1, %0|%0, %1} movq\t{%1, %0|%0, %1} movdq2q\t{%1, %0|%0, %1} movq2dq\t{%1, %0|%0, %1} - pxor\t%0, %0 - movq\t{%1, %0|%0, %1} - movq\t{%1, %0|%0, %1} - movd\t{%1, %0|%0, %1} - movd\t{%1, %0|%0, %1}" + %vpxor\t%0, %d0 + %vmovq\t{%1, %0|%0, %1} + %vmovq\t{%1, %0|%0, %1} + %vmovq\t{%1, %0|%0, %1} + %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") + (const_string "orig"))) (set_attr "mode" "DI")]) +(define_insn "*mov_internal_avx" + [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" + "=!?y,!?y,m ,!y ,*Y2,*Y2,*Y2 ,m ,r ,m") + (match_operand:MMXMODEI8 1 "vector_move_operand" + "C ,!ym,!?y,*Y2,!y ,C ,*Y2m,*Y2,irm,r"))] + "TARGET_AVX + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + pxor\t%0, %0 + movq\t{%1, %0|%0, %1} + movq\t{%1, %0|%0, %1} + movdq2q\t{%1, %0|%0, %1} + movq2dq\t{%1, %0|%0, %1} + vpxor\t%0, %0, %0 + vmovq\t{%1, %0|%0, %1} + vmovq\t{%1, %0|%0, %1} + # + #" + [(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") + (const_string "orig"))) + (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,DI,DI")]) + (define_insn "*mov_internal" - [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" - "=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m ,?r ,?m") - (match_operand:MMXMODEI 1 "vector_move_operand" - "C ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x,irm,r"))] + [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" + "=!?y,!?y,m ,!y ,*Y2,*Y2,*Y2 ,m ,*x,*x,*x,m ,r ,m") + (match_operand:MMXMODEI8 1 "vector_move_operand" + "C ,!ym,!?y,*Y2,!y ,C ,*Y2m,*Y2,C ,*x,m ,*x,irm,r"))] "TARGET_MMX - && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ pxor\t%0, %0 movq\t{%1, %0|%0, %1} @@ -110,6 +148,8 @@ #" [(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" @@ -121,16 +161,47 @@ DONE; }) -(define_insn "*movv2sf_internal_rex64" +(define_insn "*movv2sf_internal_rex64_avx" [(set (match_operand:V2SF 0 "nonimmediate_operand" - "=rm,r,*y ,*y ,m ,*y,Y ,x,x,x,m,r,x") + "=rm,r ,!?y,!?y ,m ,!y,Y2,x,x,x,m,r,x") (match_operand:V2SF 1 "vector_move_operand" - "Cr ,m ,C ,*ym,*y,Y ,*y,C,x,m,x,x,r"))] - "TARGET_64BIT && TARGET_MMX - && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" + "Cr ,m ,C ,!?ym,!y,Y2,!y,C,x,m,x,x,r"))] + "TARGET_64BIT && TARGET_AVX + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ + mov{q}\t{%1, %0|%0, %1} + mov{q}\t{%1, %0|%0, %1} + pxor\t%0, %0 movq\t{%1, %0|%0, %1} movq\t{%1, %0|%0, %1} + movdq2q\t{%1, %0|%0, %1} + movq2dq\t{%1, %0|%0, %1} + vxorps\t%0, %0, %0 + vmovaps\t{%1, %0|%0, %1} + vmovlps\t{%1, %0, %0|%0, %0, %1} + vmovlps\t{%1, %0|%0, %1} + vmovq\t{%1, %0|%0, %1} + 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") + (const_string "orig"))) + (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) + +(define_insn "*movv2sf_internal_rex64" + [(set (match_operand:V2SF 0 "nonimmediate_operand" + "=rm,r ,!?y,!?y ,m ,!y,*Y2,x,x,x,m,r,Yi") + (match_operand:V2SF 1 "vector_move_operand" + "Cr ,m ,C ,!?ym,!y,*Y2,!y,C,x,m,x,Yi,r"))] + "TARGET_64BIT && TARGET_MMX + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + mov{q}\t{%1, %0|%0, %1} + mov{q}\t{%1, %0|%0, %1} pxor\t%0, %0 movq\t{%1, %0|%0, %1} movq\t{%1, %0|%0, %1} @@ -144,15 +215,44 @@ 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 (match_operand:V2SF 0 "nonimmediate_operand" + "=!?y,!?y ,m ,!y ,*Y2,*x,*x,*x,m ,r ,m") + (match_operand:V2SF 1 "vector_move_operand" + "C ,!?ym,!?y,*Y2,!y ,C ,*x,m ,*x,irm,r"))] + "TARGET_AVX + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + "@ + pxor\t%0, %0 + movq\t{%1, %0|%0, %1} + movq\t{%1, %0|%0, %1} + movdq2q\t{%1, %0|%0, %1} + movq2dq\t{%1, %0|%0, %1} + vxorps\t%0, %0, %0 + vmovaps\t{%1, %0|%0, %1} + vmovlps\t{%1, %0, %0|%0, %0, %1} + vmovlps\t{%1, %0|%0, %1} + # + #" + [(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") + (const_string "orig"))) + (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) + (define_insn "*movv2sf_internal" [(set (match_operand:V2SF 0 "nonimmediate_operand" - "=*y,*y ,m,*y,*Y,*x,*x,*x,m ,?r ,?m") + "=!?y,!?y ,m ,!y ,*Y2,*x,*x,*x,m ,r ,m") (match_operand:V2SF 1 "vector_move_operand" - "C ,*ym,*y,*Y,*y,C ,*x,m ,*x,irm,r"))] + "C ,!?ym,!?y,*Y2,!y ,C ,*x,m ,*x,irm,r"))] "TARGET_MMX - && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" + && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ pxor\t%0, %0 movq\t{%1, %0|%0, %1} @@ -167,6 +267,7 @@ #" [(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. @@ -211,58 +312,104 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "mmx_addv2sf3" +(define_expand "mmx_addv2sf3" + [(set (match_operand:V2SF 0 "register_operand" "") + (plus:V2SF + (match_operand:V2SF 1 "nonimmediate_operand" "") + (match_operand:V2SF 2 "nonimmediate_operand" "")))] + "TARGET_3DNOW" + "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);") + +(define_insn "*mmx_addv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y") (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)" - "pfadd\\t{%2, %0|%0, %2}" + "pfadd\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) -(define_insn "mmx_subv2sf3" +(define_expand "mmx_subv2sf3" + [(set (match_operand:V2SF 0 "register_operand" "") + (minus:V2SF (match_operand:V2SF 1 "register_operand" "") + (match_operand:V2SF 2 "nonimmediate_operand" "")))] + "TARGET_3DNOW" + "") + +(define_expand "mmx_subrv2sf3" + [(set (match_operand:V2SF 0 "register_operand" "") + (minus:V2SF (match_operand:V2SF 2 "register_operand" "") + (match_operand:V2SF 1 "nonimmediate_operand" "")))] + "TARGET_3DNOW" + "") + +(define_insn "*mmx_subv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y,y") (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym") (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))] "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ - pfsub\\t{%2, %0|%0, %2} - pfsubr\\t{%2, %0|%0, %2}" + pfsub\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_subrv2sf3" +(define_expand "mmx_mulv2sf3" [(set (match_operand:V2SF 0 "register_operand" "") - (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "") - (match_operand:V2SF 1 "nonimmediate_operand" "")))] - "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))" - "") + (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "") + (match_operand:V2SF 2 "nonimmediate_operand" "")))] + "TARGET_3DNOW" + "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);") -(define_insn "mmx_mulv2sf3" +(define_insn "*mmx_mulv2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y") (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)" - "pfmul\\t{%2, %0|%0, %2}" + "pfmul\t{%2, %0|%0, %2}" [(set_attr "type" "mmxmul") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) -(define_insn "mmx_smaxv2sf3" +;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX +;; isn't really correct, as those rtl operators aren't defined when +;; applied to NaNs. Hopefully the optimizers won't get too smart on us. + +(define_expand "mmx_v2sf3" + [(set (match_operand:V2SF 0 "register_operand" "") + (smaxmin:V2SF + (match_operand:V2SF 1 "nonimmediate_operand" "") + (match_operand:V2SF 2 "nonimmediate_operand" "")))] + "TARGET_3DNOW" +{ + if (!flag_finite_math_only) + operands[1] = force_reg (V2SFmode, operands[1]); + ix86_fixup_binary_operands_no_copy (, V2SFmode, operands); +}) + +(define_insn "*mmx_v2sf3_finite" [(set (match_operand:V2SF 0 "register_operand" "=y") - (smax:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") - (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] - "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)" - "pfmax\\t{%2, %0|%0, %2}" + (smaxmin:V2SF + (match_operand:V2SF 1 "nonimmediate_operand" "%0") + (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] + "TARGET_3DNOW && flag_finite_math_only + && ix86_binary_operator_ok (, V2SFmode, operands)" + "pf\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) -(define_insn "mmx_sminv2sf3" +(define_insn "*mmx_v2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y") - (smin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") - (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] - "TARGET_3DNOW && ix86_binary_operator_ok (SMIN, V2SFmode, operands)" - "pfmin\\t{%2, %0|%0, %2}" + (smaxmin:V2SF + (match_operand:V2SF 1 "register_operand" "0") + (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] + "TARGET_3DNOW" + "pf\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_rcpv2sf2" @@ -270,8 +417,9 @@ (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] UNSPEC_PFRCP))] "TARGET_3DNOW" - "pfrcp\\t{%1, %0|%0, %1}" + "pfrcp\t{%1, %0|%0, %1}" [(set_attr "type" "mmx") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_rcpit1v2sf3" @@ -280,8 +428,9 @@ (match_operand:V2SF 2 "nonimmediate_operand" "ym")] UNSPEC_PFRCPIT1))] "TARGET_3DNOW" - "pfrcpit1\\t{%2, %0|%0, %2}" + "pfrcpit1\t{%2, %0|%0, %2}" [(set_attr "type" "mmx") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_rcpit2v2sf3" @@ -290,8 +439,9 @@ (match_operand:V2SF 2 "nonimmediate_operand" "ym")] UNSPEC_PFRCPIT2))] "TARGET_3DNOW" - "pfrcpit2\\t{%2, %0|%0, %2}" + "pfrcpit2\t{%2, %0|%0, %2}" [(set_attr "type" "mmx") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_rsqrtv2sf2" @@ -299,18 +449,20 @@ (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] UNSPEC_PFRSQRT))] "TARGET_3DNOW" - "pfrsqrt\\t{%1, %0|%0, %1}" + "pfrsqrt\t{%1, %0|%0, %1}" [(set_attr "type" "mmx") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) - + (define_insn "mmx_rsqit1v2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y") (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") (match_operand:V2SF 2 "nonimmediate_operand" "ym")] UNSPEC_PFRSQIT1))] "TARGET_3DNOW" - "pfrsqit1\\t{%2, %0|%0, %2}" + "pfrsqit1\t{%2, %0|%0, %2}" [(set_attr "type" "mmx") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_haddv2sf3" @@ -327,8 +479,9 @@ (parallel [(const_int 0)])) (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] "TARGET_3DNOW" - "pfacc\\t{%2, %0|%0, %2}" + "pfacc\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_hsubv2sf3" @@ -345,8 +498,9 @@ (parallel [(const_int 0)])) (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] "TARGET_3DNOW_A" - "pfnacc\\t{%2, %0|%0, %2}" + "pfnacc\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_addsubv2sf3" @@ -358,8 +512,9 @@ (minus:V2SF (match_dup 1) (match_dup 2)) (const_int 1)))] "TARGET_3DNOW_A" - "pfpnacc\\t{%2, %0|%0, %2}" + "pfpnacc\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -368,31 +523,41 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "mmx_gtv2sf3" +(define_expand "mmx_eqv2sf3" + [(set (match_operand:V2SI 0 "register_operand" "") + (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "") + (match_operand:V2SF 2 "nonimmediate_operand" "")))] + "TARGET_3DNOW" + "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);") + +(define_insn "*mmx_eqv2sf3" [(set (match_operand:V2SI 0 "register_operand" "=y") - (gt:V2SI (match_operand:V2SF 1 "register_operand" "0") + (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0") (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] - "TARGET_3DNOW" - "pfcmpgt\\t{%2, %0|%0, %2}" + "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_gev2sf3" +(define_insn "mmx_gtv2sf3" [(set (match_operand:V2SI 0 "register_operand" "=y") - (ge:V2SI (match_operand:V2SF 1 "register_operand" "0") + (gt:V2SI (match_operand:V2SF 1 "register_operand" "0") (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] "TARGET_3DNOW" - "pfcmpge\\t{%2, %0|%0, %2}" + "pfcmpgt\t{%2, %0|%0, %2}" [(set_attr "type" "mmxcmp") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) -(define_insn "mmx_eqv2sf3" +(define_insn "mmx_gev2sf3" [(set (match_operand:V2SI 0 "register_operand" "=y") - (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0") + (ge:V2SI (match_operand:V2SF 1 "register_operand" "0") (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] - "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)" - "pfcmpeq\\t{%2, %0|%0, %2}" + "TARGET_3DNOW" + "pfcmpge\t{%2, %0|%0, %2}" [(set_attr "type" "mmxcmp") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -405,8 +570,9 @@ [(set (match_operand:V2SI 0 "register_operand" "=y") (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))] "TARGET_3DNOW" - "pf2id\\t{%1, %0|%0, %1}" + "pf2id\t{%1, %0|%0, %1}" [(set_attr "type" "mmxcvt") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_pf2iw" @@ -416,8 +582,9 @@ (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))] "TARGET_3DNOW_A" - "pf2iw\\t{%1, %0|%0, %1}" + "pf2iw\t{%1, %0|%0, %1}" [(set_attr "type" "mmxcvt") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_pi2fw" @@ -427,16 +594,18 @@ (truncate:V2HI (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))] "TARGET_3DNOW_A" - "pi2fw\\t{%1, %0|%0, %1}" + "pi2fw\t{%1, %0|%0, %1}" [(set_attr "type" "mmxcvt") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "mmx_floatv2si2" [(set (match_operand:V2SF 0 "register_operand" "=y") (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))] "TARGET_3DNOW" - "pi2fd\\t{%1, %0|%0, %1}" + "pi2fd\t{%1, %0|%0, %1}" [(set_attr "type" "mmxcvt") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -450,8 +619,9 @@ (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym") (parallel [(const_int 1) (const_int 0)])))] "TARGET_3DNOW_A" - "pswapd\\t{%1, %0|%0, %1}" + "pswapd\t{%1, %0|%0, %1}" [(set_attr "type" "mmxcvt") + (set_attr "prefix_extra" "1") (set_attr "mode" "V2SF")]) (define_insn "*vec_dupv2sf" @@ -486,10 +656,12 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn_and_split "*vec_extractv2sf_0" - [(set (match_operand:SF 0 "nonimmediate_operand" "=x,y,m,m,frxy") + [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r") (vec_select:SF - (match_operand:V2SF 1 "nonimmediate_operand" " x,y,x,y,m") + (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m") (parallel [(const_int 0)])))] "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "#" @@ -505,18 +677,23 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "*vec_extractv2sf_1" - [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,frxy") + [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,y,x,f,r") (vec_select:SF - (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o") + (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o") (parallel [(const_int 1)])))] "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ punpckhdq\t%0, %0 unpckhps\t%0, %0 + # + # + # #" - [(set_attr "type" "mmxcvt,sselog1,*") - (set_attr "mode" "DI,V4SF,SI")]) + [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov") + (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")]) (define_split [(set (match_operand:SF 0 "register_operand" "") @@ -557,89 +734,51 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "mmx_add3" - [(set (match_operand:MMXMODEI 0 "register_operand" "=y") - (plus:MMXMODEI - (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") - (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] - "TARGET_MMX && ix86_binary_operator_ok (PLUS, mode, operands)" - "padd\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) - -(define_insn "mmx_adddi3" - [(set (match_operand:DI 0 "register_operand" "=y") - (unspec:DI - [(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") - (match_operand:DI 2 "nonimmediate_operand" "ym"))] - UNSPEC_NOP))] - "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, DImode, operands)" - "paddq\t{%2, %0|%0, %2}" +(define_expand "mmx_3" + [(set (match_operand:MMXMODEI8 0 "register_operand" "") + (plusminus:MMXMODEI8 + (match_operand:MMXMODEI8 1 "nonimmediate_operand" "") + (match_operand:MMXMODEI8 2 "nonimmediate_operand" "")))] + "TARGET_MMX || (TARGET_SSE2 && mode == V1DImode)" + "ix86_fixup_binary_operands_no_copy (, mode, operands);") + +(define_insn "*mmx_3" + [(set (match_operand:MMXMODEI8 0 "register_operand" "=y") + (plusminus:MMXMODEI8 + (match_operand:MMXMODEI8 1 "nonimmediate_operand" "0") + (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))] + "(TARGET_MMX || (TARGET_SSE2 && mode == V1DImode)) + && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") (set_attr "mode" "DI")]) -(define_insn "mmx_ssadd3" - [(set (match_operand:MMXMODE12 0 "register_operand" "=y") - (ss_plus:MMXMODE12 - (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0") - (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] +(define_expand "mmx_3" + [(set (match_operand:MMXMODE12 0 "register_operand" "") + (sat_plusminus:MMXMODE12 + (match_operand:MMXMODE12 1 "nonimmediate_operand" "") + (match_operand:MMXMODE12 2 "nonimmediate_operand" "")))] "TARGET_MMX" - "padds\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) + "ix86_fixup_binary_operands_no_copy (, mode, operands);") -(define_insn "mmx_usadd3" +(define_insn "*mmx_3" [(set (match_operand:MMXMODE12 0 "register_operand" "=y") - (us_plus:MMXMODE12 - (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0") + (sat_plusminus:MMXMODE12 + (match_operand:MMXMODE12 1 "nonimmediate_operand" "0") (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] - "TARGET_MMX" - "paddus\t{%2, %0|%0, %2}" + "TARGET_MMX && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") (set_attr "mode" "DI")]) -(define_insn "mmx_sub3" - [(set (match_operand:MMXMODEI 0 "register_operand" "=y") - (minus:MMXMODEI - (match_operand:MMXMODEI 1 "register_operand" "0") - (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] - "TARGET_MMX" - "psub\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) - -(define_insn "mmx_subdi3" - [(set (match_operand:DI 0 "register_operand" "=y") - (unspec:DI - [(minus:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:DI 2 "nonimmediate_operand" "ym"))] - UNSPEC_NOP))] - "TARGET_SSE2" - "psubq\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) - -(define_insn "mmx_sssub3" - [(set (match_operand:MMXMODE12 0 "register_operand" "=y") - (ss_minus:MMXMODE12 - (match_operand:MMXMODE12 1 "register_operand" "0") - (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] - "TARGET_MMX" - "psubs\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) - -(define_insn "mmx_ussub3" - [(set (match_operand:MMXMODE12 0 "register_operand" "=y") - (us_minus:MMXMODE12 - (match_operand:MMXMODE12 1 "register_operand" "0") - (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] +(define_expand "mmx_mulv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "") + (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "") + (match_operand:V4HI 2 "nonimmediate_operand" "")))] "TARGET_MMX" - "psubus\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) + "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") -(define_insn "mmx_mulv4hi3" +(define_insn "*mmx_mulv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0") (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] @@ -648,28 +787,56 @@ [(set_attr "type" "mmxmul") (set_attr "mode" "DI")]) -(define_insn "mmx_smulv4hi3_highpart" +(define_expand "mmx_smulv4hi3_highpart" + [(set (match_operand:V4HI 0 "register_operand" "") + (truncate:V4HI + (lshiftrt:V4SI + (mult:V4SI + (sign_extend:V4SI + (match_operand:V4HI 1 "nonimmediate_operand" "")) + (sign_extend:V4SI + (match_operand:V4HI 2 "nonimmediate_operand" ""))) + (const_int 16))))] + "TARGET_MMX" + "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") + +(define_insn "*mmx_smulv4hi3_highpart" [(set (match_operand:V4HI 0 "register_operand" "=y") (truncate:V4HI - (lshiftrt:V4SI - (mult:V4SI (sign_extend:V4SI - (match_operand:V4HI 1 "nonimmediate_operand" "%0")) - (sign_extend:V4SI - (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) - (const_int 16))))] + (lshiftrt:V4SI + (mult:V4SI + (sign_extend:V4SI + (match_operand:V4HI 1 "nonimmediate_operand" "%0")) + (sign_extend:V4SI + (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) + (const_int 16))))] "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" "pmulhw\t{%2, %0|%0, %2}" [(set_attr "type" "mmxmul") (set_attr "mode" "DI")]) -(define_insn "mmx_umulv4hi3_highpart" +(define_expand "mmx_umulv4hi3_highpart" + [(set (match_operand:V4HI 0 "register_operand" "") + (truncate:V4HI + (lshiftrt:V4SI + (mult:V4SI + (zero_extend:V4SI + (match_operand:V4HI 1 "nonimmediate_operand" "")) + (zero_extend:V4SI + (match_operand:V4HI 2 "nonimmediate_operand" ""))) + (const_int 16))))] + "TARGET_SSE || TARGET_3DNOW_A" + "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") + +(define_insn "*mmx_umulv4hi3_highpart" [(set (match_operand:V4HI 0 "register_operand" "=y") (truncate:V4HI - (lshiftrt:V4SI - (mult:V4SI (zero_extend:V4SI - (match_operand:V4HI 1 "nonimmediate_operand" "%0")) - (zero_extend:V4SI - (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) + (lshiftrt:V4SI + (mult:V4SI + (zero_extend:V4SI + (match_operand:V4HI 1 "nonimmediate_operand" "%0")) + (zero_extend:V4SI + (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) (const_int 16))))] "(TARGET_SSE || TARGET_3DNOW_A) && ix86_binary_operator_ok (MULT, V4HImode, operands)" @@ -677,7 +844,29 @@ [(set_attr "type" "mmxmul") (set_attr "mode" "DI")]) -(define_insn "mmx_pmaddwd" +(define_expand "mmx_pmaddwd" + [(set (match_operand:V2SI 0 "register_operand" "") + (plus:V2SI + (mult:V2SI + (sign_extend:V2SI + (vec_select:V2HI + (match_operand:V4HI 1 "nonimmediate_operand" "") + (parallel [(const_int 0) (const_int 2)]))) + (sign_extend:V2SI + (vec_select:V2HI + (match_operand:V4HI 2 "nonimmediate_operand" "") + (parallel [(const_int 0) (const_int 2)])))) + (mult:V2SI + (sign_extend:V2SI + (vec_select:V2HI (match_dup 1) + (parallel [(const_int 1) (const_int 3)]))) + (sign_extend:V2SI + (vec_select:V2HI (match_dup 2) + (parallel [(const_int 1) (const_int 3)]))))))] + "TARGET_MMX" + "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") + +(define_insn "*mmx_pmaddwd" [(set (match_operand:V2SI 0 "register_operand" "=y") (plus:V2SI (mult:V2SI @@ -701,7 +890,23 @@ [(set_attr "type" "mmxmul") (set_attr "mode" "DI")]) -(define_insn "mmx_pmulhrwv4hi3" +(define_expand "mmx_pmulhrwv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "") + (truncate:V4HI + (lshiftrt:V4SI + (plus:V4SI + (mult:V4SI + (sign_extend:V4SI + (match_operand:V4HI 1 "nonimmediate_operand" "")) + (sign_extend:V4SI + (match_operand:V4HI 2 "nonimmediate_operand" ""))) + (const_vector:V4SI [(const_int 32768) (const_int 32768) + (const_int 32768) (const_int 32768)])) + (const_int 16))))] + "TARGET_3DNOW" + "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") + +(define_insn "*mmx_pmulhrwv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") (truncate:V4HI (lshiftrt:V4SI @@ -715,19 +920,34 @@ (const_int 32768) (const_int 32768)])) (const_int 16))))] "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)" - "pmulhrw\\t{%2, %0|%0, %2}" + "pmulhrw\t{%2, %0|%0, %2}" [(set_attr "type" "mmxmul") + (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) -(define_insn "sse2_umulsidi3" - [(set (match_operand:DI 0 "register_operand" "=y") - (mult:DI - (zero_extend:DI - (vec_select:SI +(define_expand "sse2_umulv1siv1di3" + [(set (match_operand:V1DI 0 "register_operand" "") + (mult:V1DI + (zero_extend:V1DI + (vec_select:V1SI + (match_operand:V2SI 1 "nonimmediate_operand" "") + (parallel [(const_int 0)]))) + (zero_extend:V1DI + (vec_select:V1SI + (match_operand:V2SI 2 "nonimmediate_operand" "") + (parallel [(const_int 0)])))))] + "TARGET_SSE2" + "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);") + +(define_insn "*sse2_umulv1siv1di3" + [(set (match_operand:V1DI 0 "register_operand" "=y") + (mult:V1DI + (zero_extend:V1DI + (vec_select:V1SI (match_operand:V2SI 1 "nonimmediate_operand" "%0") (parallel [(const_int 0)]))) - (zero_extend:DI - (vec_select:SI + (zero_extend:V1DI + (vec_select:V1SI (match_operand:V2SI 2 "nonimmediate_operand" "ym") (parallel [(const_int 0)])))))] "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)" @@ -735,43 +955,41 @@ [(set_attr "type" "mmxmul") (set_attr "mode" "DI")]) -(define_insn "mmx_umaxv8qi3" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0") - (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] - "(TARGET_SSE || TARGET_3DNOW_A) - && ix86_binary_operator_ok (UMAX, V8QImode, operands)" - "pmaxub\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) +(define_expand "mmx_v4hi3" + [(set (match_operand:V4HI 0 "register_operand" "") + (smaxmin:V4HI + (match_operand:V4HI 1 "nonimmediate_operand" "") + (match_operand:V4HI 2 "nonimmediate_operand" "")))] + "TARGET_SSE || TARGET_3DNOW_A" + "ix86_fixup_binary_operands_no_copy (, V4HImode, operands);") -(define_insn "mmx_smaxv4hi3" +(define_insn "*mmx_v4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") - (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0") - (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] + (smaxmin:V4HI + (match_operand:V4HI 1 "nonimmediate_operand" "%0") + (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] "(TARGET_SSE || TARGET_3DNOW_A) - && ix86_binary_operator_ok (SMAX, V4HImode, operands)" - "pmaxsw\t{%2, %0|%0, %2}" + && ix86_binary_operator_ok (, V4HImode, operands)" + "pw\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") (set_attr "mode" "DI")]) -(define_insn "mmx_uminv8qi3" - [(set (match_operand:V8QI 0 "register_operand" "=y") - (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0") - (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] - "(TARGET_SSE || TARGET_3DNOW_A) - && ix86_binary_operator_ok (UMIN, V8QImode, operands)" - "pminub\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) +(define_expand "mmx_v8qi3" + [(set (match_operand:V8QI 0 "register_operand" "") + (umaxmin:V8QI + (match_operand:V8QI 1 "nonimmediate_operand" "") + (match_operand:V8QI 2 "nonimmediate_operand" "")))] + "TARGET_SSE || TARGET_3DNOW_A" + "ix86_fixup_binary_operands_no_copy (, V8QImode, operands);") -(define_insn "mmx_sminv4hi3" - [(set (match_operand:V4HI 0 "register_operand" "=y") - (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0") - (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] +(define_insn "*mmx_v8qi3" + [(set (match_operand:V8QI 0 "register_operand" "=y") + (umaxmin:V8QI + (match_operand:V8QI 1 "nonimmediate_operand" "%0") + (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] "(TARGET_SSE || TARGET_3DNOW_A) - && ix86_binary_operator_ok (SMIN, V4HImode, operands)" - "pminsw\t{%2, %0|%0, %2}" + && ix86_binary_operator_ok (, V8QImode, operands)" + "pb\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") (set_attr "mode" "DI")]) @@ -779,52 +997,42 @@ [(set (match_operand:MMXMODE24 0 "register_operand" "=y") (ashiftrt:MMXMODE24 (match_operand:MMXMODE24 1 "register_operand" "0") - (match_operand:DI 2 "nonmemory_operand" "yi")))] + (match_operand:SI 2 "nonmemory_operand" "yN")))] "TARGET_MMX" "psra\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_lshr3" - [(set (match_operand:MMXMODE24 0 "register_operand" "=y") - (lshiftrt:MMXMODE24 - (match_operand:MMXMODE24 1 "register_operand" "0") - (match_operand:DI 2 "nonmemory_operand" "yi")))] + [(set (match_operand:MMXMODE248 0 "register_operand" "=y") + (lshiftrt:MMXMODE248 + (match_operand:MMXMODE248 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "yN")))] "TARGET_MMX" "psrl\t{%2, %0|%0, %2}" [(set_attr "type" "mmxshft") - (set_attr "mode" "DI")]) - -(define_insn "mmx_lshrdi3" - [(set (match_operand:DI 0 "register_operand" "=y") - (unspec:DI - [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:DI 2 "nonmemory_operand" "yi"))] - UNSPEC_NOP))] - "TARGET_MMX" - "psrlq\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_ashl3" - [(set (match_operand:MMXMODE24 0 "register_operand" "=y") - (ashift:MMXMODE24 - (match_operand:MMXMODE24 1 "register_operand" "0") - (match_operand:DI 2 "nonmemory_operand" "yi")))] + [(set (match_operand:MMXMODE248 0 "register_operand" "=y") + (ashift:MMXMODE248 + (match_operand:MMXMODE248 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "yN")))] "TARGET_MMX" "psll\t{%2, %0|%0, %2}" [(set_attr "type" "mmxshft") - (set_attr "mode" "DI")]) - -(define_insn "mmx_ashldi3" - [(set (match_operand:DI 0 "register_operand" "=y") - (unspec:DI - [(ashift:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:DI 2 "nonmemory_operand" "yi"))] - UNSPEC_NOP))] - "TARGET_MMX" - "psllq\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")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -833,7 +1041,15 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "mmx_eq3" +(define_expand "mmx_eq3" + [(set (match_operand:MMXMODEI 0 "register_operand" "") + (eq:MMXMODEI + (match_operand:MMXMODEI 1 "nonimmediate_operand" "") + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))] + "TARGET_MMX" + "ix86_fixup_binary_operands_no_copy (EQ, mode, operands);") + +(define_insn "*mmx_eq3" [(set (match_operand:MMXMODEI 0 "register_operand" "=y") (eq:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") @@ -859,17 +1075,7 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "mmx_and3" - [(set (match_operand:MMXMODEI 0 "register_operand" "=y") - (and:MMXMODEI - (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") - (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] - "TARGET_MMX && ix86_binary_operator_ok (AND, mode, operands)" - "pand\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) - -(define_insn "mmx_nand3" +(define_insn "mmx_andnot3" [(set (match_operand:MMXMODEI 0 "register_operand" "=y") (and:MMXMODEI (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0")) @@ -879,26 +1085,23 @@ [(set_attr "type" "mmxadd") (set_attr "mode" "DI")]) -(define_insn "mmx_ior3" - [(set (match_operand:MMXMODEI 0 "register_operand" "=y") - (ior:MMXMODEI - (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") - (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] - "TARGET_MMX && ix86_binary_operator_ok (IOR, mode, operands)" - "por\t{%2, %0|%0, %2}" - [(set_attr "type" "mmxadd") - (set_attr "mode" "DI")]) +(define_expand "mmx_3" + [(set (match_operand:MMXMODEI 0 "register_operand" "") + (any_logic:MMXMODEI + (match_operand:MMXMODEI 1 "nonimmediate_operand" "") + (match_operand:MMXMODEI 2 "nonimmediate_operand" "")))] + "TARGET_MMX" + "ix86_fixup_binary_operands_no_copy (, mode, operands);") -(define_insn "mmx_xor3" +(define_insn "*mmx_3" [(set (match_operand:MMXMODEI 0 "register_operand" "=y") - (xor:MMXMODEI + (any_logic:MMXMODEI (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] - "TARGET_MMX && ix86_binary_operator_ok (XOR, mode, operands)" - "pxor\t{%2, %0|%0, %2}" + "TARGET_MMX && ix86_binary_operator_ok (, mode, operands)" + "p\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") - (set_attr "mode" "DI") - (set_attr "memory" "none")]) + (set_attr "mode" "DI")]) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; @@ -1047,9 +1250,13 @@ "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" @@ -1061,6 +1268,7 @@ "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" @@ -1098,6 +1306,7 @@ 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" @@ -1106,8 +1315,9 @@ (match_operand:V2SI 1 "nonimmediate_operand" "ym") (parallel [(const_int 1) (const_int 0)])))] "TARGET_3DNOW_A" - "pswapd\\t{%1, %0|%0, %1}" + "pswapd\t{%1, %0|%0, %1}" [(set_attr "type" "mmxcvt") + (set_attr "prefix_extra" "1") (set_attr "mode" "DI")]) (define_insn "*vec_dupv4hi" @@ -1118,6 +1328,7 @@ "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" @@ -1152,10 +1363,12 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn_and_split "*vec_extractv2si_0" - [(set (match_operand:SI 0 "nonimmediate_operand" "=x,y,m,m,frxy") + [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r") (vec_select:SI - (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m") + (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m") (parallel [(const_int 0)])))] "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "#" @@ -1171,10 +1384,12 @@ DONE; }) +;; Avoid combining registers from different units in a single alternative, +;; see comment above inline_secondary_memory_needed function in i386.c (define_insn "*vec_extractv2si_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y,Y,x,frxy") + [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y2,Y2,x,y,x,r") (vec_select:SI - (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,Y,0,o") + (match_operand:V2SI 1 "nonimmediate_operand" " 0,0 ,Y2,0,o,o,o") (parallel [(const_int 1)])))] "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" "@ @@ -1182,9 +1397,12 @@ punpckhdq\t%0, %0 pshufd\t{$85, %1, %0|%0, %1, 85} unpckhps\t%0, %0 + # + # #" - [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*") - (set_attr "mode" "DI,TI,TI,V4SF,SI")]) + [(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 [(set (match_operand:SI 0 "register_operand" "") @@ -1287,7 +1505,25 @@ ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(define_insn "mmx_uavgv8qi3" +(define_expand "mmx_uavgv8qi3" + [(set (match_operand:V8QI 0 "register_operand" "") + (truncate:V8QI + (lshiftrt:V8HI + (plus:V8HI + (plus:V8HI + (zero_extend:V8HI + (match_operand:V8QI 1 "nonimmediate_operand" "")) + (zero_extend:V8HI + (match_operand:V8QI 2 "nonimmediate_operand" ""))) + (const_vector:V8HI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_SSE || TARGET_3DNOW" + "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);") + +(define_insn "*mmx_uavgv8qi3" [(set (match_operand:V8QI 0 "register_operand" "=y") (truncate:V8QI (lshiftrt:V8HI @@ -1310,12 +1546,33 @@ if (TARGET_SSE || TARGET_3DNOW_A) return "pavgb\t{%2, %0|%0, %2}"; else - return "pavgusb\\t{%2, %0|%0, %2}"; + 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_insn "mmx_uavgv4hi3" +(define_expand "mmx_uavgv4hi3" + [(set (match_operand:V4HI 0 "register_operand" "") + (truncate:V4HI + (lshiftrt:V4SI + (plus:V4SI + (plus:V4SI + (zero_extend:V4SI + (match_operand:V4HI 1 "nonimmediate_operand" "")) + (zero_extend:V4SI + (match_operand:V4HI 2 "nonimmediate_operand" ""))) + (const_vector:V4SI [(const_int 1) (const_int 1) + (const_int 1) (const_int 1)])) + (const_int 1))))] + "TARGET_SSE || TARGET_3DNOW_A" + "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);") + +(define_insn "*mmx_uavgv4hi3" [(set (match_operand:V4HI 0 "register_operand" "=y") (truncate:V4HI (lshiftrt:V4SI @@ -1335,10 +1592,10 @@ (set_attr "mode" "DI")]) (define_insn "mmx_psadbw" - [(set (match_operand:DI 0 "register_operand" "=y") - (unspec:DI [(match_operand:V8QI 1 "register_operand" "0") - (match_operand:V8QI 2 "nonimmediate_operand" "ym")] - UNSPEC_PSADBW))] + [(set (match_operand:V1DI 0 "register_operand" "=y") + (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0") + (match_operand:V8QI 2 "nonimmediate_operand" "ym")] + UNSPEC_PSADBW))] "TARGET_SSE || TARGET_3DNOW_A" "psadbw\t{%2, %0|%0, %2}" [(set_attr "type" "mmxshft") @@ -1355,8 +1612,8 @@ (define_expand "mmx_maskmovq" [(set (match_operand:V8QI 0 "memory_operand" "") - (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") - (match_operand:V8QI 2 "register_operand" "y") + (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "") + (match_operand:V8QI 2 "register_operand" "") (match_dup 0)] UNSPEC_MASKMOV))] "TARGET_SSE || TARGET_3DNOW_A" @@ -1386,48 +1643,68 @@ [(set_attr "type" "mmxcvt") (set_attr "mode" "DI")]) -(define_insn "mmx_emms" - [(unspec_volatile [(const_int 0)] UNSPECV_EMMS) - (clobber (reg:XF 8)) - (clobber (reg:XF 9)) - (clobber (reg:XF 10)) - (clobber (reg:XF 11)) - (clobber (reg:XF 12)) - (clobber (reg:XF 13)) - (clobber (reg:XF 14)) - (clobber (reg:XF 15)) - (clobber (reg:DI 29)) - (clobber (reg:DI 30)) - (clobber (reg:DI 31)) - (clobber (reg:DI 32)) - (clobber (reg:DI 33)) - (clobber (reg:DI 34)) - (clobber (reg:DI 35)) - (clobber (reg:DI 36))] +(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 8)) - (clobber (reg:XF 9)) - (clobber (reg:XF 10)) - (clobber (reg:XF 11)) - (clobber (reg:XF 12)) - (clobber (reg:XF 13)) - (clobber (reg:XF 14)) - (clobber (reg:XF 15)) - (clobber (reg:DI 29)) - (clobber (reg:DI 30)) - (clobber (reg:DI 31)) - (clobber (reg:DI 32)) - (clobber (reg:DI 33)) - (clobber (reg:DI 34)) - (clobber (reg:DI 35)) - (clobber (reg:DI 36))] + (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 "memory" "none")]) + (set_attr "modrm" "0") + (set_attr "memory" "none")])