1;; GCC machine description for MMX and 3dNOW! instructions 2;; Copyright (C) 2005-2020 Free Software Foundation, Inc. 3;; 4;; This file is part of GCC. 5;; 6;; GCC is free software; you can redistribute it and/or modify 7;; it under the terms of the GNU General Public License as published by 8;; the Free Software Foundation; either version 3, or (at your option) 9;; any later version. 10;; 11;; GCC is distributed in the hope that it will be useful, 12;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14;; GNU General Public License for more details. 15;; 16;; You should have received a copy of the GNU General Public License 17;; along with GCC; see the file COPYING3. If not see 18;; <http://www.gnu.org/licenses/>. 19 20;; The MMX and 3dNOW! patterns are in the same file because they use 21;; the same register file, and 3dNOW! adds a number of extensions to 22;; the base integer MMX isa. 23 24;; Note! Except for the basic move instructions, *all* of these 25;; patterns are outside the normal optabs namespace. This is because 26;; use of these registers requires the insertion of emms or femms 27;; instructions to return to normal fpu mode. The compiler doesn't 28;; know how to do that itself, which means it's up to the user. Which 29;; means that we should never use any of these patterns except at the 30;; direction of the user via a builtin. 31 32(define_c_enum "unspec" [ 33 UNSPEC_MOVNTQ 34 UNSPEC_PFRCP 35 UNSPEC_PFRCPIT1 36 UNSPEC_PFRCPIT2 37 UNSPEC_PFRSQRT 38 UNSPEC_PFRSQIT1 39]) 40 41(define_c_enum "unspecv" [ 42 UNSPECV_EMMS 43 UNSPECV_FEMMS 44]) 45 46;; 8 byte integral modes handled by MMX (and by extension, SSE) 47(define_mode_iterator MMXMODEI [V8QI V4HI V2SI]) 48(define_mode_iterator MMXMODEI8 [V8QI V4HI V2SI (V1DI "TARGET_SSE2")]) 49 50;; All 8-byte vector modes handled by MMX 51(define_mode_iterator MMXMODE [V8QI V4HI V2SI V1DI V2SF]) 52 53;; Mix-n-match 54(define_mode_iterator MMXMODE12 [V8QI V4HI]) 55(define_mode_iterator MMXMODE24 [V4HI V2SI]) 56(define_mode_iterator MMXMODE248 [V4HI V2SI V1DI]) 57 58;; Mapping from integer vector mode to mnemonic suffix 59(define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")]) 60 61(define_mode_attr mmxdoublemode 62 [(V8QI "V8HI") (V4HI "V4SI")]) 63 64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 65;; 66;; Move patterns 67;; 68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 69 70;; All of these patterns are enabled for MMX as well as 3dNOW. 71;; This is essential for maintaining stable calling conventions. 72 73(define_expand "mov<mode>" 74 [(set (match_operand:MMXMODE 0 "nonimmediate_operand") 75 (match_operand:MMXMODE 1 "nonimmediate_operand"))] 76 "TARGET_MMX || TARGET_MMX_WITH_SSE" 77{ 78 ix86_expand_vector_move (<MODE>mode, operands); 79 DONE; 80}) 81 82(define_insn "*mov<mode>_internal" 83 [(set (match_operand:MMXMODE 0 "nonimmediate_operand" 84 "=r ,o ,r,r ,m ,?!y,!y,?!y,m ,r ,?!y,v,v,v,m,r,v,!y,*x") 85 (match_operand:MMXMODE 1 "nonimm_or_0_operand" 86 "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!y,r ,C,v,m,v,v,r,*x,!y"))] 87 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 88 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 89{ 90 switch (get_attr_type (insn)) 91 { 92 case TYPE_MULTI: 93 return "#"; 94 95 case TYPE_IMOV: 96 if (get_attr_mode (insn) == MODE_SI) 97 return "mov{l}\t{%1, %k0|%k0, %1}"; 98 else 99 return "mov{q}\t{%1, %0|%0, %1}"; 100 101 case TYPE_MMX: 102 return "pxor\t%0, %0"; 103 104 case TYPE_MMXMOV: 105 /* Handle broken assemblers that require movd instead of movq. */ 106 if (!HAVE_AS_IX86_INTERUNIT_MOVQ 107 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))) 108 return "movd\t{%1, %0|%0, %1}"; 109 return "movq\t{%1, %0|%0, %1}"; 110 111 case TYPE_SSECVT: 112 if (SSE_REG_P (operands[0])) 113 return "movq2dq\t{%1, %0|%0, %1}"; 114 else 115 return "movdq2q\t{%1, %0|%0, %1}"; 116 117 case TYPE_SSELOG1: 118 return standard_sse_constant_opcode (insn, operands); 119 120 case TYPE_SSEMOV: 121 return ix86_output_ssemov (insn, operands); 122 123 default: 124 gcc_unreachable (); 125 } 126} 127 [(set (attr "isa") 128 (cond [(eq_attr "alternative" "0,1") 129 (const_string "nox64") 130 (eq_attr "alternative" "2,3,4,9,10") 131 (const_string "x64") 132 (eq_attr "alternative" "15,16") 133 (const_string "x64_sse2") 134 (eq_attr "alternative" "17,18") 135 (const_string "sse2") 136 ] 137 (const_string "*"))) 138 (set (attr "type") 139 (cond [(eq_attr "alternative" "0,1") 140 (const_string "multi") 141 (eq_attr "alternative" "2,3,4") 142 (const_string "imov") 143 (eq_attr "alternative" "5") 144 (const_string "mmx") 145 (eq_attr "alternative" "6,7,8,9,10") 146 (const_string "mmxmov") 147 (eq_attr "alternative" "11") 148 (const_string "sselog1") 149 (eq_attr "alternative" "17,18") 150 (const_string "ssecvt") 151 ] 152 (const_string "ssemov"))) 153 (set (attr "prefix_rex") 154 (if_then_else (eq_attr "alternative" "9,10,15,16") 155 (const_string "1") 156 (const_string "*"))) 157 (set (attr "prefix") 158 (if_then_else (eq_attr "type" "sselog1,ssemov") 159 (const_string "maybe_vex") 160 (const_string "orig"))) 161 (set (attr "prefix_data16") 162 (if_then_else 163 (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI")) 164 (const_string "1") 165 (const_string "*"))) 166 (set (attr "mode") 167 (cond [(eq_attr "alternative" "2") 168 (const_string "SI") 169 (eq_attr "alternative" "11,12") 170 (cond [(match_test "<MODE>mode == V2SFmode") 171 (const_string "V4SF") 172 (ior (not (match_test "TARGET_SSE2")) 173 (match_test "optimize_function_for_size_p (cfun)")) 174 (const_string "V4SF") 175 ] 176 (const_string "TI")) 177 178 (and (eq_attr "alternative" "13,14") 179 (ior (match_test "<MODE>mode == V2SFmode") 180 (not (match_test "TARGET_SSE2")))) 181 (const_string "V2SF") 182 ] 183 (const_string "DI"))) 184 (set (attr "preferred_for_speed") 185 (cond [(eq_attr "alternative" "9,15") 186 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 187 (eq_attr "alternative" "10,16") 188 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC") 189 ] 190 (symbol_ref "true")))]) 191 192(define_split 193 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand") 194 (match_operand:MMXMODE 1 "nonimmediate_gr_operand"))] 195 "!TARGET_64BIT && reload_completed" 196 [(const_int 0)] 197 "ix86_split_long_move (operands); DONE;") 198 199(define_split 200 [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand") 201 (match_operand:MMXMODE 1 "const0_operand"))] 202 "!TARGET_64BIT && reload_completed" 203 [(const_int 0)] 204 "ix86_split_long_move (operands); DONE;") 205 206(define_expand "movmisalign<mode>" 207 [(set (match_operand:MMXMODE 0 "nonimmediate_operand") 208 (match_operand:MMXMODE 1 "nonimmediate_operand"))] 209 "TARGET_MMX || TARGET_MMX_WITH_SSE" 210{ 211 ix86_expand_vector_move (<MODE>mode, operands); 212 DONE; 213}) 214 215(define_insn "sse_movntq" 216 [(set (match_operand:DI 0 "memory_operand" "=m,m") 217 (unspec:DI [(match_operand:DI 1 "register_operand" "y,r")] 218 UNSPEC_MOVNTQ))] 219 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 220 && (TARGET_SSE || TARGET_3DNOW_A)" 221 "@ 222 movntq\t{%1, %0|%0, %1} 223 movnti\t{%1, %0|%0, %1}" 224 [(set_attr "isa" "*,x64") 225 (set_attr "mmx_isa" "native,*") 226 (set_attr "type" "mmxmov,ssemov") 227 (set_attr "mode" "DI")]) 228 229;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 230;; 231;; Parallel single-precision floating point arithmetic 232;; 233;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 234 235(define_expand "mmx_addv2sf3" 236 [(set (match_operand:V2SF 0 "register_operand") 237 (plus:V2SF 238 (match_operand:V2SF 1 "nonimmediate_operand") 239 (match_operand:V2SF 2 "nonimmediate_operand")))] 240 "TARGET_3DNOW" 241 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);") 242 243(define_insn "*mmx_addv2sf3" 244 [(set (match_operand:V2SF 0 "register_operand" "=y") 245 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") 246 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 247 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)" 248 "pfadd\t{%2, %0|%0, %2}" 249 [(set_attr "type" "mmxadd") 250 (set_attr "prefix_extra" "1") 251 (set_attr "mode" "V2SF")]) 252 253(define_expand "mmx_subv2sf3" 254 [(set (match_operand:V2SF 0 "register_operand") 255 (minus:V2SF (match_operand:V2SF 1 "register_operand") 256 (match_operand:V2SF 2 "nonimmediate_operand")))] 257 "TARGET_3DNOW") 258 259(define_expand "mmx_subrv2sf3" 260 [(set (match_operand:V2SF 0 "register_operand") 261 (minus:V2SF (match_operand:V2SF 2 "register_operand") 262 (match_operand:V2SF 1 "nonimmediate_operand")))] 263 "TARGET_3DNOW") 264 265(define_insn "*mmx_subv2sf3" 266 [(set (match_operand:V2SF 0 "register_operand" "=y,y") 267 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym") 268 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))] 269 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 270 "@ 271 pfsub\t{%2, %0|%0, %2} 272 pfsubr\t{%1, %0|%0, %1}" 273 [(set_attr "type" "mmxadd") 274 (set_attr "prefix_extra" "1") 275 (set_attr "mode" "V2SF")]) 276 277(define_expand "mmx_mulv2sf3" 278 [(set (match_operand:V2SF 0 "register_operand") 279 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand") 280 (match_operand:V2SF 2 "nonimmediate_operand")))] 281 "TARGET_3DNOW" 282 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);") 283 284(define_insn "*mmx_mulv2sf3" 285 [(set (match_operand:V2SF 0 "register_operand" "=y") 286 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") 287 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 288 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)" 289 "pfmul\t{%2, %0|%0, %2}" 290 [(set_attr "type" "mmxmul") 291 (set_attr "prefix_extra" "1") 292 (set_attr "mode" "V2SF")]) 293 294(define_expand "mmx_<code>v2sf3" 295 [(set (match_operand:V2SF 0 "register_operand") 296 (smaxmin:V2SF 297 (match_operand:V2SF 1 "nonimmediate_operand") 298 (match_operand:V2SF 2 "nonimmediate_operand")))] 299 "TARGET_3DNOW" 300{ 301 if (!flag_finite_math_only || flag_signed_zeros) 302 { 303 operands[1] = force_reg (V2SFmode, operands[1]); 304 emit_insn (gen_mmx_ieee_<maxmin_float>v2sf3 305 (operands[0], operands[1], operands[2])); 306 DONE; 307 } 308 else 309 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands); 310}) 311 312;; These versions of the min/max patterns are intentionally ignorant of 313;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 314;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 315;; are undefined in this condition, we're certain this is correct. 316 317(define_insn "*mmx_<code>v2sf3" 318 [(set (match_operand:V2SF 0 "register_operand" "=y") 319 (smaxmin:V2SF 320 (match_operand:V2SF 1 "nonimmediate_operand" "%0") 321 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 322 "TARGET_3DNOW && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)" 323 "pf<maxmin_float>\t{%2, %0|%0, %2}" 324 [(set_attr "type" "mmxadd") 325 (set_attr "prefix_extra" "1") 326 (set_attr "mode" "V2SF")]) 327 328;; These versions of the min/max patterns implement exactly the operations 329;; min = (op1 < op2 ? op1 : op2) 330;; max = (!(op1 < op2) ? op1 : op2) 331;; Their operands are not commutative, and thus they may be used in the 332;; presence of -0.0 and NaN. 333 334(define_insn "mmx_ieee_<ieee_maxmin>v2sf3" 335 [(set (match_operand:V2SF 0 "register_operand" "=y") 336 (unspec:V2SF 337 [(match_operand:V2SF 1 "register_operand" "0") 338 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 339 IEEE_MAXMIN))] 340 "TARGET_3DNOW" 341 "pf<ieee_maxmin>\t{%2, %0|%0, %2}" 342 [(set_attr "type" "mmxadd") 343 (set_attr "prefix_extra" "1") 344 (set_attr "mode" "V2SF")]) 345 346(define_insn "mmx_rcpv2sf2" 347 [(set (match_operand:V2SF 0 "register_operand" "=y") 348 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 349 UNSPEC_PFRCP))] 350 "TARGET_3DNOW" 351 "pfrcp\t{%1, %0|%0, %1}" 352 [(set_attr "type" "mmx") 353 (set_attr "prefix_extra" "1") 354 (set_attr "mode" "V2SF")]) 355 356(define_insn "mmx_rcpit1v2sf3" 357 [(set (match_operand:V2SF 0 "register_operand" "=y") 358 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 359 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 360 UNSPEC_PFRCPIT1))] 361 "TARGET_3DNOW" 362 "pfrcpit1\t{%2, %0|%0, %2}" 363 [(set_attr "type" "mmx") 364 (set_attr "prefix_extra" "1") 365 (set_attr "mode" "V2SF")]) 366 367(define_insn "mmx_rcpit2v2sf3" 368 [(set (match_operand:V2SF 0 "register_operand" "=y") 369 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 370 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 371 UNSPEC_PFRCPIT2))] 372 "TARGET_3DNOW" 373 "pfrcpit2\t{%2, %0|%0, %2}" 374 [(set_attr "type" "mmx") 375 (set_attr "prefix_extra" "1") 376 (set_attr "mode" "V2SF")]) 377 378(define_insn "mmx_rsqrtv2sf2" 379 [(set (match_operand:V2SF 0 "register_operand" "=y") 380 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 381 UNSPEC_PFRSQRT))] 382 "TARGET_3DNOW" 383 "pfrsqrt\t{%1, %0|%0, %1}" 384 [(set_attr "type" "mmx") 385 (set_attr "prefix_extra" "1") 386 (set_attr "mode" "V2SF")]) 387 388(define_insn "mmx_rsqit1v2sf3" 389 [(set (match_operand:V2SF 0 "register_operand" "=y") 390 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 391 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 392 UNSPEC_PFRSQIT1))] 393 "TARGET_3DNOW" 394 "pfrsqit1\t{%2, %0|%0, %2}" 395 [(set_attr "type" "mmx") 396 (set_attr "prefix_extra" "1") 397 (set_attr "mode" "V2SF")]) 398 399(define_insn "mmx_haddv2sf3" 400 [(set (match_operand:V2SF 0 "register_operand" "=y") 401 (vec_concat:V2SF 402 (plus:SF 403 (vec_select:SF 404 (match_operand:V2SF 1 "register_operand" "0") 405 (parallel [(const_int 0)])) 406 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) 407 (plus:SF 408 (vec_select:SF 409 (match_operand:V2SF 2 "nonimmediate_operand" "ym") 410 (parallel [(const_int 0)])) 411 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] 412 "TARGET_3DNOW" 413 "pfacc\t{%2, %0|%0, %2}" 414 [(set_attr "type" "mmxadd") 415 (set_attr "prefix_extra" "1") 416 (set_attr "mode" "V2SF")]) 417 418(define_insn "mmx_hsubv2sf3" 419 [(set (match_operand:V2SF 0 "register_operand" "=y") 420 (vec_concat:V2SF 421 (minus:SF 422 (vec_select:SF 423 (match_operand:V2SF 1 "register_operand" "0") 424 (parallel [(const_int 0)])) 425 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) 426 (minus:SF 427 (vec_select:SF 428 (match_operand:V2SF 2 "nonimmediate_operand" "ym") 429 (parallel [(const_int 0)])) 430 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] 431 "TARGET_3DNOW_A" 432 "pfnacc\t{%2, %0|%0, %2}" 433 [(set_attr "type" "mmxadd") 434 (set_attr "prefix_extra" "1") 435 (set_attr "mode" "V2SF")]) 436 437(define_insn "mmx_addsubv2sf3" 438 [(set (match_operand:V2SF 0 "register_operand" "=y") 439 (vec_concat:V2SF 440 (minus:SF 441 (vec_select:SF 442 (match_operand:V2SF 1 "register_operand" "0") 443 (parallel [(const_int 0)])) 444 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) 445 (plus:SF 446 (vec_select:SF 447 (match_operand:V2SF 2 "nonimmediate_operand" "ym") 448 (parallel [(const_int 0)])) 449 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] 450 "TARGET_3DNOW_A" 451 "pfpnacc\t{%2, %0|%0, %2}" 452 [(set_attr "type" "mmxadd") 453 (set_attr "prefix_extra" "1") 454 (set_attr "mode" "V2SF")]) 455 456;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 457;; 458;; Parallel single-precision floating point comparisons 459;; 460;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 461 462(define_expand "mmx_eqv2sf3" 463 [(set (match_operand:V2SI 0 "register_operand") 464 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand") 465 (match_operand:V2SF 2 "nonimmediate_operand")))] 466 "TARGET_3DNOW" 467 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);") 468 469(define_insn "*mmx_eqv2sf3" 470 [(set (match_operand:V2SI 0 "register_operand" "=y") 471 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0") 472 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 473 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)" 474 "pfcmpeq\t{%2, %0|%0, %2}" 475 [(set_attr "type" "mmxcmp") 476 (set_attr "prefix_extra" "1") 477 (set_attr "mode" "V2SF")]) 478 479(define_insn "mmx_gtv2sf3" 480 [(set (match_operand:V2SI 0 "register_operand" "=y") 481 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0") 482 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 483 "TARGET_3DNOW" 484 "pfcmpgt\t{%2, %0|%0, %2}" 485 [(set_attr "type" "mmxcmp") 486 (set_attr "prefix_extra" "1") 487 (set_attr "mode" "V2SF")]) 488 489(define_insn "mmx_gev2sf3" 490 [(set (match_operand:V2SI 0 "register_operand" "=y") 491 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0") 492 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 493 "TARGET_3DNOW" 494 "pfcmpge\t{%2, %0|%0, %2}" 495 [(set_attr "type" "mmxcmp") 496 (set_attr "prefix_extra" "1") 497 (set_attr "mode" "V2SF")]) 498 499;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 500;; 501;; Parallel single-precision floating point conversion operations 502;; 503;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 504 505(define_insn "mmx_pf2id" 506 [(set (match_operand:V2SI 0 "register_operand" "=y") 507 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))] 508 "TARGET_3DNOW" 509 "pf2id\t{%1, %0|%0, %1}" 510 [(set_attr "type" "mmxcvt") 511 (set_attr "prefix_extra" "1") 512 (set_attr "mode" "V2SF")]) 513 514(define_insn "mmx_pf2iw" 515 [(set (match_operand:V2SI 0 "register_operand" "=y") 516 (sign_extend:V2SI 517 (ss_truncate:V2HI 518 (fix:V2SI 519 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))] 520 "TARGET_3DNOW_A" 521 "pf2iw\t{%1, %0|%0, %1}" 522 [(set_attr "type" "mmxcvt") 523 (set_attr "prefix_extra" "1") 524 (set_attr "mode" "V2SF")]) 525 526(define_insn "mmx_pi2fw" 527 [(set (match_operand:V2SF 0 "register_operand" "=y") 528 (float:V2SF 529 (sign_extend:V2SI 530 (truncate:V2HI 531 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))] 532 "TARGET_3DNOW_A" 533 "pi2fw\t{%1, %0|%0, %1}" 534 [(set_attr "type" "mmxcvt") 535 (set_attr "prefix_extra" "1") 536 (set_attr "mode" "V2SF")]) 537 538(define_insn "mmx_floatv2si2" 539 [(set (match_operand:V2SF 0 "register_operand" "=y") 540 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))] 541 "TARGET_3DNOW" 542 "pi2fd\t{%1, %0|%0, %1}" 543 [(set_attr "type" "mmxcvt") 544 (set_attr "prefix_extra" "1") 545 (set_attr "mode" "V2SF")]) 546 547;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 548;; 549;; Parallel single-precision floating point element swizzling 550;; 551;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 552 553(define_insn "mmx_pswapdv2sf2" 554 [(set (match_operand:V2SF 0 "register_operand" "=y") 555 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym") 556 (parallel [(const_int 1) (const_int 0)])))] 557 "TARGET_3DNOW_A" 558 "pswapd\t{%1, %0|%0, %1}" 559 [(set_attr "type" "mmxcvt") 560 (set_attr "prefix_extra" "1") 561 (set_attr "mode" "V2SF")]) 562 563(define_insn_and_split "*vec_dupv2sf" 564 [(set (match_operand:V2SF 0 "register_operand" "=y,x,Yv") 565 (vec_duplicate:V2SF 566 (match_operand:SF 1 "register_operand" "0,0,Yv")))] 567 "TARGET_MMX || TARGET_MMX_WITH_SSE" 568 "@ 569 punpckldq\t%0, %0 570 # 571 #" 572 "TARGET_SSE && reload_completed 573 && SSE_REGNO_P (REGNO (operands[0]))" 574 [(set (match_dup 0) 575 (vec_duplicate:V4SF (match_dup 1)))] 576{ 577 operands[0] = lowpart_subreg (V4SFmode, operands[0], 578 GET_MODE (operands[0])); 579} 580 [(set_attr "isa" "*,sse_noavx,avx") 581 (set_attr "mmx_isa" "native,*,*") 582 (set_attr "type" "mmxcvt,ssemov,ssemov") 583 (set_attr "mode" "DI,TI,TI")]) 584 585(define_insn "*mmx_concatv2sf" 586 [(set (match_operand:V2SF 0 "register_operand" "=y,y") 587 (vec_concat:V2SF 588 (match_operand:SF 1 "nonimmediate_operand" " 0,rm") 589 (match_operand:SF 2 "nonimm_or_0_operand" "ym,C")))] 590 "TARGET_MMX && !TARGET_SSE" 591 "@ 592 punpckldq\t{%2, %0|%0, %2} 593 movd\t{%1, %0|%0, %1}" 594 [(set_attr "type" "mmxcvt,mmxmov") 595 (set_attr "mode" "DI")]) 596 597(define_expand "vec_setv2sf" 598 [(match_operand:V2SF 0 "register_operand") 599 (match_operand:SF 1 "register_operand") 600 (match_operand 2 "const_int_operand")] 601 "TARGET_MMX || TARGET_MMX_WITH_SSE" 602{ 603 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1], 604 INTVAL (operands[2])); 605 DONE; 606}) 607 608;; Avoid combining registers from different units in a single alternative, 609;; see comment above inline_secondary_memory_needed function in i386.c 610(define_insn_and_split "*vec_extractv2sf_0" 611 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r") 612 (vec_select:SF 613 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m") 614 (parallel [(const_int 0)])))] 615 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 616 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 617 "#" 618 "&& reload_completed" 619 [(set (match_dup 0) (match_dup 1))] 620 "operands[1] = gen_lowpart (SFmode, operands[1]);" 621 [(set_attr "mmx_isa" "*,*,native,native,*,*")]) 622 623;; Avoid combining registers from different units in a single alternative, 624;; see comment above inline_secondary_memory_needed function in i386.c 625(define_insn "*vec_extractv2sf_1" 626 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,x,y,x,f,r") 627 (vec_select:SF 628 (match_operand:V2SF 1 "nonimmediate_operand" " 0,x,0,o,o,o,o") 629 (parallel [(const_int 1)])))] 630 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 632 "@ 633 punpckhdq\t%0, %0 634 %vmovshdup\t{%1, %0|%0, %1} 635 shufps\t{$0xe5, %0, %0|%0, %0, 0xe5} 636 # 637 # 638 # 639 #" 640 [(set_attr "isa" "*,sse3,noavx,*,*,*,*") 641 (set_attr "mmx_isa" "native,*,*,native,*,*,*") 642 (set_attr "type" "mmxcvt,sse,sseshuf1,mmxmov,ssemov,fmov,imov") 643 (set (attr "length_immediate") 644 (if_then_else (eq_attr "alternative" "2") 645 (const_string "1") 646 (const_string "*"))) 647 (set (attr "prefix_rep") 648 (if_then_else (eq_attr "alternative" "1") 649 (const_string "1") 650 (const_string "*"))) 651 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig,orig") 652 (set_attr "mode" "DI,V4SF,V4SF,SF,SF,SF,SF")]) 653 654(define_split 655 [(set (match_operand:SF 0 "register_operand") 656 (vec_select:SF 657 (match_operand:V2SF 1 "memory_operand") 658 (parallel [(const_int 1)])))] 659 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed" 660 [(set (match_dup 0) (match_dup 1))] 661 "operands[1] = adjust_address (operands[1], SFmode, 4);") 662 663(define_expand "vec_extractv2sfsf" 664 [(match_operand:SF 0 "register_operand") 665 (match_operand:V2SF 1 "register_operand") 666 (match_operand 2 "const_int_operand")] 667 "TARGET_MMX || TARGET_MMX_WITH_SSE" 668{ 669 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0], 670 operands[1], INTVAL (operands[2])); 671 DONE; 672}) 673 674(define_expand "vec_initv2sfsf" 675 [(match_operand:V2SF 0 "register_operand") 676 (match_operand 1)] 677 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE" 678{ 679 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0], 680 operands[1]); 681 DONE; 682}) 683 684;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 685;; 686;; Parallel integral arithmetic 687;; 688;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 689 690(define_expand "mmx_<plusminus_insn><mode>3" 691 [(set (match_operand:MMXMODEI8 0 "register_operand") 692 (plusminus:MMXMODEI8 693 (match_operand:MMXMODEI8 1 "register_mmxmem_operand") 694 (match_operand:MMXMODEI8 2 "register_mmxmem_operand")))] 695 "TARGET_MMX || TARGET_MMX_WITH_SSE" 696 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") 697 698(define_expand "<plusminus_insn><mode>3" 699 [(set (match_operand:MMXMODEI 0 "register_operand") 700 (plusminus:MMXMODEI 701 (match_operand:MMXMODEI 1 "register_operand") 702 (match_operand:MMXMODEI 2 "register_operand")))] 703 "TARGET_MMX_WITH_SSE" 704 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") 705 706(define_insn "*mmx_<plusminus_insn><mode>3" 707 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y,x,Yv") 708 (plusminus:MMXMODEI8 709 (match_operand:MMXMODEI8 1 "register_mmxmem_operand" "<comm>0,0,Yv") 710 (match_operand:MMXMODEI8 2 "register_mmxmem_operand" "ym,x,Yv")))] 711 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 712 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 713 "@ 714 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2} 715 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2} 716 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" 717 [(set_attr "isa" "*,sse2_noavx,avx") 718 (set_attr "mmx_isa" "native,*,*") 719 (set_attr "type" "mmxadd,sseadd,sseadd") 720 (set_attr "mode" "DI,TI,TI")]) 721 722(define_expand "mmx_<plusminus_insn><mode>3" 723 [(set (match_operand:MMXMODE12 0 "register_operand") 724 (sat_plusminus:MMXMODE12 725 (match_operand:MMXMODE12 1 "register_mmxmem_operand") 726 (match_operand:MMXMODE12 2 "register_mmxmem_operand")))] 727 "TARGET_MMX || TARGET_MMX_WITH_SSE" 728 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") 729 730(define_insn "*mmx_<plusminus_insn><mode>3" 731 [(set (match_operand:MMXMODE12 0 "register_operand" "=y,x,Yv") 732 (sat_plusminus:MMXMODE12 733 (match_operand:MMXMODE12 1 "register_mmxmem_operand" "<comm>0,0,Yv") 734 (match_operand:MMXMODE12 2 "register_mmxmem_operand" "ym,x,Yv")))] 735 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 736 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 737 "@ 738 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2} 739 p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2} 740 vp<plusminus_mnemonic><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" 741 [(set_attr "isa" "*,sse2_noavx,avx") 742 (set_attr "mmx_isa" "native,*,*") 743 (set_attr "type" "mmxadd,sseadd,sseadd") 744 (set_attr "mode" "DI,TI,TI")]) 745 746(define_expand "mmx_mulv4hi3" 747 [(set (match_operand:V4HI 0 "register_operand") 748 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand") 749 (match_operand:V4HI 2 "register_mmxmem_operand")))] 750 "TARGET_MMX || TARGET_MMX_WITH_SSE" 751 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 752 753(define_expand "mulv4hi3" 754 [(set (match_operand:V4HI 0 "register_operand") 755 (mult:V4HI (match_operand:V4HI 1 "register_operand") 756 (match_operand:V4HI 2 "register_operand")))] 757 "TARGET_MMX_WITH_SSE" 758 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 759 760(define_insn "*mmx_mulv4hi3" 761 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 762 (mult:V4HI (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv") 763 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))] 764 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 765 && ix86_binary_operator_ok (MULT, V4HImode, operands)" 766 "@ 767 pmullw\t{%2, %0|%0, %2} 768 pmullw\t{%2, %0|%0, %2} 769 vpmullw\t{%2, %1, %0|%0, %1, %2}" 770 [(set_attr "isa" "*,sse2_noavx,avx") 771 (set_attr "mmx_isa" "native,*,*") 772 (set_attr "type" "mmxmul,ssemul,ssemul") 773 (set_attr "mode" "DI,TI,TI")]) 774 775(define_expand "mmx_smulv4hi3_highpart" 776 [(set (match_operand:V4HI 0 "register_operand") 777 (truncate:V4HI 778 (lshiftrt:V4SI 779 (mult:V4SI 780 (sign_extend:V4SI 781 (match_operand:V4HI 1 "register_mmxmem_operand")) 782 (sign_extend:V4SI 783 (match_operand:V4HI 2 "register_mmxmem_operand"))) 784 (const_int 16))))] 785 "TARGET_MMX || TARGET_MMX_WITH_SSE" 786 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 787 788(define_insn "*mmx_smulv4hi3_highpart" 789 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 790 (truncate:V4HI 791 (lshiftrt:V4SI 792 (mult:V4SI 793 (sign_extend:V4SI 794 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")) 795 (sign_extend:V4SI 796 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))) 797 (const_int 16))))] 798 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 799 && ix86_binary_operator_ok (MULT, V4HImode, operands)" 800 "@ 801 pmulhw\t{%2, %0|%0, %2} 802 pmulhw\t{%2, %0|%0, %2} 803 vpmulhw\t{%2, %1, %0|%0, %1, %2}" 804 [(set_attr "isa" "*,sse2_noavx,avx") 805 (set_attr "mmx_isa" "native,*,*") 806 (set_attr "type" "mmxmul,ssemul,ssemul") 807 (set_attr "mode" "DI,TI,TI")]) 808 809(define_expand "mmx_umulv4hi3_highpart" 810 [(set (match_operand:V4HI 0 "register_operand") 811 (truncate:V4HI 812 (lshiftrt:V4SI 813 (mult:V4SI 814 (zero_extend:V4SI 815 (match_operand:V4HI 1 "register_mmxmem_operand")) 816 (zero_extend:V4SI 817 (match_operand:V4HI 2 "register_mmxmem_operand"))) 818 (const_int 16))))] 819 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 820 && (TARGET_SSE || TARGET_3DNOW_A)" 821 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 822 823(define_insn "*mmx_umulv4hi3_highpart" 824 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 825 (truncate:V4HI 826 (lshiftrt:V4SI 827 (mult:V4SI 828 (zero_extend:V4SI 829 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")) 830 (zero_extend:V4SI 831 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))) 832 (const_int 16))))] 833 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 834 && (TARGET_SSE || TARGET_3DNOW_A) 835 && ix86_binary_operator_ok (MULT, V4HImode, operands)" 836 "@ 837 pmulhuw\t{%2, %0|%0, %2} 838 pmulhuw\t{%2, %0|%0, %2} 839 vpmulhuw\t{%2, %1, %0|%0, %1, %2}" 840 [(set_attr "isa" "*,sse2_noavx,avx") 841 (set_attr "mmx_isa" "native,*,*") 842 (set_attr "type" "mmxmul,ssemul,ssemul") 843 (set_attr "mode" "DI,TI,TI")]) 844 845(define_expand "mmx_pmaddwd" 846 [(set (match_operand:V2SI 0 "register_operand") 847 (plus:V2SI 848 (mult:V2SI 849 (sign_extend:V2SI 850 (vec_select:V2HI 851 (match_operand:V4HI 1 "register_mmxmem_operand") 852 (parallel [(const_int 0) (const_int 2)]))) 853 (sign_extend:V2SI 854 (vec_select:V2HI 855 (match_operand:V4HI 2 "register_mmxmem_operand") 856 (parallel [(const_int 0) (const_int 2)])))) 857 (mult:V2SI 858 (sign_extend:V2SI 859 (vec_select:V2HI (match_dup 1) 860 (parallel [(const_int 1) (const_int 3)]))) 861 (sign_extend:V2SI 862 (vec_select:V2HI (match_dup 2) 863 (parallel [(const_int 1) (const_int 3)]))))))] 864 "TARGET_MMX || TARGET_MMX_WITH_SSE" 865 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 866 867(define_insn "*mmx_pmaddwd" 868 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv") 869 (plus:V2SI 870 (mult:V2SI 871 (sign_extend:V2SI 872 (vec_select:V2HI 873 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv") 874 (parallel [(const_int 0) (const_int 2)]))) 875 (sign_extend:V2SI 876 (vec_select:V2HI 877 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv") 878 (parallel [(const_int 0) (const_int 2)])))) 879 (mult:V2SI 880 (sign_extend:V2SI 881 (vec_select:V2HI (match_dup 1) 882 (parallel [(const_int 1) (const_int 3)]))) 883 (sign_extend:V2SI 884 (vec_select:V2HI (match_dup 2) 885 (parallel [(const_int 1) (const_int 3)]))))))] 886 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 887 && ix86_binary_operator_ok (MULT, V4HImode, operands)" 888 "@ 889 pmaddwd\t{%2, %0|%0, %2} 890 pmaddwd\t{%2, %0|%0, %2} 891 vpmaddwd\t{%2, %1, %0|%0, %1, %2}" 892 [(set_attr "isa" "*,sse2_noavx,avx") 893 (set_attr "mmx_isa" "native,*,*") 894 (set_attr "type" "mmxmul,sseiadd,sseiadd") 895 (set_attr "mode" "DI,TI,TI")]) 896 897(define_expand "mmx_pmulhrwv4hi3" 898 [(set (match_operand:V4HI 0 "register_operand") 899 (truncate:V4HI 900 (lshiftrt:V4SI 901 (plus:V4SI 902 (mult:V4SI 903 (sign_extend:V4SI 904 (match_operand:V4HI 1 "nonimmediate_operand")) 905 (sign_extend:V4SI 906 (match_operand:V4HI 2 "nonimmediate_operand"))) 907 (const_vector:V4SI [(const_int 32768) (const_int 32768) 908 (const_int 32768) (const_int 32768)])) 909 (const_int 16))))] 910 "TARGET_3DNOW" 911 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 912 913(define_insn "*mmx_pmulhrwv4hi3" 914 [(set (match_operand:V4HI 0 "register_operand" "=y") 915 (truncate:V4HI 916 (lshiftrt:V4SI 917 (plus:V4SI 918 (mult:V4SI 919 (sign_extend:V4SI 920 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 921 (sign_extend:V4SI 922 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 923 (const_vector:V4SI [(const_int 32768) (const_int 32768) 924 (const_int 32768) (const_int 32768)])) 925 (const_int 16))))] 926 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)" 927 "pmulhrw\t{%2, %0|%0, %2}" 928 [(set_attr "type" "mmxmul") 929 (set_attr "prefix_extra" "1") 930 (set_attr "mode" "DI")]) 931 932(define_expand "sse2_umulv1siv1di3" 933 [(set (match_operand:V1DI 0 "register_operand") 934 (mult:V1DI 935 (zero_extend:V1DI 936 (vec_select:V1SI 937 (match_operand:V2SI 1 "register_mmxmem_operand") 938 (parallel [(const_int 0)]))) 939 (zero_extend:V1DI 940 (vec_select:V1SI 941 (match_operand:V2SI 2 "register_mmxmem_operand") 942 (parallel [(const_int 0)])))))] 943 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE2" 944 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);") 945 946(define_insn "*sse2_umulv1siv1di3" 947 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv") 948 (mult:V1DI 949 (zero_extend:V1DI 950 (vec_select:V1SI 951 (match_operand:V2SI 1 "register_mmxmem_operand" "%0,0,Yv") 952 (parallel [(const_int 0)]))) 953 (zero_extend:V1DI 954 (vec_select:V1SI 955 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv") 956 (parallel [(const_int 0)])))))] 957 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 958 && TARGET_SSE2 959 && ix86_binary_operator_ok (MULT, V2SImode, operands)" 960 "@ 961 pmuludq\t{%2, %0|%0, %2} 962 pmuludq\t{%2, %0|%0, %2} 963 vpmuludq\t{%2, %1, %0|%0, %1, %2}" 964 [(set_attr "isa" "*,sse2_noavx,avx") 965 (set_attr "mmx_isa" "native,*,*") 966 (set_attr "type" "mmxmul,ssemul,ssemul") 967 (set_attr "mode" "DI,TI,TI")]) 968 969(define_expand "mmx_<code>v4hi3" 970 [(set (match_operand:V4HI 0 "register_operand") 971 (smaxmin:V4HI 972 (match_operand:V4HI 1 "register_mmxmem_operand") 973 (match_operand:V4HI 2 "register_mmxmem_operand")))] 974 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 975 && (TARGET_SSE || TARGET_3DNOW_A)" 976 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);") 977 978(define_expand "<code>v4hi3" 979 [(set (match_operand:V4HI 0 "register_operand") 980 (smaxmin:V4HI 981 (match_operand:V4HI 1 "register_operand") 982 (match_operand:V4HI 2 "register_operand")))] 983 "TARGET_MMX_WITH_SSE" 984 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);") 985 986(define_insn "*mmx_<code>v4hi3" 987 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 988 (smaxmin:V4HI 989 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv") 990 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")))] 991 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 992 && (TARGET_SSE || TARGET_3DNOW_A) 993 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)" 994 "@ 995 p<maxmin_int>w\t{%2, %0|%0, %2} 996 p<maxmin_int>w\t{%2, %0|%0, %2} 997 vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}" 998 [(set_attr "isa" "*,sse2_noavx,avx") 999 (set_attr "mmx_isa" "native,*,*") 1000 (set_attr "type" "mmxadd,sseiadd,sseiadd") 1001 (set_attr "mode" "DI,TI,TI")]) 1002 1003(define_expand "mmx_<code>v8qi3" 1004 [(set (match_operand:V8QI 0 "register_operand") 1005 (umaxmin:V8QI 1006 (match_operand:V8QI 1 "register_mmxmem_operand") 1007 (match_operand:V8QI 2 "register_mmxmem_operand")))] 1008 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1009 && (TARGET_SSE || TARGET_3DNOW_A)" 1010 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);") 1011 1012(define_expand "<code>v8qi3" 1013 [(set (match_operand:V8QI 0 "register_operand") 1014 (umaxmin:V8QI 1015 (match_operand:V8QI 1 "register_operand") 1016 (match_operand:V8QI 2 "register_operand")))] 1017 "TARGET_MMX_WITH_SSE" 1018 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);") 1019 1020(define_insn "*mmx_<code>v8qi3" 1021 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv") 1022 (umaxmin:V8QI 1023 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv") 1024 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")))] 1025 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1026 && (TARGET_SSE || TARGET_3DNOW_A) 1027 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)" 1028 "@ 1029 p<maxmin_int>b\t{%2, %0|%0, %2} 1030 p<maxmin_int>b\t{%2, %0|%0, %2} 1031 vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}" 1032 [(set_attr "isa" "*,sse2_noavx,avx") 1033 (set_attr "mmx_isa" "native,*,*") 1034 (set_attr "type" "mmxadd,sseiadd,sseiadd") 1035 (set_attr "mode" "DI,TI,TI")]) 1036 1037(define_insn "mmx_ashr<mode>3" 1038 [(set (match_operand:MMXMODE24 0 "register_operand" "=y,x,Yv") 1039 (ashiftrt:MMXMODE24 1040 (match_operand:MMXMODE24 1 "register_operand" "0,0,Yv") 1041 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))] 1042 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1043 "@ 1044 psra<mmxvecsize>\t{%2, %0|%0, %2} 1045 psra<mmxvecsize>\t{%2, %0|%0, %2} 1046 vpsra<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" 1047 [(set_attr "isa" "*,sse2_noavx,avx") 1048 (set_attr "mmx_isa" "native,*,*") 1049 (set_attr "type" "mmxshft,sseishft,sseishft") 1050 (set (attr "length_immediate") 1051 (if_then_else (match_operand 2 "const_int_operand") 1052 (const_string "1") 1053 (const_string "0"))) 1054 (set_attr "mode" "DI,TI,TI")]) 1055 1056(define_expand "ashr<mode>3" 1057 [(set (match_operand:MMXMODE24 0 "register_operand") 1058 (ashiftrt:MMXMODE24 1059 (match_operand:MMXMODE24 1 "register_operand") 1060 (match_operand:DI 2 "nonmemory_operand")))] 1061 "TARGET_MMX_WITH_SSE") 1062 1063(define_insn "mmx_<shift_insn><mode>3" 1064 [(set (match_operand:MMXMODE248 0 "register_operand" "=y,x,Yv") 1065 (any_lshift:MMXMODE248 1066 (match_operand:MMXMODE248 1 "register_operand" "0,0,Yv") 1067 (match_operand:DI 2 "nonmemory_operand" "yN,xN,YvN")))] 1068 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1069 "@ 1070 p<vshift><mmxvecsize>\t{%2, %0|%0, %2} 1071 p<vshift><mmxvecsize>\t{%2, %0|%0, %2} 1072 vp<vshift><mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" 1073 [(set_attr "isa" "*,sse2_noavx,avx") 1074 (set_attr "mmx_isa" "native,*,*") 1075 (set_attr "type" "mmxshft,sseishft,sseishft") 1076 (set (attr "length_immediate") 1077 (if_then_else (match_operand 2 "const_int_operand") 1078 (const_string "1") 1079 (const_string "0"))) 1080 (set_attr "mode" "DI,TI,TI")]) 1081 1082(define_expand "<shift_insn><mode>3" 1083 [(set (match_operand:MMXMODE24 0 "register_operand") 1084 (any_lshift:MMXMODE24 1085 (match_operand:MMXMODE24 1 "register_operand") 1086 (match_operand:DI 2 "nonmemory_operand")))] 1087 "TARGET_MMX_WITH_SSE") 1088 1089;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1090;; 1091;; Parallel integral comparisons 1092;; 1093;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1094 1095(define_expand "mmx_eq<mode>3" 1096 [(set (match_operand:MMXMODEI 0 "register_operand") 1097 (eq:MMXMODEI 1098 (match_operand:MMXMODEI 1 "register_mmxmem_operand") 1099 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))] 1100 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1101 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);") 1102 1103(define_insn "*mmx_eq<mode>3" 1104 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv") 1105 (eq:MMXMODEI 1106 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv") 1107 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))] 1108 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1109 && ix86_binary_operator_ok (EQ, <MODE>mode, operands)" 1110 "@ 1111 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2} 1112 pcmpeq<mmxvecsize>\t{%2, %0|%0, %2} 1113 vpcmpeq<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" 1114 [(set_attr "isa" "*,sse2_noavx,avx") 1115 (set_attr "mmx_isa" "native,*,*") 1116 (set_attr "type" "mmxcmp,ssecmp,ssecmp") 1117 (set_attr "mode" "DI,TI,TI")]) 1118 1119(define_insn "mmx_gt<mode>3" 1120 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv") 1121 (gt:MMXMODEI 1122 (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv") 1123 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))] 1124 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1125 "@ 1126 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2} 1127 pcmpgt<mmxvecsize>\t{%2, %0|%0, %2} 1128 vpcmpgt<mmxvecsize>\t{%2, %1, %0|%0, %1, %2}" 1129 [(set_attr "isa" "*,sse2_noavx,avx") 1130 (set_attr "mmx_isa" "native,*,*") 1131 (set_attr "type" "mmxcmp,ssecmp,ssecmp") 1132 (set_attr "mode" "DI,TI,TI")]) 1133 1134;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1135;; 1136;; Parallel integral logical operations 1137;; 1138;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1139 1140(define_expand "one_cmpl<mode>2" 1141 [(set (match_operand:MMXMODEI 0 "register_operand") 1142 (xor:MMXMODEI 1143 (match_operand:MMXMODEI 1 "register_operand") 1144 (match_dup 2)))] 1145 "TARGET_MMX_WITH_SSE" 1146 "operands[2] = force_reg (<MODE>mode, CONSTM1_RTX (<MODE>mode));") 1147 1148(define_insn "mmx_andnot<mode>3" 1149 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv") 1150 (and:MMXMODEI 1151 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0,0,Yv")) 1152 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))] 1153 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1154 "@ 1155 pandn\t{%2, %0|%0, %2} 1156 pandn\t{%2, %0|%0, %2} 1157 vpandn\t{%2, %1, %0|%0, %1, %2}" 1158 [(set_attr "isa" "*,sse2_noavx,avx") 1159 (set_attr "mmx_isa" "native,*,*") 1160 (set_attr "type" "mmxadd,sselog,sselog") 1161 (set_attr "mode" "DI,TI,TI")]) 1162 1163(define_expand "mmx_<code><mode>3" 1164 [(set (match_operand:MMXMODEI 0 "register_operand") 1165 (any_logic:MMXMODEI 1166 (match_operand:MMXMODEI 1 "register_mmxmem_operand") 1167 (match_operand:MMXMODEI 2 "register_mmxmem_operand")))] 1168 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1169 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") 1170 1171(define_expand "<code><mode>3" 1172 [(set (match_operand:MMXMODEI 0 "register_operand") 1173 (any_logic:MMXMODEI 1174 (match_operand:MMXMODEI 1 "register_operand") 1175 (match_operand:MMXMODEI 2 "register_operand")))] 1176 "TARGET_MMX_WITH_SSE" 1177 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") 1178 1179(define_insn "*mmx_<code><mode>3" 1180 [(set (match_operand:MMXMODEI 0 "register_operand" "=y,x,Yv") 1181 (any_logic:MMXMODEI 1182 (match_operand:MMXMODEI 1 "register_mmxmem_operand" "%0,0,Yv") 1183 (match_operand:MMXMODEI 2 "register_mmxmem_operand" "ym,x,Yv")))] 1184 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1185 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 1186 "@ 1187 p<logic>\t{%2, %0|%0, %2} 1188 p<logic>\t{%2, %0|%0, %2} 1189 vp<logic>\t{%2, %1, %0|%0, %1, %2}" 1190 [(set_attr "isa" "*,sse2_noavx,avx") 1191 (set_attr "mmx_isa" "native,*,*") 1192 (set_attr "type" "mmxadd,sselog,sselog") 1193 (set_attr "mode" "DI,TI,TI")]) 1194 1195;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1196;; 1197;; Parallel integral element swizzling 1198;; 1199;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1200 1201;; Used in signed and unsigned truncations with saturation. 1202(define_code_iterator any_s_truncate [ss_truncate us_truncate]) 1203;; Instruction suffix for truncations with saturation. 1204(define_code_attr s_trunsuffix [(ss_truncate "s") (us_truncate "u")]) 1205 1206(define_insn_and_split "mmx_pack<s_trunsuffix>swb" 1207 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv") 1208 (vec_concat:V8QI 1209 (any_s_truncate:V4QI 1210 (match_operand:V4HI 1 "register_operand" "0,0,Yv")) 1211 (any_s_truncate:V4QI 1212 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))))] 1213 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1214 "@ 1215 pack<s_trunsuffix>swb\t{%2, %0|%0, %2} 1216 # 1217 #" 1218 "TARGET_SSE2 && reload_completed 1219 && SSE_REGNO_P (REGNO (operands[0]))" 1220 [(const_int 0)] 1221 "ix86_split_mmx_pack (operands, <any_s_truncate:CODE>); DONE;" 1222 [(set_attr "mmx_isa" "native,sse_noavx,avx") 1223 (set_attr "type" "mmxshft,sselog,sselog") 1224 (set_attr "mode" "DI,TI,TI")]) 1225 1226(define_insn_and_split "mmx_packssdw" 1227 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 1228 (vec_concat:V4HI 1229 (ss_truncate:V2HI 1230 (match_operand:V2SI 1 "register_operand" "0,0,Yv")) 1231 (ss_truncate:V2HI 1232 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv"))))] 1233 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1234 "@ 1235 packssdw\t{%2, %0|%0, %2} 1236 # 1237 #" 1238 "TARGET_SSE2 && reload_completed 1239 && SSE_REGNO_P (REGNO (operands[0]))" 1240 [(const_int 0)] 1241 "ix86_split_mmx_pack (operands, SS_TRUNCATE); DONE;" 1242 [(set_attr "mmx_isa" "native,sse_noavx,avx") 1243 (set_attr "type" "mmxshft,sselog,sselog") 1244 (set_attr "mode" "DI,TI,TI")]) 1245 1246(define_insn_and_split "mmx_punpckhbw" 1247 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv") 1248 (vec_select:V8QI 1249 (vec_concat:V16QI 1250 (match_operand:V8QI 1 "register_operand" "0,0,Yv") 1251 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")) 1252 (parallel [(const_int 4) (const_int 12) 1253 (const_int 5) (const_int 13) 1254 (const_int 6) (const_int 14) 1255 (const_int 7) (const_int 15)])))] 1256 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1257 "@ 1258 punpckhbw\t{%2, %0|%0, %2} 1259 # 1260 #" 1261 "TARGET_SSE2 && reload_completed 1262 && SSE_REGNO_P (REGNO (operands[0]))" 1263 [(const_int 0)] 1264 "ix86_split_mmx_punpck (operands, true); DONE;" 1265 [(set_attr "mmx_isa" "native,sse_noavx,avx") 1266 (set_attr "type" "mmxcvt,sselog,sselog") 1267 (set_attr "mode" "DI,TI,TI")]) 1268 1269(define_insn_and_split "mmx_punpcklbw" 1270 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv") 1271 (vec_select:V8QI 1272 (vec_concat:V16QI 1273 (match_operand:V8QI 1 "register_operand" "0,0,Yv") 1274 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")) 1275 (parallel [(const_int 0) (const_int 8) 1276 (const_int 1) (const_int 9) 1277 (const_int 2) (const_int 10) 1278 (const_int 3) (const_int 11)])))] 1279 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1280 "@ 1281 punpcklbw\t{%2, %0|%0, %k2} 1282 # 1283 #" 1284 "TARGET_SSE2 && reload_completed 1285 && SSE_REGNO_P (REGNO (operands[0]))" 1286 [(const_int 0)] 1287 "ix86_split_mmx_punpck (operands, false); DONE;" 1288 [(set_attr "mmx_isa" "native,sse_noavx,avx") 1289 (set_attr "type" "mmxcvt,sselog,sselog") 1290 (set_attr "mode" "DI,TI,TI")]) 1291 1292(define_insn_and_split "mmx_punpckhwd" 1293 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 1294 (vec_select:V4HI 1295 (vec_concat:V8HI 1296 (match_operand:V4HI 1 "register_operand" "0,0,Yv") 1297 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")) 1298 (parallel [(const_int 2) (const_int 6) 1299 (const_int 3) (const_int 7)])))] 1300 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1301 "@ 1302 punpckhwd\t{%2, %0|%0, %2} 1303 # 1304 #" 1305 "TARGET_SSE2 && reload_completed 1306 && SSE_REGNO_P (REGNO (operands[0]))" 1307 [(const_int 0)] 1308 "ix86_split_mmx_punpck (operands, true); DONE;" 1309 [(set_attr "mmx_isa" "native,sse_noavx,avx") 1310 (set_attr "type" "mmxcvt,sselog,sselog") 1311 (set_attr "mode" "DI,TI,TI")]) 1312 1313(define_insn_and_split "mmx_punpcklwd" 1314 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 1315 (vec_select:V4HI 1316 (vec_concat:V8HI 1317 (match_operand:V4HI 1 "register_operand" "0,0,Yv") 1318 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv")) 1319 (parallel [(const_int 0) (const_int 4) 1320 (const_int 1) (const_int 5)])))] 1321 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1322 "@ 1323 punpcklwd\t{%2, %0|%0, %k2} 1324 # 1325 #" 1326 "TARGET_SSE2 && reload_completed 1327 && SSE_REGNO_P (REGNO (operands[0]))" 1328 [(const_int 0)] 1329 "ix86_split_mmx_punpck (operands, false); DONE;" 1330 [(set_attr "mmx_isa" "native,sse_noavx,avx") 1331 (set_attr "type" "mmxcvt,sselog,sselog") 1332 (set_attr "mode" "DI,TI,TI")]) 1333 1334(define_insn_and_split "mmx_punpckhdq" 1335 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv") 1336 (vec_select:V2SI 1337 (vec_concat:V4SI 1338 (match_operand:V2SI 1 "register_operand" "0,0,Yv") 1339 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")) 1340 (parallel [(const_int 1) 1341 (const_int 3)])))] 1342 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1343 "@ 1344 punpckhdq\t{%2, %0|%0, %2} 1345 # 1346 #" 1347 "TARGET_SSE2 && reload_completed 1348 && SSE_REGNO_P (REGNO (operands[0]))" 1349 [(const_int 0)] 1350 "ix86_split_mmx_punpck (operands, true); DONE;" 1351 [(set_attr "mmx_isa" "native,sse_noavx,avx") 1352 (set_attr "type" "mmxcvt,sselog,sselog") 1353 (set_attr "mode" "DI,TI,TI")]) 1354 1355(define_insn_and_split "mmx_punpckldq" 1356 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv") 1357 (vec_select:V2SI 1358 (vec_concat:V4SI 1359 (match_operand:V2SI 1 "register_operand" "0,0,Yv") 1360 (match_operand:V2SI 2 "register_mmxmem_operand" "ym,x,Yv")) 1361 (parallel [(const_int 0) 1362 (const_int 2)])))] 1363 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1364 "@ 1365 punpckldq\t{%2, %0|%0, %k2} 1366 # 1367 #" 1368 "TARGET_SSE2 && reload_completed 1369 && SSE_REGNO_P (REGNO (operands[0]))" 1370 [(const_int 0)] 1371 "ix86_split_mmx_punpck (operands, false); DONE;" 1372 [(set_attr "mmx_isa" "native,sse_noavx,avx") 1373 (set_attr "type" "mmxcvt,sselog,sselog") 1374 (set_attr "mode" "DI,TI,TI")]) 1375 1376(define_insn "*mmx_pinsrd" 1377 [(set (match_operand:V2SI 0 "register_operand" "=x,Yv") 1378 (vec_merge:V2SI 1379 (vec_duplicate:V2SI 1380 (match_operand:SI 2 "nonimmediate_operand" "rm,rm")) 1381 (match_operand:V2SI 1 "register_operand" "0,Yv") 1382 (match_operand:SI 3 "const_int_operand")))] 1383 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1 1384 && ((unsigned) exact_log2 (INTVAL (operands[3])) 1385 < GET_MODE_NUNITS (V2SImode))" 1386{ 1387 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); 1388 switch (which_alternative) 1389 { 1390 case 1: 1391 return "vpinsrd\t{%3, %2, %1, %0|%0, %1, %2, %3}"; 1392 case 0: 1393 return "pinsrd\t{%3, %2, %0|%0, %2, %3}"; 1394 default: 1395 gcc_unreachable (); 1396 } 1397} 1398 [(set_attr "isa" "noavx,avx") 1399 (set_attr "prefix_data16" "1") 1400 (set_attr "prefix_extra" "1") 1401 (set_attr "type" "sselog") 1402 (set_attr "length_immediate" "1") 1403 (set_attr "prefix" "orig,vex") 1404 (set_attr "mode" "TI")]) 1405 1406(define_expand "mmx_pinsrw" 1407 [(set (match_operand:V4HI 0 "register_operand") 1408 (vec_merge:V4HI 1409 (vec_duplicate:V4HI 1410 (match_operand:SI 2 "nonimmediate_operand")) 1411 (match_operand:V4HI 1 "register_operand") 1412 (match_operand:SI 3 "const_0_to_3_operand")))] 1413 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1414 && (TARGET_SSE || TARGET_3DNOW_A)" 1415{ 1416 operands[2] = gen_lowpart (HImode, operands[2]); 1417 operands[3] = GEN_INT (1 << INTVAL (operands[3])); 1418}) 1419 1420(define_insn "*mmx_pinsrw" 1421 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 1422 (vec_merge:V4HI 1423 (vec_duplicate:V4HI 1424 (match_operand:HI 2 "nonimmediate_operand" "rm,rm,rm")) 1425 (match_operand:V4HI 1 "register_operand" "0,0,Yv") 1426 (match_operand:SI 3 "const_int_operand")))] 1427 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1428 && (TARGET_SSE || TARGET_3DNOW_A) 1429 && ((unsigned) exact_log2 (INTVAL (operands[3])) 1430 < GET_MODE_NUNITS (V4HImode))" 1431{ 1432 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); 1433 switch (which_alternative) 1434 { 1435 case 2: 1436 if (MEM_P (operands[2])) 1437 return "vpinsrw\t{%3, %2, %1, %0|%0, %1, %2, %3}"; 1438 else 1439 return "vpinsrw\t{%3, %k2, %1, %0|%0, %1, %k2, %3}"; 1440 case 1: 1441 case 0: 1442 if (MEM_P (operands[2])) 1443 return "pinsrw\t{%3, %2, %0|%0, %2, %3}"; 1444 else 1445 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}"; 1446 default: 1447 gcc_unreachable (); 1448 } 1449} 1450 [(set_attr "isa" "*,sse2_noavx,avx") 1451 (set_attr "mmx_isa" "native,*,*") 1452 (set_attr "type" "mmxcvt,sselog,sselog") 1453 (set_attr "length_immediate" "1") 1454 (set_attr "mode" "DI,TI,TI")]) 1455 1456(define_insn "*mmx_pinsrb" 1457 [(set (match_operand:V8QI 0 "register_operand" "=x,Yv") 1458 (vec_merge:V8QI 1459 (vec_duplicate:V8QI 1460 (match_operand:QI 2 "nonimmediate_operand" "rm,rm")) 1461 (match_operand:V8QI 1 "register_operand" "0,Yv") 1462 (match_operand:SI 3 "const_int_operand")))] 1463 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1 1464 && ((unsigned) exact_log2 (INTVAL (operands[3])) 1465 < GET_MODE_NUNITS (V8QImode))" 1466{ 1467 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); 1468 switch (which_alternative) 1469 { 1470 case 1: 1471 if (MEM_P (operands[2])) 1472 return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}"; 1473 else 1474 return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}"; 1475 case 0: 1476 if (MEM_P (operands[2])) 1477 return "pinsrb\t{%3, %2, %0|%0, %2, %3}"; 1478 else 1479 return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}"; 1480 default: 1481 gcc_unreachable (); 1482 } 1483} 1484 [(set_attr "isa" "noavx,avx") 1485 (set_attr "type" "sselog") 1486 (set_attr "prefix_data16" "1") 1487 (set_attr "prefix_extra" "1") 1488 (set_attr "length_immediate" "1") 1489 (set_attr "prefix" "orig,vex") 1490 (set_attr "mode" "TI")]) 1491 1492(define_insn "*mmx_pextrw" 1493 [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,r,m") 1494 (vec_select:HI 1495 (match_operand:V4HI 1 "register_operand" "y,Yv,Yv") 1496 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))] 1497 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1498 && (TARGET_SSE || TARGET_3DNOW_A)" 1499 "@ 1500 pextrw\t{%2, %1, %k0|%k0, %1, %2} 1501 %vpextrw\t{%2, %1, %k0|%k0, %1, %2} 1502 %vpextrw\t{%2, %1, %0|%0, %1, %2}" 1503 [(set_attr "isa" "*,sse2,sse4") 1504 (set_attr "mmx_isa" "native,*,*") 1505 (set_attr "type" "mmxcvt,sselog1,sselog1") 1506 (set_attr "length_immediate" "1") 1507 (set_attr "prefix" "orig,maybe_vex,maybe_vex") 1508 (set_attr "mode" "DI,TI,TI")]) 1509 1510(define_insn "*mmx_pextrw_zext" 1511 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 1512 (zero_extend:SWI48 1513 (vec_select:HI 1514 (match_operand:V4HI 1 "register_operand" "y,Yv") 1515 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))] 1516 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1517 && (TARGET_SSE || TARGET_3DNOW_A)" 1518 "@ 1519 pextrw\t{%2, %1, %k0|%k0, %1, %2} 1520 %vpextrw\t{%2, %1, %k0|%k0, %1, %2}" 1521 [(set_attr "isa" "*,sse2") 1522 (set_attr "mmx_isa" "native,*") 1523 (set_attr "type" "mmxcvt,sselog1") 1524 (set_attr "length_immediate" "1") 1525 (set_attr "prefix" "orig,maybe_vex") 1526 (set_attr "mode" "DI,TI")]) 1527 1528(define_insn "*mmx_pextrb" 1529 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m") 1530 (vec_select:QI 1531 (match_operand:V8QI 1 "register_operand" "Yv,Yv") 1532 (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))] 1533 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1" 1534 "@ 1535 %vpextrb\t{%2, %1, %k0|%k0, %1, %2} 1536 %vpextrb\t{%2, %1, %0|%0, %1, %2}" 1537 [(set_attr "type" "sselog1") 1538 (set_attr "prefix_data16" "1") 1539 (set_attr "prefix_extra" "1") 1540 (set_attr "length_immediate" "1") 1541 (set_attr "prefix" "maybe_vex") 1542 (set_attr "mode" "TI")]) 1543 1544(define_insn "*mmx_pextrb_zext" 1545 [(set (match_operand:SWI248 0 "register_operand" "=r") 1546 (zero_extend:SWI248 1547 (vec_select:QI 1548 (match_operand:V8QI 1 "register_operand" "Yv") 1549 (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))] 1550 "TARGET_MMX_WITH_SSE && TARGET_SSE4_1" 1551 "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}" 1552 [(set_attr "type" "sselog1") 1553 (set_attr "prefix_data16" "1") 1554 (set_attr "prefix_extra" "1") 1555 (set_attr "length_immediate" "1") 1556 (set_attr "prefix" "maybe_vex") 1557 (set_attr "mode" "TI")]) 1558 1559(define_expand "mmx_pshufw" 1560 [(match_operand:V4HI 0 "register_operand") 1561 (match_operand:V4HI 1 "register_mmxmem_operand") 1562 (match_operand:SI 2 "const_int_operand")] 1563 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1564 && (TARGET_SSE || TARGET_3DNOW_A)" 1565{ 1566 int mask = INTVAL (operands[2]); 1567 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1], 1568 GEN_INT ((mask >> 0) & 3), 1569 GEN_INT ((mask >> 2) & 3), 1570 GEN_INT ((mask >> 4) & 3), 1571 GEN_INT ((mask >> 6) & 3))); 1572 DONE; 1573}) 1574 1575(define_insn "mmx_pshufw_1" 1576 [(set (match_operand:V4HI 0 "register_operand" "=y,Yv") 1577 (vec_select:V4HI 1578 (match_operand:V4HI 1 "register_mmxmem_operand" "ym,Yv") 1579 (parallel [(match_operand 2 "const_0_to_3_operand") 1580 (match_operand 3 "const_0_to_3_operand") 1581 (match_operand 4 "const_0_to_3_operand") 1582 (match_operand 5 "const_0_to_3_operand")])))] 1583 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1584 && (TARGET_SSE || TARGET_3DNOW_A)" 1585{ 1586 int mask = 0; 1587 mask |= INTVAL (operands[2]) << 0; 1588 mask |= INTVAL (operands[3]) << 2; 1589 mask |= INTVAL (operands[4]) << 4; 1590 mask |= INTVAL (operands[5]) << 6; 1591 operands[2] = GEN_INT (mask); 1592 1593 switch (which_alternative) 1594 { 1595 case 0: 1596 return "pshufw\t{%2, %1, %0|%0, %1, %2}"; 1597 case 1: 1598 return "%vpshuflw\t{%2, %1, %0|%0, %1, %2}"; 1599 default: 1600 gcc_unreachable (); 1601 } 1602} 1603 [(set_attr "isa" "*,sse2") 1604 (set_attr "mmx_isa" "native,*") 1605 (set_attr "type" "mmxcvt,sselog") 1606 (set_attr "length_immediate" "1") 1607 (set_attr "mode" "DI,TI")]) 1608 1609(define_insn "mmx_pswapdv2si2" 1610 [(set (match_operand:V2SI 0 "register_operand" "=y") 1611 (vec_select:V2SI 1612 (match_operand:V2SI 1 "nonimmediate_operand" "ym") 1613 (parallel [(const_int 1) (const_int 0)])))] 1614 "TARGET_3DNOW_A" 1615 "pswapd\t{%1, %0|%0, %1}" 1616 [(set_attr "type" "mmxcvt") 1617 (set_attr "prefix_extra" "1") 1618 (set_attr "mode" "DI")]) 1619 1620(define_insn_and_split "*vec_dupv4hi" 1621 [(set (match_operand:V4HI 0 "register_operand" "=y,xYw,Yw") 1622 (vec_duplicate:V4HI 1623 (truncate:HI 1624 (match_operand:SI 1 "register_operand" "0,xYw,r"))))] 1625 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1626 && (TARGET_SSE || TARGET_3DNOW_A)" 1627 "@ 1628 pshufw\t{$0, %0, %0|%0, %0, 0} 1629 # 1630 #" 1631 "TARGET_SSE2 && reload_completed 1632 && SSE_REGNO_P (REGNO (operands[0]))" 1633 [(const_int 0)] 1634{ 1635 rtx op; 1636 operands[0] = lowpart_subreg (V8HImode, operands[0], 1637 GET_MODE (operands[0])); 1638 if (TARGET_AVX2) 1639 { 1640 operands[1] = lowpart_subreg (HImode, operands[1], 1641 GET_MODE (operands[1])); 1642 op = gen_rtx_VEC_DUPLICATE (V8HImode, operands[1]); 1643 } 1644 else 1645 { 1646 operands[1] = lowpart_subreg (V8HImode, operands[1], 1647 GET_MODE (operands[1])); 1648 rtx mask = gen_rtx_PARALLEL (VOIDmode, 1649 gen_rtvec (8, 1650 GEN_INT (0), 1651 GEN_INT (0), 1652 GEN_INT (0), 1653 GEN_INT (0), 1654 GEN_INT (4), 1655 GEN_INT (5), 1656 GEN_INT (6), 1657 GEN_INT (7))); 1658 1659 op = gen_rtx_VEC_SELECT (V8HImode, operands[1], mask); 1660 } 1661 emit_insn (gen_rtx_SET (operands[0], op)); 1662 DONE; 1663} 1664 [(set_attr "mmx_isa" "native,sse,avx") 1665 (set_attr "type" "mmxcvt,sselog1,ssemov") 1666 (set_attr "length_immediate" "1,1,0") 1667 (set_attr "mode" "DI,TI,TI")]) 1668 1669(define_insn_and_split "*vec_dupv2si" 1670 [(set (match_operand:V2SI 0 "register_operand" "=y,x,Yv,Yw") 1671 (vec_duplicate:V2SI 1672 (match_operand:SI 1 "register_operand" "0,0,Yv,r")))] 1673 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1674 "@ 1675 punpckldq\t%0, %0 1676 # 1677 # 1678 #" 1679 "TARGET_SSE && reload_completed 1680 && SSE_REGNO_P (REGNO (operands[0]))" 1681 [(set (match_dup 0) 1682 (vec_duplicate:V4SI (match_dup 1)))] 1683{ 1684 operands[0] = lowpart_subreg (V4SImode, operands[0], 1685 GET_MODE (operands[0])); 1686} 1687 [(set_attr "isa" "*,sse_noavx,avx,avx") 1688 (set_attr "mmx_isa" "native,*,*,*") 1689 (set_attr "type" "mmxcvt,ssemov,ssemov,ssemov") 1690 (set_attr "mode" "DI,TI,TI,TI")]) 1691 1692(define_insn "*mmx_concatv2si" 1693 [(set (match_operand:V2SI 0 "register_operand" "=y,y") 1694 (vec_concat:V2SI 1695 (match_operand:SI 1 "nonimmediate_operand" " 0,rm") 1696 (match_operand:SI 2 "nonimm_or_0_operand" "ym,C")))] 1697 "TARGET_MMX && !TARGET_SSE" 1698 "@ 1699 punpckldq\t{%2, %0|%0, %2} 1700 movd\t{%1, %0|%0, %1}" 1701 [(set_attr "type" "mmxcvt,mmxmov") 1702 (set_attr "mode" "DI")]) 1703 1704(define_expand "vec_setv2si" 1705 [(match_operand:V2SI 0 "register_operand") 1706 (match_operand:SI 1 "register_operand") 1707 (match_operand 2 "const_int_operand")] 1708 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1709{ 1710 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1], 1711 INTVAL (operands[2])); 1712 DONE; 1713}) 1714 1715;; Avoid combining registers from different units in a single alternative, 1716;; see comment above inline_secondary_memory_needed function in i386.c 1717(define_insn_and_split "*vec_extractv2si_0" 1718 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r,r") 1719 (vec_select:SI 1720 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m,x") 1721 (parallel [(const_int 0)])))] 1722 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1723 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1724 "#" 1725 "&& reload_completed" 1726 [(set (match_dup 0) (match_dup 1))] 1727 "operands[1] = gen_lowpart (SImode, operands[1]);" 1728 [(set_attr "isa" "*,*,*,*,*,sse2") 1729 (set_attr "mmx_isa" "*,*,native,native,*,*") 1730 (set (attr "preferred_for_speed") 1731 (cond [(eq_attr "alternative" "5") 1732 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 1733 ] 1734 (symbol_ref "true")))]) 1735 1736(define_insn "*vec_extractv2si_0_zext_sse4" 1737 [(set (match_operand:DI 0 "register_operand" "=r,x") 1738 (zero_extend:DI 1739 (vec_select:SI 1740 (match_operand:V2SI 1 "register_operand" "x,x") 1741 (parallel [(const_int 0)]))))] 1742 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE4_1" 1743 "#" 1744 [(set_attr "isa" "x64,*") 1745 (set (attr "preferred_for_speed") 1746 (cond [(eq_attr "alternative" "0") 1747 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 1748 ] 1749 (symbol_ref "true")))]) 1750 1751(define_insn "*vec_extractv2si_0_zext" 1752 [(set (match_operand:DI 0 "register_operand" "=r") 1753 (zero_extend:DI 1754 (vec_select:SI 1755 (match_operand:V2SI 1 "register_operand" "x") 1756 (parallel [(const_int 0)]))))] 1757 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1758 && TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC" 1759 "#") 1760 1761(define_split 1762 [(set (match_operand:DI 0 "register_operand") 1763 (zero_extend:DI 1764 (vec_select:SI 1765 (match_operand:V2SI 1 "register_operand") 1766 (parallel [(const_int 0)]))))] 1767 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1768 && TARGET_SSE2 && reload_completed" 1769 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))] 1770 "operands[1] = gen_lowpart (SImode, operands[1]);") 1771 1772;; Avoid combining registers from different units in a single alternative, 1773;; see comment above inline_secondary_memory_needed function in i386.c 1774(define_insn "*vec_extractv2si_1" 1775 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,rm,x,x,y,x,r") 1776 (vec_select:SI 1777 (match_operand:V2SI 1 "nonimmediate_operand" " 0,x ,x,0,o,o,o") 1778 (parallel [(const_int 1)])))] 1779 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1780 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1781 "@ 1782 punpckhdq\t%0, %0 1783 %vpextrd\t{$1, %1, %0|%0, %1, 1} 1784 %vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5} 1785 shufps\t{$0xe5, %0, %0|%0, %0, 0xe5} 1786 # 1787 # 1788 #" 1789 [(set_attr "isa" "*,sse4,sse2,noavx,*,*,*") 1790 (set_attr "mmx_isa" "native,*,*,*,native,*,*") 1791 (set_attr "type" "mmxcvt,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov") 1792 (set (attr "length_immediate") 1793 (if_then_else (eq_attr "alternative" "1,2,3") 1794 (const_string "1") 1795 (const_string "*"))) 1796 (set_attr "prefix" "orig,maybe_vex,maybe_vex,orig,orig,orig,orig") 1797 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")]) 1798 1799(define_split 1800 [(set (match_operand:SI 0 "register_operand") 1801 (vec_select:SI 1802 (match_operand:V2SI 1 "memory_operand") 1803 (parallel [(const_int 1)])))] 1804 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && reload_completed" 1805 [(set (match_dup 0) (match_dup 1))] 1806 "operands[1] = adjust_address (operands[1], SImode, 4);") 1807 1808(define_insn "*vec_extractv2si_1_zext" 1809 [(set (match_operand:DI 0 "register_operand" "=r") 1810 (zero_extend:DI 1811 (vec_select:SI 1812 (match_operand:V2SI 1 "register_operand" "x") 1813 (parallel [(const_int 1)]))))] 1814 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1815 && TARGET_64BIT && TARGET_SSE4_1" 1816 "%vpextrd\t{$1, %1, %k0|%k0, %1, 1}" 1817 [(set_attr "type" "sselog1") 1818 (set_attr "prefix_extra" "1") 1819 (set_attr "length_immediate" "1") 1820 (set_attr "prefix" "maybe_vex") 1821 (set_attr "mode" "TI")]) 1822 1823(define_insn_and_split "*vec_extractv2si_zext_mem" 1824 [(set (match_operand:DI 0 "register_operand" "=y,x,r") 1825 (zero_extend:DI 1826 (vec_select:SI 1827 (match_operand:V2SI 1 "memory_operand" "o,o,o") 1828 (parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))] 1829 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_64BIT" 1830 "#" 1831 "&& reload_completed" 1832 [(set (match_dup 0) (zero_extend:DI (match_dup 1)))] 1833{ 1834 operands[1] = adjust_address (operands[1], SImode, INTVAL (operands[2]) * 4); 1835} 1836 [(set_attr "isa" "*,sse2,*") 1837 (set_attr "mmx_isa" "native,*,*")]) 1838 1839(define_expand "vec_extractv2sisi" 1840 [(match_operand:SI 0 "register_operand") 1841 (match_operand:V2SI 1 "register_operand") 1842 (match_operand 2 "const_int_operand")] 1843 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1844{ 1845 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0], 1846 operands[1], INTVAL (operands[2])); 1847 DONE; 1848}) 1849 1850(define_expand "vec_initv2sisi" 1851 [(match_operand:V2SI 0 "register_operand") 1852 (match_operand 1)] 1853 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE" 1854{ 1855 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0], 1856 operands[1]); 1857 DONE; 1858}) 1859 1860(define_expand "vec_setv4hi" 1861 [(match_operand:V4HI 0 "register_operand") 1862 (match_operand:HI 1 "register_operand") 1863 (match_operand 2 "const_int_operand")] 1864 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1865{ 1866 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1], 1867 INTVAL (operands[2])); 1868 DONE; 1869}) 1870 1871(define_expand "vec_extractv4hihi" 1872 [(match_operand:HI 0 "register_operand") 1873 (match_operand:V4HI 1 "register_operand") 1874 (match_operand 2 "const_int_operand")] 1875 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1876{ 1877 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0], 1878 operands[1], INTVAL (operands[2])); 1879 DONE; 1880}) 1881 1882(define_expand "vec_initv4hihi" 1883 [(match_operand:V4HI 0 "register_operand") 1884 (match_operand 1)] 1885 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE" 1886{ 1887 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0], 1888 operands[1]); 1889 DONE; 1890}) 1891 1892(define_expand "vec_setv8qi" 1893 [(match_operand:V8QI 0 "register_operand") 1894 (match_operand:QI 1 "register_operand") 1895 (match_operand 2 "const_int_operand")] 1896 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1897{ 1898 ix86_expand_vector_set (TARGET_MMX_WITH_SSE, operands[0], operands[1], 1899 INTVAL (operands[2])); 1900 DONE; 1901}) 1902 1903(define_expand "vec_extractv8qiqi" 1904 [(match_operand:QI 0 "register_operand") 1905 (match_operand:V8QI 1 "register_operand") 1906 (match_operand 2 "const_int_operand")] 1907 "TARGET_MMX || TARGET_MMX_WITH_SSE" 1908{ 1909 ix86_expand_vector_extract (TARGET_MMX_WITH_SSE, operands[0], 1910 operands[1], INTVAL (operands[2])); 1911 DONE; 1912}) 1913 1914(define_expand "vec_initv8qiqi" 1915 [(match_operand:V8QI 0 "register_operand") 1916 (match_operand 1)] 1917 "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE" 1918{ 1919 ix86_expand_vector_init (TARGET_MMX_WITH_SSE, operands[0], 1920 operands[1]); 1921 DONE; 1922}) 1923 1924;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1925;; 1926;; Miscellaneous 1927;; 1928;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1929 1930(define_expand "mmx_uavg<mode>3" 1931 [(set (match_operand:MMXMODE12 0 "register_operand") 1932 (truncate:MMXMODE12 1933 (lshiftrt:<mmxdoublemode> 1934 (plus:<mmxdoublemode> 1935 (plus:<mmxdoublemode> 1936 (zero_extend:<mmxdoublemode> 1937 (match_operand:MMXMODE12 1 "register_mmxmem_operand")) 1938 (zero_extend:<mmxdoublemode> 1939 (match_operand:MMXMODE12 2 "register_mmxmem_operand"))) 1940 (match_dup 3)) 1941 (const_int 1))))] 1942 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1943 && (TARGET_SSE || TARGET_3DNOW)" 1944{ 1945 operands[3] = CONST1_RTX(<mmxdoublemode>mode); 1946 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands); 1947}) 1948 1949(define_insn "*mmx_uavgv8qi3" 1950 [(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv") 1951 (truncate:V8QI 1952 (lshiftrt:V8HI 1953 (plus:V8HI 1954 (plus:V8HI 1955 (zero_extend:V8HI 1956 (match_operand:V8QI 1 "register_mmxmem_operand" "%0,0,Yv")) 1957 (zero_extend:V8HI 1958 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv"))) 1959 (const_vector:V8HI [(const_int 1) (const_int 1) 1960 (const_int 1) (const_int 1) 1961 (const_int 1) (const_int 1) 1962 (const_int 1) (const_int 1)])) 1963 (const_int 1))))] 1964 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 1965 && (TARGET_SSE || TARGET_3DNOW) 1966 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 1967{ 1968 switch (which_alternative) 1969 { 1970 case 2: 1971 return "vpavgb\t{%2, %1, %0|%0, %1, %2}"; 1972 case 1: 1973 case 0: 1974 /* These two instructions have the same operation, but their encoding 1975 is different. Prefer the one that is de facto standard. */ 1976 if (TARGET_SSE || TARGET_3DNOW_A) 1977 return "pavgb\t{%2, %0|%0, %2}"; 1978 else 1979 return "pavgusb\t{%2, %0|%0, %2}"; 1980 default: 1981 gcc_unreachable (); 1982 } 1983} 1984 [(set_attr "isa" "*,sse2_noavx,avx") 1985 (set_attr "mmx_isa" "native,*,*") 1986 (set_attr "type" "mmxshft,sseiadd,sseiadd") 1987 (set (attr "prefix_extra") 1988 (if_then_else 1989 (not (ior (match_test "TARGET_SSE") 1990 (match_test "TARGET_3DNOW_A"))) 1991 (const_string "1") 1992 (const_string "*"))) 1993 (set_attr "mode" "DI,TI,TI")]) 1994 1995(define_insn "*mmx_uavgv4hi3" 1996 [(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv") 1997 (truncate:V4HI 1998 (lshiftrt:V4SI 1999 (plus:V4SI 2000 (plus:V4SI 2001 (zero_extend:V4SI 2002 (match_operand:V4HI 1 "register_mmxmem_operand" "%0,0,Yv")) 2003 (zero_extend:V4SI 2004 (match_operand:V4HI 2 "register_mmxmem_operand" "ym,x,Yv"))) 2005 (const_vector:V4SI [(const_int 1) (const_int 1) 2006 (const_int 1) (const_int 1)])) 2007 (const_int 1))))] 2008 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 2009 && (TARGET_SSE || TARGET_3DNOW_A) 2010 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 2011 "@ 2012 pavgw\t{%2, %0|%0, %2} 2013 pavgw\t{%2, %0|%0, %2} 2014 vpavgw\t{%2, %1, %0|%0, %1, %2}" 2015 [(set_attr "isa" "*,sse2_noavx,avx") 2016 (set_attr "mmx_isa" "native,*,*") 2017 (set_attr "type" "mmxshft,sseiadd,sseiadd") 2018 (set_attr "mode" "DI,TI,TI")]) 2019 2020(define_expand "uavg<mode>3_ceil" 2021 [(set (match_operand:MMXMODE12 0 "register_operand") 2022 (truncate:MMXMODE12 2023 (lshiftrt:<mmxdoublemode> 2024 (plus:<mmxdoublemode> 2025 (plus:<mmxdoublemode> 2026 (zero_extend:<mmxdoublemode> 2027 (match_operand:MMXMODE12 1 "register_operand")) 2028 (zero_extend:<mmxdoublemode> 2029 (match_operand:MMXMODE12 2 "register_operand"))) 2030 (match_dup 3)) 2031 (const_int 1))))] 2032 "TARGET_MMX_WITH_SSE" 2033{ 2034 operands[3] = CONST1_RTX(<mmxdoublemode>mode); 2035 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands); 2036}) 2037 2038(define_insn "mmx_psadbw" 2039 [(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv") 2040 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yv") 2041 (match_operand:V8QI 2 "register_mmxmem_operand" "ym,x,Yv")] 2042 UNSPEC_PSADBW))] 2043 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 2044 && (TARGET_SSE || TARGET_3DNOW_A)" 2045 "@ 2046 psadbw\t{%2, %0|%0, %2} 2047 psadbw\t{%2, %0|%0, %2} 2048 vpsadbw\t{%2, %1, %0|%0, %1, %2}" 2049 [(set_attr "isa" "*,sse2_noavx,avx") 2050 (set_attr "mmx_isa" "native,*,*") 2051 (set_attr "type" "mmxshft,sseiadd,sseiadd") 2052 (set_attr "mode" "DI,TI,TI")]) 2053 2054(define_expand "reduc_plus_scal_v8qi" 2055 [(plus:V8QI 2056 (match_operand:QI 0 "register_operand") 2057 (match_operand:V8QI 1 "register_operand"))] 2058 "TARGET_MMX_WITH_SSE" 2059{ 2060 rtx tmp = gen_reg_rtx (V8QImode); 2061 emit_move_insn (tmp, CONST0_RTX (V8QImode)); 2062 rtx tmp2 = gen_reg_rtx (V1DImode); 2063 emit_insn (gen_mmx_psadbw (tmp2, operands[1], tmp)); 2064 tmp2 = gen_lowpart (V8QImode, tmp2); 2065 emit_insn (gen_vec_extractv8qiqi (operands[0], tmp2, const0_rtx)); 2066 DONE; 2067}) 2068 2069(define_expand "usadv8qi" 2070 [(match_operand:V2SI 0 "register_operand") 2071 (match_operand:V8QI 1 "register_operand") 2072 (match_operand:V8QI 2 "register_operand") 2073 (match_operand:V2SI 3 "register_operand")] 2074 "TARGET_MMX_WITH_SSE" 2075{ 2076 rtx t1 = gen_reg_rtx (V1DImode); 2077 rtx t2 = gen_reg_rtx (V2SImode); 2078 emit_insn (gen_mmx_psadbw (t1, operands[1], operands[2])); 2079 convert_move (t2, t1, 0); 2080 emit_insn (gen_addv2si3 (operands[0], t2, operands[3])); 2081 DONE; 2082}) 2083 2084(define_insn_and_split "mmx_pmovmskb" 2085 [(set (match_operand:SI 0 "register_operand" "=r,r") 2086 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")] 2087 UNSPEC_MOVMSK))] 2088 "(TARGET_MMX || TARGET_MMX_WITH_SSE) 2089 && (TARGET_SSE || TARGET_3DNOW_A)" 2090 "@ 2091 pmovmskb\t{%1, %0|%0, %1} 2092 #" 2093 "TARGET_SSE2 && reload_completed 2094 && SSE_REGNO_P (REGNO (operands[1]))" 2095 [(set (match_dup 0) 2096 (unspec:SI [(match_dup 1)] UNSPEC_MOVMSK)) 2097 (set (match_dup 0) 2098 (zero_extend:SI (match_dup 2)))] 2099{ 2100 /* Generate SSE pmovmskb and zero-extend from QImode to SImode. */ 2101 operands[1] = lowpart_subreg (V16QImode, operands[1], 2102 GET_MODE (operands[1])); 2103 operands[2] = lowpart_subreg (QImode, operands[0], 2104 GET_MODE (operands[0])); 2105} 2106 [(set_attr "mmx_isa" "native,sse") 2107 (set_attr "type" "mmxcvt,ssemov") 2108 (set_attr "mode" "DI,TI")]) 2109 2110(define_expand "mmx_maskmovq" 2111 [(set (match_operand:V8QI 0 "memory_operand") 2112 (unspec:V8QI [(match_operand:V8QI 1 "register_operand") 2113 (match_operand:V8QI 2 "register_operand") 2114 (match_dup 0)] 2115 UNSPEC_MASKMOV))] 2116 "TARGET_SSE || TARGET_3DNOW_A") 2117 2118(define_insn "*mmx_maskmovq" 2119 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D")) 2120 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") 2121 (match_operand:V8QI 2 "register_operand" "y") 2122 (mem:V8QI (match_dup 0))] 2123 UNSPEC_MASKMOV))] 2124 "TARGET_SSE || TARGET_3DNOW_A" 2125 ;; @@@ check ordering of operands in intel/nonintel syntax 2126 "maskmovq\t{%2, %1|%1, %2}" 2127 [(set_attr "type" "mmxcvt") 2128 (set_attr "znver1_decode" "vector") 2129 (set_attr "mode" "DI")]) 2130 2131(define_int_iterator EMMS 2132 [(UNSPECV_EMMS "TARGET_MMX") 2133 (UNSPECV_FEMMS "TARGET_3DNOW")]) 2134 2135(define_int_attr emms 2136 [(UNSPECV_EMMS "emms") 2137 (UNSPECV_FEMMS "femms")]) 2138 2139(define_expand "mmx_<emms>" 2140 [(parallel 2141 [(unspec_volatile [(const_int 0)] EMMS) 2142 (clobber (reg:XF ST0_REG)) 2143 (clobber (reg:XF ST1_REG)) 2144 (clobber (reg:XF ST2_REG)) 2145 (clobber (reg:XF ST3_REG)) 2146 (clobber (reg:XF ST4_REG)) 2147 (clobber (reg:XF ST5_REG)) 2148 (clobber (reg:XF ST6_REG)) 2149 (clobber (reg:XF ST7_REG)) 2150 (clobber (reg:DI MM0_REG)) 2151 (clobber (reg:DI MM1_REG)) 2152 (clobber (reg:DI MM2_REG)) 2153 (clobber (reg:DI MM3_REG)) 2154 (clobber (reg:DI MM4_REG)) 2155 (clobber (reg:DI MM5_REG)) 2156 (clobber (reg:DI MM6_REG)) 2157 (clobber (reg:DI MM7_REG))])] 2158 "TARGET_MMX || TARGET_MMX_WITH_SSE" 2159{ 2160 if (!TARGET_MMX) 2161 { 2162 emit_insn (gen_nop ()); 2163 DONE; 2164 } 2165}) 2166 2167(define_insn "*mmx_<emms>" 2168 [(unspec_volatile [(const_int 0)] EMMS) 2169 (clobber (reg:XF ST0_REG)) 2170 (clobber (reg:XF ST1_REG)) 2171 (clobber (reg:XF ST2_REG)) 2172 (clobber (reg:XF ST3_REG)) 2173 (clobber (reg:XF ST4_REG)) 2174 (clobber (reg:XF ST5_REG)) 2175 (clobber (reg:XF ST6_REG)) 2176 (clobber (reg:XF ST7_REG)) 2177 (clobber (reg:DI MM0_REG)) 2178 (clobber (reg:DI MM1_REG)) 2179 (clobber (reg:DI MM2_REG)) 2180 (clobber (reg:DI MM3_REG)) 2181 (clobber (reg:DI MM4_REG)) 2182 (clobber (reg:DI MM5_REG)) 2183 (clobber (reg:DI MM6_REG)) 2184 (clobber (reg:DI MM7_REG))] 2185 "" 2186 "<emms>" 2187 [(set_attr "type" "mmx") 2188 (set_attr "modrm" "0") 2189 (set_attr "memory" "none")]) 2190