;; GCC machine description for MMX and 3dNOW! instructions
-;; Copyright (C) 2005, 2007
+;; Copyright (C) 2005, 2007, 2008, 2009
;; Free Software Foundation, Inc.
;;
;; This file is part of GCC.
(define_insn "*mov<mode>_internal_rex64"
[(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
- "=rm,r,!?y,!?y ,m ,!y,Y2,x,x ,m,r,x")
+ "=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,x,r"))]
+ "Cr ,m,C ,!?ym,!?y,*Y2,!y,C,xm,x,Yi,r"))]
"TARGET_64BIT && TARGET_MMX
&& !(MEM_P (operands[0]) && MEM_P (operands[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<mode>_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<mode>_internal"
[(set (match_operand:MMXMODEI8 0 "nonimmediate_operand"
"=!?y,!?y,m ,!y ,*Y2,*Y2,*Y2 ,m ,*x,*x,*x,m ,r ,m")
#"
[(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"
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,Y2,x,x,x,m,r,x")
(match_operand:V2SF 1 "vector_move_operand"
"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]))"
"@
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 ,*Y2,*x,*x,*x,m ,r ,m")
#"
[(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.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(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_<code>v2sf3"
+;; ??? 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_<code>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 (<CODE>, V2SFmode, operands);
+})
+
+(define_insn "*mmx_<code>v2sf3_finite"
[(set (match_operand:V2SF 0 "register_operand" "=y")
(smaxmin:V2SF
(match_operand:V2SF 1 "nonimmediate_operand" "%0")
(match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
- "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)"
- "pf<maxminfprefix>\\t{%2, %0|%0, %2}"
+ "TARGET_3DNOW && flag_finite_math_only
+ && 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"
+ [(set (match_operand:V2SF 0 "register_operand" "=y")
+ (smaxmin:V2SF
+ (match_operand:V2SF 1 "register_operand" "0")
+ (match_operand:V2SF 2 "nonimmediate_operand" "ym")))]
+ "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"
(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"
(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"
(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"
(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"
(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"
(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"
(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"
(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")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(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")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[(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"
(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"
(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")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(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"
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]))"
"#"
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" "")
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define_insn "mmx_add<mode>3"
+(define_expand "mmx_<plusminus_insn><mode>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>mode == V1DImode)"
+ "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
+
+(define_insn "*mmx_<plusminus_insn><mode>3"
[(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
- (plus:MMXMODEI8
- (match_operand:MMXMODEI8 1 "nonimmediate_operand" "%0")
+ (plusminus:MMXMODEI8
+ (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0")
(match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
"(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))
- && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
- "padd<mmxvecsize>\t{%2, %0|%0, %2}"
- [(set_attr "type" "mmxadd")
- (set_attr "mode" "DI")])
-
-(define_insn "mmx_ssadd<mode>3"
- [(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")))]
- "TARGET_MMX"
- "padds<mmxvecsize>\t{%2, %0|%0, %2}"
+ && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
(set_attr "mode" "DI")])
-(define_insn "mmx_usadd<mode>3"
- [(set (match_operand:MMXMODE12 0 "register_operand" "=y")
- (us_plus:MMXMODE12
- (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0")
- (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
+(define_expand "mmx_<plusminus_insn><mode>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"
- "paddus<mmxvecsize>\t{%2, %0|%0, %2}"
- [(set_attr "type" "mmxadd")
- (set_attr "mode" "DI")])
-
-(define_insn "mmx_sub<mode>3"
- [(set (match_operand:MMXMODEI8 0 "register_operand" "=y")
- (minus:MMXMODEI8
- (match_operand:MMXMODEI8 1 "register_operand" "0")
- (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))]
- "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode))"
- "psub<mmxvecsize>\t{%2, %0|%0, %2}"
- [(set_attr "type" "mmxadd")
- (set_attr "mode" "DI")])
+ "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
-(define_insn "mmx_sssub<mode>3"
+(define_insn "*mmx_<plusminus_insn><mode>3"
[(set (match_operand:MMXMODE12 0 "register_operand" "=y")
- (ss_minus:MMXMODE12
- (match_operand:MMXMODE12 1 "register_operand" "0")
+ (sat_plusminus:MMXMODE12
+ (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0")
(match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))]
- "TARGET_MMX"
- "psubs<mmxvecsize>\t{%2, %0|%0, %2}"
+ "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
+ "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
(set_attr "mode" "DI")])
-(define_insn "mmx_ussub<mode>3"
- [(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<mmxvecsize>\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")))]
[(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)"
[(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
[(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
(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_umulv1siv1di3"
+(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
[(set_attr "type" "mmxmul")
(set_attr "mode" "DI")])
-(define_insn "mmx_<code>v4hi3"
+(define_expand "mmx_<code>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 (<CODE>, V4HImode, operands);")
+
+(define_insn "*mmx_<code>v4hi3"
[(set (match_operand:V4HI 0 "register_operand" "=y")
(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)"
+ && ix86_binary_operator_ok (<CODE>, V4HImode, operands)"
"p<maxminiprefix>w\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
(set_attr "mode" "DI")])
-(define_insn "mmx_<code>v8qi3"
+(define_expand "mmx_<code>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 (<CODE>, V8QImode, operands);")
+
+(define_insn "*mmx_<code>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 (UMIN, V8QImode, operands)"
+ && ix86_binary_operator_ok (<CODE>, V8QImode, operands)"
"p<maxminiprefix>b\t{%2, %0|%0, %2}"
[(set_attr "type" "mmxadd")
(set_attr "mode" "DI")])
"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_insn "mmx_eq<mode>3"
+(define_expand "mmx_eq<mode>3"
+ [(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>mode, operands);")
+
+(define_insn "*mmx_eq<mode>3"
[(set (match_operand:MMXMODEI 0 "register_operand" "=y")
(eq:MMXMODEI
(match_operand:MMXMODEI 1 "nonimmediate_operand" "%0")
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define_insn "mmx_nand<mode>3"
+(define_insn "mmx_andnot<mode>3"
[(set (match_operand:MMXMODEI 0 "register_operand" "=y")
(and:MMXMODEI
(not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0"))
[(set_attr "type" "mmxadd")
(set_attr "mode" "DI")])
-(define_insn "mmx_<code><mode>3"
+(define_expand "mmx_<code><mode>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 (<CODE>, <MODE>mode, operands);")
+
+(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"
(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"
"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"
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]))"
"#"
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,Y2,Y2,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 ,Y2,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]))"
"@
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" "")
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(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
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
[(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 "modrm" "0")
(set_attr "memory" "none")])