1;; GCC machine description for MMX and 3dNOW! instructions 2;; Copyright (C) 2005-2013 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]) 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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 62;; 63;; Move patterns 64;; 65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 66 67;; All of these patterns are enabled for MMX as well as 3dNOW. 68;; This is essential for maintaining stable calling conventions. 69 70(define_expand "mov<mode>" 71 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand") 72 (match_operand:MMXMODEI8 1 "nonimmediate_operand"))] 73 "TARGET_MMX" 74{ 75 ix86_expand_vector_move (<MODE>mode, operands); 76 DONE; 77}) 78 79;; movd instead of movq is required to handle broken assemblers. 80(define_insn "*mov<mode>_internal_rex64" 81 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" 82 "=rm,r,!?y,!y,!?y,m ,!y ,*x,x,x ,m,r ,Yi") 83 (match_operand:MMXMODEI8 1 "vector_move_operand" 84 "Cr ,m,C ,!y,m ,!?y,*x,!y ,C,xm,x,Yi,r"))] 85 "TARGET_64BIT && TARGET_MMX 86 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 87 "@ 88 mov{q}\t{%1, %0|%0, %1} 89 mov{q}\t{%1, %0|%0, %1} 90 pxor\t%0, %0 91 movq\t{%1, %0|%0, %1} 92 movq\t{%1, %0|%0, %1} 93 movq\t{%1, %0|%0, %1} 94 movdq2q\t{%1, %0|%0, %1} 95 movq2dq\t{%1, %0|%0, %1} 96 %vpxor\t%0, %d0 97 %vmovq\t{%1, %0|%0, %1} 98 %vmovq\t{%1, %0|%0, %1} 99 %vmovd\t{%1, %0|%0, %1} 100 %vmovd\t{%1, %0|%0, %1}" 101 [(set (attr "type") 102 (cond [(eq_attr "alternative" "0,1") 103 (const_string "imov") 104 (eq_attr "alternative" "2") 105 (const_string "mmx") 106 (eq_attr "alternative" "3,4,5") 107 (const_string "mmxmov") 108 (eq_attr "alternative" "6,7") 109 (const_string "ssecvt") 110 (eq_attr "alternative" "8") 111 (const_string "sselog1") 112 ] 113 (const_string "ssemov"))) 114 (set (attr "unit") 115 (if_then_else (eq_attr "alternative" "6,7") 116 (const_string "mmx") 117 (const_string "*"))) 118 (set (attr "prefix_rep") 119 (if_then_else (eq_attr "alternative" "6,7,9") 120 (const_string "1") 121 (const_string "*"))) 122 (set (attr "prefix_data16") 123 (if_then_else (eq_attr "alternative" "10,11,12") 124 (const_string "1") 125 (const_string "*"))) 126 (set (attr "prefix_rex") 127 (if_then_else (eq_attr "alternative" "9,10") 128 (symbol_ref "x86_extended_reg_mentioned_p (insn)") 129 (const_string "*"))) 130 (set (attr "prefix") 131 (if_then_else (eq_attr "alternative" "8,9,10,11,12") 132 (const_string "maybe_vex") 133 (const_string "orig"))) 134 (set_attr "mode" "DI")]) 135 136(define_insn "*mov<mode>_internal" 137 [(set (match_operand:MMXMODEI8 0 "nonimmediate_operand" 138 "=!?y,!y,!?y,m ,!y,*x,*x,*x ,m ,*x,*x,*x,m ,r ,m") 139 (match_operand:MMXMODEI8 1 "vector_move_operand" 140 "C ,!y,m ,!?y,*x,!y,C ,*xm,*x,C ,*x,m ,*x,irm,r"))] 141 "!TARGET_64BIT && TARGET_MMX 142 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 143 "@ 144 pxor\t%0, %0 145 movq\t{%1, %0|%0, %1} 146 movq\t{%1, %0|%0, %1} 147 movq\t{%1, %0|%0, %1} 148 movdq2q\t{%1, %0|%0, %1} 149 movq2dq\t{%1, %0|%0, %1} 150 %vpxor\t%0, %d0 151 %vmovq\t{%1, %0|%0, %1} 152 %vmovq\t{%1, %0|%0, %1} 153 xorps\t%0, %0 154 movaps\t{%1, %0|%0, %1} 155 movlps\t{%1, %0|%0, %1} 156 movlps\t{%1, %0|%0, %1} 157 # 158 #" 159 [(set (attr "isa") 160 (cond [(eq_attr "alternative" "4,5,6,7,8") 161 (const_string "sse2") 162 (eq_attr "alternative" "9,10,11,12") 163 (const_string "noavx") 164 ] 165 (const_string "*"))) 166 (set (attr "type") 167 (cond [(eq_attr "alternative" "0") 168 (const_string "mmx") 169 (eq_attr "alternative" "1,2,3") 170 (const_string "mmxmov") 171 (eq_attr "alternative" "4,5") 172 (const_string "ssecvt") 173 (eq_attr "alternative" "6,9") 174 (const_string "sselog1") 175 (eq_attr "alternative" "13,14") 176 (const_string "multi") 177 ] 178 (const_string "ssemov"))) 179 (set (attr "unit") 180 (if_then_else (eq_attr "alternative" "4,5") 181 (const_string "mmx") 182 (const_string "*"))) 183 (set (attr "prefix_rep") 184 (if_then_else 185 (ior (eq_attr "alternative" "4,5") 186 (and (eq_attr "alternative" "7") 187 (not (match_test "TARGET_AVX")))) 188 (const_string "1") 189 (const_string "*"))) 190 (set (attr "prefix_data16") 191 (if_then_else 192 (and (eq_attr "alternative" "8") 193 (not (match_test "TARGET_AVX"))) 194 (const_string "1") 195 (const_string "*"))) 196 (set (attr "prefix") 197 (if_then_else (eq_attr "alternative" "6,7,8") 198 (const_string "maybe_vex") 199 (const_string "orig"))) 200 (set_attr "mode" "DI,DI,DI,DI,DI,DI,TI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) 201 202(define_expand "movv2sf" 203 [(set (match_operand:V2SF 0 "nonimmediate_operand") 204 (match_operand:V2SF 1 "nonimmediate_operand"))] 205 "TARGET_MMX" 206{ 207 ix86_expand_vector_move (V2SFmode, operands); 208 DONE; 209}) 210 211;; movd instead of movq is required to handle broken assemblers. 212(define_insn "*movv2sf_internal_rex64" 213 [(set (match_operand:V2SF 0 "nonimmediate_operand" 214 "=rm,r,!?y,!y,!?y,m ,!y,*x,x,x,x,m,r ,Yi") 215 (match_operand:V2SF 1 "vector_move_operand" 216 "Cr ,m,C ,!y,m ,!?y,*x,!y,C,x,m,x,Yi,r"))] 217 "TARGET_64BIT && TARGET_MMX 218 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 219 "@ 220 mov{q}\t{%1, %0|%0, %1} 221 mov{q}\t{%1, %0|%0, %1} 222 pxor\t%0, %0 223 movq\t{%1, %0|%0, %1} 224 movq\t{%1, %0|%0, %1} 225 movq\t{%1, %0|%0, %1} 226 movdq2q\t{%1, %0|%0, %1} 227 movq2dq\t{%1, %0|%0, %1} 228 %vxorps\t%0, %d0 229 %vmovaps\t{%1, %0|%0, %1} 230 %vmovlps\t{%1, %d0|%d0, %1} 231 %vmovlps\t{%1, %0|%0, %1} 232 %vmovd\t{%1, %0|%0, %1} 233 %vmovd\t{%1, %0|%0, %1}" 234 [(set (attr "type") 235 (cond [(eq_attr "alternative" "0,1") 236 (const_string "imov") 237 (eq_attr "alternative" "2") 238 (const_string "mmx") 239 (eq_attr "alternative" "3,4,5") 240 (const_string "mmxmov") 241 (eq_attr "alternative" "6,7") 242 (const_string "ssecvt") 243 (eq_attr "alternative" "9") 244 (const_string "sselog1") 245 ] 246 (const_string "ssemov"))) 247 (set (attr "unit") 248 (if_then_else (eq_attr "alternative" "6,7") 249 (const_string "mmx") 250 (const_string "*"))) 251 (set (attr "prefix_rep") 252 (if_then_else (eq_attr "alternative" "6,7") 253 (const_string "1") 254 (const_string "*"))) 255 (set (attr "length_vex") 256 (if_then_else 257 (and (eq_attr "alternative" "12,13") 258 (match_test "TARGET_AVX")) 259 (const_string "4") 260 (const_string "*"))) 261 (set (attr "prefix") 262 (if_then_else (eq_attr "alternative" "8,9,10,11,12,13") 263 (const_string "maybe_vex") 264 (const_string "orig"))) 265 (set_attr "mode" "DI,DI,DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) 266 267(define_insn "*movv2sf_internal" 268 [(set (match_operand:V2SF 0 "nonimmediate_operand" 269 "=!?y,!y,!?y,m ,!y,*x,*x,*x,*x,m ,r ,m") 270 (match_operand:V2SF 1 "vector_move_operand" 271 "C ,!y,m ,!?y,*x,!y,C ,*x,m ,*x,irm,r"))] 272 "!TARGET_64BIT && TARGET_MMX 273 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 274 "@ 275 pxor\t%0, %0 276 movq\t{%1, %0|%0, %1} 277 movq\t{%1, %0|%0, %1} 278 movq\t{%1, %0|%0, %1} 279 movdq2q\t{%1, %0|%0, %1} 280 movq2dq\t{%1, %0|%0, %1} 281 %vxorps\t%0, %d0 282 %vmovaps\t{%1, %0|%0, %1} 283 %vmovlps\t{%1, %d0|%d0, %1} 284 %vmovlps\t{%1, %0|%0, %1} 285 # 286 #" 287 [(set (attr "isa") 288 (if_then_else (eq_attr "alternative" "4,5") 289 (const_string "sse2") 290 (const_string "*"))) 291 (set (attr "type") 292 (cond [(eq_attr "alternative" "0") 293 (const_string "mmx") 294 (eq_attr "alternative" "1,2,3") 295 (const_string "mmxmov") 296 (eq_attr "alternative" "4,5") 297 (const_string "ssecvt") 298 (eq_attr "alternative" "6") 299 (const_string "sselog1") 300 (eq_attr "alternative" "10,11") 301 (const_string "multi") 302 ] 303 (const_string "ssemov"))) 304 (set (attr "unit") 305 (if_then_else (eq_attr "alternative" "4,5") 306 (const_string "mmx") 307 (const_string "*"))) 308 (set (attr "prefix_rep") 309 (if_then_else (eq_attr "alternative" "4,5") 310 (const_string "1") 311 (const_string "*"))) 312 (set (attr "prefix") 313 (if_then_else (eq_attr "alternative" "6,7,8,9") 314 (const_string "maybe_vex") 315 (const_string "orig"))) 316 (set_attr "mode" "DI,DI,DI,DI,DI,DI,V4SF,V4SF,V2SF,V2SF,DI,DI")]) 317 318;; %%% This multiword shite has got to go. 319(define_split 320 [(set (match_operand:MMXMODE 0 "nonimmediate_operand") 321 (match_operand:MMXMODE 1 "general_operand"))] 322 "!TARGET_64BIT && reload_completed 323 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]) 324 || MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" 325 [(const_int 0)] 326 "ix86_split_long_move (operands); DONE;") 327 328(define_expand "push<mode>1" 329 [(match_operand:MMXMODE 0 "register_operand")] 330 "TARGET_MMX" 331{ 332 ix86_expand_push (<MODE>mode, operands[0]); 333 DONE; 334}) 335 336(define_expand "movmisalign<mode>" 337 [(set (match_operand:MMXMODE 0 "nonimmediate_operand") 338 (match_operand:MMXMODE 1 "nonimmediate_operand"))] 339 "TARGET_MMX" 340{ 341 ix86_expand_vector_move (<MODE>mode, operands); 342 DONE; 343}) 344 345(define_insn "sse_movntq" 346 [(set (match_operand:DI 0 "memory_operand" "=m") 347 (unspec:DI [(match_operand:DI 1 "register_operand" "y")] 348 UNSPEC_MOVNTQ))] 349 "TARGET_SSE || TARGET_3DNOW_A" 350 "movntq\t{%1, %0|%0, %1}" 351 [(set_attr "type" "mmxmov") 352 (set_attr "mode" "DI")]) 353 354;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 355;; 356;; Parallel single-precision floating point arithmetic 357;; 358;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 359 360(define_expand "mmx_addv2sf3" 361 [(set (match_operand:V2SF 0 "register_operand") 362 (plus:V2SF 363 (match_operand:V2SF 1 "nonimmediate_operand") 364 (match_operand:V2SF 2 "nonimmediate_operand")))] 365 "TARGET_3DNOW" 366 "ix86_fixup_binary_operands_no_copy (PLUS, V2SFmode, operands);") 367 368(define_insn "*mmx_addv2sf3" 369 [(set (match_operand:V2SF 0 "register_operand" "=y") 370 (plus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") 371 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 372 "TARGET_3DNOW && ix86_binary_operator_ok (PLUS, V2SFmode, operands)" 373 "pfadd\t{%2, %0|%0, %2}" 374 [(set_attr "type" "mmxadd") 375 (set_attr "prefix_extra" "1") 376 (set_attr "mode" "V2SF")]) 377 378(define_expand "mmx_subv2sf3" 379 [(set (match_operand:V2SF 0 "register_operand") 380 (minus:V2SF (match_operand:V2SF 1 "register_operand") 381 (match_operand:V2SF 2 "nonimmediate_operand")))] 382 "TARGET_3DNOW") 383 384(define_expand "mmx_subrv2sf3" 385 [(set (match_operand:V2SF 0 "register_operand") 386 (minus:V2SF (match_operand:V2SF 2 "register_operand") 387 (match_operand:V2SF 1 "nonimmediate_operand")))] 388 "TARGET_3DNOW") 389 390(define_insn "*mmx_subv2sf3" 391 [(set (match_operand:V2SF 0 "register_operand" "=y,y") 392 (minus:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "0,ym") 393 (match_operand:V2SF 2 "nonimmediate_operand" "ym,0")))] 394 "TARGET_3DNOW && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 395 "@ 396 pfsub\t{%2, %0|%0, %2} 397 pfsubr\t{%1, %0|%0, %1}" 398 [(set_attr "type" "mmxadd") 399 (set_attr "prefix_extra" "1") 400 (set_attr "mode" "V2SF")]) 401 402(define_expand "mmx_mulv2sf3" 403 [(set (match_operand:V2SF 0 "register_operand") 404 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand") 405 (match_operand:V2SF 2 "nonimmediate_operand")))] 406 "TARGET_3DNOW" 407 "ix86_fixup_binary_operands_no_copy (MULT, V2SFmode, operands);") 408 409(define_insn "*mmx_mulv2sf3" 410 [(set (match_operand:V2SF 0 "register_operand" "=y") 411 (mult:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "%0") 412 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 413 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V2SFmode, operands)" 414 "pfmul\t{%2, %0|%0, %2}" 415 [(set_attr "type" "mmxmul") 416 (set_attr "prefix_extra" "1") 417 (set_attr "mode" "V2SF")]) 418 419;; ??? For !flag_finite_math_only, the representation with SMIN/SMAX 420;; isn't really correct, as those rtl operators aren't defined when 421;; applied to NaNs. Hopefully the optimizers won't get too smart on us. 422 423(define_expand "mmx_<code>v2sf3" 424 [(set (match_operand:V2SF 0 "register_operand") 425 (smaxmin:V2SF 426 (match_operand:V2SF 1 "nonimmediate_operand") 427 (match_operand:V2SF 2 "nonimmediate_operand")))] 428 "TARGET_3DNOW" 429{ 430 if (!flag_finite_math_only) 431 operands[1] = force_reg (V2SFmode, operands[1]); 432 ix86_fixup_binary_operands_no_copy (<CODE>, V2SFmode, operands); 433}) 434 435(define_insn "*mmx_<code>v2sf3_finite" 436 [(set (match_operand:V2SF 0 "register_operand" "=y") 437 (smaxmin:V2SF 438 (match_operand:V2SF 1 "nonimmediate_operand" "%0") 439 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 440 "TARGET_3DNOW && flag_finite_math_only 441 && ix86_binary_operator_ok (<CODE>, V2SFmode, operands)" 442 "pf<maxmin_float>\t{%2, %0|%0, %2}" 443 [(set_attr "type" "mmxadd") 444 (set_attr "prefix_extra" "1") 445 (set_attr "mode" "V2SF")]) 446 447(define_insn "*mmx_<code>v2sf3" 448 [(set (match_operand:V2SF 0 "register_operand" "=y") 449 (smaxmin:V2SF 450 (match_operand:V2SF 1 "register_operand" "0") 451 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 452 "TARGET_3DNOW" 453 "pf<maxmin_float>\t{%2, %0|%0, %2}" 454 [(set_attr "type" "mmxadd") 455 (set_attr "prefix_extra" "1") 456 (set_attr "mode" "V2SF")]) 457 458(define_insn "mmx_rcpv2sf2" 459 [(set (match_operand:V2SF 0 "register_operand" "=y") 460 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 461 UNSPEC_PFRCP))] 462 "TARGET_3DNOW" 463 "pfrcp\t{%1, %0|%0, %1}" 464 [(set_attr "type" "mmx") 465 (set_attr "prefix_extra" "1") 466 (set_attr "mode" "V2SF")]) 467 468(define_insn "mmx_rcpit1v2sf3" 469 [(set (match_operand:V2SF 0 "register_operand" "=y") 470 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 471 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 472 UNSPEC_PFRCPIT1))] 473 "TARGET_3DNOW" 474 "pfrcpit1\t{%2, %0|%0, %2}" 475 [(set_attr "type" "mmx") 476 (set_attr "prefix_extra" "1") 477 (set_attr "mode" "V2SF")]) 478 479(define_insn "mmx_rcpit2v2sf3" 480 [(set (match_operand:V2SF 0 "register_operand" "=y") 481 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 482 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 483 UNSPEC_PFRCPIT2))] 484 "TARGET_3DNOW" 485 "pfrcpit2\t{%2, %0|%0, %2}" 486 [(set_attr "type" "mmx") 487 (set_attr "prefix_extra" "1") 488 (set_attr "mode" "V2SF")]) 489 490(define_insn "mmx_rsqrtv2sf2" 491 [(set (match_operand:V2SF 0 "register_operand" "=y") 492 (unspec:V2SF [(match_operand:V2SF 1 "nonimmediate_operand" "ym")] 493 UNSPEC_PFRSQRT))] 494 "TARGET_3DNOW" 495 "pfrsqrt\t{%1, %0|%0, %1}" 496 [(set_attr "type" "mmx") 497 (set_attr "prefix_extra" "1") 498 (set_attr "mode" "V2SF")]) 499 500(define_insn "mmx_rsqit1v2sf3" 501 [(set (match_operand:V2SF 0 "register_operand" "=y") 502 (unspec:V2SF [(match_operand:V2SF 1 "register_operand" "0") 503 (match_operand:V2SF 2 "nonimmediate_operand" "ym")] 504 UNSPEC_PFRSQIT1))] 505 "TARGET_3DNOW" 506 "pfrsqit1\t{%2, %0|%0, %2}" 507 [(set_attr "type" "mmx") 508 (set_attr "prefix_extra" "1") 509 (set_attr "mode" "V2SF")]) 510 511(define_insn "mmx_haddv2sf3" 512 [(set (match_operand:V2SF 0 "register_operand" "=y") 513 (vec_concat:V2SF 514 (plus:SF 515 (vec_select:SF 516 (match_operand:V2SF 1 "register_operand" "0") 517 (parallel [(const_int 0)])) 518 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) 519 (plus:SF 520 (vec_select:SF 521 (match_operand:V2SF 2 "nonimmediate_operand" "ym") 522 (parallel [(const_int 0)])) 523 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] 524 "TARGET_3DNOW" 525 "pfacc\t{%2, %0|%0, %2}" 526 [(set_attr "type" "mmxadd") 527 (set_attr "prefix_extra" "1") 528 (set_attr "mode" "V2SF")]) 529 530(define_insn "mmx_hsubv2sf3" 531 [(set (match_operand:V2SF 0 "register_operand" "=y") 532 (vec_concat:V2SF 533 (minus:SF 534 (vec_select:SF 535 (match_operand:V2SF 1 "register_operand" "0") 536 (parallel [(const_int 0)])) 537 (vec_select:SF (match_dup 1) (parallel [(const_int 1)]))) 538 (minus:SF 539 (vec_select:SF 540 (match_operand:V2SF 2 "nonimmediate_operand" "ym") 541 (parallel [(const_int 0)])) 542 (vec_select:SF (match_dup 2) (parallel [(const_int 1)])))))] 543 "TARGET_3DNOW_A" 544 "pfnacc\t{%2, %0|%0, %2}" 545 [(set_attr "type" "mmxadd") 546 (set_attr "prefix_extra" "1") 547 (set_attr "mode" "V2SF")]) 548 549(define_insn "mmx_addsubv2sf3" 550 [(set (match_operand:V2SF 0 "register_operand" "=y") 551 (vec_merge:V2SF 552 (plus:V2SF 553 (match_operand:V2SF 1 "register_operand" "0") 554 (match_operand:V2SF 2 "nonimmediate_operand" "ym")) 555 (minus:V2SF (match_dup 1) (match_dup 2)) 556 (const_int 1)))] 557 "TARGET_3DNOW_A" 558 "pfpnacc\t{%2, %0|%0, %2}" 559 [(set_attr "type" "mmxadd") 560 (set_attr "prefix_extra" "1") 561 (set_attr "mode" "V2SF")]) 562 563;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 564;; 565;; Parallel single-precision floating point comparisons 566;; 567;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 568 569(define_expand "mmx_eqv2sf3" 570 [(set (match_operand:V2SI 0 "register_operand") 571 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand") 572 (match_operand:V2SF 2 "nonimmediate_operand")))] 573 "TARGET_3DNOW" 574 "ix86_fixup_binary_operands_no_copy (EQ, V2SFmode, operands);") 575 576(define_insn "*mmx_eqv2sf3" 577 [(set (match_operand:V2SI 0 "register_operand" "=y") 578 (eq:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "%0") 579 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 580 "TARGET_3DNOW && ix86_binary_operator_ok (EQ, V2SFmode, operands)" 581 "pfcmpeq\t{%2, %0|%0, %2}" 582 [(set_attr "type" "mmxcmp") 583 (set_attr "prefix_extra" "1") 584 (set_attr "mode" "V2SF")]) 585 586(define_insn "mmx_gtv2sf3" 587 [(set (match_operand:V2SI 0 "register_operand" "=y") 588 (gt:V2SI (match_operand:V2SF 1 "register_operand" "0") 589 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 590 "TARGET_3DNOW" 591 "pfcmpgt\t{%2, %0|%0, %2}" 592 [(set_attr "type" "mmxcmp") 593 (set_attr "prefix_extra" "1") 594 (set_attr "mode" "V2SF")]) 595 596(define_insn "mmx_gev2sf3" 597 [(set (match_operand:V2SI 0 "register_operand" "=y") 598 (ge:V2SI (match_operand:V2SF 1 "register_operand" "0") 599 (match_operand:V2SF 2 "nonimmediate_operand" "ym")))] 600 "TARGET_3DNOW" 601 "pfcmpge\t{%2, %0|%0, %2}" 602 [(set_attr "type" "mmxcmp") 603 (set_attr "prefix_extra" "1") 604 (set_attr "mode" "V2SF")]) 605 606;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 607;; 608;; Parallel single-precision floating point conversion operations 609;; 610;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 611 612(define_insn "mmx_pf2id" 613 [(set (match_operand:V2SI 0 "register_operand" "=y") 614 (fix:V2SI (match_operand:V2SF 1 "nonimmediate_operand" "ym")))] 615 "TARGET_3DNOW" 616 "pf2id\t{%1, %0|%0, %1}" 617 [(set_attr "type" "mmxcvt") 618 (set_attr "prefix_extra" "1") 619 (set_attr "mode" "V2SF")]) 620 621(define_insn "mmx_pf2iw" 622 [(set (match_operand:V2SI 0 "register_operand" "=y") 623 (sign_extend:V2SI 624 (ss_truncate:V2HI 625 (fix:V2SI 626 (match_operand:V2SF 1 "nonimmediate_operand" "ym")))))] 627 "TARGET_3DNOW_A" 628 "pf2iw\t{%1, %0|%0, %1}" 629 [(set_attr "type" "mmxcvt") 630 (set_attr "prefix_extra" "1") 631 (set_attr "mode" "V2SF")]) 632 633(define_insn "mmx_pi2fw" 634 [(set (match_operand:V2SF 0 "register_operand" "=y") 635 (float:V2SF 636 (sign_extend:V2SI 637 (truncate:V2HI 638 (match_operand:V2SI 1 "nonimmediate_operand" "ym")))))] 639 "TARGET_3DNOW_A" 640 "pi2fw\t{%1, %0|%0, %1}" 641 [(set_attr "type" "mmxcvt") 642 (set_attr "prefix_extra" "1") 643 (set_attr "mode" "V2SF")]) 644 645(define_insn "mmx_floatv2si2" 646 [(set (match_operand:V2SF 0 "register_operand" "=y") 647 (float:V2SF (match_operand:V2SI 1 "nonimmediate_operand" "ym")))] 648 "TARGET_3DNOW" 649 "pi2fd\t{%1, %0|%0, %1}" 650 [(set_attr "type" "mmxcvt") 651 (set_attr "prefix_extra" "1") 652 (set_attr "mode" "V2SF")]) 653 654;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 655;; 656;; Parallel single-precision floating point element swizzling 657;; 658;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 659 660(define_insn "mmx_pswapdv2sf2" 661 [(set (match_operand:V2SF 0 "register_operand" "=y") 662 (vec_select:V2SF (match_operand:V2SF 1 "nonimmediate_operand" "ym") 663 (parallel [(const_int 1) (const_int 0)])))] 664 "TARGET_3DNOW_A" 665 "pswapd\t{%1, %0|%0, %1}" 666 [(set_attr "type" "mmxcvt") 667 (set_attr "prefix_extra" "1") 668 (set_attr "mode" "V2SF")]) 669 670(define_insn "*vec_dupv2sf" 671 [(set (match_operand:V2SF 0 "register_operand" "=y") 672 (vec_duplicate:V2SF 673 (match_operand:SF 1 "register_operand" "0")))] 674 "TARGET_MMX" 675 "punpckldq\t%0, %0" 676 [(set_attr "type" "mmxcvt") 677 (set_attr "mode" "DI")]) 678 679(define_insn "*mmx_concatv2sf" 680 [(set (match_operand:V2SF 0 "register_operand" "=y,y") 681 (vec_concat:V2SF 682 (match_operand:SF 1 "nonimmediate_operand" " 0,rm") 683 (match_operand:SF 2 "vector_move_operand" "ym,C")))] 684 "TARGET_MMX && !TARGET_SSE" 685 "@ 686 punpckldq\t{%2, %0|%0, %2} 687 movd\t{%1, %0|%0, %1}" 688 [(set_attr "type" "mmxcvt,mmxmov") 689 (set_attr "mode" "DI")]) 690 691(define_expand "vec_setv2sf" 692 [(match_operand:V2SF 0 "register_operand") 693 (match_operand:SF 1 "register_operand") 694 (match_operand 2 "const_int_operand")] 695 "TARGET_MMX" 696{ 697 ix86_expand_vector_set (false, operands[0], operands[1], 698 INTVAL (operands[2])); 699 DONE; 700}) 701 702;; Avoid combining registers from different units in a single alternative, 703;; see comment above inline_secondary_memory_needed function in i386.c 704(define_insn_and_split "*vec_extractv2sf_0" 705 [(set (match_operand:SF 0 "nonimmediate_operand" "=x, m,y ,m,f,r") 706 (vec_select:SF 707 (match_operand:V2SF 1 "nonimmediate_operand" " xm,x,ym,y,m,m") 708 (parallel [(const_int 0)])))] 709 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 710 "#" 711 "&& reload_completed" 712 [(const_int 0)] 713{ 714 rtx op1 = operands[1]; 715 if (REG_P (op1)) 716 op1 = gen_rtx_REG (SFmode, REGNO (op1)); 717 else 718 op1 = gen_lowpart (SFmode, op1); 719 emit_move_insn (operands[0], op1); 720 DONE; 721}) 722 723;; Avoid combining registers from different units in a single alternative, 724;; see comment above inline_secondary_memory_needed function in i386.c 725(define_insn "*vec_extractv2sf_1" 726 [(set (match_operand:SF 0 "nonimmediate_operand" "=y,x,y,x,f,r") 727 (vec_select:SF 728 (match_operand:V2SF 1 "nonimmediate_operand" " 0,0,o,o,o,o") 729 (parallel [(const_int 1)])))] 730 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 731 "@ 732 punpckhdq\t%0, %0 733 unpckhps\t%0, %0 734 # 735 # 736 # 737 #" 738 [(set_attr "type" "mmxcvt,sselog1,mmxmov,ssemov,fmov,imov") 739 (set_attr "mode" "DI,V4SF,SF,SF,SF,SF")]) 740 741(define_split 742 [(set (match_operand:SF 0 "register_operand") 743 (vec_select:SF 744 (match_operand:V2SF 1 "memory_operand") 745 (parallel [(const_int 1)])))] 746 "TARGET_MMX && reload_completed" 747 [(const_int 0)] 748{ 749 operands[1] = adjust_address (operands[1], SFmode, 4); 750 emit_move_insn (operands[0], operands[1]); 751 DONE; 752}) 753 754(define_expand "vec_extractv2sf" 755 [(match_operand:SF 0 "register_operand") 756 (match_operand:V2SF 1 "register_operand") 757 (match_operand 2 "const_int_operand")] 758 "TARGET_MMX" 759{ 760 ix86_expand_vector_extract (false, operands[0], operands[1], 761 INTVAL (operands[2])); 762 DONE; 763}) 764 765(define_expand "vec_initv2sf" 766 [(match_operand:V2SF 0 "register_operand") 767 (match_operand 1)] 768 "TARGET_SSE" 769{ 770 ix86_expand_vector_init (false, operands[0], operands[1]); 771 DONE; 772}) 773 774;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 775;; 776;; Parallel integral arithmetic 777;; 778;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 779 780(define_expand "mmx_<plusminus_insn><mode>3" 781 [(set (match_operand:MMXMODEI8 0 "register_operand") 782 (plusminus:MMXMODEI8 783 (match_operand:MMXMODEI8 1 "nonimmediate_operand") 784 (match_operand:MMXMODEI8 2 "nonimmediate_operand")))] 785 "TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)" 786 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") 787 788(define_insn "*mmx_<plusminus_insn><mode>3" 789 [(set (match_operand:MMXMODEI8 0 "register_operand" "=y") 790 (plusminus:MMXMODEI8 791 (match_operand:MMXMODEI8 1 "nonimmediate_operand" "<comm>0") 792 (match_operand:MMXMODEI8 2 "nonimmediate_operand" "ym")))] 793 "(TARGET_MMX || (TARGET_SSE2 && <MODE>mode == V1DImode)) 794 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 795 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}" 796 [(set_attr "type" "mmxadd") 797 (set_attr "mode" "DI")]) 798 799(define_expand "mmx_<plusminus_insn><mode>3" 800 [(set (match_operand:MMXMODE12 0 "register_operand") 801 (sat_plusminus:MMXMODE12 802 (match_operand:MMXMODE12 1 "nonimmediate_operand") 803 (match_operand:MMXMODE12 2 "nonimmediate_operand")))] 804 "TARGET_MMX" 805 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") 806 807(define_insn "*mmx_<plusminus_insn><mode>3" 808 [(set (match_operand:MMXMODE12 0 "register_operand" "=y") 809 (sat_plusminus:MMXMODE12 810 (match_operand:MMXMODE12 1 "nonimmediate_operand" "<comm>0") 811 (match_operand:MMXMODE12 2 "nonimmediate_operand" "ym")))] 812 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 813 "p<plusminus_mnemonic><mmxvecsize>\t{%2, %0|%0, %2}" 814 [(set_attr "type" "mmxadd") 815 (set_attr "mode" "DI")]) 816 817(define_expand "mmx_mulv4hi3" 818 [(set (match_operand:V4HI 0 "register_operand") 819 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand") 820 (match_operand:V4HI 2 "nonimmediate_operand")))] 821 "TARGET_MMX" 822 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 823 824(define_insn "*mmx_mulv4hi3" 825 [(set (match_operand:V4HI 0 "register_operand" "=y") 826 (mult:V4HI (match_operand:V4HI 1 "nonimmediate_operand" "%0") 827 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] 828 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" 829 "pmullw\t{%2, %0|%0, %2}" 830 [(set_attr "type" "mmxmul") 831 (set_attr "mode" "DI")]) 832 833(define_expand "mmx_smulv4hi3_highpart" 834 [(set (match_operand:V4HI 0 "register_operand") 835 (truncate:V4HI 836 (lshiftrt:V4SI 837 (mult:V4SI 838 (sign_extend:V4SI 839 (match_operand:V4HI 1 "nonimmediate_operand")) 840 (sign_extend:V4SI 841 (match_operand:V4HI 2 "nonimmediate_operand"))) 842 (const_int 16))))] 843 "TARGET_MMX" 844 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 845 846(define_insn "*mmx_smulv4hi3_highpart" 847 [(set (match_operand:V4HI 0 "register_operand" "=y") 848 (truncate:V4HI 849 (lshiftrt:V4SI 850 (mult:V4SI 851 (sign_extend:V4SI 852 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 853 (sign_extend:V4SI 854 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 855 (const_int 16))))] 856 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" 857 "pmulhw\t{%2, %0|%0, %2}" 858 [(set_attr "type" "mmxmul") 859 (set_attr "mode" "DI")]) 860 861(define_expand "mmx_umulv4hi3_highpart" 862 [(set (match_operand:V4HI 0 "register_operand") 863 (truncate:V4HI 864 (lshiftrt:V4SI 865 (mult:V4SI 866 (zero_extend:V4SI 867 (match_operand:V4HI 1 "nonimmediate_operand")) 868 (zero_extend:V4SI 869 (match_operand:V4HI 2 "nonimmediate_operand"))) 870 (const_int 16))))] 871 "TARGET_SSE || TARGET_3DNOW_A" 872 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 873 874(define_insn "*mmx_umulv4hi3_highpart" 875 [(set (match_operand:V4HI 0 "register_operand" "=y") 876 (truncate:V4HI 877 (lshiftrt:V4SI 878 (mult:V4SI 879 (zero_extend:V4SI 880 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 881 (zero_extend:V4SI 882 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 883 (const_int 16))))] 884 "(TARGET_SSE || TARGET_3DNOW_A) 885 && ix86_binary_operator_ok (MULT, V4HImode, operands)" 886 "pmulhuw\t{%2, %0|%0, %2}" 887 [(set_attr "type" "mmxmul") 888 (set_attr "mode" "DI")]) 889 890(define_expand "mmx_pmaddwd" 891 [(set (match_operand:V2SI 0 "register_operand") 892 (plus:V2SI 893 (mult:V2SI 894 (sign_extend:V2SI 895 (vec_select:V2HI 896 (match_operand:V4HI 1 "nonimmediate_operand") 897 (parallel [(const_int 0) (const_int 2)]))) 898 (sign_extend:V2SI 899 (vec_select:V2HI 900 (match_operand:V4HI 2 "nonimmediate_operand") 901 (parallel [(const_int 0) (const_int 2)])))) 902 (mult:V2SI 903 (sign_extend:V2SI 904 (vec_select:V2HI (match_dup 1) 905 (parallel [(const_int 1) (const_int 3)]))) 906 (sign_extend:V2SI 907 (vec_select:V2HI (match_dup 2) 908 (parallel [(const_int 1) (const_int 3)]))))))] 909 "TARGET_MMX" 910 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 911 912(define_insn "*mmx_pmaddwd" 913 [(set (match_operand:V2SI 0 "register_operand" "=y") 914 (plus:V2SI 915 (mult:V2SI 916 (sign_extend:V2SI 917 (vec_select:V2HI 918 (match_operand:V4HI 1 "nonimmediate_operand" "%0") 919 (parallel [(const_int 0) (const_int 2)]))) 920 (sign_extend:V2SI 921 (vec_select:V2HI 922 (match_operand:V4HI 2 "nonimmediate_operand" "ym") 923 (parallel [(const_int 0) (const_int 2)])))) 924 (mult:V2SI 925 (sign_extend:V2SI 926 (vec_select:V2HI (match_dup 1) 927 (parallel [(const_int 1) (const_int 3)]))) 928 (sign_extend:V2SI 929 (vec_select:V2HI (match_dup 2) 930 (parallel [(const_int 1) (const_int 3)]))))))] 931 "TARGET_MMX && ix86_binary_operator_ok (MULT, V4HImode, operands)" 932 "pmaddwd\t{%2, %0|%0, %2}" 933 [(set_attr "type" "mmxmul") 934 (set_attr "mode" "DI")]) 935 936(define_expand "mmx_pmulhrwv4hi3" 937 [(set (match_operand:V4HI 0 "register_operand") 938 (truncate:V4HI 939 (lshiftrt:V4SI 940 (plus:V4SI 941 (mult:V4SI 942 (sign_extend:V4SI 943 (match_operand:V4HI 1 "nonimmediate_operand")) 944 (sign_extend:V4SI 945 (match_operand:V4HI 2 "nonimmediate_operand"))) 946 (const_vector:V4SI [(const_int 32768) (const_int 32768) 947 (const_int 32768) (const_int 32768)])) 948 (const_int 16))))] 949 "TARGET_3DNOW" 950 "ix86_fixup_binary_operands_no_copy (MULT, V4HImode, operands);") 951 952(define_insn "*mmx_pmulhrwv4hi3" 953 [(set (match_operand:V4HI 0 "register_operand" "=y") 954 (truncate:V4HI 955 (lshiftrt:V4SI 956 (plus:V4SI 957 (mult:V4SI 958 (sign_extend:V4SI 959 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 960 (sign_extend:V4SI 961 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 962 (const_vector:V4SI [(const_int 32768) (const_int 32768) 963 (const_int 32768) (const_int 32768)])) 964 (const_int 16))))] 965 "TARGET_3DNOW && ix86_binary_operator_ok (MULT, V4HImode, operands)" 966 "pmulhrw\t{%2, %0|%0, %2}" 967 [(set_attr "type" "mmxmul") 968 (set_attr "prefix_extra" "1") 969 (set_attr "mode" "DI")]) 970 971(define_expand "sse2_umulv1siv1di3" 972 [(set (match_operand:V1DI 0 "register_operand") 973 (mult:V1DI 974 (zero_extend:V1DI 975 (vec_select:V1SI 976 (match_operand:V2SI 1 "nonimmediate_operand") 977 (parallel [(const_int 0)]))) 978 (zero_extend:V1DI 979 (vec_select:V1SI 980 (match_operand:V2SI 2 "nonimmediate_operand") 981 (parallel [(const_int 0)])))))] 982 "TARGET_SSE2" 983 "ix86_fixup_binary_operands_no_copy (MULT, V2SImode, operands);") 984 985(define_insn "*sse2_umulv1siv1di3" 986 [(set (match_operand:V1DI 0 "register_operand" "=y") 987 (mult:V1DI 988 (zero_extend:V1DI 989 (vec_select:V1SI 990 (match_operand:V2SI 1 "nonimmediate_operand" "%0") 991 (parallel [(const_int 0)]))) 992 (zero_extend:V1DI 993 (vec_select:V1SI 994 (match_operand:V2SI 2 "nonimmediate_operand" "ym") 995 (parallel [(const_int 0)])))))] 996 "TARGET_SSE2 && ix86_binary_operator_ok (MULT, V2SImode, operands)" 997 "pmuludq\t{%2, %0|%0, %2}" 998 [(set_attr "type" "mmxmul") 999 (set_attr "mode" "DI")]) 1000 1001(define_expand "mmx_<code>v4hi3" 1002 [(set (match_operand:V4HI 0 "register_operand") 1003 (smaxmin:V4HI 1004 (match_operand:V4HI 1 "nonimmediate_operand") 1005 (match_operand:V4HI 2 "nonimmediate_operand")))] 1006 "TARGET_SSE || TARGET_3DNOW_A" 1007 "ix86_fixup_binary_operands_no_copy (<CODE>, V4HImode, operands);") 1008 1009(define_insn "*mmx_<code>v4hi3" 1010 [(set (match_operand:V4HI 0 "register_operand" "=y") 1011 (smaxmin:V4HI 1012 (match_operand:V4HI 1 "nonimmediate_operand" "%0") 1013 (match_operand:V4HI 2 "nonimmediate_operand" "ym")))] 1014 "(TARGET_SSE || TARGET_3DNOW_A) 1015 && ix86_binary_operator_ok (<CODE>, V4HImode, operands)" 1016 "p<maxmin_int>w\t{%2, %0|%0, %2}" 1017 [(set_attr "type" "mmxadd") 1018 (set_attr "mode" "DI")]) 1019 1020(define_expand "mmx_<code>v8qi3" 1021 [(set (match_operand:V8QI 0 "register_operand") 1022 (umaxmin:V8QI 1023 (match_operand:V8QI 1 "nonimmediate_operand") 1024 (match_operand:V8QI 2 "nonimmediate_operand")))] 1025 "TARGET_SSE || TARGET_3DNOW_A" 1026 "ix86_fixup_binary_operands_no_copy (<CODE>, V8QImode, operands);") 1027 1028(define_insn "*mmx_<code>v8qi3" 1029 [(set (match_operand:V8QI 0 "register_operand" "=y") 1030 (umaxmin:V8QI 1031 (match_operand:V8QI 1 "nonimmediate_operand" "%0") 1032 (match_operand:V8QI 2 "nonimmediate_operand" "ym")))] 1033 "(TARGET_SSE || TARGET_3DNOW_A) 1034 && ix86_binary_operator_ok (<CODE>, V8QImode, operands)" 1035 "p<maxmin_int>b\t{%2, %0|%0, %2}" 1036 [(set_attr "type" "mmxadd") 1037 (set_attr "mode" "DI")]) 1038 1039(define_insn "mmx_ashr<mode>3" 1040 [(set (match_operand:MMXMODE24 0 "register_operand" "=y") 1041 (ashiftrt:MMXMODE24 1042 (match_operand:MMXMODE24 1 "register_operand" "0") 1043 (match_operand:SI 2 "nonmemory_operand" "yN")))] 1044 "TARGET_MMX" 1045 "psra<mmxvecsize>\t{%2, %0|%0, %2}" 1046 [(set_attr "type" "mmxshft") 1047 (set (attr "length_immediate") 1048 (if_then_else (match_operand 2 "const_int_operand") 1049 (const_string "1") 1050 (const_string "0"))) 1051 (set_attr "mode" "DI")]) 1052 1053(define_insn "mmx_<shift_insn><mode>3" 1054 [(set (match_operand:MMXMODE248 0 "register_operand" "=y") 1055 (any_lshift:MMXMODE248 1056 (match_operand:MMXMODE248 1 "register_operand" "0") 1057 (match_operand:SI 2 "nonmemory_operand" "yN")))] 1058 "TARGET_MMX" 1059 "p<vshift><mmxvecsize>\t{%2, %0|%0, %2}" 1060 [(set_attr "type" "mmxshft") 1061 (set (attr "length_immediate") 1062 (if_then_else (match_operand 2 "const_int_operand") 1063 (const_string "1") 1064 (const_string "0"))) 1065 (set_attr "mode" "DI")]) 1066 1067;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1068;; 1069;; Parallel integral comparisons 1070;; 1071;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1072 1073(define_expand "mmx_eq<mode>3" 1074 [(set (match_operand:MMXMODEI 0 "register_operand") 1075 (eq:MMXMODEI 1076 (match_operand:MMXMODEI 1 "nonimmediate_operand") 1077 (match_operand:MMXMODEI 2 "nonimmediate_operand")))] 1078 "TARGET_MMX" 1079 "ix86_fixup_binary_operands_no_copy (EQ, <MODE>mode, operands);") 1080 1081(define_insn "*mmx_eq<mode>3" 1082 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 1083 (eq:MMXMODEI 1084 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") 1085 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 1086 "TARGET_MMX && ix86_binary_operator_ok (EQ, <MODE>mode, operands)" 1087 "pcmpeq<mmxvecsize>\t{%2, %0|%0, %2}" 1088 [(set_attr "type" "mmxcmp") 1089 (set_attr "mode" "DI")]) 1090 1091(define_insn "mmx_gt<mode>3" 1092 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 1093 (gt:MMXMODEI 1094 (match_operand:MMXMODEI 1 "register_operand" "0") 1095 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 1096 "TARGET_MMX" 1097 "pcmpgt<mmxvecsize>\t{%2, %0|%0, %2}" 1098 [(set_attr "type" "mmxcmp") 1099 (set_attr "mode" "DI")]) 1100 1101;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1102;; 1103;; Parallel integral logical operations 1104;; 1105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1106 1107(define_insn "mmx_andnot<mode>3" 1108 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 1109 (and:MMXMODEI 1110 (not:MMXMODEI (match_operand:MMXMODEI 1 "register_operand" "0")) 1111 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 1112 "TARGET_MMX" 1113 "pandn\t{%2, %0|%0, %2}" 1114 [(set_attr "type" "mmxadd") 1115 (set_attr "mode" "DI")]) 1116 1117(define_expand "mmx_<code><mode>3" 1118 [(set (match_operand:MMXMODEI 0 "register_operand") 1119 (any_logic:MMXMODEI 1120 (match_operand:MMXMODEI 1 "nonimmediate_operand") 1121 (match_operand:MMXMODEI 2 "nonimmediate_operand")))] 1122 "TARGET_MMX" 1123 "ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);") 1124 1125(define_insn "*mmx_<code><mode>3" 1126 [(set (match_operand:MMXMODEI 0 "register_operand" "=y") 1127 (any_logic:MMXMODEI 1128 (match_operand:MMXMODEI 1 "nonimmediate_operand" "%0") 1129 (match_operand:MMXMODEI 2 "nonimmediate_operand" "ym")))] 1130 "TARGET_MMX && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 1131 "p<logic>\t{%2, %0|%0, %2}" 1132 [(set_attr "type" "mmxadd") 1133 (set_attr "mode" "DI")]) 1134 1135;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1136;; 1137;; Parallel integral element swizzling 1138;; 1139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1140 1141(define_insn "mmx_packsswb" 1142 [(set (match_operand:V8QI 0 "register_operand" "=y") 1143 (vec_concat:V8QI 1144 (ss_truncate:V4QI 1145 (match_operand:V4HI 1 "register_operand" "0")) 1146 (ss_truncate:V4QI 1147 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))] 1148 "TARGET_MMX" 1149 "packsswb\t{%2, %0|%0, %2}" 1150 [(set_attr "type" "mmxshft") 1151 (set_attr "mode" "DI")]) 1152 1153(define_insn "mmx_packssdw" 1154 [(set (match_operand:V4HI 0 "register_operand" "=y") 1155 (vec_concat:V4HI 1156 (ss_truncate:V2HI 1157 (match_operand:V2SI 1 "register_operand" "0")) 1158 (ss_truncate:V2HI 1159 (match_operand:V2SI 2 "nonimmediate_operand" "ym"))))] 1160 "TARGET_MMX" 1161 "packssdw\t{%2, %0|%0, %2}" 1162 [(set_attr "type" "mmxshft") 1163 (set_attr "mode" "DI")]) 1164 1165(define_insn "mmx_packuswb" 1166 [(set (match_operand:V8QI 0 "register_operand" "=y") 1167 (vec_concat:V8QI 1168 (us_truncate:V4QI 1169 (match_operand:V4HI 1 "register_operand" "0")) 1170 (us_truncate:V4QI 1171 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))))] 1172 "TARGET_MMX" 1173 "packuswb\t{%2, %0|%0, %2}" 1174 [(set_attr "type" "mmxshft") 1175 (set_attr "mode" "DI")]) 1176 1177(define_insn "mmx_punpckhbw" 1178 [(set (match_operand:V8QI 0 "register_operand" "=y") 1179 (vec_select:V8QI 1180 (vec_concat:V16QI 1181 (match_operand:V8QI 1 "register_operand" "0") 1182 (match_operand:V8QI 2 "nonimmediate_operand" "ym")) 1183 (parallel [(const_int 4) (const_int 12) 1184 (const_int 5) (const_int 13) 1185 (const_int 6) (const_int 14) 1186 (const_int 7) (const_int 15)])))] 1187 "TARGET_MMX" 1188 "punpckhbw\t{%2, %0|%0, %2}" 1189 [(set_attr "type" "mmxcvt") 1190 (set_attr "mode" "DI")]) 1191 1192(define_insn "mmx_punpcklbw" 1193 [(set (match_operand:V8QI 0 "register_operand" "=y") 1194 (vec_select:V8QI 1195 (vec_concat:V16QI 1196 (match_operand:V8QI 1 "register_operand" "0") 1197 (match_operand:V8QI 2 "nonimmediate_operand" "ym")) 1198 (parallel [(const_int 0) (const_int 8) 1199 (const_int 1) (const_int 9) 1200 (const_int 2) (const_int 10) 1201 (const_int 3) (const_int 11)])))] 1202 "TARGET_MMX" 1203 "punpcklbw\t{%2, %0|%0, %2}" 1204 [(set_attr "type" "mmxcvt") 1205 (set_attr "mode" "DI")]) 1206 1207(define_insn "mmx_punpckhwd" 1208 [(set (match_operand:V4HI 0 "register_operand" "=y") 1209 (vec_select:V4HI 1210 (vec_concat:V8HI 1211 (match_operand:V4HI 1 "register_operand" "0") 1212 (match_operand:V4HI 2 "nonimmediate_operand" "ym")) 1213 (parallel [(const_int 2) (const_int 6) 1214 (const_int 3) (const_int 7)])))] 1215 "TARGET_MMX" 1216 "punpckhwd\t{%2, %0|%0, %2}" 1217 [(set_attr "type" "mmxcvt") 1218 (set_attr "mode" "DI")]) 1219 1220(define_insn "mmx_punpcklwd" 1221 [(set (match_operand:V4HI 0 "register_operand" "=y") 1222 (vec_select:V4HI 1223 (vec_concat:V8HI 1224 (match_operand:V4HI 1 "register_operand" "0") 1225 (match_operand:V4HI 2 "nonimmediate_operand" "ym")) 1226 (parallel [(const_int 0) (const_int 4) 1227 (const_int 1) (const_int 5)])))] 1228 "TARGET_MMX" 1229 "punpcklwd\t{%2, %0|%0, %2}" 1230 [(set_attr "type" "mmxcvt") 1231 (set_attr "mode" "DI")]) 1232 1233(define_insn "mmx_punpckhdq" 1234 [(set (match_operand:V2SI 0 "register_operand" "=y") 1235 (vec_select:V2SI 1236 (vec_concat:V4SI 1237 (match_operand:V2SI 1 "register_operand" "0") 1238 (match_operand:V2SI 2 "nonimmediate_operand" "ym")) 1239 (parallel [(const_int 1) 1240 (const_int 3)])))] 1241 "TARGET_MMX" 1242 "punpckhdq\t{%2, %0|%0, %2}" 1243 [(set_attr "type" "mmxcvt") 1244 (set_attr "mode" "DI")]) 1245 1246(define_insn "mmx_punpckldq" 1247 [(set (match_operand:V2SI 0 "register_operand" "=y") 1248 (vec_select:V2SI 1249 (vec_concat:V4SI 1250 (match_operand:V2SI 1 "register_operand" "0") 1251 (match_operand:V2SI 2 "nonimmediate_operand" "ym")) 1252 (parallel [(const_int 0) 1253 (const_int 2)])))] 1254 "TARGET_MMX" 1255 "punpckldq\t{%2, %0|%0, %2}" 1256 [(set_attr "type" "mmxcvt") 1257 (set_attr "mode" "DI")]) 1258 1259(define_expand "mmx_pinsrw" 1260 [(set (match_operand:V4HI 0 "register_operand") 1261 (vec_merge:V4HI 1262 (vec_duplicate:V4HI 1263 (match_operand:SI 2 "nonimmediate_operand")) 1264 (match_operand:V4HI 1 "register_operand") 1265 (match_operand:SI 3 "const_0_to_3_operand")))] 1266 "TARGET_SSE || TARGET_3DNOW_A" 1267{ 1268 operands[2] = gen_lowpart (HImode, operands[2]); 1269 operands[3] = GEN_INT (1 << INTVAL (operands[3])); 1270}) 1271 1272(define_insn "*mmx_pinsrw" 1273 [(set (match_operand:V4HI 0 "register_operand" "=y") 1274 (vec_merge:V4HI 1275 (vec_duplicate:V4HI 1276 (match_operand:HI 2 "nonimmediate_operand" "rm")) 1277 (match_operand:V4HI 1 "register_operand" "0") 1278 (match_operand:SI 3 "const_int_operand")))] 1279 "(TARGET_SSE || TARGET_3DNOW_A) 1280 && ((unsigned) exact_log2 (INTVAL (operands[3])) 1281 < GET_MODE_NUNITS (V4HImode))" 1282{ 1283 operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3]))); 1284 if (MEM_P (operands[2])) 1285 return "pinsrw\t{%3, %2, %0|%0, %2, %3}"; 1286 else 1287 return "pinsrw\t{%3, %k2, %0|%0, %k2, %3}"; 1288} 1289 [(set_attr "type" "mmxcvt") 1290 (set_attr "length_immediate" "1") 1291 (set_attr "mode" "DI")]) 1292 1293(define_insn "mmx_pextrw" 1294 [(set (match_operand:SI 0 "register_operand" "=r") 1295 (zero_extend:SI 1296 (vec_select:HI 1297 (match_operand:V4HI 1 "register_operand" "y") 1298 (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n")]))))] 1299 "TARGET_SSE || TARGET_3DNOW_A" 1300 "pextrw\t{%2, %1, %0|%0, %1, %2}" 1301 [(set_attr "type" "mmxcvt") 1302 (set_attr "length_immediate" "1") 1303 (set_attr "mode" "DI")]) 1304 1305(define_expand "mmx_pshufw" 1306 [(match_operand:V4HI 0 "register_operand") 1307 (match_operand:V4HI 1 "nonimmediate_operand") 1308 (match_operand:SI 2 "const_int_operand")] 1309 "TARGET_SSE || TARGET_3DNOW_A" 1310{ 1311 int mask = INTVAL (operands[2]); 1312 emit_insn (gen_mmx_pshufw_1 (operands[0], operands[1], 1313 GEN_INT ((mask >> 0) & 3), 1314 GEN_INT ((mask >> 2) & 3), 1315 GEN_INT ((mask >> 4) & 3), 1316 GEN_INT ((mask >> 6) & 3))); 1317 DONE; 1318}) 1319 1320(define_insn "mmx_pshufw_1" 1321 [(set (match_operand:V4HI 0 "register_operand" "=y") 1322 (vec_select:V4HI 1323 (match_operand:V4HI 1 "nonimmediate_operand" "ym") 1324 (parallel [(match_operand 2 "const_0_to_3_operand") 1325 (match_operand 3 "const_0_to_3_operand") 1326 (match_operand 4 "const_0_to_3_operand") 1327 (match_operand 5 "const_0_to_3_operand")])))] 1328 "TARGET_SSE || TARGET_3DNOW_A" 1329{ 1330 int mask = 0; 1331 mask |= INTVAL (operands[2]) << 0; 1332 mask |= INTVAL (operands[3]) << 2; 1333 mask |= INTVAL (operands[4]) << 4; 1334 mask |= INTVAL (operands[5]) << 6; 1335 operands[2] = GEN_INT (mask); 1336 1337 return "pshufw\t{%2, %1, %0|%0, %1, %2}"; 1338} 1339 [(set_attr "type" "mmxcvt") 1340 (set_attr "length_immediate" "1") 1341 (set_attr "mode" "DI")]) 1342 1343(define_insn "mmx_pswapdv2si2" 1344 [(set (match_operand:V2SI 0 "register_operand" "=y") 1345 (vec_select:V2SI 1346 (match_operand:V2SI 1 "nonimmediate_operand" "ym") 1347 (parallel [(const_int 1) (const_int 0)])))] 1348 "TARGET_3DNOW_A" 1349 "pswapd\t{%1, %0|%0, %1}" 1350 [(set_attr "type" "mmxcvt") 1351 (set_attr "prefix_extra" "1") 1352 (set_attr "mode" "DI")]) 1353 1354(define_insn "*vec_dupv4hi" 1355 [(set (match_operand:V4HI 0 "register_operand" "=y") 1356 (vec_duplicate:V4HI 1357 (truncate:HI 1358 (match_operand:SI 1 "register_operand" "0"))))] 1359 "TARGET_SSE || TARGET_3DNOW_A" 1360 "pshufw\t{$0, %0, %0|%0, %0, 0}" 1361 [(set_attr "type" "mmxcvt") 1362 (set_attr "length_immediate" "1") 1363 (set_attr "mode" "DI")]) 1364 1365(define_insn "*vec_dupv2si" 1366 [(set (match_operand:V2SI 0 "register_operand" "=y") 1367 (vec_duplicate:V2SI 1368 (match_operand:SI 1 "register_operand" "0")))] 1369 "TARGET_MMX" 1370 "punpckldq\t%0, %0" 1371 [(set_attr "type" "mmxcvt") 1372 (set_attr "mode" "DI")]) 1373 1374(define_insn "*mmx_concatv2si" 1375 [(set (match_operand:V2SI 0 "register_operand" "=y,y") 1376 (vec_concat:V2SI 1377 (match_operand:SI 1 "nonimmediate_operand" " 0,rm") 1378 (match_operand:SI 2 "vector_move_operand" "ym,C")))] 1379 "TARGET_MMX && !TARGET_SSE" 1380 "@ 1381 punpckldq\t{%2, %0|%0, %2} 1382 movd\t{%1, %0|%0, %1}" 1383 [(set_attr "type" "mmxcvt,mmxmov") 1384 (set_attr "mode" "DI")]) 1385 1386(define_expand "vec_setv2si" 1387 [(match_operand:V2SI 0 "register_operand") 1388 (match_operand:SI 1 "register_operand") 1389 (match_operand 2 "const_int_operand")] 1390 "TARGET_MMX" 1391{ 1392 ix86_expand_vector_set (false, operands[0], operands[1], 1393 INTVAL (operands[2])); 1394 DONE; 1395}) 1396 1397;; Avoid combining registers from different units in a single alternative, 1398;; see comment above inline_secondary_memory_needed function in i386.c 1399(define_insn_and_split "*vec_extractv2si_0" 1400 [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r") 1401 (vec_select:SI 1402 (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m") 1403 (parallel [(const_int 0)])))] 1404 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1405 "#" 1406 "&& reload_completed" 1407 [(const_int 0)] 1408{ 1409 rtx op1 = operands[1]; 1410 if (REG_P (op1)) 1411 op1 = gen_rtx_REG (SImode, REGNO (op1)); 1412 else 1413 op1 = gen_lowpart (SImode, op1); 1414 emit_move_insn (operands[0], op1); 1415 DONE; 1416}) 1417 1418;; Avoid combining registers from different units in a single alternative, 1419;; see comment above inline_secondary_memory_needed function in i386.c 1420(define_insn "*vec_extractv2si_1" 1421 [(set (match_operand:SI 0 "nonimmediate_operand" "=y,x,x,x,y,x,r") 1422 (vec_select:SI 1423 (match_operand:V2SI 1 "nonimmediate_operand" " 0,0,x,0,o,o,o") 1424 (parallel [(const_int 1)])))] 1425 "TARGET_MMX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1426 "@ 1427 punpckhdq\t%0, %0 1428 punpckhdq\t%0, %0 1429 pshufd\t{$85, %1, %0|%0, %1, 85} 1430 unpckhps\t%0, %0 1431 # 1432 # 1433 #" 1434 [(set (attr "isa") 1435 (if_then_else (eq_attr "alternative" "1,2") 1436 (const_string "sse2") 1437 (const_string "*"))) 1438 (set_attr "type" "mmxcvt,sselog1,sselog1,sselog1,mmxmov,ssemov,imov") 1439 (set_attr "length_immediate" "*,*,1,*,*,*,*") 1440 (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")]) 1441 1442(define_split 1443 [(set (match_operand:SI 0 "register_operand") 1444 (vec_select:SI 1445 (match_operand:V2SI 1 "memory_operand") 1446 (parallel [(const_int 1)])))] 1447 "TARGET_MMX && reload_completed" 1448 [(const_int 0)] 1449{ 1450 operands[1] = adjust_address (operands[1], SImode, 4); 1451 emit_move_insn (operands[0], operands[1]); 1452 DONE; 1453}) 1454 1455(define_expand "vec_extractv2si" 1456 [(match_operand:SI 0 "register_operand") 1457 (match_operand:V2SI 1 "register_operand") 1458 (match_operand 2 "const_int_operand")] 1459 "TARGET_MMX" 1460{ 1461 ix86_expand_vector_extract (false, operands[0], operands[1], 1462 INTVAL (operands[2])); 1463 DONE; 1464}) 1465 1466(define_expand "vec_initv2si" 1467 [(match_operand:V2SI 0 "register_operand") 1468 (match_operand 1)] 1469 "TARGET_SSE" 1470{ 1471 ix86_expand_vector_init (false, operands[0], operands[1]); 1472 DONE; 1473}) 1474 1475(define_expand "vec_setv4hi" 1476 [(match_operand:V4HI 0 "register_operand") 1477 (match_operand:HI 1 "register_operand") 1478 (match_operand 2 "const_int_operand")] 1479 "TARGET_MMX" 1480{ 1481 ix86_expand_vector_set (false, operands[0], operands[1], 1482 INTVAL (operands[2])); 1483 DONE; 1484}) 1485 1486(define_expand "vec_extractv4hi" 1487 [(match_operand:HI 0 "register_operand") 1488 (match_operand:V4HI 1 "register_operand") 1489 (match_operand 2 "const_int_operand")] 1490 "TARGET_MMX" 1491{ 1492 ix86_expand_vector_extract (false, operands[0], operands[1], 1493 INTVAL (operands[2])); 1494 DONE; 1495}) 1496 1497(define_expand "vec_initv4hi" 1498 [(match_operand:V4HI 0 "register_operand") 1499 (match_operand 1)] 1500 "TARGET_SSE" 1501{ 1502 ix86_expand_vector_init (false, operands[0], operands[1]); 1503 DONE; 1504}) 1505 1506(define_expand "vec_setv8qi" 1507 [(match_operand:V8QI 0 "register_operand") 1508 (match_operand:QI 1 "register_operand") 1509 (match_operand 2 "const_int_operand")] 1510 "TARGET_MMX" 1511{ 1512 ix86_expand_vector_set (false, operands[0], operands[1], 1513 INTVAL (operands[2])); 1514 DONE; 1515}) 1516 1517(define_expand "vec_extractv8qi" 1518 [(match_operand:QI 0 "register_operand") 1519 (match_operand:V8QI 1 "register_operand") 1520 (match_operand 2 "const_int_operand")] 1521 "TARGET_MMX" 1522{ 1523 ix86_expand_vector_extract (false, operands[0], operands[1], 1524 INTVAL (operands[2])); 1525 DONE; 1526}) 1527 1528(define_expand "vec_initv8qi" 1529 [(match_operand:V8QI 0 "register_operand") 1530 (match_operand 1)] 1531 "TARGET_SSE" 1532{ 1533 ix86_expand_vector_init (false, operands[0], operands[1]); 1534 DONE; 1535}) 1536 1537;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1538;; 1539;; Miscellaneous 1540;; 1541;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1542 1543(define_expand "mmx_uavgv8qi3" 1544 [(set (match_operand:V8QI 0 "register_operand") 1545 (truncate:V8QI 1546 (lshiftrt:V8HI 1547 (plus:V8HI 1548 (plus:V8HI 1549 (zero_extend:V8HI 1550 (match_operand:V8QI 1 "nonimmediate_operand")) 1551 (zero_extend:V8HI 1552 (match_operand:V8QI 2 "nonimmediate_operand"))) 1553 (const_vector:V8HI [(const_int 1) (const_int 1) 1554 (const_int 1) (const_int 1) 1555 (const_int 1) (const_int 1) 1556 (const_int 1) (const_int 1)])) 1557 (const_int 1))))] 1558 "TARGET_SSE || TARGET_3DNOW" 1559 "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);") 1560 1561(define_insn "*mmx_uavgv8qi3" 1562 [(set (match_operand:V8QI 0 "register_operand" "=y") 1563 (truncate:V8QI 1564 (lshiftrt:V8HI 1565 (plus:V8HI 1566 (plus:V8HI 1567 (zero_extend:V8HI 1568 (match_operand:V8QI 1 "nonimmediate_operand" "%0")) 1569 (zero_extend:V8HI 1570 (match_operand:V8QI 2 "nonimmediate_operand" "ym"))) 1571 (const_vector:V8HI [(const_int 1) (const_int 1) 1572 (const_int 1) (const_int 1) 1573 (const_int 1) (const_int 1) 1574 (const_int 1) (const_int 1)])) 1575 (const_int 1))))] 1576 "(TARGET_SSE || TARGET_3DNOW) 1577 && ix86_binary_operator_ok (PLUS, V8QImode, operands)" 1578{ 1579 /* These two instructions have the same operation, but their encoding 1580 is different. Prefer the one that is de facto standard. */ 1581 if (TARGET_SSE || TARGET_3DNOW_A) 1582 return "pavgb\t{%2, %0|%0, %2}"; 1583 else 1584 return "pavgusb\t{%2, %0|%0, %2}"; 1585} 1586 [(set_attr "type" "mmxshft") 1587 (set (attr "prefix_extra") 1588 (if_then_else 1589 (not (ior (match_test "TARGET_SSE") 1590 (match_test "TARGET_3DNOW_A"))) 1591 (const_string "1") 1592 (const_string "*"))) 1593 (set_attr "mode" "DI")]) 1594 1595(define_expand "mmx_uavgv4hi3" 1596 [(set (match_operand:V4HI 0 "register_operand") 1597 (truncate:V4HI 1598 (lshiftrt:V4SI 1599 (plus:V4SI 1600 (plus:V4SI 1601 (zero_extend:V4SI 1602 (match_operand:V4HI 1 "nonimmediate_operand")) 1603 (zero_extend:V4SI 1604 (match_operand:V4HI 2 "nonimmediate_operand"))) 1605 (const_vector:V4SI [(const_int 1) (const_int 1) 1606 (const_int 1) (const_int 1)])) 1607 (const_int 1))))] 1608 "TARGET_SSE || TARGET_3DNOW_A" 1609 "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);") 1610 1611(define_insn "*mmx_uavgv4hi3" 1612 [(set (match_operand:V4HI 0 "register_operand" "=y") 1613 (truncate:V4HI 1614 (lshiftrt:V4SI 1615 (plus:V4SI 1616 (plus:V4SI 1617 (zero_extend:V4SI 1618 (match_operand:V4HI 1 "nonimmediate_operand" "%0")) 1619 (zero_extend:V4SI 1620 (match_operand:V4HI 2 "nonimmediate_operand" "ym"))) 1621 (const_vector:V4SI [(const_int 1) (const_int 1) 1622 (const_int 1) (const_int 1)])) 1623 (const_int 1))))] 1624 "(TARGET_SSE || TARGET_3DNOW_A) 1625 && ix86_binary_operator_ok (PLUS, V4HImode, operands)" 1626 "pavgw\t{%2, %0|%0, %2}" 1627 [(set_attr "type" "mmxshft") 1628 (set_attr "mode" "DI")]) 1629 1630(define_insn "mmx_psadbw" 1631 [(set (match_operand:V1DI 0 "register_operand" "=y") 1632 (unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0") 1633 (match_operand:V8QI 2 "nonimmediate_operand" "ym")] 1634 UNSPEC_PSADBW))] 1635 "TARGET_SSE || TARGET_3DNOW_A" 1636 "psadbw\t{%2, %0|%0, %2}" 1637 [(set_attr "type" "mmxshft") 1638 (set_attr "mode" "DI")]) 1639 1640(define_insn "mmx_pmovmskb" 1641 [(set (match_operand:SI 0 "register_operand" "=r") 1642 (unspec:SI [(match_operand:V8QI 1 "register_operand" "y")] 1643 UNSPEC_MOVMSK))] 1644 "TARGET_SSE || TARGET_3DNOW_A" 1645 "pmovmskb\t{%1, %0|%0, %1}" 1646 [(set_attr "type" "mmxcvt") 1647 (set_attr "mode" "DI")]) 1648 1649(define_expand "mmx_maskmovq" 1650 [(set (match_operand:V8QI 0 "memory_operand") 1651 (unspec:V8QI [(match_operand:V8QI 1 "register_operand") 1652 (match_operand:V8QI 2 "register_operand") 1653 (match_dup 0)] 1654 UNSPEC_MASKMOV))] 1655 "TARGET_SSE || TARGET_3DNOW_A") 1656 1657(define_insn "*mmx_maskmovq" 1658 [(set (mem:V8QI (match_operand:P 0 "register_operand" "D")) 1659 (unspec:V8QI [(match_operand:V8QI 1 "register_operand" "y") 1660 (match_operand:V8QI 2 "register_operand" "y") 1661 (mem:V8QI (match_dup 0))] 1662 UNSPEC_MASKMOV))] 1663 "TARGET_SSE || TARGET_3DNOW_A" 1664 ;; @@@ check ordering of operands in intel/nonintel syntax 1665 "maskmovq\t{%2, %1|%1, %2}" 1666 [(set_attr "type" "mmxcvt") 1667 (set_attr "mode" "DI")]) 1668 1669(define_expand "mmx_emms" 1670 [(match_par_dup 0 [(const_int 0)])] 1671 "TARGET_MMX" 1672{ 1673 int regno; 1674 1675 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17)); 1676 1677 XVECEXP (operands[0], 0, 0) 1678 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx), 1679 UNSPECV_EMMS); 1680 1681 for (regno = 0; regno < 8; regno++) 1682 { 1683 XVECEXP (operands[0], 0, regno + 1) 1684 = gen_rtx_CLOBBER (VOIDmode, 1685 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno)); 1686 1687 XVECEXP (operands[0], 0, regno + 9) 1688 = gen_rtx_CLOBBER (VOIDmode, 1689 gen_rtx_REG (DImode, FIRST_MMX_REG + regno)); 1690 } 1691}) 1692 1693(define_insn "*mmx_emms" 1694 [(match_parallel 0 "emms_operation" 1695 [(unspec_volatile [(const_int 0)] UNSPECV_EMMS)])] 1696 "TARGET_MMX" 1697 "emms" 1698 [(set_attr "type" "mmx") 1699 (set_attr "modrm" "0") 1700 (set_attr "memory" "none")]) 1701 1702(define_expand "mmx_femms" 1703 [(match_par_dup 0 [(const_int 0)])] 1704 "TARGET_3DNOW" 1705{ 1706 int regno; 1707 1708 operands[0] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (17)); 1709 1710 XVECEXP (operands[0], 0, 0) 1711 = gen_rtx_UNSPEC_VOLATILE (VOIDmode, gen_rtvec (1, const0_rtx), 1712 UNSPECV_FEMMS); 1713 1714 for (regno = 0; regno < 8; regno++) 1715 { 1716 XVECEXP (operands[0], 0, regno + 1) 1717 = gen_rtx_CLOBBER (VOIDmode, 1718 gen_rtx_REG (XFmode, FIRST_STACK_REG + regno)); 1719 1720 XVECEXP (operands[0], 0, regno + 9) 1721 = gen_rtx_CLOBBER (VOIDmode, 1722 gen_rtx_REG (DImode, FIRST_MMX_REG + regno)); 1723 } 1724}) 1725 1726(define_insn "*mmx_femms" 1727 [(match_parallel 0 "emms_operation" 1728 [(unspec_volatile [(const_int 0)] UNSPECV_FEMMS)])] 1729 "TARGET_3DNOW" 1730 "femms" 1731 [(set_attr "type" "mmx") 1732 (set_attr "modrm" "0") 1733 (set_attr "memory" "none")]) 1734