1;; GCC machine description for MMX and 3dNOW! instructions 2;; Copyright (C) 2005 3;; Free Software Foundation, Inc. 4;; 5;; This file is part of GCC. 6;; 7;; GCC is free software; you can redistribute it and/or modify 8;; it under the terms of the GNU General Public License as published by 9;; the Free Software Foundation; either version 2, or (at your option) 10;; any later version. 11;; 12;; GCC is distributed in the hope that it will be useful, 13;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15;; GNU General Public License for more details. 16;; 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING. If not, write to 19;; the Free Software Foundation, 51 Franklin Street, Fifth Floor, 20;; Boston, MA 02110-1301, USA. 21 22;; The MMX and 3dNOW! patterns are in the same file because they use 23;; the same register file, and 3dNOW! adds a number of extensions to 24;; the base integer MMX isa. 25 26;; Note! Except for the basic move instructions, *all* of these 27;; patterns are outside the normal optabs namespace. This is because 28;; use of these registers requires the insertion of emms or femms 29;; instructions to return to normal fpu mode. The compiler doesn't 30;; know how to do that itself, which means it's up to the user. Which 31;; means that we should never use any of these patterns except at the 32;; direction of the user via a builtin. 33 34;; 8 byte integral modes handled by MMX (and by extension, SSE) 35(define_mode_macro MMXMODEI [V8QI V4HI V2SI]) 36 37;; All 8-byte vector modes handled by MMX 38(define_mode_macro MMXMODE [V8QI V4HI V2SI V2SF]) 39 40;; Mix-n-match 41(define_mode_macro MMXMODE12 [V8QI V4HI]) 42(define_mode_macro MMXMODE24 [V4HI V2SI]) 43 44;; Mapping from integer vector mode to mnemonic suffix 45(define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (DI "q")]) 46 47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 48;; 49;; Move patterns 50;; 51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 52 53;; All of these patterns are enabled for MMX as well as 3dNOW. 54;; This is essential for maintaining stable calling conventions. 55 56(define_expand "mov<mode>" 57 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" "") 58 (match_operand:MMXMODEI 1 "nonimmediate_operand" ""))] 59 "TARGET_MMX" 60{ 61 ix86_expand_vector_move (<MODE>mode, operands); 62 DONE; 63}) 64 65(define_insn "*mov<mode>_internal_rex64" 66 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" 67 "=rm,r,*y,*y ,m ,*y,Y ,x,x ,m,r,x") 68 (match_operand:MMXMODEI 1 "vector_move_operand" 69 "Cr ,m,C ,*ym,*y,Y ,*y,C,xm,x,x,r"))] 70 "TARGET_64BIT && TARGET_MMX 71 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 72 "@ 73 movq\t{%1, %0|%0, %1} 74 movq\t{%1, %0|%0, %1} 75 pxor\t%0, %0 76 movq\t{%1, %0|%0, %1} 77 movq\t{%1, %0|%0, %1} 78 movdq2q\t{%1, %0|%0, %1} 79 movq2dq\t{%1, %0|%0, %1} 80 pxor\t%0, %0 81 movq\t{%1, %0|%0, %1} 82 movq\t{%1, %0|%0, %1} 83 movd\t{%1, %0|%0, %1} 84 movd\t{%1, %0|%0, %1}" 85 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,ssemov") 86 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*") 87 (set_attr "mode" "DI")]) 88 89(define_insn "*mov<mode>_internal" 90 [(set (match_operand:MMXMODEI 0 "nonimmediate_operand" 91 "=*y,*y ,m ,*y,*Y,*Y,*Y ,m ,*x,*x,*x,m ,?r ,?m") 92 (match_operand:MMXMODEI 1 "vector_move_operand" 93 "C ,*ym,*y,*Y,*y,C ,*Ym,*Y,C ,*x,m ,*x,irm,r"))] 94 "TARGET_MMX 95 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 96 "@ 97 pxor\t%0, %0 98 movq\t{%1, %0|%0, %1} 99 movq\t{%1, %0|%0, %1} 100 movdq2q\t{%1, %0|%0, %1} 101 movq2dq\t{%1, %0|%0, %1} 102 pxor\t%0, %0 103 movq\t{%1, %0|%0, %1} 104 movq\t{%1, %0|%0, %1} 105 xorps\t%0, %0 106 movaps\t{%1, %0|%0, %1} 107 movlps\t{%1, %0|%0, %1} 108 movlps\t{%1, %0|%0, %1} 109 # 110 #" 111 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov,*,*") 112 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*,*,*,*") 113 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) 114 115(define_expand "movv2sf" 116 [(set (match_operand:V2SF 0 "nonimmediate_operand" "") 117 (match_operand:V2SF 1 "nonimmediate_operand" ""))] 118 "TARGET_MMX" 119{ 120 ix86_expand_vector_move (V2SFmode, operands); 121 DONE; 122}) 123 124(define_insn "*movv2sf_internal_rex64" 125 [(set (match_operand:V2SF 0 "nonimmediate_operand" 126 "=rm,r,*y ,*y ,m ,*y,Y ,x,x,x,m,r,x") 127 (match_operand:V2SF 1 "vector_move_operand" 128 "Cr ,m ,C ,*ym,*y,Y ,*y,C,x,m,x,x,r"))] 129 "TARGET_64BIT && TARGET_MMX 130 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 131 "@ 132 movq\t{%1, %0|%0, %1} 133 movq\t{%1, %0|%0, %1} 134 pxor\t%0, %0 135 movq\t{%1, %0|%0, %1} 136 movq\t{%1, %0|%0, %1} 137 movdq2q\t{%1, %0|%0, %1} 138 movq2dq\t{%1, %0|%0, %1} 139 xorps\t%0, %0 140 movaps\t{%1, %0|%0, %1} 141 movlps\t{%1, %0|%0, %1} 142 movlps\t{%1, %0|%0, %1} 143 movd\t{%1, %0|%0, %1} 144 movd\t{%1, %0|%0, %1}" 145 [(set_attr "type" "imov,imov,mmx,mmxmov,mmxmov,ssecvt,ssecvt,ssemov,sselog1,ssemov,ssemov,ssemov,ssemov") 146 (set_attr "unit" "*,*,*,*,*,mmx,mmx,*,*,*,*,*,*") 147 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) 148 149(define_insn "*movv2sf_internal" 150 [(set (match_operand:V2SF 0 "nonimmediate_operand" 151 "=*y,*y ,m,*y,*Y,*x,*x,*x,m ,?r ,?m") 152 (match_operand:V2SF 1 "vector_move_operand" 153 "C ,*ym,*y,*Y,*y,C ,*x,m ,*x,irm,r"))] 154 "TARGET_MMX 155 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" 156 "@ 157 pxor\t%0, %0 158 movq\t{%1, %0|%0, %1} 159 movq\t{%1, %0|%0, %1} 160 movdq2q\t{%1, %0|%0, %1} 161 movq2dq\t{%1, %0|%0, %1} 162 xorps\t%0, %0 163 movaps\t{%1, %0|%0, %1} 164 movlps\t{%1, %0|%0, %1} 165 movlps\t{%1, %0|%0, %1} 166 # 167 #" 168 [(set_attr "type" "mmx,mmxmov,mmxmov,ssecvt,ssecvt,sselog1,ssemov,ssemov,ssemov,*,*") 169 (set_attr "unit" "*,*,*,mmx,mmx,*,*,*,*,*,*") 170 (set_attr "mode" "DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) 171 172;; %%% This multiword shite has got to go. 173(define_split 174 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "") 175 (match_operand:MMXMODE 1 "general_operand" ""))] 176 "!TARGET_64BIT && reload_completed 177 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0])) 178 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))" 179 [(const_int 0)] 180 "ix86_split_long_move (operands); DONE;") 181 182(define_expand "push<mode>1" 183 [(match_operand:MMXMODE 0 "register_operand" "")] 184 "TARGET_MMX" 185{ 186 ix86_expand_push (<MODE>mode, operands[0]); 187 DONE; 188}) 189 190(define_expand "movmisalign<mode>" 191 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" "") 192 (match_operand:MMXMODE 1 "nonimmediate_operand" ""))] 193 "TARGET_MMX" 194{ 195 ix86_expand_vector_move (<MODE>mode, operands); 196 DONE; 197}) 198 199(define_insn "sse_movntdi" 200 [(set (match_operand:DI 0 "memory_operand" "=m") 201 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 202 UNSPEC_MOVNT))] 203 "TARGET_SSE || TARGET_3DNOW_A" 204 "movntq\t{%1, %0|%0, %1}" 205 [(set_attr "type" "mmxmov") 206 (set_attr "mode" "DI")]) 207 208;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 209;; 210;; Parallel single-precision floating point arithmetic 211;; 212;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 213 214(define_insn "mmx_addv2sf3" 215 [(set (match_operand:V2SF 0 "register_operand" "=y") 216 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") 217 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 218 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)" 219 "pfadd\\t{%2, %0|%0, %2}" 220 [(set_attr "type" "mmxadd") 221 (set_attr "mode" "V2SF")]) 222 223(define_insn "mmx_subv2sf3" 224 [(set (match_operand:V2SF 0 "register_operand" "=y,y") 225 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym") 226 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))] 227 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 228 "@ 229 pfsub\\t{%2, %0|%0, %2} 230 pfsubr\\t{%2, %0|%0, %2}" 231 [(set_attr "type" "mmxadd") 232 (set_attr "mode" "V2SF")]) 233 234(define_expand "mmx_subrv2sf3" 235 [(set (match_operand:V2SF 0 "register_operand" "") 236 (minus:V2SF (match_operand:V2SF 2 "nonimmediate_operand" "") 237 (match_operand:V2SF 1 "nonimmediate_operand" "")))] 238 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 239 "") 240 241(define_insn "mmx_mulv2sf3" 242 [(set (match_operand:V2SF 0 "register_operand" "=y") 243 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") 244 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 245 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)" 246 "pfmul\\t{%2, %0|%0, %2}" 247 [(set_attr "type" "mmxmul") 248 (set_attr "mode" "V2SF")]) 249 250(define_insn "mmx_smaxv2sf3" 251 [(set (match_operand:V2SF 0 "register_operand" "=y") 252 (smax:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") 253 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 254 "TARGET_3DNOW && ix86_binary_operator_ok (SMAX, V2SFmode, operands)" 255 "pfmax\\t{%2, %0|%0, %2}" 256 [(set_attr "type" "mmxadd") 257 (set_attr "mode" "V2SF")]) 258 259(define_insn "mmx_sminv2sf3" 260 [(set (match_operand:V2SF 0 "register_operand" "=y") 261 (smin:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") 262 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 263 "TARGET_3DNOW && ix86_binary_operator_ok (SMIN, V2SFmode, operands)" 264 "pfmin\\t{%2, %0|%0, %2}" 265 [(set_attr "type" "mmxadd") 266 (set_attr "mode" "V2SF")]) 267 268(define_insn "mmx_rcpv2sf2" 269 [(set (match_operand:V2SF 0 "register_operand" "=y") 270 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 271 UNSPEC_PFRCP))] 272 "TARGET_3DNOW" 273 "pfrcp\\t{%1, %0|%0, %1}" 274 [(set_attr "type" "mmx") 275 (set_attr "mode" "V2SF")]) 276 277(define_insn "mmx_rcpit1v2sf3" 278 [(set (match_operand:V2SF 0 "register_operand" "=y") 279 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 280 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 281 UNSPEC_PFRCPIT1))] 282 "TARGET_3DNOW" 283 "pfrcpit1\\t{%2, %0|%0, %2}" 284 [(set_attr "type" "mmx") 285 (set_attr "mode" "V2SF")]) 286 287(define_insn "mmx_rcpit2v2sf3" 288 [(set (match_operand:V2SF 0 "register_operand" "=y") 289 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 290 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 291 UNSPEC_PFRCPIT2))] 292 "TARGET_3DNOW" 293 "pfrcpit2\\t{%2, %0|%0, %2}" 294 [(set_attr "type" "mmx") 295 (set_attr "mode" "V2SF")]) 296 297(define_insn "mmx_rsqrtv2sf2" 298 [(set (match_operand:V2SF 0 "register_operand" "=y") 299 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 300 UNSPEC_PFRSQRT))] 301 "TARGET_3DNOW" 302 "pfrsqrt\\t{%1, %0|%0, %1}" 303 [(set_attr "type" "mmx") 304 (set_attr "mode" "V2SF")]) 305 306(define_insn "mmx_rsqit1v2sf3" 307 [(set (match_operand:V2SF 0 "register_operand" "=y") 308 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 309 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 310 UNSPEC_PFRSQIT1))] 311 "TARGET_3DNOW" 312 "pfrsqit1\\t{%2, %0|%0, %2}" 313 [(set_attr "type" "mmx") 314 (set_attr "mode" "V2SF")]) 315 316(define_insn "mmx_haddv2sf3" 317 [(set (match_operand:V2SF 0 "register_operand" "=y") 318 (vec_concat:V2SF 319 (plus:SF 320 (vec_select:SF 321 (match_operand:V2SF 1 "register_operand" "0") 322 (parallel [(const_int 0)])) 323 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) 324 (plus:SF 325 (vec_select:SF 326 (match_operand:V2SF 2 "nonimmediate_operand" "ym") 327 (parallel [(const_int 0)])) 328 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] 329 "TARGET_3DNOW" 330 "pfacc\\t{%2, %0|%0, %2}" 331 [(set_attr "type" "mmxadd") 332 (set_attr "mode" "V2SF")]) 333 334(define_insn "mmx_hsubv2sf3" 335 [(set (match_operand:V2SF 0 "register_operand" "=y") 336 (vec_concat:V2SF 337 (minus:SF 338 (vec_select:SF 339 (match_operand:V2SF 1 "register_operand" "0") 340 (parallel [(const_int 0)])) 341 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) 342 (minus:SF 343 (vec_select:SF 344 (match_operand:V2SF 2 "nonimmediate_operand" "ym") 345 (parallel [(const_int 0)])) 346 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] 347 "TARGET_3DNOW_A" 348 "pfnacc\\t{%2, %0|%0, %2}" 349 [(set_attr "type" "mmxadd") 350 (set_attr "mode" "V2SF")]) 351 352(define_insn "mmx_addsubv2sf3" 353 [(set (match_operand:V2SF 0 "register_operand" "=y") 354 (vec_merge:V2SF 355 (plus:V2SF 356 (match_operand:V2SF 1 "register_operand" "0") 357 (match_operand:V2SF 2 "nonimmediate_operand" "ym")) 358 (minus:V2SF (match_dup 1) (match_dup 2)) 359 (const_int 1)))] 360 "TARGET_3DNOW_A" 361 "pfpnacc\\t{%2, %0|%0, %2}" 362 [(set_attr "type" "mmxadd") 363 (set_attr "mode" "V2SF")]) 364 365;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 366;; 367;; Parallel single-precision floating point comparisons 368;; 369;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 370 371(define_insn "mmx_gtv2sf3" 372 [(set (match_operand:V2SI 0 "register_operand" "=y") 373 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0") 374 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 375 "TARGET_3DNOW" 376 "pfcmpgt\\t{%2, %0|%0, %2}" 377 [(set_attr "type" "mmxcmp") 378 (set_attr "mode" "V2SF")]) 379 380(define_insn "mmx_gev2sf3" 381 [(set (match_operand:V2SI 0 "register_operand" "=y") 382 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0") 383 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 384 "TARGET_3DNOW" 385 "pfcmpge\\t{%2, %0|%0, %2}" 386 [(set_attr "type" "mmxcmp") 387 (set_attr "mode" "V2SF")]) 388 389(define_insn "mmx_eqv2sf3" 390 [(set (match_operand:V2SI 0 "register_operand" "=y") 391 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0") 392 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 393 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)" 394 "pfcmpeq\\t{%2, %0|%0, %2}" 395 [(set_attr "type" "mmxcmp") 396 (set_attr "mode" "V2SF")]) 397 398;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 399;; 400;; Parallel single-precision floating point conversion operations 401;; 402;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 403 404(define_insn "mmx_pf2id" 405 [(set (match_operand:V2SI 0 "register_operand" "=y") 406 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))] 407 "TARGET_3DNOW" 408 "pf2id\\t{%1, %0|%0, %1}" 409 [(set_attr "type" "mmxcvt") 410 (set_attr "mode" "V2SF")]) 411 412(define_insn "mmx_pf2iw" 413 [(set (match_operand:V2SI 0 "register_operand" "=y") 414 (sign_extend:V2SI 415 (ss_truncate:V2HI 416 (fix:V2SI 417 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))] 418 "TARGET_3DNOW_A" 419 "pf2iw\\t{%1, %0|%0, %1}" 420 [(set_attr "type" "mmxcvt") 421 (set_attr "mode" "V2SF")]) 422 423(define_insn "mmx_pi2fw" 424 [(set (match_operand:V2SF 0 "register_operand" "=y") 425 (float:V2SF 426 (sign_extend:V2SI 427 (truncate:V2HI 428 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))] 429 "TARGET_3DNOW_A" 430 "pi2fw\\t{%1, %0|%0, %1}" 431 [(set_attr "type" "mmxcvt") 432 (set_attr "mode" "V2SF")]) 433 434(define_insn "mmx_floatv2si2" 435 [(set (match_operand:V2SF 0 "register_operand" "=y") 436 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))] 437 "TARGET_3DNOW" 438 "pi2fd\\t{%1, %0|%0, %1}" 439 [(set_attr "type" "mmxcvt") 440 (set_attr "mode" "V2SF")]) 441 442;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 443;; 444;; Parallel single-precision floating point element swizzling 445;; 446;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 447 448(define_insn "mmx_pswapdv2sf2" 449 [(set (match_operand:V2SF 0 "register_operand" "=y") 450 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym") 451 (parallel [(const_int 1) (const_int 0)])))] 452 "TARGET_3DNOW_A" 453 "pswapd\\t{%1, %0|%0, %1}" 454 [(set_attr "type" "mmxcvt") 455 (set_attr "mode" "V2SF")]) 456 457(define_insn "*vec_dupv2sf" 458 [(set (match_operand:V2SF 0 "register_operand" "=y") 459 (vec_duplicate:V2SF 460 (match_operand:SF 1 "register_operand" "0")))] 461 "TARGET_MMX" 462 "punpckldq\t%0, %0" 463 [(set_attr "type" "mmxcvt") 464 (set_attr "mode" "DI")]) 465 466(define_insn "*mmx_concatv2sf" 467 [(set (match_operand:V2SF 0 "register_operand" "=y,y") 468 (vec_concat:V2SF 469 (match_operand:SF 1 "nonimmediate_operand" " 0,rm") 470 (match_operand:SF 2 "vector_move_operand" "ym,C")))] 471 "TARGET_MMX && !TARGET_SSE" 472 "@ 473 punpckldq\t{%2, %0|%0, %2} 474 movd\t{%1, %0|%0, %1}" 475 [(set_attr "type" "mmxcvt,mmxmov") 476 (set_attr "mode" "DI")]) 477 478(define_expand "vec_setv2sf" 479 [(match_operand:V2SF 0 "register_operand" "") 480 (match_operand:SF 1 "register_operand" "") 481 (match_operand 2 "const_int_operand" "")] 482 "TARGET_MMX" 483{ 484 ix86_expand_vector_set (false, operands[0], operands[1], 485 INTVAL (operands[2])); 486 DONE; 487}) 488 489(define_insn_and_split "*vec_extractv2sf_0" 490 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,y,m,m,frxy") 491 (vec_select:SF 492 (match_operand:V2SF 1 "nonimmediate_operand" " x,y,x,y,m") 493 (parallel [(const_int 0)])))] 494 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 495 "#" 496 "&& reload_completed" 497 [(const_int 0)] 498{ 499 rtx op1 = operands[1]; 500 if (REG_P (op1)) 501 op1 = gen_rtx_REG (SFmode, REGNO (op1)); 502 else 503 op1 = gen_lowpart (SFmode, op1); 504 emit_move_insn (operands[0], op1); 505 DONE; 506}) 507 508(define_insn "*vec_extractv2sf_1" 509 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,frxy") 510 (vec_select:SF 511 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o") 512 (parallel [(const_int 1)])))] 513 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 514 "@ 515 punpckhdq\t%0, %0 516 unpckhps\t%0, %0 517 #" 518 [(set_attr "type" "mmxcvt,sselog1,*") 519 (set_attr "mode" "DI,V4SF,SI")]) 520 521(define_split 522 [(set (match_operand:SF 0 "register_operand" "") 523 (vec_select:SF 524 (match_operand:V2SF 1 "memory_operand" "") 525 (parallel [(const_int 1)])))] 526 "TARGET_MMX && reload_completed" 527 [(const_int 0)] 528{ 529 operands[1] = adjust_address (operands[1], SFmode, 4); 530 emit_move_insn (operands[0], operands[1]); 531 DONE; 532}) 533 534(define_expand "vec_extractv2sf" 535 [(match_operand:SF 0 "register_operand" "") 536 (match_operand:V2SF 1 "register_operand" "") 537 (match_operand 2 "const_int_operand" "")] 538 "TARGET_MMX" 539{ 540 ix86_expand_vector_extract (false, operands[0], operands[1], 541 INTVAL (operands[2])); 542 DONE; 543}) 544 545(define_expand "vec_initv2sf" 546 [(match_operand:V2SF 0 "register_operand" "") 547 (match_operand 1 "" "")] 548 "TARGET_SSE" 549{ 550 ix86_expand_vector_init (false, operands[0], operands[1]); 551 DONE; 552}) 553 554;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 555;; 556;; Parallel integral arithmetic 557;; 558;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 559 560(define_insn "mmx_add<mode>3" 561 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 562 (plus:MMXMODEI 563 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") 564 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 565 "TARGET_MMX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 566 "padd<mmxvecsize>\t{%2, %0|%0, %2}" 567 [(set_attr "type" "mmxadd") 568 (set_attr "mode" "DI")]) 569 570(define_insn "mmx_adddi3" 571 [(set (match_operand:DI 0 "register_operand" "=y") 572 (unspec:DI 573 [(plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") 574 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 575 UNSPEC_NOP))] 576 "TARGET_SSE2 && ix86_binary_operator_ok (PLUS, DImode, operands)" 577 "paddq\t{%2, %0|%0, %2}" 578 [(set_attr "type" "mmxadd") 579 (set_attr "mode" "DI")]) 580 581(define_insn "mmx_ssadd<mode>3" 582 [(set (match_operand:MMXMODE12 0 "register_operand" "=y") 583 (ss_plus:MMXMODE12 584 (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0") 585 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] 586 "TARGET_MMX" 587 "padds<mmxvecsize>\t{%2, %0|%0, %2}" 588 [(set_attr "type" "mmxadd") 589 (set_attr "mode" "DI")]) 590 591(define_insn "mmx_usadd<mode>3" 592 [(set (match_operand:MMXMODE12 0 "register_operand" "=y") 593 (us_plus:MMXMODE12 594 (match_operand:MMXMODE12 1 "nonimmediate_operand" "%0") 595 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] 596 "TARGET_MMX" 597 "paddus<mmxvecsize>\t{%2, %0|%0, %2}" 598 [(set_attr "type" "mmxadd") 599 (set_attr "mode" "DI")]) 600 601(define_insn "mmx_sub<mode>3" 602 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 603 (minus:MMXMODEI 604 (match_operand:MMXMODEI 1 "register_operand" "0") 605 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 606 "TARGET_MMX" 607 "psub<mmxvecsize>\t{%2, %0|%0, %2}" 608 [(set_attr "type" "mmxadd") 609 (set_attr "mode" "DI")]) 610 611(define_insn "mmx_subdi3" 612 [(set (match_operand:DI 0 "register_operand" "=y") 613 (unspec:DI 614 [(minus:DI (match_operand:DI 1 "register_operand" "0") 615 (match_operand:DI 2 "nonimmediate_operand" "ym"))] 616 UNSPEC_NOP))] 617 "TARGET_SSE2" 618 "psubq\t{%2, %0|%0, %2}" 619 [(set_attr "type" "mmxadd") 620 (set_attr "mode" "DI")]) 621 622(define_insn "mmx_sssub<mode>3" 623 [(set (match_operand:MMXMODE12 0 "register_operand" "=y") 624 (ss_minus:MMXMODE12 625 (match_operand:MMXMODE12 1 "register_operand" "0") 626 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] 627 "TARGET_MMX" 628 "psubs<mmxvecsize>\t{%2, %0|%0, %2}" 629 [(set_attr "type" "mmxadd") 630 (set_attr "mode" "DI")]) 631 632(define_insn "mmx_ussub<mode>3" 633 [(set (match_operand:MMXMODE12 0 "register_operand" "=y") 634 (us_minus:MMXMODE12 635 (match_operand:MMXMODE12 1 "register_operand" "0") 636 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] 637 "TARGET_MMX" 638 "psubus<mmxvecsize>\t{%2, %0|%0, %2}" 639 [(set_attr "type" "mmxadd") 640 (set_attr "mode" "DI")]) 641 642(define_insn "mmx_mulv4hi3" 643 [(set (match_operand:V4HI 0 "register_operand" "=y") 644 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0") 645 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] 646 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" 647 "pmullw\t{%2, %0|%0, %2}" 648 [(set_attr "type" "mmxmul") 649 (set_attr "mode" "DI")]) 650 651(define_insn "mmx_smulv4hi3_highpart" 652 [(set (match_operand:V4HI 0 "register_operand" "=y") 653 (truncate:V4HI 654 (lshiftrt:V4SI 655 (mult:V4SI (sign_extend:V4SI 656 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 657 (sign_extend:V4SI 658 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 659 (const_int 16))))] 660 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" 661 "pmulhw\t{%2, %0|%0, %2}" 662 [(set_attr "type" "mmxmul") 663 (set_attr "mode" "DI")]) 664 665(define_insn "mmx_umulv4hi3_highpart" 666 [(set (match_operand:V4HI 0 "register_operand" "=y") 667 (truncate:V4HI 668 (lshiftrt:V4SI 669 (mult:V4SI (zero_extend:V4SI 670 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 671 (zero_extend:V4SI 672 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 673 (const_int 16))))] 674 "(TARGET_SSE || TARGET_3DNOW_A) 675 && ix86_binary_operator_ok (MULT, V4HImode, operands)" 676 "pmulhuw\t{%2, %0|%0, %2}" 677 [(set_attr "type" "mmxmul") 678 (set_attr "mode" "DI")]) 679 680(define_insn "mmx_pmaddwd" 681 [(set (match_operand:V2SI 0 "register_operand" "=y") 682 (plus:V2SI 683 (mult:V2SI 684 (sign_extend:V2SI 685 (vec_select:V2HI 686 (match_operand:V4HI 1 "nonimmediate_operand" "%0") 687 (parallel [(const_int 0) (const_int 2)]))) 688 (sign_extend:V2SI 689 (vec_select:V2HI 690 (match_operand:V4HI 2 "nonimmediate_operand" "ym") 691 (parallel [(const_int 0) (const_int 2)])))) 692 (mult:V2SI 693 (sign_extend:V2SI 694 (vec_select:V2HI (match_dup 1) 695 (parallel [(const_int 1) (const_int 3)]))) 696 (sign_extend:V2SI 697 (vec_select:V2HI (match_dup 2) 698 (parallel [(const_int 1) (const_int 3)]))))))] 699 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" 700 "pmaddwd\t{%2, %0|%0, %2}" 701 [(set_attr "type" "mmxmul") 702 (set_attr "mode" "DI")]) 703 704(define_insn "mmx_pmulhrwv4hi3" 705 [(set (match_operand:V4HI 0 "register_operand" "=y") 706 (truncate:V4HI 707 (lshiftrt:V4SI 708 (plus:V4SI 709 (mult:V4SI 710 (sign_extend:V4SI 711 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 712 (sign_extend:V4SI 713 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 714 (const_vector:V4SI [(const_int 32768) (const_int 32768) 715 (const_int 32768) (const_int 32768)])) 716 (const_int 16))))] 717 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)" 718 "pmulhrw\\t{%2, %0|%0, %2}" 719 [(set_attr "type" "mmxmul") 720 (set_attr "mode" "DI")]) 721 722(define_insn "sse2_umulsidi3" 723 [(set (match_operand:DI 0 "register_operand" "=y") 724 (mult:DI 725 (zero_extend:DI 726 (vec_select:SI 727 (match_operand:V2SI 1 "nonimmediate_operand" "%0") 728 (parallel [(const_int 0)]))) 729 (zero_extend:DI 730 (vec_select:SI 731 (match_operand:V2SI 2 "nonimmediate_operand" "ym") 732 (parallel [(const_int 0)])))))] 733 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)" 734 "pmuludq\t{%2, %0|%0, %2}" 735 [(set_attr "type" "mmxmul") 736 (set_attr "mode" "DI")]) 737 738(define_insn "mmx_umaxv8qi3" 739 [(set (match_operand:V8QI 0 "register_operand" "=y") 740 (umax:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0") 741 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] 742 "(TARGET_SSE || TARGET_3DNOW_A) 743 && ix86_binary_operator_ok (UMAX, V8QImode, operands)" 744 "pmaxub\t{%2, %0|%0, %2}" 745 [(set_attr "type" "mmxadd") 746 (set_attr "mode" "DI")]) 747 748(define_insn "mmx_smaxv4hi3" 749 [(set (match_operand:V4HI 0 "register_operand" "=y") 750 (smax:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0") 751 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] 752 "(TARGET_SSE || TARGET_3DNOW_A) 753 && ix86_binary_operator_ok (SMAX, V4HImode, operands)" 754 "pmaxsw\t{%2, %0|%0, %2}" 755 [(set_attr "type" "mmxadd") 756 (set_attr "mode" "DI")]) 757 758(define_insn "mmx_uminv8qi3" 759 [(set (match_operand:V8QI 0 "register_operand" "=y") 760 (umin:V8QI (match_operand:V8QI 1 "nonimmediate_operand" "%0") 761 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] 762 "(TARGET_SSE || TARGET_3DNOW_A) 763 && ix86_binary_operator_ok (UMIN, V8QImode, operands)" 764 "pminub\t{%2, %0|%0, %2}" 765 [(set_attr "type" "mmxadd") 766 (set_attr "mode" "DI")]) 767 768(define_insn "mmx_sminv4hi3" 769 [(set (match_operand:V4HI 0 "register_operand" "=y") 770 (smin:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0") 771 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] 772 "(TARGET_SSE || TARGET_3DNOW_A) 773 && ix86_binary_operator_ok (SMIN, V4HImode, operands)" 774 "pminsw\t{%2, %0|%0, %2}" 775 [(set_attr "type" "mmxadd") 776 (set_attr "mode" "DI")]) 777 778(define_insn "mmx_ashr<mode>3" 779 [(set (match_operand:MMXMODE24 0 "register_operand" "=y") 780 (ashiftrt:MMXMODE24 781 (match_operand:MMXMODE24 1 "register_operand" "0") 782 (match_operand:DI 2 "nonmemory_operand" "yi")))] 783 "TARGET_MMX" 784 "psra<mmxvecsize>\t{%2, %0|%0, %2}" 785 [(set_attr "type" "mmxshft") 786 (set_attr "mode" "DI")]) 787 788(define_insn "mmx_lshr<mode>3" 789 [(set (match_operand:MMXMODE24 0 "register_operand" "=y") 790 (lshiftrt:MMXMODE24 791 (match_operand:MMXMODE24 1 "register_operand" "0") 792 (match_operand:DI 2 "nonmemory_operand" "yi")))] 793 "TARGET_MMX" 794 "psrl<mmxvecsize>\t{%2, %0|%0, %2}" 795 [(set_attr "type" "mmxshft") 796 (set_attr "mode" "DI")]) 797 798(define_insn "mmx_lshrdi3" 799 [(set (match_operand:DI 0 "register_operand" "=y") 800 (unspec:DI 801 [(lshiftrt:DI (match_operand:DI 1 "register_operand" "0") 802 (match_operand:DI 2 "nonmemory_operand" "yi"))] 803 UNSPEC_NOP))] 804 "TARGET_MMX" 805 "psrlq\t{%2, %0|%0, %2}" 806 [(set_attr "type" "mmxshft") 807 (set_attr "mode" "DI")]) 808 809(define_insn "mmx_ashl<mode>3" 810 [(set (match_operand:MMXMODE24 0 "register_operand" "=y") 811 (ashift:MMXMODE24 812 (match_operand:MMXMODE24 1 "register_operand" "0") 813 (match_operand:DI 2 "nonmemory_operand" "yi")))] 814 "TARGET_MMX" 815 "psll<mmxvecsize>\t{%2, %0|%0, %2}" 816 [(set_attr "type" "mmxshft") 817 (set_attr "mode" "DI")]) 818 819(define_insn "mmx_ashldi3" 820 [(set (match_operand:DI 0 "register_operand" "=y") 821 (unspec:DI 822 [(ashift:DI (match_operand:DI 1 "register_operand" "0") 823 (match_operand:DI 2 "nonmemory_operand" "yi"))] 824 UNSPEC_NOP))] 825 "TARGET_MMX" 826 "psllq\t{%2, %0|%0, %2}" 827 [(set_attr "type" "mmxshft") 828 (set_attr "mode" "DI")]) 829 830;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 831;; 832;; Parallel integral comparisons 833;; 834;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 835 836(define_insn "mmx_eq<mode>3" 837 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 838 (eq:MMXMODEI 839 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") 840 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 841 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)" 842 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}" 843 [(set_attr "type" "mmxcmp") 844 (set_attr "mode" "DI")]) 845 846(define_insn "mmx_gt<mode>3" 847 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 848 (gt:MMXMODEI 849 (match_operand:MMXMODEI 1 "register_operand" "0") 850 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 851 "TARGET_MMX" 852 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}" 853 [(set_attr "type" "mmxcmp") 854 (set_attr "mode" "DI")]) 855 856;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 857;; 858;; Parallel integral logical operations 859;; 860;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 861 862(define_insn "mmx_and<mode>3" 863 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 864 (and:MMXMODEI 865 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") 866 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 867 "TARGET_MMX && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 868 "pand\t{%2, %0|%0, %2}" 869 [(set_attr "type" "mmxadd") 870 (set_attr "mode" "DI")]) 871 872(define_insn "mmx_nand<mode>3" 873 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 874 (and:MMXMODEI 875 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0")) 876 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 877 "TARGET_MMX" 878 "pandn\t{%2, %0|%0, %2}" 879 [(set_attr "type" "mmxadd") 880 (set_attr "mode" "DI")]) 881 882(define_insn "mmx_ior<mode>3" 883 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 884 (ior:MMXMODEI 885 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") 886 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 887 "TARGET_MMX && ix86_binary_operator_ok (IOR, <MODE>mode, operands)" 888 "por\t{%2, %0|%0, %2}" 889 [(set_attr "type" "mmxadd") 890 (set_attr "mode" "DI")]) 891 892(define_insn "mmx_xor<mode>3" 893 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 894 (xor:MMXMODEI 895 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") 896 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 897 "TARGET_MMX && ix86_binary_operator_ok (XOR, <MODE>mode, operands)" 898 "pxor\t{%2, %0|%0, %2}" 899 [(set_attr "type" "mmxadd") 900 (set_attr "mode" "DI") 901 (set_attr "memory" "none")]) 902 903;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 904;; 905;; Parallel integral element swizzling 906;; 907;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 908 909(define_insn "mmx_packsswb" 910 [(set (match_operand:V8QI 0 "register_operand" "=y") 911 (vec_concat:V8QI 912 (ss_truncate:V4QI 913 (match_operand:V4HI 1 "register_operand" "0")) 914 (ss_truncate:V4QI 915 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))] 916 "TARGET_MMX" 917 "packsswb\t{%2, %0|%0, %2}" 918 [(set_attr "type" "mmxshft") 919 (set_attr "mode" "DI")]) 920 921(define_insn "mmx_packssdw" 922 [(set (match_operand:V4HI 0 "register_operand" "=y") 923 (vec_concat:V4HI 924 (ss_truncate:V2HI 925 (match_operand:V2SI 1 "register_operand" "0")) 926 (ss_truncate:V2HI 927 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))] 928 "TARGET_MMX" 929 "packssdw\t{%2, %0|%0, %2}" 930 [(set_attr "type" "mmxshft") 931 (set_attr "mode" "DI")]) 932 933(define_insn "mmx_packuswb" 934 [(set (match_operand:V8QI 0 "register_operand" "=y") 935 (vec_concat:V8QI 936 (us_truncate:V4QI 937 (match_operand:V4HI 1 "register_operand" "0")) 938 (us_truncate:V4QI 939 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))] 940 "TARGET_MMX" 941 "packuswb\t{%2, %0|%0, %2}" 942 [(set_attr "type" "mmxshft") 943 (set_attr "mode" "DI")]) 944 945(define_insn "mmx_punpckhbw" 946 [(set (match_operand:V8QI 0 "register_operand" "=y") 947 (vec_select:V8QI 948 (vec_concat:V16QI 949 (match_operand:V8QI 1 "register_operand" "0") 950 (match_operand:V8QI 2 "nonimmediate_operand" "ym")) 951 (parallel [(const_int 4) (const_int 12) 952 (const_int 5) (const_int 13) 953 (const_int 6) (const_int 14) 954 (const_int 7) (const_int 15)])))] 955 "TARGET_MMX" 956 "punpckhbw\t{%2, %0|%0, %2}" 957 [(set_attr "type" "mmxcvt") 958 (set_attr "mode" "DI")]) 959 960(define_insn "mmx_punpcklbw" 961 [(set (match_operand:V8QI 0 "register_operand" "=y") 962 (vec_select:V8QI 963 (vec_concat:V16QI 964 (match_operand:V8QI 1 "register_operand" "0") 965 (match_operand:V8QI 2 "nonimmediate_operand" "ym")) 966 (parallel [(const_int 0) (const_int 8) 967 (const_int 1) (const_int 9) 968 (const_int 2) (const_int 10) 969 (const_int 3) (const_int 11)])))] 970 "TARGET_MMX" 971 "punpcklbw\t{%2, %0|%0, %2}" 972 [(set_attr "type" "mmxcvt") 973 (set_attr "mode" "DI")]) 974 975(define_insn "mmx_punpckhwd" 976 [(set (match_operand:V4HI 0 "register_operand" "=y") 977 (vec_select:V4HI 978 (vec_concat:V8HI 979 (match_operand:V4HI 1 "register_operand" "0") 980 (match_operand:V4HI 2 "nonimmediate_operand" "ym")) 981 (parallel [(const_int 2) (const_int 6) 982 (const_int 3) (const_int 7)])))] 983 "TARGET_MMX" 984 "punpckhwd\t{%2, %0|%0, %2}" 985 [(set_attr "type" "mmxcvt") 986 (set_attr "mode" "DI")]) 987 988(define_insn "mmx_punpcklwd" 989 [(set (match_operand:V4HI 0 "register_operand" "=y") 990 (vec_select:V4HI 991 (vec_concat:V8HI 992 (match_operand:V4HI 1 "register_operand" "0") 993 (match_operand:V4HI 2 "nonimmediate_operand" "ym")) 994 (parallel [(const_int 0) (const_int 4) 995 (const_int 1) (const_int 5)])))] 996 "TARGET_MMX" 997 "punpcklwd\t{%2, %0|%0, %2}" 998 [(set_attr "type" "mmxcvt") 999 (set_attr "mode" "DI")]) 1000 1001(define_insn "mmx_punpckhdq" 1002 [(set (match_operand:V2SI 0 "register_operand" "=y") 1003 (vec_select:V2SI 1004 (vec_concat:V4SI 1005 (match_operand:V2SI 1 "register_operand" "0") 1006 (match_operand:V2SI 2 "nonimmediate_operand" "ym")) 1007 (parallel [(const_int 1) 1008 (const_int 3)])))] 1009 "TARGET_MMX" 1010 "punpckhdq\t{%2, %0|%0, %2}" 1011 [(set_attr "type" "mmxcvt") 1012 (set_attr "mode" "DI")]) 1013 1014(define_insn "mmx_punpckldq" 1015 [(set (match_operand:V2SI 0 "register_operand" "=y") 1016 (vec_select:V2SI 1017 (vec_concat:V4SI 1018 (match_operand:V2SI 1 "register_operand" "0") 1019 (match_operand:V2SI 2 "nonimmediate_operand" "ym")) 1020 (parallel [(const_int 0) 1021 (const_int 2)])))] 1022 "TARGET_MMX" 1023 "punpckldq\t{%2, %0|%0, %2}" 1024 [(set_attr "type" "mmxcvt") 1025 (set_attr "mode" "DI")]) 1026 1027(define_expand "mmx_pinsrw" 1028 [(set (match_operand:V4HI 0 "register_operand" "") 1029 (vec_merge:V4HI 1030 (vec_duplicate:V4HI 1031 (match_operand:SI 2 "nonimmediate_operand" "")) 1032 (match_operand:V4HI 1 "register_operand" "") 1033 (match_operand:SI 3 "const_0_to_3_operand" "")))] 1034 "TARGET_SSE || TARGET_3DNOW_A" 1035{ 1036 operands[2] = gen_lowpart (HImode, operands[2]); 1037 operands[3] = GEN_INT (1 << INTVAL (operands[3])); 1038}) 1039 1040(define_insn "*mmx_pinsrw" 1041 [(set (match_operand:V4HI 0 "register_operand" "=y") 1042 (vec_merge:V4HI 1043 (vec_duplicate:V4HI 1044 (match_operand:HI 2 "nonimmediate_operand" "rm")) 1045 (match_operand:V4HI 1 "register_operand" "0") 1046 (match_operand:SI 3 "const_pow2_1_to_8_operand" "n")))] 1047 "TARGET_SSE || TARGET_3DNOW_A" 1048{ 1049 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); 1050 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}"; 1051} 1052 [(set_attr "type" "mmxcvt") 1053 (set_attr "mode" "DI")]) 1054 1055(define_insn "mmx_pextrw" 1056 [(set (match_operand:SI 0 "register_operand" "=r") 1057 (zero_extend:SI 1058 (vec_select:HI 1059 (match_operand:V4HI 1 "register_operand" "y") 1060 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))] 1061 "TARGET_SSE || TARGET_3DNOW_A" 1062 "pextrw\t{%2, %1, %0|%0, %1, %2}" 1063 [(set_attr "type" "mmxcvt") 1064 (set_attr "mode" "DI")]) 1065 1066(define_expand "mmx_pshufw" 1067 [(match_operand:V4HI 0 "register_operand" "") 1068 (match_operand:V4HI 1 "nonimmediate_operand" "") 1069 (match_operand:SI 2 "const_int_operand" "")] 1070 "TARGET_SSE || TARGET_3DNOW_A" 1071{ 1072 int mask = INTVAL (operands[2]); 1073 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1], 1074 GEN_INT ((mask >> 0) & 3), 1075 GEN_INT ((mask >> 2) & 3), 1076 GEN_INT ((mask >> 4) & 3), 1077 GEN_INT ((mask >> 6) & 3))); 1078 DONE; 1079}) 1080 1081(define_insn "mmx_pshufw_1" 1082 [(set (match_operand:V4HI 0 "register_operand" "=y") 1083 (vec_select:V4HI 1084 (match_operand:V4HI 1 "nonimmediate_operand" "ym") 1085 (parallel [(match_operand 2 "const_0_to_3_operand" "") 1086 (match_operand 3 "const_0_to_3_operand" "") 1087 (match_operand 4 "const_0_to_3_operand" "") 1088 (match_operand 5 "const_0_to_3_operand" "")])))] 1089 "TARGET_SSE || TARGET_3DNOW_A" 1090{ 1091 int mask = 0; 1092 mask |= INTVAL (operands[2]) << 0; 1093 mask |= INTVAL (operands[3]) << 2; 1094 mask |= INTVAL (operands[4]) << 4; 1095 mask |= INTVAL (operands[5]) << 6; 1096 operands[2] = GEN_INT (mask); 1097 1098 return "pshufw\t{%2, %1, %0|%0, %1, %2}"; 1099} 1100 [(set_attr "type" "mmxcvt") 1101 (set_attr "mode" "DI")]) 1102 1103(define_insn "mmx_pswapdv2si2" 1104 [(set (match_operand:V2SI 0 "register_operand" "=y") 1105 (vec_select:V2SI 1106 (match_operand:V2SI 1 "nonimmediate_operand" "ym") 1107 (parallel [(const_int 1) (const_int 0)])))] 1108 "TARGET_3DNOW_A" 1109 "pswapd\\t{%1, %0|%0, %1}" 1110 [(set_attr "type" "mmxcvt") 1111 (set_attr "mode" "DI")]) 1112 1113(define_insn "*vec_dupv4hi" 1114 [(set (match_operand:V4HI 0 "register_operand" "=y") 1115 (vec_duplicate:V4HI 1116 (truncate:HI 1117 (match_operand:SI 1 "register_operand" "0"))))] 1118 "TARGET_SSE || TARGET_3DNOW_A" 1119 "pshufw\t{$0, %0, %0|%0, %0, 0}" 1120 [(set_attr "type" "mmxcvt") 1121 (set_attr "mode" "DI")]) 1122 1123(define_insn "*vec_dupv2si" 1124 [(set (match_operand:V2SI 0 "register_operand" "=y") 1125 (vec_duplicate:V2SI 1126 (match_operand:SI 1 "register_operand" "0")))] 1127 "TARGET_MMX" 1128 "punpckldq\t%0, %0" 1129 [(set_attr "type" "mmxcvt") 1130 (set_attr "mode" "DI")]) 1131 1132(define_insn "*mmx_concatv2si" 1133 [(set (match_operand:V2SI 0 "register_operand" "=y,y") 1134 (vec_concat:V2SI 1135 (match_operand:SI 1 "nonimmediate_operand" " 0,rm") 1136 (match_operand:SI 2 "vector_move_operand" "ym,C")))] 1137 "TARGET_MMX && !TARGET_SSE" 1138 "@ 1139 punpckldq\t{%2, %0|%0, %2} 1140 movd\t{%1, %0|%0, %1}" 1141 [(set_attr "type" "mmxcvt,mmxmov") 1142 (set_attr "mode" "DI")]) 1143 1144(define_expand "vec_setv2si" 1145 [(match_operand:V2SI 0 "register_operand" "") 1146 (match_operand:SI 1 "register_operand" "") 1147 (match_operand 2 "const_int_operand" "")] 1148 "TARGET_MMX" 1149{ 1150 ix86_expand_vector_set (false, operands[0], operands[1], 1151 INTVAL (operands[2])); 1152 DONE; 1153}) 1154 1155(define_insn_and_split "*vec_extractv2si_0" 1156 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,y,m,m,frxy") 1157 (vec_select:SI 1158 (match_operand:V2SI 1 "nonimmediate_operand" " x,y,x,y,m") 1159 (parallel [(const_int 0)])))] 1160 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1161 "#" 1162 "&& reload_completed" 1163 [(const_int 0)] 1164{ 1165 rtx op1 = operands[1]; 1166 if (REG_P (op1)) 1167 op1 = gen_rtx_REG (SImode, REGNO (op1)); 1168 else 1169 op1 = gen_lowpart (SImode, op1); 1170 emit_move_insn (operands[0], op1); 1171 DONE; 1172}) 1173 1174(define_insn "*vec_extractv2si_1" 1175 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,Y,Y,x,frxy") 1176 (vec_select:SI 1177 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,Y,0,o") 1178 (parallel [(const_int 1)])))] 1179 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1180 "@ 1181 punpckhdq\t%0, %0 1182 punpckhdq\t%0, %0 1183 pshufd\t{$85, %1, %0|%0, %1, 85} 1184 unpckhps\t%0, %0 1185 #" 1186 [(set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,*") 1187 (set_attr "mode" "DI,TI,TI,V4SF,SI")]) 1188 1189(define_split 1190 [(set (match_operand:SI 0 "register_operand" "") 1191 (vec_select:SI 1192 (match_operand:V2SI 1 "memory_operand" "") 1193 (parallel [(const_int 1)])))] 1194 "TARGET_MMX && reload_completed" 1195 [(const_int 0)] 1196{ 1197 operands[1] = adjust_address (operands[1], SImode, 4); 1198 emit_move_insn (operands[0], operands[1]); 1199 DONE; 1200}) 1201 1202(define_expand "vec_extractv2si" 1203 [(match_operand:SI 0 "register_operand" "") 1204 (match_operand:V2SI 1 "register_operand" "") 1205 (match_operand 2 "const_int_operand" "")] 1206 "TARGET_MMX" 1207{ 1208 ix86_expand_vector_extract (false, operands[0], operands[1], 1209 INTVAL (operands[2])); 1210 DONE; 1211}) 1212 1213(define_expand "vec_initv2si" 1214 [(match_operand:V2SI 0 "register_operand" "") 1215 (match_operand 1 "" "")] 1216 "TARGET_SSE" 1217{ 1218 ix86_expand_vector_init (false, operands[0], operands[1]); 1219 DONE; 1220}) 1221 1222(define_expand "vec_setv4hi" 1223 [(match_operand:V4HI 0 "register_operand" "") 1224 (match_operand:HI 1 "register_operand" "") 1225 (match_operand 2 "const_int_operand" "")] 1226 "TARGET_MMX" 1227{ 1228 ix86_expand_vector_set (false, operands[0], operands[1], 1229 INTVAL (operands[2])); 1230 DONE; 1231}) 1232 1233(define_expand "vec_extractv4hi" 1234 [(match_operand:HI 0 "register_operand" "") 1235 (match_operand:V4HI 1 "register_operand" "") 1236 (match_operand 2 "const_int_operand" "")] 1237 "TARGET_MMX" 1238{ 1239 ix86_expand_vector_extract (false, operands[0], operands[1], 1240 INTVAL (operands[2])); 1241 DONE; 1242}) 1243 1244(define_expand "vec_initv4hi" 1245 [(match_operand:V4HI 0 "register_operand" "") 1246 (match_operand 1 "" "")] 1247 "TARGET_SSE" 1248{ 1249 ix86_expand_vector_init (false, operands[0], operands[1]); 1250 DONE; 1251}) 1252 1253(define_expand "vec_setv8qi" 1254 [(match_operand:V8QI 0 "register_operand" "") 1255 (match_operand:QI 1 "register_operand" "") 1256 (match_operand 2 "const_int_operand" "")] 1257 "TARGET_MMX" 1258{ 1259 ix86_expand_vector_set (false, operands[0], operands[1], 1260 INTVAL (operands[2])); 1261 DONE; 1262}) 1263 1264(define_expand "vec_extractv8qi" 1265 [(match_operand:QI 0 "register_operand" "") 1266 (match_operand:V8QI 1 "register_operand" "") 1267 (match_operand 2 "const_int_operand" "")] 1268 "TARGET_MMX" 1269{ 1270 ix86_expand_vector_extract (false, operands[0], operands[1], 1271 INTVAL (operands[2])); 1272 DONE; 1273}) 1274 1275(define_expand "vec_initv8qi" 1276 [(match_operand:V8QI 0 "register_operand" "") 1277 (match_operand 1 "" "")] 1278 "TARGET_SSE" 1279{ 1280 ix86_expand_vector_init (false, operands[0], operands[1]); 1281 DONE; 1282}) 1283 1284;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1285;; 1286;; Miscellaneous 1287;; 1288;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1289 1290(define_insn "mmx_uavgv8qi3" 1291 [(set (match_operand:V8QI 0 "register_operand" "=y") 1292 (truncate:V8QI 1293 (lshiftrt:V8HI 1294 (plus:V8HI 1295 (plus:V8HI 1296 (zero_extend:V8HI 1297 (match_operand:V8QI 1 "nonimmediate_operand" "%0")) 1298 (zero_extend:V8HI 1299 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))) 1300 (const_vector:V8HI [(const_int 1) (const_int 1) 1301 (const_int 1) (const_int 1) 1302 (const_int 1) (const_int 1) 1303 (const_int 1) (const_int 1)])) 1304 (const_int 1))))] 1305 "(TARGET_SSE || TARGET_3DNOW) 1306 && ix86_binary_operator_ok (PLUS, V8QImode, operands)" 1307{ 1308 /* These two instructions have the same operation, but their encoding 1309 is different. Prefer the one that is de facto standard. */ 1310 if (TARGET_SSE || TARGET_3DNOW_A) 1311 return "pavgb\t{%2, %0|%0, %2}"; 1312 else 1313 return "pavgusb\\t{%2, %0|%0, %2}"; 1314} 1315 [(set_attr "type" "mmxshft") 1316 (set_attr "mode" "DI")]) 1317 1318(define_insn "mmx_uavgv4hi3" 1319 [(set (match_operand:V4HI 0 "register_operand" "=y") 1320 (truncate:V4HI 1321 (lshiftrt:V4SI 1322 (plus:V4SI 1323 (plus:V4SI 1324 (zero_extend:V4SI 1325 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 1326 (zero_extend:V4SI 1327 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 1328 (const_vector:V4SI [(const_int 1) (const_int 1) 1329 (const_int 1) (const_int 1)])) 1330 (const_int 1))))] 1331 "(TARGET_SSE || TARGET_3DNOW_A) 1332 && ix86_binary_operator_ok (PLUS, V4HImode, operands)" 1333 "pavgw\t{%2, %0|%0, %2}" 1334 [(set_attr "type" "mmxshft") 1335 (set_attr "mode" "DI")]) 1336 1337(define_insn "mmx_psadbw" 1338 [(set (match_operand:DI 0 "register_operand" "=y") 1339 (unspec:DI [(match_operand:V8QI 1 "register_operand" "0") 1340 (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 1341 UNSPEC_PSADBW))] 1342 "TARGET_SSE || TARGET_3DNOW_A" 1343 "psadbw\t{%2, %0|%0, %2}" 1344 [(set_attr "type" "mmxshft") 1345 (set_attr "mode" "DI")]) 1346 1347(define_insn "mmx_pmovmskb" 1348 [(set (match_operand:SI 0 "register_operand" "=r") 1349 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 1350 UNSPEC_MOVMSK))] 1351 "TARGET_SSE || TARGET_3DNOW_A" 1352 "pmovmskb\t{%1, %0|%0, %1}" 1353 [(set_attr "type" "mmxcvt") 1354 (set_attr "mode" "DI")]) 1355 1356(define_expand "mmx_maskmovq" 1357 [(set (match_operand:V8QI 0 "memory_operand" "") 1358 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") 1359 (match_operand:V8QI 2 "register_operand" "y") 1360 (match_dup 0)] 1361 UNSPEC_MASKMOV))] 1362 "TARGET_SSE || TARGET_3DNOW_A" 1363 "") 1364 1365(define_insn "*mmx_maskmovq" 1366 [(set (mem:V8QI (match_operand:SI 0 "register_operand" "D")) 1367 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") 1368 (match_operand:V8QI 2 "register_operand" "y") 1369 (mem:V8QI (match_dup 0))] 1370 UNSPEC_MASKMOV))] 1371 "(TARGET_SSE || TARGET_3DNOW_A) && !TARGET_64BIT" 1372 ;; @@@ check ordering of operands in intel/nonintel syntax 1373 "maskmovq\t{%2, %1|%1, %2}" 1374 [(set_attr "type" "mmxcvt") 1375 (set_attr "mode" "DI")]) 1376 1377(define_insn "*mmx_maskmovq_rex" 1378 [(set (mem:V8QI (match_operand:DI 0 "register_operand" "D")) 1379 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") 1380 (match_operand:V8QI 2 "register_operand" "y") 1381 (mem:V8QI (match_dup 0))] 1382 UNSPEC_MASKMOV))] 1383 "(TARGET_SSE || TARGET_3DNOW_A) && TARGET_64BIT" 1384 ;; @@@ check ordering of operands in intel/nonintel syntax 1385 "maskmovq\t{%2, %1|%1, %2}" 1386 [(set_attr "type" "mmxcvt") 1387 (set_attr "mode" "DI")]) 1388 1389(define_insn "mmx_emms" 1390 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS) 1391 (clobber (reg:XF 8)) 1392 (clobber (reg:XF 9)) 1393 (clobber (reg:XF 10)) 1394 (clobber (reg:XF 11)) 1395 (clobber (reg:XF 12)) 1396 (clobber (reg:XF 13)) 1397 (clobber (reg:XF 14)) 1398 (clobber (reg:XF 15)) 1399 (clobber (reg:DI 29)) 1400 (clobber (reg:DI 30)) 1401 (clobber (reg:DI 31)) 1402 (clobber (reg:DI 32)) 1403 (clobber (reg:DI 33)) 1404 (clobber (reg:DI 34)) 1405 (clobber (reg:DI 35)) 1406 (clobber (reg:DI 36))] 1407 "TARGET_MMX" 1408 "emms" 1409 [(set_attr "type" "mmx") 1410 (set_attr "memory" "unknown")]) 1411 1412(define_insn "mmx_femms" 1413 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS) 1414 (clobber (reg:XF 8)) 1415 (clobber (reg:XF 9)) 1416 (clobber (reg:XF 10)) 1417 (clobber (reg:XF 11)) 1418 (clobber (reg:XF 12)) 1419 (clobber (reg:XF 13)) 1420 (clobber (reg:XF 14)) 1421 (clobber (reg:XF 15)) 1422 (clobber (reg:DI 29)) 1423 (clobber (reg:DI 30)) 1424 (clobber (reg:DI 31)) 1425 (clobber (reg:DI 32)) 1426 (clobber (reg:DI 33)) 1427 (clobber (reg:DI 34)) 1428 (clobber (reg:DI 35)) 1429 (clobber (reg:DI 36))] 1430 "TARGET_3DNOW" 1431 "femms" 1432 [(set_attr "type" "mmx") 1433 (set_attr "memory" "none")]) 1434