1;; GCC machine description for IA-32 and x86-64. 2;; Copyright (C) 1988-2018 Free Software Foundation, Inc. 3;; Mostly by William Schelter. 4;; x86_64 support added by Jan Hubicka 5;; 6;; This file is part of GCC. 7;; 8;; GCC is free software; you can redistribute it and/or modify 9;; it under the terms of the GNU General Public License as published by 10;; the Free Software Foundation; either version 3, or (at your option) 11;; any later version. 12;; 13;; GCC is distributed in the hope that it will be useful, 14;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16;; GNU General Public License for more details. 17;; 18;; You should have received a copy of the GNU General Public License 19;; along with GCC; see the file COPYING3. If not see 20;; <http://www.gnu.org/licenses/>. */ 21;; 22;; The original PO technology requires these to be ordered by speed, 23;; so that assigner will pick the fastest. 24;; 25;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 26;; 27;; The special asm out single letter directives following a '%' are: 28;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand. 29;; C -- print opcode suffix for set/cmov insn. 30;; c -- like C, but print reversed condition 31;; F,f -- likewise, but for floating-point. 32;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.", 33;; otherwise nothing 34;; R -- print the prefix for register names. 35;; z -- print the opcode suffix for the size of the current operand. 36;; Z -- likewise, with special suffixes for x87 instructions. 37;; * -- print a star (in certain assembler syntax) 38;; A -- print an absolute memory reference. 39;; E -- print address with DImode register names if TARGET_64BIT. 40;; w -- print the operand as if it's a "word" (HImode) even if it isn't. 41;; s -- print a shift double count, followed by the assemblers argument 42;; delimiter. 43;; b -- print the QImode name of the register for the indicated operand. 44;; %b0 would print %al if operands[0] is reg 0. 45;; w -- likewise, print the HImode name of the register. 46;; k -- likewise, print the SImode name of the register. 47;; q -- likewise, print the DImode name of the register. 48;; x -- likewise, print the V4SFmode name of the register. 49;; t -- likewise, print the V8SFmode name of the register. 50;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh. 51;; y -- print "st(0)" instead of "st" as a register. 52;; d -- print duplicated register operand for AVX instruction. 53;; D -- print condition for SSE cmp instruction. 54;; P -- if PIC, print an @PLT suffix. 55;; p -- print raw symbol name. 56;; X -- don't print any sort of PIC '@' suffix for a symbol. 57;; & -- print some in-use local-dynamic symbol name. 58;; H -- print a memory address offset by 8; used for sse high-parts 59;; K -- print HLE lock prefix 60;; Y -- print condition for XOP pcom* instruction. 61;; + -- print a branch hint as 'cs' or 'ds' prefix 62;; ; -- print a semicolon (after prefixes due to bug in older gas). 63;; ~ -- print "i" if TARGET_AVX2, "f" otherwise. 64;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode 65;; ! -- print MPX or NOTRACK prefix for jxx/call/ret instructions if required. 66 67(define_c_enum "unspec" [ 68 ;; Relocation specifiers 69 UNSPEC_GOT 70 UNSPEC_GOTOFF 71 UNSPEC_GOTPCREL 72 UNSPEC_GOTTPOFF 73 UNSPEC_TPOFF 74 UNSPEC_NTPOFF 75 UNSPEC_DTPOFF 76 UNSPEC_GOTNTPOFF 77 UNSPEC_INDNTPOFF 78 UNSPEC_PLTOFF 79 UNSPEC_MACHOPIC_OFFSET 80 UNSPEC_PCREL 81 UNSPEC_SIZEOF 82 83 ;; Prologue support 84 UNSPEC_STACK_ALLOC 85 UNSPEC_SET_GOT 86 UNSPEC_SET_RIP 87 UNSPEC_SET_GOT_OFFSET 88 UNSPEC_MEMORY_BLOCKAGE 89 UNSPEC_PROBE_STACK 90 91 ;; TLS support 92 UNSPEC_TP 93 UNSPEC_TLS_GD 94 UNSPEC_TLS_LD_BASE 95 UNSPEC_TLSDESC 96 UNSPEC_TLS_IE_SUN 97 98 ;; Other random patterns 99 UNSPEC_SCAS 100 UNSPEC_FNSTSW 101 UNSPEC_SAHF 102 UNSPEC_NOTRAP 103 UNSPEC_PARITY 104 UNSPEC_FSTCW 105 UNSPEC_FLDCW 106 UNSPEC_REP 107 UNSPEC_LD_MPIC ; load_macho_picbase 108 UNSPEC_TRUNC_NOOP 109 UNSPEC_DIV_ALREADY_SPLIT 110 UNSPEC_PAUSE 111 UNSPEC_LEA_ADDR 112 UNSPEC_XBEGIN_ABORT 113 UNSPEC_STOS 114 UNSPEC_PEEPSIB 115 UNSPEC_INSN_FALSE_DEP 116 UNSPEC_SBB 117 118 ;; For SSE/MMX support: 119 UNSPEC_FIX_NOTRUNC 120 UNSPEC_MASKMOV 121 UNSPEC_MOVMSK 122 UNSPEC_RCP 123 UNSPEC_RSQRT 124 UNSPEC_PSADBW 125 126 ;; Generic math support 127 UNSPEC_COPYSIGN 128 UNSPEC_IEEE_MIN ; not commutative 129 UNSPEC_IEEE_MAX ; not commutative 130 131 ;; x87 Floating point 132 UNSPEC_SIN 133 UNSPEC_COS 134 UNSPEC_FPATAN 135 UNSPEC_FYL2X 136 UNSPEC_FYL2XP1 137 UNSPEC_FRNDINT 138 UNSPEC_FIST 139 UNSPEC_F2XM1 140 UNSPEC_TAN 141 UNSPEC_FXAM 142 143 ;; x87 Rounding 144 UNSPEC_FRNDINT_FLOOR 145 UNSPEC_FRNDINT_CEIL 146 UNSPEC_FRNDINT_TRUNC 147 UNSPEC_FRNDINT_MASK_PM 148 UNSPEC_FIST_FLOOR 149 UNSPEC_FIST_CEIL 150 151 ;; x87 Double output FP 152 UNSPEC_SINCOS_COS 153 UNSPEC_SINCOS_SIN 154 UNSPEC_XTRACT_FRACT 155 UNSPEC_XTRACT_EXP 156 UNSPEC_FSCALE_FRACT 157 UNSPEC_FSCALE_EXP 158 UNSPEC_FPREM_F 159 UNSPEC_FPREM_U 160 UNSPEC_FPREM1_F 161 UNSPEC_FPREM1_U 162 163 UNSPEC_C2_FLAG 164 UNSPEC_FXAM_MEM 165 166 ;; SSP patterns 167 UNSPEC_SP_SET 168 UNSPEC_SP_TEST 169 170 ;; For ROUND support 171 UNSPEC_ROUND 172 173 ;; For CRC32 support 174 UNSPEC_CRC32 175 176 ;; For LZCNT suppoprt 177 UNSPEC_LZCNT 178 179 ;; For BMI support 180 UNSPEC_TZCNT 181 UNSPEC_BEXTR 182 183 ;; For BMI2 support 184 UNSPEC_PDEP 185 UNSPEC_PEXT 186 187 UNSPEC_BNDMK 188 UNSPEC_BNDMK_ADDR 189 UNSPEC_BNDSTX 190 UNSPEC_BNDLDX 191 UNSPEC_BNDLDX_ADDR 192 UNSPEC_BNDCL 193 UNSPEC_BNDCU 194 UNSPEC_BNDCN 195 UNSPEC_MPX_FENCE 196 197 ;; IRET support 198 UNSPEC_INTERRUPT_RETURN 199]) 200 201(define_c_enum "unspecv" [ 202 UNSPECV_UD2 203 UNSPECV_BLOCKAGE 204 UNSPECV_STACK_PROBE 205 UNSPECV_PROBE_STACK_RANGE 206 UNSPECV_ALIGN 207 UNSPECV_PROLOGUE_USE 208 UNSPECV_SPLIT_STACK_RETURN 209 UNSPECV_CLD 210 UNSPECV_NOPS 211 UNSPECV_RDTSC 212 UNSPECV_RDTSCP 213 UNSPECV_RDPMC 214 UNSPECV_LLWP_INTRINSIC 215 UNSPECV_SLWP_INTRINSIC 216 UNSPECV_LWPVAL_INTRINSIC 217 UNSPECV_LWPINS_INTRINSIC 218 UNSPECV_RDFSBASE 219 UNSPECV_RDGSBASE 220 UNSPECV_WRFSBASE 221 UNSPECV_WRGSBASE 222 UNSPECV_FXSAVE 223 UNSPECV_FXRSTOR 224 UNSPECV_FXSAVE64 225 UNSPECV_FXRSTOR64 226 UNSPECV_XSAVE 227 UNSPECV_XRSTOR 228 UNSPECV_XSAVE64 229 UNSPECV_XRSTOR64 230 UNSPECV_XSAVEOPT 231 UNSPECV_XSAVEOPT64 232 UNSPECV_XSAVES 233 UNSPECV_XRSTORS 234 UNSPECV_XSAVES64 235 UNSPECV_XRSTORS64 236 UNSPECV_XSAVEC 237 UNSPECV_XSAVEC64 238 UNSPECV_XGETBV 239 UNSPECV_XSETBV 240 UNSPECV_WBINVD 241 UNSPECV_WBNOINVD 242 243 ;; For atomic compound assignments. 244 UNSPECV_FNSTENV 245 UNSPECV_FLDENV 246 UNSPECV_FNSTSW 247 UNSPECV_FNCLEX 248 249 ;; For RDRAND support 250 UNSPECV_RDRAND 251 252 ;; For RDSEED support 253 UNSPECV_RDSEED 254 255 ;; For RTM support 256 UNSPECV_XBEGIN 257 UNSPECV_XEND 258 UNSPECV_XABORT 259 UNSPECV_XTEST 260 261 UNSPECV_NLGR 262 263 ;; For CLWB support 264 UNSPECV_CLWB 265 266 ;; For CLFLUSHOPT support 267 UNSPECV_CLFLUSHOPT 268 269 ;; For MONITORX and MWAITX support 270 UNSPECV_MONITORX 271 UNSPECV_MWAITX 272 273 ;; For CLZERO support 274 UNSPECV_CLZERO 275 276 ;; For RDPKRU and WRPKRU support 277 UNSPECV_PKU 278 279 ;; For RDPID support 280 UNSPECV_RDPID 281 282 ;; For CET support 283 UNSPECV_NOP_ENDBR 284 UNSPECV_NOP_RDSSP 285 UNSPECV_INCSSP 286 UNSPECV_SAVEPREVSSP 287 UNSPECV_RSTORSSP 288 UNSPECV_WRSS 289 UNSPECV_WRUSS 290 UNSPECV_SETSSBSY 291 UNSPECV_CLRSSBSY 292 UNSPECV_MOVDIRI 293 UNSPECV_MOVDIR64B 294]) 295 296;; Constants to represent rounding modes in the ROUND instruction 297(define_constants 298 [(ROUND_FLOOR 0x1) 299 (ROUND_CEIL 0x2) 300 (ROUND_TRUNC 0x3) 301 (ROUND_MXCSR 0x4) 302 (ROUND_NO_EXC 0x8) 303 ]) 304 305;; Constants to represent AVX512F embeded rounding 306(define_constants 307 [(ROUND_NEAREST_INT 0) 308 (ROUND_NEG_INF 1) 309 (ROUND_POS_INF 2) 310 (ROUND_ZERO 3) 311 (NO_ROUND 4) 312 (ROUND_SAE 8) 313 ]) 314 315;; Constants to represent pcomtrue/pcomfalse variants 316(define_constants 317 [(PCOM_FALSE 0) 318 (PCOM_TRUE 1) 319 (COM_FALSE_S 2) 320 (COM_FALSE_P 3) 321 (COM_TRUE_S 4) 322 (COM_TRUE_P 5) 323 ]) 324 325;; Constants used in the XOP pperm instruction 326(define_constants 327 [(PPERM_SRC 0x00) /* copy source */ 328 (PPERM_INVERT 0x20) /* invert source */ 329 (PPERM_REVERSE 0x40) /* bit reverse source */ 330 (PPERM_REV_INV 0x60) /* bit reverse & invert src */ 331 (PPERM_ZERO 0x80) /* all 0's */ 332 (PPERM_ONES 0xa0) /* all 1's */ 333 (PPERM_SIGN 0xc0) /* propagate sign bit */ 334 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */ 335 (PPERM_SRC1 0x00) /* use first source byte */ 336 (PPERM_SRC2 0x10) /* use second source byte */ 337 ]) 338 339;; Registers by name. 340(define_constants 341 [(AX_REG 0) 342 (DX_REG 1) 343 (CX_REG 2) 344 (BX_REG 3) 345 (SI_REG 4) 346 (DI_REG 5) 347 (BP_REG 6) 348 (SP_REG 7) 349 (ST0_REG 8) 350 (ST1_REG 9) 351 (ST2_REG 10) 352 (ST3_REG 11) 353 (ST4_REG 12) 354 (ST5_REG 13) 355 (ST6_REG 14) 356 (ST7_REG 15) 357 (ARGP_REG 16) 358 (FLAGS_REG 17) 359 (FPSR_REG 18) 360 (FPCR_REG 19) 361 (FRAME_REG 20) 362 (XMM0_REG 21) 363 (XMM1_REG 22) 364 (XMM2_REG 23) 365 (XMM3_REG 24) 366 (XMM4_REG 25) 367 (XMM5_REG 26) 368 (XMM6_REG 27) 369 (XMM7_REG 28) 370 (MM0_REG 29) 371 (MM1_REG 30) 372 (MM2_REG 31) 373 (MM3_REG 32) 374 (MM4_REG 33) 375 (MM5_REG 34) 376 (MM6_REG 35) 377 (MM7_REG 36) 378 (R8_REG 37) 379 (R9_REG 38) 380 (R10_REG 39) 381 (R11_REG 40) 382 (R12_REG 41) 383 (R13_REG 42) 384 (R14_REG 43) 385 (R15_REG 44) 386 (XMM8_REG 45) 387 (XMM9_REG 46) 388 (XMM10_REG 47) 389 (XMM11_REG 48) 390 (XMM12_REG 49) 391 (XMM13_REG 50) 392 (XMM14_REG 51) 393 (XMM15_REG 52) 394 (XMM16_REG 53) 395 (XMM17_REG 54) 396 (XMM18_REG 55) 397 (XMM19_REG 56) 398 (XMM20_REG 57) 399 (XMM21_REG 58) 400 (XMM22_REG 59) 401 (XMM23_REG 60) 402 (XMM24_REG 61) 403 (XMM25_REG 62) 404 (XMM26_REG 63) 405 (XMM27_REG 64) 406 (XMM28_REG 65) 407 (XMM29_REG 66) 408 (XMM30_REG 67) 409 (XMM31_REG 68) 410 (MASK0_REG 69) 411 (MASK1_REG 70) 412 (MASK2_REG 71) 413 (MASK3_REG 72) 414 (MASK4_REG 73) 415 (MASK5_REG 74) 416 (MASK6_REG 75) 417 (MASK7_REG 76) 418 (BND0_REG 77) 419 (BND1_REG 78) 420 (BND2_REG 79) 421 (BND3_REG 80) 422 (FIRST_PSEUDO_REG 81) 423 ]) 424 425;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 426;; from i386.c. 427 428;; In C guard expressions, put expressions which may be compile-time 429;; constants first. This allows for better optimization. For 430;; example, write "TARGET_64BIT && reload_completed", not 431;; "reload_completed && TARGET_64BIT". 432 433 434;; Processor type. 435(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem, 436 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3, 437 bdver4,btver2,znver1" 438 (const (symbol_ref "ix86_schedule"))) 439 440;; A basic instruction type. Refinements due to arguments to be 441;; provided in other attributes. 442(define_attr "type" 443 "other,multi, 444 alu,alu1,negnot,imov,imovx,lea, 445 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1, 446 imul,imulx,idiv,icmp,test,ibr,setcc,icmov, 447 push,pop,call,callv,leave, 448 str,bitmanip, 449 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp, 450 fxch,fistp,fisttp,frndint, 451 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1, 452 ssemul,sseimul,ssediv,sselog,sselog1, 453 sseishft,sseishft1,ssecmp,ssecomi, 454 ssecvt,ssecvt1,sseicvt,sseins, 455 sseshuf,sseshuf1,ssemuladd,sse4arg, 456 lwp,mskmov,msklog, 457 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft, 458 mpxmov,mpxmk,mpxchk,mpxld,mpxst" 459 (const_string "other")) 460 461;; Main data type used by the insn 462(define_attr "mode" 463 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF, 464 V2DF,V2SF,V1DF,V8DF" 465 (const_string "unknown")) 466 467;; The CPU unit operations uses. 468(define_attr "unit" "integer,i387,sse,mmx,unknown" 469 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp, 470 fxch,fistp,fisttp,frndint") 471 (const_string "i387") 472 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1, 473 ssemul,sseimul,ssediv,sselog,sselog1, 474 sseishft,sseishft1,ssecmp,ssecomi, 475 ssecvt,ssecvt1,sseicvt,sseins, 476 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov") 477 (const_string "sse") 478 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 479 (const_string "mmx") 480 (eq_attr "type" "other") 481 (const_string "unknown")] 482 (const_string "integer"))) 483 484;; The (bounding maximum) length of an instruction immediate. 485(define_attr "length_immediate" "" 486 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave, 487 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk, 488 mpxld,mpxst") 489 (const_int 0) 490 (eq_attr "unit" "i387,sse,mmx") 491 (const_int 0) 492 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1, 493 rotate,rotatex,rotate1,imul,icmp,push,pop") 494 (symbol_ref "ix86_attr_length_immediate_default (insn, true)") 495 (eq_attr "type" "imov,test") 496 (symbol_ref "ix86_attr_length_immediate_default (insn, false)") 497 (eq_attr "type" "call") 498 (if_then_else (match_operand 0 "constant_call_address_operand") 499 (const_int 4) 500 (const_int 0)) 501 (eq_attr "type" "callv") 502 (if_then_else (match_operand 1 "constant_call_address_operand") 503 (const_int 4) 504 (const_int 0)) 505 ;; We don't know the size before shorten_branches. Expect 506 ;; the instruction to fit for better scheduling. 507 (eq_attr "type" "ibr") 508 (const_int 1) 509 ] 510 (symbol_ref "/* Update immediate_length and other attributes! */ 511 gcc_unreachable (),1"))) 512 513;; The (bounding maximum) length of an instruction address. 514(define_attr "length_address" "" 515 (cond [(eq_attr "type" "str,other,multi,fxch") 516 (const_int 0) 517 (and (eq_attr "type" "call") 518 (match_operand 0 "constant_call_address_operand")) 519 (const_int 0) 520 (and (eq_attr "type" "callv") 521 (match_operand 1 "constant_call_address_operand")) 522 (const_int 0) 523 ] 524 (symbol_ref "ix86_attr_length_address_default (insn)"))) 525 526;; Set when length prefix is used. 527(define_attr "prefix_data16" "" 528 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 529 (const_int 0) 530 (eq_attr "mode" "HI") 531 (const_int 1) 532 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI")) 533 (const_int 1) 534 ] 535 (const_int 0))) 536 537;; Set when string REP prefix is used. 538(define_attr "prefix_rep" "" 539 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 540 (const_int 0) 541 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 542 (const_int 1) 543 (and (eq_attr "type" "ibr,call,callv") 544 (match_test "ix86_bnd_prefixed_insn_p (insn)")) 545 (const_int 1) 546 ] 547 (const_int 0))) 548 549;; Set when 0f opcode prefix is used. 550(define_attr "prefix_0f" "" 551 (if_then_else 552 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov, 553 mpxmk,mpxmov,mpxchk,mpxld,mpxst") 554 (eq_attr "unit" "sse,mmx")) 555 (const_int 1) 556 (const_int 0))) 557 558;; Set when REX opcode prefix is used. 559(define_attr "prefix_rex" "" 560 (cond [(not (match_test "TARGET_64BIT")) 561 (const_int 0) 562 (and (eq_attr "mode" "DI") 563 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr") 564 (eq_attr "unit" "!mmx"))) 565 (const_int 1) 566 (and (eq_attr "mode" "QI") 567 (match_test "x86_extended_QIreg_mentioned_p (insn)")) 568 (const_int 1) 569 (match_test "x86_extended_reg_mentioned_p (insn)") 570 (const_int 1) 571 (and (eq_attr "type" "imovx") 572 (match_operand:QI 1 "ext_QIreg_operand")) 573 (const_int 1) 574 ] 575 (const_int 0))) 576 577;; There are also additional prefixes in 3DNOW, SSSE3. 578;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte, 579;; sseiadd1,ssecvt1 to 0f7a with no DREX byte. 580;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a. 581(define_attr "prefix_extra" "" 582 (cond [(eq_attr "type" "ssemuladd,sse4arg") 583 (const_int 2) 584 (eq_attr "type" "sseiadd1,ssecvt1") 585 (const_int 1) 586 ] 587 (const_int 0))) 588 589;; Set when BND opcode prefix may be used. 590(define_attr "maybe_prefix_bnd" "" (const_int 0)) 591 592;; Prefix used: original, VEX or maybe VEX. 593(define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex" 594 (cond [(eq_attr "mode" "OI,V8SF,V4DF") 595 (const_string "vex") 596 (eq_attr "mode" "XI,V16SF,V8DF") 597 (const_string "evex") 598 ] 599 (const_string "orig"))) 600 601;; VEX W bit is used. 602(define_attr "prefix_vex_w" "" (const_int 0)) 603 604;; The length of VEX prefix 605;; Only instructions with 0f prefix can have 2 byte VEX prefix, 606;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is 607;; still prefix_0f 1, with prefix_extra 1. 608(define_attr "length_vex" "" 609 (if_then_else (and (eq_attr "prefix_0f" "1") 610 (eq_attr "prefix_extra" "0")) 611 (if_then_else (eq_attr "prefix_vex_w" "1") 612 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)") 613 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)")) 614 (if_then_else (eq_attr "prefix_vex_w" "1") 615 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)") 616 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)")))) 617 618;; 4-bytes evex prefix and 1 byte opcode. 619(define_attr "length_evex" "" (const_int 5)) 620 621;; Set when modrm byte is used. 622(define_attr "modrm" "" 623 (cond [(eq_attr "type" "str,leave") 624 (const_int 0) 625 (eq_attr "unit" "i387") 626 (const_int 0) 627 (and (eq_attr "type" "incdec") 628 (and (not (match_test "TARGET_64BIT")) 629 (ior (match_operand:SI 1 "register_operand") 630 (match_operand:HI 1 "register_operand")))) 631 (const_int 0) 632 (and (eq_attr "type" "push") 633 (not (match_operand 1 "memory_operand"))) 634 (const_int 0) 635 (and (eq_attr "type" "pop") 636 (not (match_operand 0 "memory_operand"))) 637 (const_int 0) 638 (and (eq_attr "type" "imov") 639 (and (not (eq_attr "mode" "DI")) 640 (ior (and (match_operand 0 "register_operand") 641 (match_operand 1 "immediate_operand")) 642 (ior (and (match_operand 0 "ax_reg_operand") 643 (match_operand 1 "memory_displacement_only_operand")) 644 (and (match_operand 0 "memory_displacement_only_operand") 645 (match_operand 1 "ax_reg_operand")))))) 646 (const_int 0) 647 (and (eq_attr "type" "call") 648 (match_operand 0 "constant_call_address_operand")) 649 (const_int 0) 650 (and (eq_attr "type" "callv") 651 (match_operand 1 "constant_call_address_operand")) 652 (const_int 0) 653 (and (eq_attr "type" "alu,alu1,icmp,test") 654 (match_operand 0 "ax_reg_operand")) 655 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))") 656 ] 657 (const_int 1))) 658 659(define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown" 660 (cond [(eq_attr "modrm" "0") 661 (const_string "none") 662 (eq_attr "type" "alu,imul,ishift") 663 (const_string "op02") 664 (eq_attr "type" "imov,imovx,lea,alu1,icmp") 665 (const_string "op01") 666 (eq_attr "type" "incdec") 667 (const_string "incdec") 668 (eq_attr "type" "push,pop") 669 (const_string "pushpop")] 670 (const_string "unknown"))) 671 672;; The (bounding maximum) length of an instruction in bytes. 673;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 674;; Later we may want to split them and compute proper length as for 675;; other insns. 676(define_attr "length" "" 677 (cond [(eq_attr "type" "other,multi,fistp,frndint") 678 (const_int 16) 679 (eq_attr "type" "fcmp") 680 (const_int 4) 681 (eq_attr "unit" "i387") 682 (plus (const_int 2) 683 (plus (attr "prefix_data16") 684 (attr "length_address"))) 685 (ior (eq_attr "prefix" "evex") 686 (and (ior (eq_attr "prefix" "maybe_evex") 687 (eq_attr "prefix" "maybe_vex")) 688 (match_test "TARGET_AVX512F"))) 689 (plus (attr "length_evex") 690 (plus (attr "length_immediate") 691 (plus (attr "modrm") 692 (attr "length_address")))) 693 (ior (eq_attr "prefix" "vex") 694 (and (ior (eq_attr "prefix" "maybe_vex") 695 (eq_attr "prefix" "maybe_evex")) 696 (match_test "TARGET_AVX"))) 697 (plus (attr "length_vex") 698 (plus (attr "length_immediate") 699 (plus (attr "modrm") 700 (attr "length_address"))))] 701 (plus (plus (attr "modrm") 702 (plus (attr "prefix_0f") 703 (plus (attr "prefix_rex") 704 (plus (attr "prefix_extra") 705 (const_int 1))))) 706 (plus (attr "prefix_rep") 707 (plus (attr "prefix_data16") 708 (plus (attr "length_immediate") 709 (attr "length_address"))))))) 710 711;; The `memory' attribute is `none' if no memory is referenced, `load' or 712;; `store' if there is a simple memory reference therein, or `unknown' 713;; if the instruction is complex. 714 715(define_attr "memory" "none,load,store,both,unknown" 716 (cond [(eq_attr "type" "other,multi,str,lwp") 717 (const_string "unknown") 718 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk") 719 (const_string "none") 720 (eq_attr "type" "fistp,leave") 721 (const_string "both") 722 (eq_attr "type" "frndint") 723 (const_string "load") 724 (eq_attr "type" "mpxld") 725 (const_string "load") 726 (eq_attr "type" "mpxst") 727 (const_string "store") 728 (eq_attr "type" "push") 729 (if_then_else (match_operand 1 "memory_operand") 730 (const_string "both") 731 (const_string "store")) 732 (eq_attr "type" "pop") 733 (if_then_else (match_operand 0 "memory_operand") 734 (const_string "both") 735 (const_string "load")) 736 (eq_attr "type" "setcc") 737 (if_then_else (match_operand 0 "memory_operand") 738 (const_string "store") 739 (const_string "none")) 740 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 741 (if_then_else (ior (match_operand 0 "memory_operand") 742 (match_operand 1 "memory_operand")) 743 (const_string "load") 744 (const_string "none")) 745 (eq_attr "type" "ibr") 746 (if_then_else (match_operand 0 "memory_operand") 747 (const_string "load") 748 (const_string "none")) 749 (eq_attr "type" "call") 750 (if_then_else (match_operand 0 "constant_call_address_operand") 751 (const_string "none") 752 (const_string "load")) 753 (eq_attr "type" "callv") 754 (if_then_else (match_operand 1 "constant_call_address_operand") 755 (const_string "none") 756 (const_string "load")) 757 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1") 758 (match_operand 1 "memory_operand")) 759 (const_string "both") 760 (and (match_operand 0 "memory_operand") 761 (match_operand 1 "memory_operand")) 762 (const_string "both") 763 (match_operand 0 "memory_operand") 764 (const_string "store") 765 (match_operand 1 "memory_operand") 766 (const_string "load") 767 (and (eq_attr "type" 768 "!alu1,negnot,ishift1,rotate1, 769 imov,imovx,icmp,test,bitmanip, 770 fmov,fcmp,fsgn, 771 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt, 772 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1, 773 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov") 774 (match_operand 2 "memory_operand")) 775 (const_string "load") 776 (and (eq_attr "type" "icmov,ssemuladd,sse4arg") 777 (match_operand 3 "memory_operand")) 778 (const_string "load") 779 ] 780 (const_string "none"))) 781 782;; Indicates if an instruction has both an immediate and a displacement. 783 784(define_attr "imm_disp" "false,true,unknown" 785 (cond [(eq_attr "type" "other,multi") 786 (const_string "unknown") 787 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 788 (and (match_operand 0 "memory_displacement_operand") 789 (match_operand 1 "immediate_operand"))) 790 (const_string "true") 791 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv") 792 (and (match_operand 0 "memory_displacement_operand") 793 (match_operand 2 "immediate_operand"))) 794 (const_string "true") 795 ] 796 (const_string "false"))) 797 798;; Indicates if an FP operation has an integer source. 799 800(define_attr "fp_int_src" "false,true" 801 (const_string "false")) 802 803;; Defines rounding mode of an FP operation. 804 805(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 806 (const_string "any")) 807 808;; Define attribute to classify add/sub insns that consumes carry flag (CF) 809(define_attr "use_carry" "0,1" (const_string "0")) 810 811;; Define attribute to indicate unaligned ssemov insns 812(define_attr "movu" "0,1" (const_string "0")) 813 814;; Used to control the "enabled" attribute on a per-instruction basis. 815(define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64, 816 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx, 817 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f, 818 avx512bw,noavx512bw,avx512dq,noavx512dq, 819 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw" 820 (const_string "base")) 821 822(define_attr "enabled" "" 823 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT") 824 (eq_attr "isa" "x64_sse4") 825 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1") 826 (eq_attr "isa" "x64_sse4_noavx") 827 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX") 828 (eq_attr "isa" "x64_avx") 829 (symbol_ref "TARGET_64BIT && TARGET_AVX") 830 (eq_attr "isa" "x64_avx512dq") 831 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ") 832 (eq_attr "isa" "x64_avx512bw") 833 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW") 834 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT") 835 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2") 836 (eq_attr "isa" "sse2_noavx") 837 (symbol_ref "TARGET_SSE2 && !TARGET_AVX") 838 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3") 839 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1") 840 (eq_attr "isa" "sse4_noavx") 841 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX") 842 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX") 843 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX") 844 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2") 845 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2") 846 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI") 847 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2") 848 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4") 849 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA") 850 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F") 851 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F") 852 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW") 853 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW") 854 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ") 855 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ") 856 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL") 857 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL") 858 ] 859 (const_int 1))) 860 861(define_attr "preferred_for_size" "" (const_int 1)) 862(define_attr "preferred_for_speed" "" (const_int 1)) 863 864;; Describe a user's asm statement. 865(define_asm_attributes 866 [(set_attr "length" "128") 867 (set_attr "type" "multi")]) 868 869(define_code_iterator plusminus [plus minus]) 870 871(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus]) 872 873(define_code_iterator multdiv [mult div]) 874 875;; Base name for define_insn 876(define_code_attr plusminus_insn 877 [(plus "add") (ss_plus "ssadd") (us_plus "usadd") 878 (minus "sub") (ss_minus "sssub") (us_minus "ussub")]) 879 880;; Base name for insn mnemonic. 881(define_code_attr plusminus_mnemonic 882 [(plus "add") (ss_plus "adds") (us_plus "addus") 883 (minus "sub") (ss_minus "subs") (us_minus "subus")]) 884(define_code_attr multdiv_mnemonic 885 [(mult "mul") (div "div")]) 886 887;; Mark commutative operators as such in constraints. 888(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%") 889 (minus "") (ss_minus "") (us_minus "")]) 890 891;; Mapping of max and min 892(define_code_iterator maxmin [smax smin umax umin]) 893 894;; Mapping of signed max and min 895(define_code_iterator smaxmin [smax smin]) 896 897;; Mapping of unsigned max and min 898(define_code_iterator umaxmin [umax umin]) 899 900;; Base name for integer and FP insn mnemonic 901(define_code_attr maxmin_int [(smax "maxs") (smin "mins") 902 (umax "maxu") (umin "minu")]) 903(define_code_attr maxmin_float [(smax "max") (smin "min")]) 904 905(define_int_iterator IEEE_MAXMIN 906 [UNSPEC_IEEE_MAX 907 UNSPEC_IEEE_MIN]) 908 909(define_int_attr ieee_maxmin 910 [(UNSPEC_IEEE_MAX "max") 911 (UNSPEC_IEEE_MIN "min")]) 912 913;; Mapping of logic operators 914(define_code_iterator any_logic [and ior xor]) 915(define_code_iterator any_or [ior xor]) 916(define_code_iterator fpint_logic [and xor]) 917 918;; Base name for insn mnemonic. 919(define_code_attr logic [(and "and") (ior "or") (xor "xor")]) 920 921;; Mapping of logic-shift operators 922(define_code_iterator any_lshift [ashift lshiftrt]) 923 924;; Mapping of shift-right operators 925(define_code_iterator any_shiftrt [lshiftrt ashiftrt]) 926 927;; Mapping of all shift operators 928(define_code_iterator any_shift [ashift lshiftrt ashiftrt]) 929 930;; Base name for define_insn 931(define_code_attr shift_insn 932 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")]) 933 934;; Base name for insn mnemonic. 935(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")]) 936(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")]) 937 938;; Mapping of rotate operators 939(define_code_iterator any_rotate [rotate rotatert]) 940 941;; Base name for define_insn 942(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")]) 943 944;; Base name for insn mnemonic. 945(define_code_attr rotate [(rotate "rol") (rotatert "ror")]) 946 947;; Mapping of abs neg operators 948(define_code_iterator absneg [abs neg]) 949 950;; Base name for x87 insn mnemonic. 951(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")]) 952 953;; Used in signed and unsigned widening multiplications. 954(define_code_iterator any_extend [sign_extend zero_extend]) 955 956;; Prefix for insn menmonic. 957(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")]) 958 959;; Prefix for define_insn 960(define_code_attr u [(sign_extend "") (zero_extend "u")]) 961(define_code_attr s [(sign_extend "s") (zero_extend "u")]) 962(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")]) 963 964;; Used in signed and unsigned truncations. 965(define_code_iterator any_truncate [ss_truncate truncate us_truncate]) 966;; Instruction suffix for truncations. 967(define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")]) 968 969;; Used in signed and unsigned fix. 970(define_code_iterator any_fix [fix unsigned_fix]) 971(define_code_attr fixsuffix [(fix "") (unsigned_fix "u")]) 972 973;; Used in signed and unsigned float. 974(define_code_iterator any_float [float unsigned_float]) 975(define_code_attr floatsuffix [(float "") (unsigned_float "u")]) 976 977;; All integer modes. 978(define_mode_iterator SWI1248x [QI HI SI DI]) 979 980;; All integer modes without QImode. 981(define_mode_iterator SWI248x [HI SI DI]) 982 983;; All integer modes without QImode and HImode. 984(define_mode_iterator SWI48x [SI DI]) 985 986;; All integer modes without SImode and DImode. 987(define_mode_iterator SWI12 [QI HI]) 988 989;; All integer modes without DImode. 990(define_mode_iterator SWI124 [QI HI SI]) 991 992;; All integer modes without QImode and DImode. 993(define_mode_iterator SWI24 [HI SI]) 994 995;; Single word integer modes. 996(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")]) 997 998;; Single word integer modes without QImode. 999(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")]) 1000 1001;; Single word integer modes without QImode and HImode. 1002(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")]) 1003 1004;; All math-dependant single and double word integer modes. 1005(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH") 1006 (HI "TARGET_HIMODE_MATH") 1007 SI DI (TI "TARGET_64BIT")]) 1008 1009;; Math-dependant single word integer modes. 1010(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH") 1011 (HI "TARGET_HIMODE_MATH") 1012 SI (DI "TARGET_64BIT")]) 1013 1014;; Math-dependant integer modes without DImode. 1015(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH") 1016 (HI "TARGET_HIMODE_MATH") 1017 SI]) 1018 1019;; Math-dependant integer modes with DImode. 1020(define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH") 1021 (HI "TARGET_HIMODE_MATH") 1022 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")]) 1023 1024;; Math-dependant single word integer modes without QImode. 1025(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH") 1026 SI (DI "TARGET_64BIT")]) 1027 1028;; Double word integer modes. 1029(define_mode_iterator DWI [(DI "!TARGET_64BIT") 1030 (TI "TARGET_64BIT")]) 1031 1032;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not 1033;; compile time constant, it is faster to use <MODE_SIZE> than 1034;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on 1035;; command line options just use GET_MODE_SIZE macro. 1036(define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16") 1037 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)") 1038 (V16QI "16") (V32QI "32") (V64QI "64") 1039 (V8HI "16") (V16HI "32") (V32HI "64") 1040 (V4SI "16") (V8SI "32") (V16SI "64") 1041 (V2DI "16") (V4DI "32") (V8DI "64") 1042 (V1TI "16") (V2TI "32") (V4TI "64") 1043 (V2DF "16") (V4DF "32") (V8DF "64") 1044 (V4SF "16") (V8SF "32") (V16SF "64")]) 1045 1046;; Double word integer modes as mode attribute. 1047(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")]) 1048(define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")]) 1049 1050;; LEA mode corresponding to an integer mode 1051(define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")]) 1052 1053;; Half mode for double word integer modes. 1054(define_mode_iterator DWIH [(SI "!TARGET_64BIT") 1055 (DI "TARGET_64BIT")]) 1056 1057;; Bound modes. 1058(define_mode_iterator BND [(BND32 "!TARGET_LP64") 1059 (BND64 "TARGET_LP64")]) 1060 1061;; Pointer mode corresponding to bound mode. 1062(define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")]) 1063 1064;; MPX check types 1065(define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN]) 1066 1067;; Check name 1068(define_int_attr bndcheck [(UNSPEC_BNDCL "cl") 1069 (UNSPEC_BNDCU "cu") 1070 (UNSPEC_BNDCN "cn")]) 1071 1072;; Instruction suffix for integer modes. 1073(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")]) 1074 1075;; Instruction suffix for masks. 1076(define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")]) 1077 1078;; Pointer size prefix for integer modes (Intel asm dialect) 1079(define_mode_attr iptrsize [(QI "BYTE") 1080 (HI "WORD") 1081 (SI "DWORD") 1082 (DI "QWORD")]) 1083 1084;; Register class for integer modes. 1085(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) 1086 1087;; Immediate operand constraint for integer modes. 1088(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")]) 1089 1090;; General operand constraint for word modes. 1091(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")]) 1092 1093;; Immediate operand constraint for double integer modes. 1094(define_mode_attr di [(SI "nF") (DI "Wd")]) 1095 1096;; Immediate operand constraint for shifts. 1097(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")]) 1098 1099;; Print register name in the specified mode. 1100(define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")]) 1101 1102;; General operand predicate for integer modes. 1103(define_mode_attr general_operand 1104 [(QI "general_operand") 1105 (HI "general_operand") 1106 (SI "x86_64_general_operand") 1107 (DI "x86_64_general_operand") 1108 (TI "x86_64_general_operand")]) 1109 1110;; General operand predicate for integer modes, where for TImode 1111;; we need both words of the operand to be general operands. 1112(define_mode_attr general_hilo_operand 1113 [(QI "general_operand") 1114 (HI "general_operand") 1115 (SI "x86_64_general_operand") 1116 (DI "x86_64_general_operand") 1117 (TI "x86_64_hilo_general_operand")]) 1118 1119;; General sign extend operand predicate for integer modes, 1120;; which disallows VOIDmode operands and thus it is suitable 1121;; for use inside sign_extend. 1122(define_mode_attr general_sext_operand 1123 [(QI "sext_operand") 1124 (HI "sext_operand") 1125 (SI "x86_64_sext_operand") 1126 (DI "x86_64_sext_operand")]) 1127 1128;; General sign/zero extend operand predicate for integer modes. 1129(define_mode_attr general_szext_operand 1130 [(QI "general_operand") 1131 (HI "general_operand") 1132 (SI "x86_64_szext_general_operand") 1133 (DI "x86_64_szext_general_operand")]) 1134 1135;; Immediate operand predicate for integer modes. 1136(define_mode_attr immediate_operand 1137 [(QI "immediate_operand") 1138 (HI "immediate_operand") 1139 (SI "x86_64_immediate_operand") 1140 (DI "x86_64_immediate_operand")]) 1141 1142;; Nonmemory operand predicate for integer modes. 1143(define_mode_attr nonmemory_operand 1144 [(QI "nonmemory_operand") 1145 (HI "nonmemory_operand") 1146 (SI "x86_64_nonmemory_operand") 1147 (DI "x86_64_nonmemory_operand")]) 1148 1149;; Operand predicate for shifts. 1150(define_mode_attr shift_operand 1151 [(QI "nonimmediate_operand") 1152 (HI "nonimmediate_operand") 1153 (SI "nonimmediate_operand") 1154 (DI "shiftdi_operand") 1155 (TI "register_operand")]) 1156 1157;; Operand predicate for shift argument. 1158(define_mode_attr shift_immediate_operand 1159 [(QI "const_1_to_31_operand") 1160 (HI "const_1_to_31_operand") 1161 (SI "const_1_to_31_operand") 1162 (DI "const_1_to_63_operand")]) 1163 1164;; Input operand predicate for arithmetic left shifts. 1165(define_mode_attr ashl_input_operand 1166 [(QI "nonimmediate_operand") 1167 (HI "nonimmediate_operand") 1168 (SI "nonimmediate_operand") 1169 (DI "ashldi_input_operand") 1170 (TI "reg_or_pm1_operand")]) 1171 1172;; SSE and x87 SFmode and DFmode floating point modes 1173(define_mode_iterator MODEF [SF DF]) 1174 1175;; All x87 floating point modes 1176(define_mode_iterator X87MODEF [SF DF XF]) 1177 1178;; SSE instruction suffix for various modes 1179(define_mode_attr ssemodesuffix 1180 [(SF "ss") (DF "sd") 1181 (V16SF "ps") (V8DF "pd") 1182 (V8SF "ps") (V4DF "pd") 1183 (V4SF "ps") (V2DF "pd") 1184 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q") 1185 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q") 1186 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")]) 1187 1188;; SSE vector suffix for floating point modes 1189(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")]) 1190 1191;; SSE vector mode corresponding to a scalar mode 1192(define_mode_attr ssevecmode 1193 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")]) 1194(define_mode_attr ssevecmodelower 1195 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")]) 1196 1197;; AVX512F vector mode corresponding to a scalar mode 1198(define_mode_attr avx512fvecmode 1199 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")]) 1200 1201;; Instruction suffix for REX 64bit operators. 1202(define_mode_attr rex64suffix [(SI "") (DI "{q}")]) 1203 1204;; This mode iterator allows :P to be used for patterns that operate on 1205;; pointer-sized quantities. Exactly one of the two alternatives will match. 1206(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 1207 1208;; This mode iterator allows :W to be used for patterns that operate on 1209;; word_mode sized quantities. 1210(define_mode_iterator W 1211 [(SI "word_mode == SImode") (DI "word_mode == DImode")]) 1212 1213;; This mode iterator allows :PTR to be used for patterns that operate on 1214;; ptr_mode sized quantities. 1215(define_mode_iterator PTR 1216 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")]) 1217 1218;; Scheduling descriptions 1219 1220(include "pentium.md") 1221(include "ppro.md") 1222(include "k6.md") 1223(include "athlon.md") 1224(include "bdver1.md") 1225(include "bdver3.md") 1226(include "btver2.md") 1227(include "znver1.md") 1228(include "geode.md") 1229(include "atom.md") 1230(include "slm.md") 1231(include "core2.md") 1232(include "haswell.md") 1233 1234 1235;; Operand and operator predicates and constraints 1236 1237(include "predicates.md") 1238(include "constraints.md") 1239 1240 1241;; Compare and branch/compare and store instructions. 1242 1243(define_expand "cbranch<mode>4" 1244 [(set (reg:CC FLAGS_REG) 1245 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand") 1246 (match_operand:SDWIM 2 "<general_operand>"))) 1247 (set (pc) (if_then_else 1248 (match_operator 0 "ordered_comparison_operator" 1249 [(reg:CC FLAGS_REG) (const_int 0)]) 1250 (label_ref (match_operand 3)) 1251 (pc)))] 1252 "" 1253{ 1254 if (MEM_P (operands[1]) && MEM_P (operands[2])) 1255 operands[1] = force_reg (<MODE>mode, operands[1]); 1256 ix86_expand_branch (GET_CODE (operands[0]), 1257 operands[1], operands[2], operands[3]); 1258 DONE; 1259}) 1260 1261(define_expand "cstore<mode>4" 1262 [(set (reg:CC FLAGS_REG) 1263 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand") 1264 (match_operand:SWIM 3 "<general_operand>"))) 1265 (set (match_operand:QI 0 "register_operand") 1266 (match_operator 1 "ordered_comparison_operator" 1267 [(reg:CC FLAGS_REG) (const_int 0)]))] 1268 "" 1269{ 1270 if (MEM_P (operands[2]) && MEM_P (operands[3])) 1271 operands[2] = force_reg (<MODE>mode, operands[2]); 1272 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1273 operands[2], operands[3]); 1274 DONE; 1275}) 1276 1277(define_expand "cmp<mode>_1" 1278 [(set (reg:CC FLAGS_REG) 1279 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand") 1280 (match_operand:SWI48 1 "<general_operand>")))]) 1281 1282(define_mode_iterator SWI1248_AVX512BWDQ2_64 1283 [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ") 1284 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")]) 1285 1286(define_insn "*cmp<mode>_ccz_1" 1287 [(set (reg FLAGS_REG) 1288 (compare (match_operand:SWI1248_AVX512BWDQ2_64 0 1289 "nonimmediate_operand" "<r>,?m<r>,$k") 1290 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))] 1291 "ix86_match_ccmode (insn, CCZmode)" 1292 "@ 1293 test{<imodesuffix>}\t%0, %0 1294 cmp{<imodesuffix>}\t{%1, %0|%0, %1} 1295 ktest<mskmodesuffix>\t%0, %0" 1296 [(set_attr "type" "test,icmp,msklog") 1297 (set_attr "length_immediate" "0,1,*") 1298 (set_attr "modrm_class" "op0,unknown,*") 1299 (set_attr "prefix" "*,*,vex") 1300 (set_attr "mode" "<MODE>")]) 1301 1302(define_insn "*cmp<mode>_ccno_1" 1303 [(set (reg FLAGS_REG) 1304 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>") 1305 (match_operand:SWI 1 "const0_operand")))] 1306 "ix86_match_ccmode (insn, CCNOmode)" 1307 "@ 1308 test{<imodesuffix>}\t%0, %0 1309 cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1310 [(set_attr "type" "test,icmp") 1311 (set_attr "length_immediate" "0,1") 1312 (set_attr "modrm_class" "op0,unknown") 1313 (set_attr "mode" "<MODE>")]) 1314 1315(define_insn "*cmp<mode>_1" 1316 [(set (reg FLAGS_REG) 1317 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 1318 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))] 1319 "ix86_match_ccmode (insn, CCmode)" 1320 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1321 [(set_attr "type" "icmp") 1322 (set_attr "mode" "<MODE>")]) 1323 1324(define_insn "*cmp<mode>_minus_1" 1325 [(set (reg FLAGS_REG) 1326 (compare 1327 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 1328 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) 1329 (const_int 0)))] 1330 "ix86_match_ccmode (insn, CCGOCmode)" 1331 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1332 [(set_attr "type" "icmp") 1333 (set_attr "mode" "<MODE>")]) 1334 1335(define_insn "*cmpqi_ext_1" 1336 [(set (reg FLAGS_REG) 1337 (compare 1338 (match_operand:QI 0 "nonimmediate_operand" "QBc,m") 1339 (subreg:QI 1340 (zero_extract:SI 1341 (match_operand 1 "ext_register_operand" "Q,Q") 1342 (const_int 8) 1343 (const_int 8)) 0)))] 1344 "ix86_match_ccmode (insn, CCmode)" 1345 "cmp{b}\t{%h1, %0|%0, %h1}" 1346 [(set_attr "isa" "*,nox64") 1347 (set_attr "type" "icmp") 1348 (set_attr "mode" "QI")]) 1349 1350(define_insn "*cmpqi_ext_2" 1351 [(set (reg FLAGS_REG) 1352 (compare 1353 (subreg:QI 1354 (zero_extract:SI 1355 (match_operand 0 "ext_register_operand" "Q") 1356 (const_int 8) 1357 (const_int 8)) 0) 1358 (match_operand:QI 1 "const0_operand")))] 1359 "ix86_match_ccmode (insn, CCNOmode)" 1360 "test{b}\t%h0, %h0" 1361 [(set_attr "type" "test") 1362 (set_attr "length_immediate" "0") 1363 (set_attr "mode" "QI")]) 1364 1365(define_expand "cmpqi_ext_3" 1366 [(set (reg:CC FLAGS_REG) 1367 (compare:CC 1368 (subreg:QI 1369 (zero_extract:SI 1370 (match_operand 0 "ext_register_operand") 1371 (const_int 8) 1372 (const_int 8)) 0) 1373 (match_operand:QI 1 "const_int_operand")))]) 1374 1375(define_insn "*cmpqi_ext_3" 1376 [(set (reg FLAGS_REG) 1377 (compare 1378 (subreg:QI 1379 (zero_extract:SI 1380 (match_operand 0 "ext_register_operand" "Q,Q") 1381 (const_int 8) 1382 (const_int 8)) 0) 1383 (match_operand:QI 1 "general_operand" "QnBc,m")))] 1384 "ix86_match_ccmode (insn, CCmode)" 1385 "cmp{b}\t{%1, %h0|%h0, %1}" 1386 [(set_attr "isa" "*,nox64") 1387 (set_attr "type" "icmp") 1388 (set_attr "mode" "QI")]) 1389 1390(define_insn "*cmpqi_ext_4" 1391 [(set (reg FLAGS_REG) 1392 (compare 1393 (subreg:QI 1394 (zero_extract:SI 1395 (match_operand 0 "ext_register_operand" "Q") 1396 (const_int 8) 1397 (const_int 8)) 0) 1398 (subreg:QI 1399 (zero_extract:SI 1400 (match_operand 1 "ext_register_operand" "Q") 1401 (const_int 8) 1402 (const_int 8)) 0)))] 1403 "ix86_match_ccmode (insn, CCmode)" 1404 "cmp{b}\t{%h1, %h0|%h0, %h1}" 1405 [(set_attr "type" "icmp") 1406 (set_attr "mode" "QI")]) 1407 1408;; These implement float point compares. 1409;; %%% See if we can get away with VOIDmode operands on the actual insns, 1410;; which would allow mix and match FP modes on the compares. Which is what 1411;; the old patterns did, but with many more of them. 1412 1413(define_expand "cbranchxf4" 1414 [(set (reg:CC FLAGS_REG) 1415 (compare:CC (match_operand:XF 1 "nonmemory_operand") 1416 (match_operand:XF 2 "nonmemory_operand"))) 1417 (set (pc) (if_then_else 1418 (match_operator 0 "ix86_fp_comparison_operator" 1419 [(reg:CC FLAGS_REG) 1420 (const_int 0)]) 1421 (label_ref (match_operand 3)) 1422 (pc)))] 1423 "TARGET_80387" 1424{ 1425 ix86_expand_branch (GET_CODE (operands[0]), 1426 operands[1], operands[2], operands[3]); 1427 DONE; 1428}) 1429 1430(define_expand "cstorexf4" 1431 [(set (reg:CC FLAGS_REG) 1432 (compare:CC (match_operand:XF 2 "nonmemory_operand") 1433 (match_operand:XF 3 "nonmemory_operand"))) 1434 (set (match_operand:QI 0 "register_operand") 1435 (match_operator 1 "ix86_fp_comparison_operator" 1436 [(reg:CC FLAGS_REG) 1437 (const_int 0)]))] 1438 "TARGET_80387" 1439{ 1440 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1441 operands[2], operands[3]); 1442 DONE; 1443}) 1444 1445(define_expand "cbranch<mode>4" 1446 [(set (reg:CC FLAGS_REG) 1447 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand") 1448 (match_operand:MODEF 2 "cmp_fp_expander_operand"))) 1449 (set (pc) (if_then_else 1450 (match_operator 0 "ix86_fp_comparison_operator" 1451 [(reg:CC FLAGS_REG) 1452 (const_int 0)]) 1453 (label_ref (match_operand 3)) 1454 (pc)))] 1455 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1456{ 1457 ix86_expand_branch (GET_CODE (operands[0]), 1458 operands[1], operands[2], operands[3]); 1459 DONE; 1460}) 1461 1462(define_expand "cstore<mode>4" 1463 [(set (reg:CC FLAGS_REG) 1464 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand") 1465 (match_operand:MODEF 3 "cmp_fp_expander_operand"))) 1466 (set (match_operand:QI 0 "register_operand") 1467 (match_operator 1 "ix86_fp_comparison_operator" 1468 [(reg:CC FLAGS_REG) 1469 (const_int 0)]))] 1470 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1471{ 1472 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1473 operands[2], operands[3]); 1474 DONE; 1475}) 1476 1477(define_expand "cbranchcc4" 1478 [(set (pc) (if_then_else 1479 (match_operator 0 "comparison_operator" 1480 [(match_operand 1 "flags_reg_operand") 1481 (match_operand 2 "const0_operand")]) 1482 (label_ref (match_operand 3)) 1483 (pc)))] 1484 "" 1485{ 1486 ix86_expand_branch (GET_CODE (operands[0]), 1487 operands[1], operands[2], operands[3]); 1488 DONE; 1489}) 1490 1491(define_expand "cstorecc4" 1492 [(set (match_operand:QI 0 "register_operand") 1493 (match_operator 1 "comparison_operator" 1494 [(match_operand 2 "flags_reg_operand") 1495 (match_operand 3 "const0_operand")]))] 1496 "" 1497{ 1498 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1499 operands[2], operands[3]); 1500 DONE; 1501}) 1502 1503 1504;; FP compares, step 1: 1505;; Set the FP condition codes. 1506 1507;; We may not use "#" to split and emit these, since the REG_DEAD notes 1508;; used to manage the reg stack popping would not be preserved. 1509 1510(define_insn "*cmp<mode>_0_i387" 1511 [(set (match_operand:HI 0 "register_operand" "=a") 1512 (unspec:HI 1513 [(compare:CCFP 1514 (match_operand:X87MODEF 1 "register_operand" "f") 1515 (match_operand:X87MODEF 2 "const0_operand"))] 1516 UNSPEC_FNSTSW))] 1517 "TARGET_80387" 1518 "* return output_fp_compare (insn, operands, false, false);" 1519 [(set_attr "type" "multi") 1520 (set_attr "unit" "i387") 1521 (set_attr "mode" "<MODE>")]) 1522 1523(define_insn_and_split "*cmp<mode>_0_cc_i387" 1524 [(set (reg:CCFP FLAGS_REG) 1525 (compare:CCFP 1526 (match_operand:X87MODEF 1 "register_operand" "f") 1527 (match_operand:X87MODEF 2 "const0_operand"))) 1528 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1529 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" 1530 "#" 1531 "&& reload_completed" 1532 [(set (match_dup 0) 1533 (unspec:HI 1534 [(compare:CCFP (match_dup 1)(match_dup 2))] 1535 UNSPEC_FNSTSW)) 1536 (set (reg:CC FLAGS_REG) 1537 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1538 "" 1539 [(set_attr "type" "multi") 1540 (set_attr "unit" "i387") 1541 (set_attr "mode" "<MODE>")]) 1542 1543(define_insn "*cmpxf_i387" 1544 [(set (match_operand:HI 0 "register_operand" "=a") 1545 (unspec:HI 1546 [(compare:CCFP 1547 (match_operand:XF 1 "register_operand" "f") 1548 (match_operand:XF 2 "register_operand" "f"))] 1549 UNSPEC_FNSTSW))] 1550 "TARGET_80387" 1551 "* return output_fp_compare (insn, operands, false, false);" 1552 [(set_attr "type" "multi") 1553 (set_attr "unit" "i387") 1554 (set_attr "mode" "XF")]) 1555 1556(define_insn_and_split "*cmpxf_cc_i387" 1557 [(set (reg:CCFP FLAGS_REG) 1558 (compare:CCFP 1559 (match_operand:XF 1 "register_operand" "f") 1560 (match_operand:XF 2 "register_operand" "f"))) 1561 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1562 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" 1563 "#" 1564 "&& reload_completed" 1565 [(set (match_dup 0) 1566 (unspec:HI 1567 [(compare:CCFP (match_dup 1)(match_dup 2))] 1568 UNSPEC_FNSTSW)) 1569 (set (reg:CC FLAGS_REG) 1570 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1571 "" 1572 [(set_attr "type" "multi") 1573 (set_attr "unit" "i387") 1574 (set_attr "mode" "XF")]) 1575 1576(define_insn "*cmp<mode>_i387" 1577 [(set (match_operand:HI 0 "register_operand" "=a") 1578 (unspec:HI 1579 [(compare:CCFP 1580 (match_operand:MODEF 1 "register_operand" "f") 1581 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))] 1582 UNSPEC_FNSTSW))] 1583 "TARGET_80387" 1584 "* return output_fp_compare (insn, operands, false, false);" 1585 [(set_attr "type" "multi") 1586 (set_attr "unit" "i387") 1587 (set_attr "mode" "<MODE>")]) 1588 1589(define_insn_and_split "*cmp<mode>_cc_i387" 1590 [(set (reg:CCFP FLAGS_REG) 1591 (compare:CCFP 1592 (match_operand:MODEF 1 "register_operand" "f") 1593 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))) 1594 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1595 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" 1596 "#" 1597 "&& reload_completed" 1598 [(set (match_dup 0) 1599 (unspec:HI 1600 [(compare:CCFP (match_dup 1)(match_dup 2))] 1601 UNSPEC_FNSTSW)) 1602 (set (reg:CC FLAGS_REG) 1603 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1604 "" 1605 [(set_attr "type" "multi") 1606 (set_attr "unit" "i387") 1607 (set_attr "mode" "<MODE>")]) 1608 1609(define_insn "*cmpu<mode>_i387" 1610 [(set (match_operand:HI 0 "register_operand" "=a") 1611 (unspec:HI 1612 [(unspec:CCFP 1613 [(compare:CCFP 1614 (match_operand:X87MODEF 1 "register_operand" "f") 1615 (match_operand:X87MODEF 2 "register_operand" "f"))] 1616 UNSPEC_NOTRAP)] 1617 UNSPEC_FNSTSW))] 1618 "TARGET_80387" 1619 "* return output_fp_compare (insn, operands, false, true);" 1620 [(set_attr "type" "multi") 1621 (set_attr "unit" "i387") 1622 (set_attr "mode" "<MODE>")]) 1623 1624(define_insn_and_split "*cmpu<mode>_cc_i387" 1625 [(set (reg:CCFP FLAGS_REG) 1626 (unspec:CCFP 1627 [(compare:CCFP 1628 (match_operand:X87MODEF 1 "register_operand" "f") 1629 (match_operand:X87MODEF 2 "register_operand" "f"))] 1630 UNSPEC_NOTRAP)) 1631 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1632 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" 1633 "#" 1634 "&& reload_completed" 1635 [(set (match_dup 0) 1636 (unspec:HI 1637 [(unspec:CCFP 1638 [(compare:CCFP (match_dup 1)(match_dup 2))] 1639 UNSPEC_NOTRAP)] 1640 UNSPEC_FNSTSW)) 1641 (set (reg:CC FLAGS_REG) 1642 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1643 "" 1644 [(set_attr "type" "multi") 1645 (set_attr "unit" "i387") 1646 (set_attr "mode" "<MODE>")]) 1647 1648(define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387" 1649 [(set (match_operand:HI 0 "register_operand" "=a") 1650 (unspec:HI 1651 [(compare:CCFP 1652 (match_operand:X87MODEF 1 "register_operand" "f") 1653 (float:X87MODEF 1654 (match_operand:SWI24 2 "memory_operand" "m")))] 1655 UNSPEC_FNSTSW))] 1656 "TARGET_80387 1657 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 1658 || optimize_function_for_size_p (cfun))" 1659 "* return output_fp_compare (insn, operands, false, false);" 1660 [(set_attr "type" "multi") 1661 (set_attr "unit" "i387") 1662 (set_attr "fp_int_src" "true") 1663 (set_attr "mode" "<SWI24:MODE>")]) 1664 1665(define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387" 1666 [(set (reg:CCFP FLAGS_REG) 1667 (compare:CCFP 1668 (match_operand:X87MODEF 1 "register_operand" "f") 1669 (float:X87MODEF 1670 (match_operand:SWI24 2 "memory_operand" "m")))) 1671 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1672 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE 1673 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 1674 || optimize_function_for_size_p (cfun))" 1675 "#" 1676 "&& reload_completed" 1677 [(set (match_dup 0) 1678 (unspec:HI 1679 [(compare:CCFP 1680 (match_dup 1) 1681 (float:X87MODEF (match_dup 2)))] 1682 UNSPEC_FNSTSW)) 1683 (set (reg:CC FLAGS_REG) 1684 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1685 "" 1686 [(set_attr "type" "multi") 1687 (set_attr "unit" "i387") 1688 (set_attr "fp_int_src" "true") 1689 (set_attr "mode" "<SWI24:MODE>")]) 1690 1691;; FP compares, step 2 1692;; Move the fpsw to ax. 1693 1694(define_insn "x86_fnstsw_1" 1695 [(set (match_operand:HI 0 "register_operand" "=a") 1696 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 1697 "TARGET_80387" 1698 "fnstsw\t%0" 1699 [(set_attr "length" "2") 1700 (set_attr "mode" "SI") 1701 (set_attr "unit" "i387")]) 1702 1703;; FP compares, step 3 1704;; Get ax into flags, general case. 1705 1706(define_insn "x86_sahf_1" 1707 [(set (reg:CC FLAGS_REG) 1708 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 1709 UNSPEC_SAHF))] 1710 "TARGET_SAHF" 1711{ 1712#ifndef HAVE_AS_IX86_SAHF 1713 if (TARGET_64BIT) 1714 return ASM_BYTE "0x9e"; 1715 else 1716#endif 1717 return "sahf"; 1718} 1719 [(set_attr "length" "1") 1720 (set_attr "athlon_decode" "vector") 1721 (set_attr "amdfam10_decode" "direct") 1722 (set_attr "bdver1_decode" "direct") 1723 (set_attr "mode" "SI")]) 1724 1725;; Pentium Pro can do steps 1 through 3 in one go. 1726;; (these instructions set flags directly) 1727 1728(define_subst_attr "unord" "unord_subst" "" "u") 1729(define_subst_attr "unordered" "unord_subst" "false" "true") 1730 1731(define_subst "unord_subst" 1732 [(set (match_operand:CCFP 0) 1733 (match_operand:CCFP 1))] 1734 "" 1735 [(set (match_dup 0) 1736 (unspec:CCFP 1737 [(match_dup 1)] 1738 UNSPEC_NOTRAP))]) 1739 1740(define_insn "*cmpi<unord><MODEF:mode>" 1741 [(set (reg:CCFP FLAGS_REG) 1742 (compare:CCFP 1743 (match_operand:MODEF 0 "register_operand" "f,v") 1744 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))] 1745 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 1746 || (TARGET_80387 && TARGET_CMOVE)" 1747 "@ 1748 * return output_fp_compare (insn, operands, true, <unordered>); 1749 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}" 1750 [(set_attr "type" "fcmp,ssecomi") 1751 (set_attr "prefix" "orig,maybe_vex") 1752 (set_attr "mode" "<MODEF:MODE>") 1753 (set_attr "prefix_rep" "*,0") 1754 (set (attr "prefix_data16") 1755 (cond [(eq_attr "alternative" "0") 1756 (const_string "*") 1757 (eq_attr "mode" "DF") 1758 (const_string "1") 1759 ] 1760 (const_string "0"))) 1761 (set_attr "athlon_decode" "vector") 1762 (set_attr "amdfam10_decode" "direct") 1763 (set_attr "bdver1_decode" "double") 1764 (set_attr "znver1_decode" "double") 1765 (set (attr "enabled") 1766 (if_then_else 1767 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")) 1768 (if_then_else 1769 (eq_attr "alternative" "0") 1770 (symbol_ref "TARGET_MIX_SSE_I387") 1771 (symbol_ref "true")) 1772 (if_then_else 1773 (eq_attr "alternative" "0") 1774 (symbol_ref "true") 1775 (symbol_ref "false"))))]) 1776 1777(define_insn "*cmpi<unord>xf_i387" 1778 [(set (reg:CCFP FLAGS_REG) 1779 (compare:CCFP 1780 (match_operand:XF 0 "register_operand" "f") 1781 (match_operand:XF 1 "register_operand" "f")))] 1782 "TARGET_80387 && TARGET_CMOVE" 1783 "* return output_fp_compare (insn, operands, true, <unordered>);" 1784 [(set_attr "type" "fcmp") 1785 (set_attr "mode" "XF") 1786 (set_attr "athlon_decode" "vector") 1787 (set_attr "amdfam10_decode" "direct") 1788 (set_attr "bdver1_decode" "double") 1789 (set_attr "znver1_decode" "double")]) 1790 1791;; Push/pop instructions. 1792 1793(define_insn "*push<mode>2" 1794 [(set (match_operand:DWI 0 "push_operand" "=<") 1795 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))] 1796 "" 1797 "#" 1798 [(set_attr "type" "multi") 1799 (set_attr "mode" "<MODE>")]) 1800 1801(define_split 1802 [(set (match_operand:DWI 0 "push_operand") 1803 (match_operand:DWI 1 "general_gr_operand"))] 1804 "reload_completed" 1805 [(const_int 0)] 1806 "ix86_split_long_move (operands); DONE;") 1807 1808(define_insn "*pushdi2_rex64" 1809 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1810 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1811 "TARGET_64BIT" 1812 "@ 1813 push{q}\t%1 1814 #" 1815 [(set_attr "type" "push,multi") 1816 (set_attr "mode" "DI")]) 1817 1818;; Convert impossible pushes of immediate to existing instructions. 1819;; First try to get scratch register and go through it. In case this 1820;; fails, push sign extended lower part first and then overwrite 1821;; upper part by 32bit move. 1822(define_peephole2 1823 [(match_scratch:DI 2 "r") 1824 (set (match_operand:DI 0 "push_operand") 1825 (match_operand:DI 1 "immediate_operand"))] 1826 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1827 && !x86_64_immediate_operand (operands[1], DImode)" 1828 [(set (match_dup 2) (match_dup 1)) 1829 (set (match_dup 0) (match_dup 2))]) 1830 1831;; We need to define this as both peepholer and splitter for case 1832;; peephole2 pass is not run. 1833;; "&& 1" is needed to keep it from matching the previous pattern. 1834(define_peephole2 1835 [(set (match_operand:DI 0 "push_operand") 1836 (match_operand:DI 1 "immediate_operand"))] 1837 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1838 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1839 [(set (match_dup 0) (match_dup 1)) 1840 (set (match_dup 2) (match_dup 3))] 1841{ 1842 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1843 1844 operands[1] = gen_lowpart (DImode, operands[2]); 1845 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx, 1846 GEN_INT (4))); 1847}) 1848 1849(define_split 1850 [(set (match_operand:DI 0 "push_operand") 1851 (match_operand:DI 1 "immediate_operand"))] 1852 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1853 ? epilogue_completed : reload_completed) 1854 && !symbolic_operand (operands[1], DImode) 1855 && !x86_64_immediate_operand (operands[1], DImode)" 1856 [(set (match_dup 0) (match_dup 1)) 1857 (set (match_dup 2) (match_dup 3))] 1858{ 1859 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1860 1861 operands[1] = gen_lowpart (DImode, operands[2]); 1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx, 1863 GEN_INT (4))); 1864}) 1865 1866(define_insn "*pushsi2" 1867 [(set (match_operand:SI 0 "push_operand" "=<") 1868 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1869 "!TARGET_64BIT" 1870 "push{l}\t%1" 1871 [(set_attr "type" "push") 1872 (set_attr "mode" "SI")]) 1873 1874;; emit_push_insn when it calls move_by_pieces requires an insn to 1875;; "push a byte/word". But actually we use pushl, which has the effect 1876;; of rounding the amount pushed up to a word. 1877 1878;; For TARGET_64BIT we always round up to 8 bytes. 1879(define_insn "*push<mode>2_rex64" 1880 [(set (match_operand:SWI124 0 "push_operand" "=X") 1881 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))] 1882 "TARGET_64BIT" 1883 "push{q}\t%q1" 1884 [(set_attr "type" "push") 1885 (set_attr "mode" "DI")]) 1886 1887(define_insn "*push<mode>2" 1888 [(set (match_operand:SWI12 0 "push_operand" "=X") 1889 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))] 1890 "!TARGET_64BIT" 1891 "push{l}\t%k1" 1892 [(set_attr "type" "push") 1893 (set_attr "mode" "SI")]) 1894 1895(define_insn "*push<mode>2_prologue" 1896 [(set (match_operand:W 0 "push_operand" "=<") 1897 (match_operand:W 1 "general_no_elim_operand" "r<i>*m")) 1898 (clobber (mem:BLK (scratch)))] 1899 "" 1900 "push{<imodesuffix>}\t%1" 1901 [(set_attr "type" "push") 1902 (set_attr "mode" "<MODE>")]) 1903 1904(define_insn "*pop<mode>1" 1905 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m") 1906 (match_operand:W 1 "pop_operand" ">"))] 1907 "" 1908 "pop{<imodesuffix>}\t%0" 1909 [(set_attr "type" "pop") 1910 (set_attr "mode" "<MODE>")]) 1911 1912(define_insn "*pop<mode>1_epilogue" 1913 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m") 1914 (match_operand:W 1 "pop_operand" ">")) 1915 (clobber (mem:BLK (scratch)))] 1916 "" 1917 "pop{<imodesuffix>}\t%0" 1918 [(set_attr "type" "pop") 1919 (set_attr "mode" "<MODE>")]) 1920 1921(define_insn "*pushfl<mode>2" 1922 [(set (match_operand:W 0 "push_operand" "=<") 1923 (match_operand:W 1 "flags_reg_operand"))] 1924 "" 1925 "pushf{<imodesuffix>}" 1926 [(set_attr "type" "push") 1927 (set_attr "mode" "<MODE>")]) 1928 1929(define_insn "*popfl<mode>1" 1930 [(set (match_operand:W 0 "flags_reg_operand") 1931 (match_operand:W 1 "pop_operand" ">"))] 1932 "" 1933 "popf{<imodesuffix>}" 1934 [(set_attr "type" "pop") 1935 (set_attr "mode" "<MODE>")]) 1936 1937 1938;; Reload patterns to support multi-word load/store 1939;; with non-offsetable address. 1940(define_expand "reload_noff_store" 1941 [(parallel [(match_operand 0 "memory_operand" "=m") 1942 (match_operand 1 "register_operand" "r") 1943 (match_operand:DI 2 "register_operand" "=&r")])] 1944 "TARGET_64BIT" 1945{ 1946 rtx mem = operands[0]; 1947 rtx addr = XEXP (mem, 0); 1948 1949 emit_move_insn (operands[2], addr); 1950 mem = replace_equiv_address_nv (mem, operands[2]); 1951 1952 emit_insn (gen_rtx_SET (mem, operands[1])); 1953 DONE; 1954}) 1955 1956(define_expand "reload_noff_load" 1957 [(parallel [(match_operand 0 "register_operand" "=r") 1958 (match_operand 1 "memory_operand" "m") 1959 (match_operand:DI 2 "register_operand" "=r")])] 1960 "TARGET_64BIT" 1961{ 1962 rtx mem = operands[1]; 1963 rtx addr = XEXP (mem, 0); 1964 1965 emit_move_insn (operands[2], addr); 1966 mem = replace_equiv_address_nv (mem, operands[2]); 1967 1968 emit_insn (gen_rtx_SET (operands[0], mem)); 1969 DONE; 1970}) 1971 1972;; Move instructions. 1973 1974(define_expand "movxi" 1975 [(set (match_operand:XI 0 "nonimmediate_operand") 1976 (match_operand:XI 1 "general_operand"))] 1977 "TARGET_AVX512F" 1978 "ix86_expand_vector_move (XImode, operands); DONE;") 1979 1980(define_expand "movoi" 1981 [(set (match_operand:OI 0 "nonimmediate_operand") 1982 (match_operand:OI 1 "general_operand"))] 1983 "TARGET_AVX" 1984 "ix86_expand_vector_move (OImode, operands); DONE;") 1985 1986(define_expand "movti" 1987 [(set (match_operand:TI 0 "nonimmediate_operand") 1988 (match_operand:TI 1 "general_operand"))] 1989 "TARGET_64BIT || TARGET_SSE" 1990{ 1991 if (TARGET_64BIT) 1992 ix86_expand_move (TImode, operands); 1993 else 1994 ix86_expand_vector_move (TImode, operands); 1995 DONE; 1996}) 1997 1998;; This expands to what emit_move_complex would generate if we didn't 1999;; have a movti pattern. Having this avoids problems with reload on 2000;; 32-bit targets when SSE is present, but doesn't seem to be harmful 2001;; to have around all the time. 2002(define_expand "movcdi" 2003 [(set (match_operand:CDI 0 "nonimmediate_operand") 2004 (match_operand:CDI 1 "general_operand"))] 2005 "" 2006{ 2007 if (push_operand (operands[0], CDImode)) 2008 emit_move_complex_push (CDImode, operands[0], operands[1]); 2009 else 2010 emit_move_complex_parts (operands[0], operands[1]); 2011 DONE; 2012}) 2013 2014(define_expand "mov<mode>" 2015 [(set (match_operand:SWI1248x 0 "nonimmediate_operand") 2016 (match_operand:SWI1248x 1 "general_operand"))] 2017 "" 2018 "ix86_expand_move (<MODE>mode, operands); DONE;") 2019 2020(define_insn "*mov<mode>_xor" 2021 [(set (match_operand:SWI48 0 "register_operand" "=r") 2022 (match_operand:SWI48 1 "const0_operand")) 2023 (clobber (reg:CC FLAGS_REG))] 2024 "reload_completed" 2025 "xor{l}\t%k0, %k0" 2026 [(set_attr "type" "alu1") 2027 (set_attr "modrm_class" "op0") 2028 (set_attr "mode" "SI") 2029 (set_attr "length_immediate" "0")]) 2030 2031(define_insn "*mov<mode>_or" 2032 [(set (match_operand:SWI48 0 "register_operand" "=r") 2033 (match_operand:SWI48 1 "constm1_operand")) 2034 (clobber (reg:CC FLAGS_REG))] 2035 "reload_completed" 2036 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 2037 [(set_attr "type" "alu1") 2038 (set_attr "mode" "<MODE>") 2039 (set_attr "length_immediate" "1")]) 2040 2041(define_insn "*movxi_internal_avx512f" 2042 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m") 2043 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))] 2044 "TARGET_AVX512F 2045 && (register_operand (operands[0], XImode) 2046 || register_operand (operands[1], XImode))" 2047{ 2048 switch (get_attr_type (insn)) 2049 { 2050 case TYPE_SSELOG1: 2051 return standard_sse_constant_opcode (insn, operands); 2052 2053 case TYPE_SSEMOV: 2054 if (misaligned_operand (operands[0], XImode) 2055 || misaligned_operand (operands[1], XImode)) 2056 return "vmovdqu32\t{%1, %0|%0, %1}"; 2057 else 2058 return "vmovdqa32\t{%1, %0|%0, %1}"; 2059 2060 default: 2061 gcc_unreachable (); 2062 } 2063} 2064 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov") 2065 (set_attr "prefix" "evex") 2066 (set_attr "mode" "XI")]) 2067 2068(define_insn "*movoi_internal_avx" 2069 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m") 2070 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))] 2071 "TARGET_AVX 2072 && (register_operand (operands[0], OImode) 2073 || register_operand (operands[1], OImode))" 2074{ 2075 switch (get_attr_type (insn)) 2076 { 2077 case TYPE_SSELOG1: 2078 return standard_sse_constant_opcode (insn, operands); 2079 2080 case TYPE_SSEMOV: 2081 if (misaligned_operand (operands[0], OImode) 2082 || misaligned_operand (operands[1], OImode)) 2083 { 2084 if (get_attr_mode (insn) == MODE_V8SF) 2085 return "vmovups\t{%1, %0|%0, %1}"; 2086 else if (get_attr_mode (insn) == MODE_XI) 2087 return "vmovdqu32\t{%1, %0|%0, %1}"; 2088 else 2089 return "vmovdqu\t{%1, %0|%0, %1}"; 2090 } 2091 else 2092 { 2093 if (get_attr_mode (insn) == MODE_V8SF) 2094 return "vmovaps\t{%1, %0|%0, %1}"; 2095 else if (get_attr_mode (insn) == MODE_XI) 2096 return "vmovdqa32\t{%1, %0|%0, %1}"; 2097 else 2098 return "vmovdqa\t{%1, %0|%0, %1}"; 2099 } 2100 2101 default: 2102 gcc_unreachable (); 2103 } 2104} 2105 [(set_attr "isa" "*,avx2,*,*") 2106 (set_attr "type" "sselog1,sselog1,ssemov,ssemov") 2107 (set_attr "prefix" "vex") 2108 (set (attr "mode") 2109 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 2110 (match_operand 1 "ext_sse_reg_operand")) 2111 (const_string "XI") 2112 (and (eq_attr "alternative" "1") 2113 (match_test "TARGET_AVX512VL")) 2114 (const_string "XI") 2115 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") 2116 (and (eq_attr "alternative" "3") 2117 (match_test "TARGET_SSE_TYPELESS_STORES"))) 2118 (const_string "V8SF") 2119 ] 2120 (const_string "OI")))]) 2121 2122(define_insn "*movti_internal" 2123 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd") 2124 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Ye,r"))] 2125 "(TARGET_64BIT 2126 && !(MEM_P (operands[0]) && MEM_P (operands[1]))) 2127 || (TARGET_SSE 2128 && nonimmediate_or_sse_const_operand (operands[1], TImode) 2129 && (register_operand (operands[0], TImode) 2130 || register_operand (operands[1], TImode)))" 2131{ 2132 switch (get_attr_type (insn)) 2133 { 2134 case TYPE_MULTI: 2135 return "#"; 2136 2137 case TYPE_SSELOG1: 2138 return standard_sse_constant_opcode (insn, operands); 2139 2140 case TYPE_SSEMOV: 2141 /* TDmode values are passed as TImode on the stack. Moving them 2142 to stack may result in unaligned memory access. */ 2143 if (misaligned_operand (operands[0], TImode) 2144 || misaligned_operand (operands[1], TImode)) 2145 { 2146 if (get_attr_mode (insn) == MODE_V4SF) 2147 return "%vmovups\t{%1, %0|%0, %1}"; 2148 else if (get_attr_mode (insn) == MODE_XI) 2149 return "vmovdqu32\t{%1, %0|%0, %1}"; 2150 else 2151 return "%vmovdqu\t{%1, %0|%0, %1}"; 2152 } 2153 else 2154 { 2155 if (get_attr_mode (insn) == MODE_V4SF) 2156 return "%vmovaps\t{%1, %0|%0, %1}"; 2157 else if (get_attr_mode (insn) == MODE_XI) 2158 return "vmovdqa32\t{%1, %0|%0, %1}"; 2159 else 2160 return "%vmovdqa\t{%1, %0|%0, %1}"; 2161 } 2162 2163 default: 2164 gcc_unreachable (); 2165 } 2166} 2167 [(set (attr "isa") 2168 (cond [(eq_attr "alternative" "0,1,6,7") 2169 (const_string "x64") 2170 (eq_attr "alternative" "3") 2171 (const_string "sse2") 2172 ] 2173 (const_string "*"))) 2174 (set (attr "type") 2175 (cond [(eq_attr "alternative" "0,1,6,7") 2176 (const_string "multi") 2177 (eq_attr "alternative" "2,3") 2178 (const_string "sselog1") 2179 ] 2180 (const_string "ssemov"))) 2181 (set (attr "prefix") 2182 (if_then_else (eq_attr "type" "sselog1,ssemov") 2183 (const_string "maybe_vex") 2184 (const_string "orig"))) 2185 (set (attr "mode") 2186 (cond [(eq_attr "alternative" "0,1") 2187 (const_string "DI") 2188 (ior (match_operand 0 "ext_sse_reg_operand") 2189 (match_operand 1 "ext_sse_reg_operand")) 2190 (const_string "XI") 2191 (and (eq_attr "alternative" "3") 2192 (match_test "TARGET_AVX512VL")) 2193 (const_string "XI") 2194 (ior (not (match_test "TARGET_SSE2")) 2195 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") 2196 (and (eq_attr "alternative" "5") 2197 (match_test "TARGET_SSE_TYPELESS_STORES")))) 2198 (const_string "V4SF") 2199 (match_test "TARGET_AVX") 2200 (const_string "TI") 2201 (match_test "optimize_function_for_size_p (cfun)") 2202 (const_string "V4SF") 2203 ] 2204 (const_string "TI")))]) 2205 2206(define_split 2207 [(set (match_operand:TI 0 "sse_reg_operand") 2208 (match_operand:TI 1 "general_reg_operand"))] 2209 "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC 2210 && reload_completed" 2211 [(set (match_dup 2) 2212 (vec_merge:V2DI 2213 (vec_duplicate:V2DI (match_dup 3)) 2214 (match_dup 2) 2215 (const_int 2)))] 2216{ 2217 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode); 2218 operands[3] = gen_highpart (DImode, operands[1]); 2219 2220 emit_move_insn (gen_lowpart (DImode, operands[0]), 2221 gen_lowpart (DImode, operands[1])); 2222}) 2223 2224(define_insn "*movdi_internal" 2225 [(set (match_operand:DI 0 "nonimmediate_operand" 2226 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?*Yd,?r ,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m") 2227 (match_operand:DI 1 "general_operand" 2228 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Ye,r ,*Yj,r ,*Yj ,*Yn ,*r,*km,*k,*k"))] 2229 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2230{ 2231 switch (get_attr_type (insn)) 2232 { 2233 case TYPE_MSKMOV: 2234 return "kmovq\t{%1, %0|%0, %1}"; 2235 2236 case TYPE_MULTI: 2237 return "#"; 2238 2239 case TYPE_MMX: 2240 return "pxor\t%0, %0"; 2241 2242 case TYPE_MMXMOV: 2243 /* Handle broken assemblers that require movd instead of movq. */ 2244 if (!HAVE_AS_IX86_INTERUNIT_MOVQ 2245 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))) 2246 return "movd\t{%1, %0|%0, %1}"; 2247 return "movq\t{%1, %0|%0, %1}"; 2248 2249 case TYPE_SSELOG1: 2250 return standard_sse_constant_opcode (insn, operands); 2251 2252 case TYPE_SSEMOV: 2253 switch (get_attr_mode (insn)) 2254 { 2255 case MODE_DI: 2256 /* Handle broken assemblers that require movd instead of movq. */ 2257 if (!HAVE_AS_IX86_INTERUNIT_MOVQ 2258 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))) 2259 return "%vmovd\t{%1, %0|%0, %1}"; 2260 return "%vmovq\t{%1, %0|%0, %1}"; 2261 2262 case MODE_TI: 2263 /* Handle AVX512 registers set. */ 2264 if (EXT_REX_SSE_REG_P (operands[0]) 2265 || EXT_REX_SSE_REG_P (operands[1])) 2266 return "vmovdqa64\t{%1, %0|%0, %1}"; 2267 return "%vmovdqa\t{%1, %0|%0, %1}"; 2268 2269 case MODE_V2SF: 2270 gcc_assert (!TARGET_AVX); 2271 return "movlps\t{%1, %0|%0, %1}"; 2272 case MODE_V4SF: 2273 return "%vmovaps\t{%1, %0|%0, %1}"; 2274 2275 default: 2276 gcc_unreachable (); 2277 } 2278 2279 case TYPE_SSECVT: 2280 if (SSE_REG_P (operands[0])) 2281 return "movq2dq\t{%1, %0|%0, %1}"; 2282 else 2283 return "movdq2q\t{%1, %0|%0, %1}"; 2284 2285 case TYPE_LEA: 2286 return "lea{q}\t{%E1, %0|%0, %E1}"; 2287 2288 case TYPE_IMOV: 2289 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2290 if (get_attr_mode (insn) == MODE_SI) 2291 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2292 else if (which_alternative == 4) 2293 return "movabs{q}\t{%1, %0|%0, %1}"; 2294 else if (ix86_use_lea_for_mov (insn, operands)) 2295 return "lea{q}\t{%E1, %0|%0, %E1}"; 2296 else 2297 return "mov{q}\t{%1, %0|%0, %1}"; 2298 2299 default: 2300 gcc_unreachable (); 2301 } 2302} 2303 [(set (attr "isa") 2304 (cond [(eq_attr "alternative" "0,1,17,18") 2305 (const_string "nox64") 2306 (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25") 2307 (const_string "x64") 2308 ] 2309 (const_string "*"))) 2310 (set (attr "type") 2311 (cond [(eq_attr "alternative" "0,1,17,18") 2312 (const_string "multi") 2313 (eq_attr "alternative" "6") 2314 (const_string "mmx") 2315 (eq_attr "alternative" "7,8,9,10,11") 2316 (const_string "mmxmov") 2317 (eq_attr "alternative" "12") 2318 (const_string "sselog1") 2319 (eq_attr "alternative" "13,14,15,16,19,20") 2320 (const_string "ssemov") 2321 (eq_attr "alternative" "21,22") 2322 (const_string "ssecvt") 2323 (eq_attr "alternative" "23,24,25,26") 2324 (const_string "mskmov") 2325 (and (match_operand 0 "register_operand") 2326 (match_operand 1 "pic_32bit_operand")) 2327 (const_string "lea") 2328 ] 2329 (const_string "imov"))) 2330 (set (attr "modrm") 2331 (if_then_else 2332 (and (eq_attr "alternative" "4") (eq_attr "type" "imov")) 2333 (const_string "0") 2334 (const_string "*"))) 2335 (set (attr "length_immediate") 2336 (if_then_else 2337 (and (eq_attr "alternative" "4") (eq_attr "type" "imov")) 2338 (const_string "8") 2339 (const_string "*"))) 2340 (set (attr "prefix_rex") 2341 (if_then_else 2342 (eq_attr "alternative" "10,11,19,20") 2343 (const_string "1") 2344 (const_string "*"))) 2345 (set (attr "prefix") 2346 (if_then_else (eq_attr "type" "sselog1,ssemov") 2347 (const_string "maybe_vex") 2348 (const_string "orig"))) 2349 (set (attr "prefix_data16") 2350 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI")) 2351 (const_string "1") 2352 (const_string "*"))) 2353 (set (attr "mode") 2354 (cond [(eq_attr "alternative" "2") 2355 (const_string "SI") 2356 (eq_attr "alternative" "12,13") 2357 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 2358 (match_operand 1 "ext_sse_reg_operand")) 2359 (const_string "TI") 2360 (ior (not (match_test "TARGET_SSE2")) 2361 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) 2362 (const_string "V4SF") 2363 (match_test "TARGET_AVX") 2364 (const_string "TI") 2365 (match_test "optimize_function_for_size_p (cfun)") 2366 (const_string "V4SF") 2367 ] 2368 (const_string "TI")) 2369 2370 (and (eq_attr "alternative" "14,15,16") 2371 (not (match_test "TARGET_SSE2"))) 2372 (const_string "V2SF") 2373 ] 2374 (const_string "DI"))) 2375 (set (attr "enabled") 2376 (cond [(eq_attr "alternative" "15") 2377 (if_then_else 2378 (match_test "TARGET_STV && TARGET_SSE2") 2379 (symbol_ref "false") 2380 (const_string "*")) 2381 (eq_attr "alternative" "16") 2382 (if_then_else 2383 (match_test "TARGET_STV && TARGET_SSE2") 2384 (symbol_ref "true") 2385 (symbol_ref "false")) 2386 ] 2387 (const_string "*")))]) 2388 2389(define_split 2390 [(set (match_operand:<DWI> 0 "general_reg_operand") 2391 (match_operand:<DWI> 1 "sse_reg_operand"))] 2392 "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC 2393 && reload_completed" 2394 [(set (match_dup 2) 2395 (vec_select:DWIH 2396 (match_dup 3) 2397 (parallel [(const_int 1)])))] 2398{ 2399 operands[2] = gen_highpart (<MODE>mode, operands[0]); 2400 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode); 2401 2402 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), 2403 gen_lowpart (<MODE>mode, operands[1])); 2404}) 2405 2406(define_split 2407 [(set (match_operand:DWI 0 "nonimmediate_gr_operand") 2408 (match_operand:DWI 1 "general_gr_operand"))] 2409 "reload_completed" 2410 [(const_int 0)] 2411 "ix86_split_long_move (operands); DONE;") 2412 2413(define_split 2414 [(set (match_operand:DI 0 "sse_reg_operand") 2415 (match_operand:DI 1 "general_reg_operand"))] 2416 "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC 2417 && reload_completed" 2418 [(set (match_dup 2) 2419 (vec_merge:V4SI 2420 (vec_duplicate:V4SI (match_dup 3)) 2421 (match_dup 2) 2422 (const_int 2)))] 2423{ 2424 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode); 2425 operands[3] = gen_highpart (SImode, operands[1]); 2426 2427 emit_move_insn (gen_lowpart (SImode, operands[0]), 2428 gen_lowpart (SImode, operands[1])); 2429}) 2430 2431;; movabsq $0x0012345678000000, %rax is longer 2432;; than movl $0x12345678, %eax; shlq $24, %rax. 2433(define_peephole2 2434 [(set (match_operand:DI 0 "register_operand") 2435 (match_operand:DI 1 "const_int_operand"))] 2436 "TARGET_64BIT 2437 && optimize_insn_for_size_p () 2438 && LEGACY_INT_REG_P (operands[0]) 2439 && !x86_64_immediate_operand (operands[1], DImode) 2440 && !x86_64_zext_immediate_operand (operands[1], DImode) 2441 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1]))) 2442 & ~(HOST_WIDE_INT) 0xffffffff) 2443 && peep2_regno_dead_p (0, FLAGS_REG)" 2444 [(set (match_dup 0) (match_dup 1)) 2445 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) 2446 (clobber (reg:CC FLAGS_REG))])] 2447{ 2448 int shift = ctz_hwi (UINTVAL (operands[1])); 2449 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode); 2450 operands[2] = gen_int_mode (shift, QImode); 2451}) 2452 2453(define_insn "*movsi_internal" 2454 [(set (match_operand:SI 0 "nonimmediate_operand" 2455 "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm") 2456 (match_operand:SI 1 "general_operand" 2457 "g ,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,r ,*r,*km,*k"))] 2458 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2459{ 2460 switch (get_attr_type (insn)) 2461 { 2462 case TYPE_SSELOG1: 2463 return standard_sse_constant_opcode (insn, operands); 2464 2465 case TYPE_MSKMOV: 2466 return "kmovd\t{%1, %0|%0, %1}"; 2467 2468 case TYPE_SSEMOV: 2469 switch (get_attr_mode (insn)) 2470 { 2471 case MODE_SI: 2472 return "%vmovd\t{%1, %0|%0, %1}"; 2473 case MODE_TI: 2474 return "%vmovdqa\t{%1, %0|%0, %1}"; 2475 case MODE_XI: 2476 return "vmovdqa32\t{%g1, %g0|%g0, %g1}"; 2477 2478 case MODE_V4SF: 2479 return "%vmovaps\t{%1, %0|%0, %1}"; 2480 2481 case MODE_SF: 2482 gcc_assert (!TARGET_AVX); 2483 return "movss\t{%1, %0|%0, %1}"; 2484 2485 default: 2486 gcc_unreachable (); 2487 } 2488 2489 case TYPE_MMX: 2490 return "pxor\t%0, %0"; 2491 2492 case TYPE_MMXMOV: 2493 switch (get_attr_mode (insn)) 2494 { 2495 case MODE_DI: 2496 return "movq\t{%1, %0|%0, %1}"; 2497 case MODE_SI: 2498 return "movd\t{%1, %0|%0, %1}"; 2499 2500 default: 2501 gcc_unreachable (); 2502 } 2503 2504 case TYPE_LEA: 2505 return "lea{l}\t{%E1, %0|%0, %E1}"; 2506 2507 case TYPE_IMOV: 2508 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2509 if (ix86_use_lea_for_mov (insn, operands)) 2510 return "lea{l}\t{%E1, %0|%0, %E1}"; 2511 else 2512 return "mov{l}\t{%1, %0|%0, %1}"; 2513 2514 default: 2515 gcc_unreachable (); 2516 } 2517} 2518 [(set (attr "type") 2519 (cond [(eq_attr "alternative" "2") 2520 (const_string "mmx") 2521 (eq_attr "alternative" "3,4,5,6,7") 2522 (const_string "mmxmov") 2523 (eq_attr "alternative" "8") 2524 (const_string "sselog1") 2525 (eq_attr "alternative" "9,10,11,12,13") 2526 (const_string "ssemov") 2527 (eq_attr "alternative" "14,15,16") 2528 (const_string "mskmov") 2529 (and (match_operand 0 "register_operand") 2530 (match_operand 1 "pic_32bit_operand")) 2531 (const_string "lea") 2532 ] 2533 (const_string "imov"))) 2534 (set (attr "prefix") 2535 (if_then_else (eq_attr "type" "sselog1,ssemov") 2536 (const_string "maybe_vex") 2537 (const_string "orig"))) 2538 (set (attr "prefix_data16") 2539 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 2540 (const_string "1") 2541 (const_string "*"))) 2542 (set (attr "mode") 2543 (cond [(eq_attr "alternative" "2,3") 2544 (const_string "DI") 2545 (eq_attr "alternative" "8,9") 2546 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 2547 (match_operand 1 "ext_sse_reg_operand")) 2548 (const_string "XI") 2549 (ior (not (match_test "TARGET_SSE2")) 2550 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) 2551 (const_string "V4SF") 2552 (match_test "TARGET_AVX") 2553 (const_string "TI") 2554 (match_test "optimize_function_for_size_p (cfun)") 2555 (const_string "V4SF") 2556 ] 2557 (const_string "TI")) 2558 2559 (and (eq_attr "alternative" "10,11") 2560 (not (match_test "TARGET_SSE2"))) 2561 (const_string "SF") 2562 ] 2563 (const_string "SI")))]) 2564 2565(define_insn "*movhi_internal" 2566 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m") 2567 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))] 2568 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2569{ 2570 switch (get_attr_type (insn)) 2571 { 2572 case TYPE_IMOVX: 2573 /* movzwl is faster than movw on p2 due to partial word stalls, 2574 though not as fast as an aligned movl. */ 2575 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 2576 2577 case TYPE_MSKMOV: 2578 switch (which_alternative) 2579 { 2580 case 4: 2581 return "kmovw\t{%k1, %0|%0, %k1}"; 2582 case 6: 2583 return "kmovw\t{%1, %k0|%k0, %1}"; 2584 case 5: 2585 case 7: 2586 return "kmovw\t{%1, %0|%0, %1}"; 2587 default: 2588 gcc_unreachable (); 2589 } 2590 2591 default: 2592 if (get_attr_mode (insn) == MODE_SI) 2593 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2594 else 2595 return "mov{w}\t{%1, %0|%0, %1}"; 2596 } 2597} 2598 [(set (attr "type") 2599 (cond [(eq_attr "alternative" "4,5,6,7") 2600 (const_string "mskmov") 2601 (match_test "optimize_function_for_size_p (cfun)") 2602 (const_string "imov") 2603 (and (eq_attr "alternative" "0") 2604 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2605 (not (match_test "TARGET_HIMODE_MATH")))) 2606 (const_string "imov") 2607 (and (eq_attr "alternative" "1,2") 2608 (match_operand:HI 1 "aligned_operand")) 2609 (const_string "imov") 2610 (and (match_test "TARGET_MOVX") 2611 (eq_attr "alternative" "0,2")) 2612 (const_string "imovx") 2613 ] 2614 (const_string "imov"))) 2615 (set (attr "prefix") 2616 (if_then_else (eq_attr "alternative" "4,5,6,7") 2617 (const_string "vex") 2618 (const_string "orig"))) 2619 (set (attr "mode") 2620 (cond [(eq_attr "type" "imovx") 2621 (const_string "SI") 2622 (and (eq_attr "alternative" "1,2") 2623 (match_operand:HI 1 "aligned_operand")) 2624 (const_string "SI") 2625 (and (eq_attr "alternative" "0") 2626 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2627 (not (match_test "TARGET_HIMODE_MATH")))) 2628 (const_string "SI") 2629 ] 2630 (const_string "HI")))]) 2631 2632;; Situation is quite tricky about when to choose full sized (SImode) move 2633;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 2634;; partial register dependency machines (such as AMD Athlon), where QImode 2635;; moves issue extra dependency and for partial register stalls machines 2636;; that don't use QImode patterns (and QImode move cause stall on the next 2637;; instruction). 2638;; 2639;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 2640;; register stall machines with, where we use QImode instructions, since 2641;; partial register stall can be caused there. Then we use movzx. 2642 2643(define_insn "*movqi_internal" 2644 [(set (match_operand:QI 0 "nonimmediate_operand" 2645 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k") 2646 (match_operand:QI 1 "general_operand" 2647 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))] 2648 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2649{ 2650 static char buf[128]; 2651 const char *ops; 2652 const char *suffix; 2653 2654 switch (get_attr_type (insn)) 2655 { 2656 case TYPE_IMOVX: 2657 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])); 2658 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 2659 2660 case TYPE_MSKMOV: 2661 switch (which_alternative) 2662 { 2663 case 9: 2664 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}"; 2665 break; 2666 case 11: 2667 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}"; 2668 break; 2669 case 12: 2670 case 13: 2671 gcc_assert (TARGET_AVX512DQ); 2672 /* FALLTHRU */ 2673 case 10: 2674 ops = "kmov%s\t{%%1, %%0|%%0, %%1}"; 2675 break; 2676 default: 2677 gcc_unreachable (); 2678 } 2679 2680 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b"; 2681 2682 snprintf (buf, sizeof (buf), ops, suffix); 2683 return buf; 2684 2685 default: 2686 if (get_attr_mode (insn) == MODE_SI) 2687 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2688 else 2689 return "mov{b}\t{%1, %0|%0, %1}"; 2690 } 2691} 2692 [(set (attr "isa") 2693 (cond [(eq_attr "alternative" "1,2") 2694 (const_string "x64") 2695 (eq_attr "alternative" "12,13") 2696 (const_string "avx512dq") 2697 ] 2698 (const_string "*"))) 2699 (set (attr "type") 2700 (cond [(eq_attr "alternative" "9,10,11,12,13") 2701 (const_string "mskmov") 2702 (and (eq_attr "alternative" "7") 2703 (not (match_operand:QI 1 "aligned_operand"))) 2704 (const_string "imovx") 2705 (match_test "optimize_function_for_size_p (cfun)") 2706 (const_string "imov") 2707 (and (eq_attr "alternative" "5") 2708 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2709 (not (match_test "TARGET_QIMODE_MATH")))) 2710 (const_string "imov") 2711 (eq_attr "alternative" "5,7") 2712 (const_string "imovx") 2713 (and (match_test "TARGET_MOVX") 2714 (eq_attr "alternative" "4")) 2715 (const_string "imovx") 2716 ] 2717 (const_string "imov"))) 2718 (set (attr "prefix") 2719 (if_then_else (eq_attr "alternative" "9,10,11") 2720 (const_string "vex") 2721 (const_string "orig"))) 2722 (set (attr "mode") 2723 (cond [(eq_attr "alternative" "5,6,7") 2724 (const_string "SI") 2725 (eq_attr "alternative" "8") 2726 (const_string "QI") 2727 (and (eq_attr "alternative" "9,10,11") 2728 (not (match_test "TARGET_AVX512DQ"))) 2729 (const_string "HI") 2730 (eq_attr "type" "imovx") 2731 (const_string "SI") 2732 ;; For -Os, 8-bit immediates are always shorter than 32-bit 2733 ;; ones. 2734 (and (eq_attr "type" "imov") 2735 (and (eq_attr "alternative" "3") 2736 (match_test "optimize_function_for_size_p (cfun)"))) 2737 (const_string "QI") 2738 ;; For -Os, movl where one or both operands are NON_Q_REGS 2739 ;; and both are LEGACY_REGS is shorter than movb. 2740 ;; Otherwise movb and movl sizes are the same, so decide purely 2741 ;; based on speed factors. 2742 (and (eq_attr "type" "imov") 2743 (and (eq_attr "alternative" "1") 2744 (match_test "optimize_function_for_size_p (cfun)"))) 2745 (const_string "SI") 2746 (and (eq_attr "type" "imov") 2747 (and (eq_attr "alternative" "0,1,2,3") 2748 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY") 2749 (not (match_test "TARGET_PARTIAL_REG_STALL"))))) 2750 (const_string "SI") 2751 ;; Avoid partial register stalls when not using QImode arithmetic 2752 (and (eq_attr "type" "imov") 2753 (and (eq_attr "alternative" "0,1,2,3") 2754 (and (match_test "TARGET_PARTIAL_REG_STALL") 2755 (not (match_test "TARGET_QIMODE_MATH"))))) 2756 (const_string "SI") 2757 ] 2758 (const_string "QI")))]) 2759 2760;; Stores and loads of ax to arbitrary constant address. 2761;; We fake an second form of instruction to force reload to load address 2762;; into register when rax is not available 2763(define_insn "*movabs<mode>_1" 2764 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2765 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))] 2766 "TARGET_LP64 && ix86_check_movabs (insn, 0)" 2767{ 2768 /* Recover the full memory rtx. */ 2769 operands[0] = SET_DEST (PATTERN (insn)); 2770 switch (which_alternative) 2771 { 2772 case 0: 2773 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}"; 2774 case 1: 2775 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 2776 default: 2777 gcc_unreachable (); 2778 } 2779} 2780 [(set_attr "type" "imov") 2781 (set_attr "modrm" "0,*") 2782 (set_attr "length_address" "8,0") 2783 (set_attr "length_immediate" "0,*") 2784 (set_attr "memory" "store") 2785 (set_attr "mode" "<MODE>")]) 2786 2787(define_insn "*movabs<mode>_2" 2788 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r") 2789 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2790 "TARGET_LP64 && ix86_check_movabs (insn, 1)" 2791{ 2792 /* Recover the full memory rtx. */ 2793 operands[1] = SET_SRC (PATTERN (insn)); 2794 switch (which_alternative) 2795 { 2796 case 0: 2797 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}"; 2798 case 1: 2799 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 2800 default: 2801 gcc_unreachable (); 2802 } 2803} 2804 [(set_attr "type" "imov") 2805 (set_attr "modrm" "0,*") 2806 (set_attr "length_address" "8,0") 2807 (set_attr "length_immediate" "0") 2808 (set_attr "memory" "load") 2809 (set_attr "mode" "<MODE>")]) 2810 2811(define_insn "*swap<mode>" 2812 [(set (match_operand:SWI48 0 "register_operand" "+r") 2813 (match_operand:SWI48 1 "register_operand" "+r")) 2814 (set (match_dup 1) 2815 (match_dup 0))] 2816 "" 2817 "xchg{<imodesuffix>}\t%1, %0" 2818 [(set_attr "type" "imov") 2819 (set_attr "mode" "<MODE>") 2820 (set_attr "pent_pair" "np") 2821 (set_attr "athlon_decode" "vector") 2822 (set_attr "amdfam10_decode" "double") 2823 (set_attr "bdver1_decode" "double")]) 2824 2825(define_insn "*swap<mode>" 2826 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r") 2827 (match_operand:SWI12 1 "register_operand" "+<r>,r")) 2828 (set (match_dup 1) 2829 (match_dup 0))] 2830 "" 2831 "@ 2832 xchg{<imodesuffix>}\t%1, %0 2833 xchg{l}\t%k1, %k0" 2834 [(set_attr "type" "imov") 2835 (set_attr "mode" "<MODE>,SI") 2836 (set (attr "preferred_for_size") 2837 (cond [(eq_attr "alternative" "0") 2838 (symbol_ref "false")] 2839 (symbol_ref "true"))) 2840 ;; Potential partial reg stall on alternative 1. 2841 (set (attr "preferred_for_speed") 2842 (cond [(eq_attr "alternative" "1") 2843 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 2844 (symbol_ref "true"))) 2845 (set_attr "pent_pair" "np") 2846 (set_attr "athlon_decode" "vector") 2847 (set_attr "amdfam10_decode" "double") 2848 (set_attr "bdver1_decode" "double")]) 2849 2850(define_expand "movstrict<mode>" 2851 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand")) 2852 (match_operand:SWI12 1 "general_operand"))] 2853 "" 2854{ 2855 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) 2856 FAIL; 2857 if (SUBREG_P (operands[0]) 2858 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT) 2859 FAIL; 2860 /* Don't generate memory->memory moves, go through a register */ 2861 if (MEM_P (operands[0]) && MEM_P (operands[1])) 2862 operands[1] = force_reg (<MODE>mode, operands[1]); 2863}) 2864 2865(define_insn "*movstrict<mode>_1" 2866 [(set (strict_low_part 2867 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>")) 2868 (match_operand:SWI12 1 "general_operand" "<r>n,m"))] 2869 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2871 "mov{<imodesuffix>}\t{%1, %0|%0, %1}" 2872 [(set_attr "type" "imov") 2873 (set_attr "mode" "<MODE>")]) 2874 2875(define_insn "*movstrict<mode>_xor" 2876 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 2877 (match_operand:SWI12 1 "const0_operand")) 2878 (clobber (reg:CC FLAGS_REG))] 2879 "reload_completed" 2880 "xor{<imodesuffix>}\t%0, %0" 2881 [(set_attr "type" "alu1") 2882 (set_attr "modrm_class" "op0") 2883 (set_attr "mode" "<MODE>") 2884 (set_attr "length_immediate" "0")]) 2885 2886(define_expand "extv<mode>" 2887 [(set (match_operand:SWI24 0 "register_operand") 2888 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand") 2889 (match_operand:SI 2 "const_int_operand") 2890 (match_operand:SI 3 "const_int_operand")))] 2891 "" 2892{ 2893 /* Handle extractions from %ah et al. */ 2894 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 2895 FAIL; 2896 2897 unsigned int regno = reg_or_subregno (operands[1]); 2898 2899 /* Be careful to expand only with registers having upper parts. */ 2900 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno)) 2901 operands[1] = copy_to_reg (operands[1]); 2902}) 2903 2904(define_insn "*extv<mode>" 2905 [(set (match_operand:SWI24 0 "register_operand" "=R") 2906 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q") 2907 (const_int 8) 2908 (const_int 8)))] 2909 "" 2910 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 2911 [(set_attr "type" "imovx") 2912 (set_attr "mode" "SI")]) 2913 2914(define_expand "extzv<mode>" 2915 [(set (match_operand:SWI248 0 "register_operand") 2916 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand") 2917 (match_operand:SI 2 "const_int_operand") 2918 (match_operand:SI 3 "const_int_operand")))] 2919 "" 2920{ 2921 if (ix86_expand_pextr (operands)) 2922 DONE; 2923 2924 /* Handle extractions from %ah et al. */ 2925 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 2926 FAIL; 2927 2928 unsigned int regno = reg_or_subregno (operands[1]); 2929 2930 /* Be careful to expand only with registers having upper parts. */ 2931 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno)) 2932 operands[1] = copy_to_reg (operands[1]); 2933}) 2934 2935(define_insn "*extzvqi_mem_rex64" 2936 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn") 2937 (subreg:QI 2938 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 2939 (const_int 8) 2940 (const_int 8)) 0))] 2941 "TARGET_64BIT && reload_completed" 2942 "mov{b}\t{%h1, %0|%0, %h1}" 2943 [(set_attr "type" "imov") 2944 (set_attr "mode" "QI")]) 2945 2946(define_insn "*extzv<mode>" 2947 [(set (match_operand:SWI248 0 "register_operand" "=R") 2948 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q") 2949 (const_int 8) 2950 (const_int 8)))] 2951 "" 2952 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 2953 [(set_attr "type" "imovx") 2954 (set_attr "mode" "SI")]) 2955 2956(define_insn "*extzvqi" 2957 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m") 2958 (subreg:QI 2959 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q") 2960 (const_int 8) 2961 (const_int 8)) 0))] 2962 "" 2963{ 2964 switch (get_attr_type (insn)) 2965 { 2966 case TYPE_IMOVX: 2967 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2968 default: 2969 return "mov{b}\t{%h1, %0|%0, %h1}"; 2970 } 2971} 2972 [(set_attr "isa" "*,*,nox64") 2973 (set (attr "type") 2974 (if_then_else (and (match_operand:QI 0 "register_operand") 2975 (ior (not (match_operand:QI 0 "QIreg_operand")) 2976 (match_test "TARGET_MOVX"))) 2977 (const_string "imovx") 2978 (const_string "imov"))) 2979 (set (attr "mode") 2980 (if_then_else (eq_attr "type" "imovx") 2981 (const_string "SI") 2982 (const_string "QI")))]) 2983 2984(define_peephole2 2985 [(set (match_operand:QI 0 "register_operand") 2986 (subreg:QI 2987 (zero_extract:SI (match_operand 1 "ext_register_operand") 2988 (const_int 8) 2989 (const_int 8)) 0)) 2990 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))] 2991 "TARGET_64BIT 2992 && peep2_reg_dead_p (2, operands[0])" 2993 [(set (match_dup 2) 2994 (subreg:QI 2995 (zero_extract:SI (match_dup 1) 2996 (const_int 8) 2997 (const_int 8)) 0))]) 2998 2999(define_expand "insv<mode>" 3000 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand") 3001 (match_operand:SI 1 "const_int_operand") 3002 (match_operand:SI 2 "const_int_operand")) 3003 (match_operand:SWI248 3 "register_operand"))] 3004 "" 3005{ 3006 rtx dst; 3007 3008 if (ix86_expand_pinsr (operands)) 3009 DONE; 3010 3011 /* Handle insertions to %ah et al. */ 3012 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 3013 FAIL; 3014 3015 unsigned int regno = reg_or_subregno (operands[0]); 3016 3017 /* Be careful to expand only with registers having upper parts. */ 3018 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno)) 3019 dst = copy_to_reg (operands[0]); 3020 else 3021 dst = operands[0]; 3022 3023 emit_insn (gen_insv<mode>_1 (dst, operands[3])); 3024 3025 /* Fix up the destination if needed. */ 3026 if (dst != operands[0]) 3027 emit_move_insn (operands[0], dst); 3028 3029 DONE; 3030}) 3031 3032(define_insn "*insvqi_1_mem_rex64" 3033 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 3034 (const_int 8) 3035 (const_int 8)) 3036 (subreg:SI 3037 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))] 3038 "TARGET_64BIT && reload_completed" 3039 "mov{b}\t{%1, %h0|%h0, %1}" 3040 [(set_attr "type" "imov") 3041 (set_attr "mode" "QI")]) 3042 3043(define_insn "insv<mode>_1" 3044 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q") 3045 (const_int 8) 3046 (const_int 8)) 3047 (match_operand:SWI248 1 "general_operand" "QnBc,m"))] 3048 "" 3049{ 3050 if (CONST_INT_P (operands[1])) 3051 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode); 3052 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 3053} 3054 [(set_attr "isa" "*,nox64") 3055 (set_attr "type" "imov") 3056 (set_attr "mode" "QI")]) 3057 3058(define_insn "*insvqi_1" 3059 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 3060 (const_int 8) 3061 (const_int 8)) 3062 (subreg:SI 3063 (match_operand:QI 1 "general_operand" "QnBc,m") 0))] 3064 "" 3065 "mov{b}\t{%1, %h0|%h0, %1}" 3066 [(set_attr "isa" "*,nox64") 3067 (set_attr "type" "imov") 3068 (set_attr "mode" "QI")]) 3069 3070(define_peephole2 3071 [(set (match_operand:QI 0 "register_operand") 3072 (match_operand:QI 1 "norex_memory_operand")) 3073 (set (zero_extract:SI (match_operand 2 "ext_register_operand") 3074 (const_int 8) 3075 (const_int 8)) 3076 (subreg:SI (match_dup 0) 0))] 3077 "TARGET_64BIT 3078 && peep2_reg_dead_p (2, operands[0])" 3079 [(set (zero_extract:SI (match_dup 2) 3080 (const_int 8) 3081 (const_int 8)) 3082 (subreg:SI (match_dup 1) 0))]) 3083 3084(define_code_iterator any_extract [sign_extract zero_extract]) 3085 3086(define_insn "*insvqi_2" 3087 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 3088 (const_int 8) 3089 (const_int 8)) 3090 (any_extract:SI (match_operand 1 "ext_register_operand" "Q") 3091 (const_int 8) 3092 (const_int 8)))] 3093 "" 3094 "mov{b}\t{%h1, %h0|%h0, %h1}" 3095 [(set_attr "type" "imov") 3096 (set_attr "mode" "QI")]) 3097 3098(define_insn "*insvqi_3" 3099 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 3100 (const_int 8) 3101 (const_int 8)) 3102 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q") 3103 (const_int 8)))] 3104 "" 3105 "mov{b}\t{%h1, %h0|%h0, %h1}" 3106 [(set_attr "type" "imov") 3107 (set_attr "mode" "QI")]) 3108 3109;; Floating point push instructions. 3110 3111(define_insn "*pushtf" 3112 [(set (match_operand:TF 0 "push_operand" "=<,<") 3113 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))] 3114 "TARGET_64BIT || TARGET_SSE" 3115{ 3116 /* This insn should be already split before reg-stack. */ 3117 gcc_unreachable (); 3118} 3119 [(set_attr "isa" "*,x64") 3120 (set_attr "type" "multi") 3121 (set_attr "unit" "sse,*") 3122 (set_attr "mode" "TF,DI")]) 3123 3124;; %%% Kill this when call knows how to work this out. 3125(define_split 3126 [(set (match_operand:TF 0 "push_operand") 3127 (match_operand:TF 1 "sse_reg_operand"))] 3128 "TARGET_SSE && reload_completed" 3129 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) 3130 (set (match_dup 0) (match_dup 1))] 3131{ 3132 /* Preserve memory attributes. */ 3133 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 3134}) 3135 3136(define_insn_and_split "*pushxf_rounded" 3137 [(set (mem:XF 3138 (pre_modify:P 3139 (reg:P SP_REG) 3140 (plus:P (reg:P SP_REG) (const_int -16)))) 3141 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))] 3142 "TARGET_64BIT" 3143 "#" 3144 "&& 1" 3145 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) 3146 (set (match_dup 1) (match_dup 0))] 3147{ 3148 rtx pat = PATTERN (curr_insn); 3149 operands[1] = SET_DEST (pat); 3150 3151 /* Preserve memory attributes. */ 3152 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx); 3153} 3154 [(set_attr "type" "multi") 3155 (set_attr "unit" "i387,*,*,*") 3156 (set (attr "mode") 3157 (cond [(eq_attr "alternative" "1,2,3") 3158 (const_string "DI") 3159 ] 3160 (const_string "XF"))) 3161 (set (attr "preferred_for_size") 3162 (cond [(eq_attr "alternative" "1") 3163 (symbol_ref "false")] 3164 (symbol_ref "true")))]) 3165 3166(define_insn "*pushxf" 3167 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<") 3168 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))] 3169 "" 3170{ 3171 /* This insn should be already split before reg-stack. */ 3172 gcc_unreachable (); 3173} 3174 [(set_attr "isa" "*,*,*,nox64,x64") 3175 (set_attr "type" "multi") 3176 (set_attr "unit" "i387,*,*,*,*") 3177 (set (attr "mode") 3178 (cond [(eq_attr "alternative" "1,2,3,4") 3179 (if_then_else (match_test "TARGET_64BIT") 3180 (const_string "DI") 3181 (const_string "SI")) 3182 ] 3183 (const_string "XF"))) 3184 (set (attr "preferred_for_size") 3185 (cond [(eq_attr "alternative" "1") 3186 (symbol_ref "false")] 3187 (symbol_ref "true")))]) 3188 3189;; %%% Kill this when call knows how to work this out. 3190(define_split 3191 [(set (match_operand:XF 0 "push_operand") 3192 (match_operand:XF 1 "fp_register_operand"))] 3193 "reload_completed" 3194 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 3195 (set (match_dup 0) (match_dup 1))] 3196{ 3197 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode))); 3198 /* Preserve memory attributes. */ 3199 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 3200}) 3201 3202(define_insn "*pushdf" 3203 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<") 3204 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))] 3205 "" 3206{ 3207 /* This insn should be already split before reg-stack. */ 3208 gcc_unreachable (); 3209} 3210 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2") 3211 (set_attr "type" "multi") 3212 (set_attr "unit" "i387,*,*,*,*,sse") 3213 (set_attr "mode" "DF,SI,SI,SI,DI,DF") 3214 (set (attr "preferred_for_size") 3215 (cond [(eq_attr "alternative" "1") 3216 (symbol_ref "false")] 3217 (symbol_ref "true"))) 3218 (set (attr "preferred_for_speed") 3219 (cond [(eq_attr "alternative" "1") 3220 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")] 3221 (symbol_ref "true")))]) 3222 3223;; %%% Kill this when call knows how to work this out. 3224(define_split 3225 [(set (match_operand:DF 0 "push_operand") 3226 (match_operand:DF 1 "any_fp_register_operand"))] 3227 "reload_completed" 3228 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 3229 (set (match_dup 0) (match_dup 1))] 3230{ 3231 /* Preserve memory attributes. */ 3232 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 3233}) 3234 3235(define_insn "*pushsf_rex64" 3236 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 3237 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 3238 "TARGET_64BIT" 3239{ 3240 /* Anything else should be already split before reg-stack. */ 3241 gcc_assert (which_alternative == 1); 3242 return "push{q}\t%q1"; 3243} 3244 [(set_attr "type" "multi,push,multi") 3245 (set_attr "unit" "i387,*,*") 3246 (set_attr "mode" "SF,DI,SF")]) 3247 3248(define_insn "*pushsf" 3249 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 3250 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))] 3251 "!TARGET_64BIT" 3252{ 3253 /* Anything else should be already split before reg-stack. */ 3254 gcc_assert (which_alternative == 1); 3255 return "push{l}\t%1"; 3256} 3257 [(set_attr "type" "multi,push,multi") 3258 (set_attr "unit" "i387,*,*") 3259 (set_attr "mode" "SF,SI,SF")]) 3260 3261;; %%% Kill this when call knows how to work this out. 3262(define_split 3263 [(set (match_operand:SF 0 "push_operand") 3264 (match_operand:SF 1 "any_fp_register_operand"))] 3265 "reload_completed" 3266 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 3267 (set (match_dup 0) (match_dup 1))] 3268{ 3269 rtx op = XEXP (operands[0], 0); 3270 if (GET_CODE (op) == PRE_DEC) 3271 { 3272 gcc_assert (!TARGET_64BIT); 3273 op = GEN_INT (-4); 3274 } 3275 else 3276 { 3277 op = XEXP (XEXP (op, 1), 1); 3278 gcc_assert (CONST_INT_P (op)); 3279 } 3280 operands[2] = op; 3281 /* Preserve memory attributes. */ 3282 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 3283}) 3284 3285(define_split 3286 [(set (match_operand:SF 0 "push_operand") 3287 (match_operand:SF 1 "memory_operand"))] 3288 "reload_completed 3289 && find_constant_src (insn)" 3290 [(set (match_dup 0) (match_dup 2))] 3291 "operands[2] = find_constant_src (curr_insn);") 3292 3293(define_split 3294 [(set (match_operand 0 "push_operand") 3295 (match_operand 1 "general_gr_operand"))] 3296 "reload_completed 3297 && (GET_MODE (operands[0]) == TFmode 3298 || GET_MODE (operands[0]) == XFmode 3299 || GET_MODE (operands[0]) == DFmode)" 3300 [(const_int 0)] 3301 "ix86_split_long_move (operands); DONE;") 3302 3303;; Floating point move instructions. 3304 3305(define_expand "movtf" 3306 [(set (match_operand:TF 0 "nonimmediate_operand") 3307 (match_operand:TF 1 "nonimmediate_operand"))] 3308 "TARGET_64BIT || TARGET_SSE" 3309 "ix86_expand_move (TFmode, operands); DONE;") 3310 3311(define_expand "mov<mode>" 3312 [(set (match_operand:X87MODEF 0 "nonimmediate_operand") 3313 (match_operand:X87MODEF 1 "general_operand"))] 3314 "" 3315 "ix86_expand_move (<MODE>mode, operands); DONE;") 3316 3317(define_insn "*movtf_internal" 3318 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o") 3319 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))] 3320 "(TARGET_64BIT || TARGET_SSE) 3321 && !(MEM_P (operands[0]) && MEM_P (operands[1])) 3322 && (lra_in_progress || reload_completed 3323 || !CONST_DOUBLE_P (operands[1]) 3324 || ((optimize_function_for_size_p (cfun) 3325 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)) 3326 && standard_sse_constant_p (operands[1], TFmode) == 1 3327 && !memory_operand (operands[0], TFmode)) 3328 || (!TARGET_MEMORY_MISMATCH_STALL 3329 && memory_operand (operands[0], TFmode)))" 3330{ 3331 switch (get_attr_type (insn)) 3332 { 3333 case TYPE_SSELOG1: 3334 return standard_sse_constant_opcode (insn, operands); 3335 3336 case TYPE_SSEMOV: 3337 /* Handle misaligned load/store since we 3338 don't have movmisaligntf pattern. */ 3339 if (misaligned_operand (operands[0], TFmode) 3340 || misaligned_operand (operands[1], TFmode)) 3341 { 3342 if (get_attr_mode (insn) == MODE_V4SF) 3343 return "%vmovups\t{%1, %0|%0, %1}"; 3344 else if (TARGET_AVX512VL 3345 && (EXT_REX_SSE_REG_P (operands[0]) 3346 || EXT_REX_SSE_REG_P (operands[1]))) 3347 return "vmovdqu64\t{%1, %0|%0, %1}"; 3348 else 3349 return "%vmovdqu\t{%1, %0|%0, %1}"; 3350 } 3351 else 3352 { 3353 if (get_attr_mode (insn) == MODE_V4SF) 3354 return "%vmovaps\t{%1, %0|%0, %1}"; 3355 else if (TARGET_AVX512VL 3356 && (EXT_REX_SSE_REG_P (operands[0]) 3357 || EXT_REX_SSE_REG_P (operands[1]))) 3358 return "vmovdqa64\t{%1, %0|%0, %1}"; 3359 else 3360 return "%vmovdqa\t{%1, %0|%0, %1}"; 3361 } 3362 3363 case TYPE_MULTI: 3364 return "#"; 3365 3366 default: 3367 gcc_unreachable (); 3368 } 3369} 3370 [(set_attr "isa" "*,*,*,x64,x64") 3371 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi") 3372 (set (attr "prefix") 3373 (if_then_else (eq_attr "type" "sselog1,ssemov") 3374 (const_string "maybe_vex") 3375 (const_string "orig"))) 3376 (set (attr "mode") 3377 (cond [(eq_attr "alternative" "3,4") 3378 (const_string "DI") 3379 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") 3380 (const_string "V4SF") 3381 (and (eq_attr "alternative" "2") 3382 (match_test "TARGET_SSE_TYPELESS_STORES")) 3383 (const_string "V4SF") 3384 (match_test "TARGET_AVX") 3385 (const_string "TI") 3386 (ior (not (match_test "TARGET_SSE2")) 3387 (match_test "optimize_function_for_size_p (cfun)")) 3388 (const_string "V4SF") 3389 ] 3390 (const_string "TI")))]) 3391 3392(define_split 3393 [(set (match_operand:TF 0 "nonimmediate_gr_operand") 3394 (match_operand:TF 1 "general_gr_operand"))] 3395 "reload_completed" 3396 [(const_int 0)] 3397 "ix86_split_long_move (operands); DONE;") 3398 3399;; Possible store forwarding (partial memory) stall 3400;; in alternatives 4, 6, 7 and 8. 3401(define_insn "*movxf_internal" 3402 [(set (match_operand:XF 0 "nonimmediate_operand" 3403 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o") 3404 (match_operand:XF 1 "general_operand" 3405 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))] 3406 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3407 && (lra_in_progress || reload_completed 3408 || !CONST_DOUBLE_P (operands[1]) 3409 || ((optimize_function_for_size_p (cfun) 3410 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)) 3411 && standard_80387_constant_p (operands[1]) > 0 3412 && !memory_operand (operands[0], XFmode)) 3413 || (!TARGET_MEMORY_MISMATCH_STALL 3414 && memory_operand (operands[0], XFmode)) 3415 || !TARGET_HARD_XF_REGS)" 3416{ 3417 switch (get_attr_type (insn)) 3418 { 3419 case TYPE_FMOV: 3420 if (which_alternative == 2) 3421 return standard_80387_constant_opcode (operands[1]); 3422 return output_387_reg_move (insn, operands); 3423 3424 case TYPE_MULTI: 3425 return "#"; 3426 3427 default: 3428 gcc_unreachable (); 3429 } 3430} 3431 [(set (attr "isa") 3432 (cond [(eq_attr "alternative" "7,10") 3433 (const_string "nox64") 3434 (eq_attr "alternative" "8,11") 3435 (const_string "x64") 3436 ] 3437 (const_string "*"))) 3438 (set (attr "type") 3439 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11") 3440 (const_string "multi") 3441 ] 3442 (const_string "fmov"))) 3443 (set (attr "mode") 3444 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11") 3445 (if_then_else (match_test "TARGET_64BIT") 3446 (const_string "DI") 3447 (const_string "SI")) 3448 ] 3449 (const_string "XF"))) 3450 (set (attr "preferred_for_size") 3451 (cond [(eq_attr "alternative" "3,4") 3452 (symbol_ref "false")] 3453 (symbol_ref "true"))) 3454 (set (attr "enabled") 3455 (cond [(eq_attr "alternative" "9,10,11") 3456 (if_then_else 3457 (match_test "TARGET_HARD_XF_REGS") 3458 (symbol_ref "false") 3459 (const_string "*")) 3460 (not (match_test "TARGET_HARD_XF_REGS")) 3461 (symbol_ref "false") 3462 ] 3463 (const_string "*")))]) 3464 3465(define_split 3466 [(set (match_operand:XF 0 "nonimmediate_gr_operand") 3467 (match_operand:XF 1 "general_gr_operand"))] 3468 "reload_completed" 3469 [(const_int 0)] 3470 "ix86_split_long_move (operands); DONE;") 3471 3472;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7. 3473(define_insn "*movdf_internal" 3474 [(set (match_operand:DF 0 "nonimmediate_operand" 3475 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r ,o ,r ,m") 3476 (match_operand:DF 1 "general_operand" 3477 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))] 3478 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3479 && (lra_in_progress || reload_completed 3480 || !CONST_DOUBLE_P (operands[1]) 3481 || ((optimize_function_for_size_p (cfun) 3482 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)) 3483 && ((IS_STACK_MODE (DFmode) 3484 && standard_80387_constant_p (operands[1]) > 0) 3485 || (TARGET_SSE2 && TARGET_SSE_MATH 3486 && standard_sse_constant_p (operands[1], DFmode) == 1)) 3487 && !memory_operand (operands[0], DFmode)) 3488 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL) 3489 && memory_operand (operands[0], DFmode)) 3490 || !TARGET_HARD_DF_REGS)" 3491{ 3492 switch (get_attr_type (insn)) 3493 { 3494 case TYPE_FMOV: 3495 if (which_alternative == 2) 3496 return standard_80387_constant_opcode (operands[1]); 3497 return output_387_reg_move (insn, operands); 3498 3499 case TYPE_MULTI: 3500 return "#"; 3501 3502 case TYPE_IMOV: 3503 if (get_attr_mode (insn) == MODE_SI) 3504 return "mov{l}\t{%1, %k0|%k0, %1}"; 3505 else if (which_alternative == 11) 3506 return "movabs{q}\t{%1, %0|%0, %1}"; 3507 else 3508 return "mov{q}\t{%1, %0|%0, %1}"; 3509 3510 case TYPE_SSELOG1: 3511 return standard_sse_constant_opcode (insn, operands); 3512 3513 case TYPE_SSEMOV: 3514 switch (get_attr_mode (insn)) 3515 { 3516 case MODE_DF: 3517 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3518 return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; 3519 return "%vmovsd\t{%1, %0|%0, %1}"; 3520 3521 case MODE_V4SF: 3522 return "%vmovaps\t{%1, %0|%0, %1}"; 3523 case MODE_V8DF: 3524 return "vmovapd\t{%g1, %g0|%g0, %g1}"; 3525 case MODE_V2DF: 3526 return "%vmovapd\t{%1, %0|%0, %1}"; 3527 3528 case MODE_V2SF: 3529 gcc_assert (!TARGET_AVX); 3530 return "movlps\t{%1, %0|%0, %1}"; 3531 case MODE_V1DF: 3532 gcc_assert (!TARGET_AVX); 3533 return "movlpd\t{%1, %0|%0, %1}"; 3534 3535 case MODE_DI: 3536 /* Handle broken assemblers that require movd instead of movq. */ 3537 if (!HAVE_AS_IX86_INTERUNIT_MOVQ 3538 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))) 3539 return "%vmovd\t{%1, %0|%0, %1}"; 3540 return "%vmovq\t{%1, %0|%0, %1}"; 3541 3542 default: 3543 gcc_unreachable (); 3544 } 3545 3546 default: 3547 gcc_unreachable (); 3548 } 3549} 3550 [(set (attr "isa") 3551 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23") 3552 (const_string "nox64") 3553 (eq_attr "alternative" "8,9,10,11,20,21,24,25") 3554 (const_string "x64") 3555 (eq_attr "alternative" "12,13,14,15") 3556 (const_string "sse2") 3557 ] 3558 (const_string "*"))) 3559 (set (attr "type") 3560 (cond [(eq_attr "alternative" "0,1,2") 3561 (const_string "fmov") 3562 (eq_attr "alternative" "3,4,5,6,7,22,23") 3563 (const_string "multi") 3564 (eq_attr "alternative" "8,9,10,11,24,25") 3565 (const_string "imov") 3566 (eq_attr "alternative" "12,16") 3567 (const_string "sselog1") 3568 ] 3569 (const_string "ssemov"))) 3570 (set (attr "modrm") 3571 (if_then_else (eq_attr "alternative" "11") 3572 (const_string "0") 3573 (const_string "*"))) 3574 (set (attr "length_immediate") 3575 (if_then_else (eq_attr "alternative" "11") 3576 (const_string "8") 3577 (const_string "*"))) 3578 (set (attr "prefix") 3579 (if_then_else (eq_attr "type" "sselog1,ssemov") 3580 (const_string "maybe_vex") 3581 (const_string "orig"))) 3582 (set (attr "prefix_data16") 3583 (if_then_else 3584 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI")) 3585 (eq_attr "mode" "V1DF")) 3586 (const_string "1") 3587 (const_string "*"))) 3588 (set (attr "mode") 3589 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23") 3590 (const_string "SI") 3591 (eq_attr "alternative" "8,9,11,20,21,24,25") 3592 (const_string "DI") 3593 3594 /* xorps is one byte shorter for non-AVX targets. */ 3595 (eq_attr "alternative" "12,16") 3596 (cond [(not (match_test "TARGET_SSE2")) 3597 (const_string "V4SF") 3598 (and (match_test "TARGET_AVX512F") 3599 (not (match_test "TARGET_PREFER_AVX256"))) 3600 (const_string "XI") 3601 (match_test "TARGET_AVX") 3602 (const_string "V2DF") 3603 (match_test "optimize_function_for_size_p (cfun)") 3604 (const_string "V4SF") 3605 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3606 (const_string "TI") 3607 ] 3608 (const_string "V2DF")) 3609 3610 /* For architectures resolving dependencies on 3611 whole SSE registers use movapd to break dependency 3612 chains, otherwise use short move to avoid extra work. */ 3613 3614 /* movaps is one byte shorter for non-AVX targets. */ 3615 (eq_attr "alternative" "13,17") 3616 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256")) 3617 (not (match_test "TARGET_AVX512VL"))) 3618 (ior (match_operand 0 "ext_sse_reg_operand") 3619 (match_operand 1 "ext_sse_reg_operand"))) 3620 (const_string "V8DF") 3621 (ior (not (match_test "TARGET_SSE2")) 3622 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) 3623 (const_string "V4SF") 3624 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3625 (const_string "V2DF") 3626 (match_test "TARGET_AVX") 3627 (const_string "DF") 3628 (match_test "optimize_function_for_size_p (cfun)") 3629 (const_string "V4SF") 3630 ] 3631 (const_string "DF")) 3632 3633 /* For architectures resolving dependencies on register 3634 parts we may avoid extra work to zero out upper part 3635 of register. */ 3636 (eq_attr "alternative" "14,18") 3637 (cond [(not (match_test "TARGET_SSE2")) 3638 (const_string "V2SF") 3639 (match_test "TARGET_AVX") 3640 (const_string "DF") 3641 (match_test "TARGET_SSE_SPLIT_REGS") 3642 (const_string "V1DF") 3643 ] 3644 (const_string "DF")) 3645 3646 (and (eq_attr "alternative" "15,19") 3647 (not (match_test "TARGET_SSE2"))) 3648 (const_string "V2SF") 3649 ] 3650 (const_string "DF"))) 3651 (set (attr "preferred_for_size") 3652 (cond [(eq_attr "alternative" "3,4") 3653 (symbol_ref "false")] 3654 (symbol_ref "true"))) 3655 (set (attr "preferred_for_speed") 3656 (cond [(eq_attr "alternative" "3,4") 3657 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")] 3658 (symbol_ref "true"))) 3659 (set (attr "enabled") 3660 (cond [(eq_attr "alternative" "22,23,24,25") 3661 (if_then_else 3662 (match_test "TARGET_HARD_DF_REGS") 3663 (symbol_ref "false") 3664 (const_string "*")) 3665 (not (match_test "TARGET_HARD_DF_REGS")) 3666 (symbol_ref "false") 3667 ] 3668 (const_string "*")))]) 3669 3670(define_split 3671 [(set (match_operand:DF 0 "nonimmediate_gr_operand") 3672 (match_operand:DF 1 "general_gr_operand"))] 3673 "!TARGET_64BIT && reload_completed" 3674 [(const_int 0)] 3675 "ix86_split_long_move (operands); DONE;") 3676 3677(define_insn "*movsf_internal" 3678 [(set (match_operand:SF 0 "nonimmediate_operand" 3679 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m") 3680 (match_operand:SF 1 "general_operand" 3681 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))] 3682 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3683 && (lra_in_progress || reload_completed 3684 || !CONST_DOUBLE_P (operands[1]) 3685 || ((optimize_function_for_size_p (cfun) 3686 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)) 3687 && ((IS_STACK_MODE (SFmode) 3688 && standard_80387_constant_p (operands[1]) > 0) 3689 || (TARGET_SSE && TARGET_SSE_MATH 3690 && standard_sse_constant_p (operands[1], SFmode) == 1))) 3691 || memory_operand (operands[0], SFmode) 3692 || !TARGET_HARD_SF_REGS)" 3693{ 3694 switch (get_attr_type (insn)) 3695 { 3696 case TYPE_FMOV: 3697 if (which_alternative == 2) 3698 return standard_80387_constant_opcode (operands[1]); 3699 return output_387_reg_move (insn, operands); 3700 3701 case TYPE_IMOV: 3702 return "mov{l}\t{%1, %0|%0, %1}"; 3703 3704 case TYPE_SSELOG1: 3705 return standard_sse_constant_opcode (insn, operands); 3706 3707 case TYPE_SSEMOV: 3708 switch (get_attr_mode (insn)) 3709 { 3710 case MODE_SF: 3711 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3712 return "vmovss\t{%1, %0, %0|%0, %0, %1}"; 3713 return "%vmovss\t{%1, %0|%0, %1}"; 3714 3715 case MODE_V16SF: 3716 return "vmovaps\t{%g1, %g0|%g0, %g1}"; 3717 case MODE_V4SF: 3718 return "%vmovaps\t{%1, %0|%0, %1}"; 3719 3720 case MODE_SI: 3721 return "%vmovd\t{%1, %0|%0, %1}"; 3722 3723 default: 3724 gcc_unreachable (); 3725 } 3726 3727 case TYPE_MMXMOV: 3728 switch (get_attr_mode (insn)) 3729 { 3730 case MODE_DI: 3731 return "movq\t{%1, %0|%0, %1}"; 3732 case MODE_SI: 3733 return "movd\t{%1, %0|%0, %1}"; 3734 3735 default: 3736 gcc_unreachable (); 3737 } 3738 3739 default: 3740 gcc_unreachable (); 3741 } 3742} 3743 [(set (attr "type") 3744 (cond [(eq_attr "alternative" "0,1,2") 3745 (const_string "fmov") 3746 (eq_attr "alternative" "3,4,16,17") 3747 (const_string "imov") 3748 (eq_attr "alternative" "5") 3749 (const_string "sselog1") 3750 (eq_attr "alternative" "11,12,13,14,15") 3751 (const_string "mmxmov") 3752 ] 3753 (const_string "ssemov"))) 3754 (set (attr "prefix") 3755 (if_then_else (eq_attr "type" "sselog1,ssemov") 3756 (const_string "maybe_vex") 3757 (const_string "orig"))) 3758 (set (attr "prefix_data16") 3759 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 3760 (const_string "1") 3761 (const_string "*"))) 3762 (set (attr "mode") 3763 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17") 3764 (const_string "SI") 3765 (eq_attr "alternative" "11") 3766 (const_string "DI") 3767 (eq_attr "alternative" "5") 3768 (cond [(not (match_test "TARGET_SSE2")) 3769 (const_string "V4SF") 3770 (and (match_test "TARGET_AVX512F") 3771 (not (match_test "TARGET_PREFER_AVX256"))) 3772 (const_string "V16SF") 3773 (match_test "TARGET_AVX") 3774 (const_string "V4SF") 3775 (match_test "optimize_function_for_size_p (cfun)") 3776 (const_string "V4SF") 3777 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3778 (const_string "TI") 3779 ] 3780 (const_string "V4SF")) 3781 3782 /* For architectures resolving dependencies on 3783 whole SSE registers use APS move to break dependency 3784 chains, otherwise use short move to avoid extra work. 3785 3786 Do the same for architectures resolving dependencies on 3787 the parts. While in DF mode it is better to always handle 3788 just register parts, the SF mode is different due to lack 3789 of instructions to load just part of the register. It is 3790 better to maintain the whole registers in single format 3791 to avoid problems on using packed logical operations. */ 3792 (eq_attr "alternative" "6") 3793 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256")) 3794 (not (match_test "TARGET_AVX512VL"))) 3795 (ior (match_operand 0 "ext_sse_reg_operand") 3796 (match_operand 1 "ext_sse_reg_operand"))) 3797 (const_string "V16SF") 3798 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3799 (match_test "TARGET_SSE_SPLIT_REGS")) 3800 (const_string "V4SF") 3801 ] 3802 (const_string "SF")) 3803 ] 3804 (const_string "SF"))) 3805 (set (attr "enabled") 3806 (cond [(eq_attr "alternative" "16,17") 3807 (if_then_else 3808 (match_test "TARGET_HARD_SF_REGS") 3809 (symbol_ref "false") 3810 (const_string "*")) 3811 (not (match_test "TARGET_HARD_SF_REGS")) 3812 (symbol_ref "false") 3813 ] 3814 (const_string "*")))]) 3815 3816(define_split 3817 [(set (match_operand 0 "any_fp_register_operand") 3818 (match_operand 1 "nonimmediate_operand"))] 3819 "reload_completed 3820 && (GET_MODE (operands[0]) == TFmode 3821 || GET_MODE (operands[0]) == XFmode 3822 || GET_MODE (operands[0]) == DFmode 3823 || GET_MODE (operands[0]) == SFmode) 3824 && ix86_standard_x87sse_constant_load_p (insn, operands[0])" 3825 [(set (match_dup 0) (match_dup 2))] 3826 "operands[2] = find_constant_src (curr_insn);") 3827 3828(define_split 3829 [(set (match_operand 0 "any_fp_register_operand") 3830 (float_extend (match_operand 1 "nonimmediate_operand")))] 3831 "reload_completed 3832 && (GET_MODE (operands[0]) == TFmode 3833 || GET_MODE (operands[0]) == XFmode 3834 || GET_MODE (operands[0]) == DFmode) 3835 && ix86_standard_x87sse_constant_load_p (insn, operands[0])" 3836 [(set (match_dup 0) (match_dup 2))] 3837 "operands[2] = find_constant_src (curr_insn);") 3838 3839;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence 3840(define_split 3841 [(set (match_operand:X87MODEF 0 "fp_register_operand") 3842 (match_operand:X87MODEF 1 "immediate_operand"))] 3843 "reload_completed 3844 && (standard_80387_constant_p (operands[1]) == 8 3845 || standard_80387_constant_p (operands[1]) == 9)" 3846 [(set (match_dup 0)(match_dup 1)) 3847 (set (match_dup 0) 3848 (neg:X87MODEF (match_dup 0)))] 3849{ 3850 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1]))) 3851 operands[1] = CONST0_RTX (<MODE>mode); 3852 else 3853 operands[1] = CONST1_RTX (<MODE>mode); 3854}) 3855 3856(define_insn "swapxf" 3857 [(set (match_operand:XF 0 "register_operand" "+f") 3858 (match_operand:XF 1 "register_operand" "+f")) 3859 (set (match_dup 1) 3860 (match_dup 0))] 3861 "TARGET_80387" 3862{ 3863 if (STACK_TOP_P (operands[0])) 3864 return "fxch\t%1"; 3865 else 3866 return "fxch\t%0"; 3867} 3868 [(set_attr "type" "fxch") 3869 (set_attr "mode" "XF")]) 3870 3871(define_insn "*swap<mode>" 3872 [(set (match_operand:MODEF 0 "fp_register_operand" "+f") 3873 (match_operand:MODEF 1 "fp_register_operand" "+f")) 3874 (set (match_dup 1) 3875 (match_dup 0))] 3876 "TARGET_80387 || reload_completed" 3877{ 3878 if (STACK_TOP_P (operands[0])) 3879 return "fxch\t%1"; 3880 else 3881 return "fxch\t%0"; 3882} 3883 [(set_attr "type" "fxch") 3884 (set_attr "mode" "<MODE>")]) 3885 3886;; Zero extension instructions 3887 3888(define_expand "zero_extendsidi2" 3889 [(set (match_operand:DI 0 "nonimmediate_operand") 3890 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]) 3891 3892(define_insn "*zero_extendsidi2" 3893 [(set (match_operand:DI 0 "nonimmediate_operand" 3894 "=r,?r,?o,r ,o,?*Ym,?!*y,$r,$Yi,$x,*x,*v,*r") 3895 (zero_extend:DI 3896 (match_operand:SI 1 "x86_64_zext_operand" 3897 "0 ,rm,r ,rmWz,0,r ,m ,Yj,r ,m ,*x,*v,*k")))] 3898 "" 3899{ 3900 switch (get_attr_type (insn)) 3901 { 3902 case TYPE_IMOVX: 3903 if (ix86_use_lea_for_mov (insn, operands)) 3904 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 3905 else 3906 return "mov{l}\t{%1, %k0|%k0, %1}"; 3907 3908 case TYPE_MULTI: 3909 return "#"; 3910 3911 case TYPE_MMXMOV: 3912 return "movd\t{%1, %0|%0, %1}"; 3913 3914 case TYPE_SSEMOV: 3915 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])) 3916 { 3917 if (EXT_REX_SSE_REG_P (operands[0]) 3918 || EXT_REX_SSE_REG_P (operands[1])) 3919 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}"; 3920 else 3921 return "%vpmovzxdq\t{%1, %0|%0, %1}"; 3922 } 3923 3924 if (GENERAL_REG_P (operands[0])) 3925 return "%vmovd\t{%1, %k0|%k0, %1}"; 3926 3927 return "%vmovd\t{%1, %0|%0, %1}"; 3928 3929 case TYPE_MSKMOV: 3930 return "kmovd\t{%1, %k0|%k0, %1}"; 3931 3932 default: 3933 gcc_unreachable (); 3934 } 3935} 3936 [(set (attr "isa") 3937 (cond [(eq_attr "alternative" "0,1,2") 3938 (const_string "nox64") 3939 (eq_attr "alternative" "3") 3940 (const_string "x64") 3941 (eq_attr "alternative" "9") 3942 (const_string "sse2") 3943 (eq_attr "alternative" "10") 3944 (const_string "sse4") 3945 (eq_attr "alternative" "11") 3946 (const_string "avx512f") 3947 (eq_attr "alternative" "12") 3948 (const_string "x64_avx512bw") 3949 ] 3950 (const_string "*"))) 3951 (set (attr "type") 3952 (cond [(eq_attr "alternative" "0,1,2,4") 3953 (const_string "multi") 3954 (eq_attr "alternative" "5,6") 3955 (const_string "mmxmov") 3956 (eq_attr "alternative" "7") 3957 (if_then_else (match_test "TARGET_64BIT") 3958 (const_string "ssemov") 3959 (const_string "multi")) 3960 (eq_attr "alternative" "8,9,10,11") 3961 (const_string "ssemov") 3962 (eq_attr "alternative" "12") 3963 (const_string "mskmov") 3964 ] 3965 (const_string "imovx"))) 3966 (set (attr "prefix_extra") 3967 (if_then_else (eq_attr "alternative" "10,11") 3968 (const_string "1") 3969 (const_string "*"))) 3970 (set (attr "prefix") 3971 (if_then_else (eq_attr "type" "ssemov") 3972 (const_string "maybe_vex") 3973 (const_string "orig"))) 3974 (set (attr "prefix_0f") 3975 (if_then_else (eq_attr "type" "imovx") 3976 (const_string "0") 3977 (const_string "*"))) 3978 (set (attr "mode") 3979 (cond [(eq_attr "alternative" "5,6") 3980 (const_string "DI") 3981 (and (eq_attr "alternative" "7") 3982 (match_test "TARGET_64BIT")) 3983 (const_string "TI") 3984 (eq_attr "alternative" "8,10,11") 3985 (const_string "TI") 3986 ] 3987 (const_string "SI")))]) 3988 3989(define_split 3990 [(set (match_operand:DI 0 "memory_operand") 3991 (zero_extend:DI (match_operand:SI 1 "memory_operand")))] 3992 "reload_completed" 3993 [(set (match_dup 4) (const_int 0))] 3994 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3995 3996(define_split 3997 [(set (match_operand:DI 0 "general_reg_operand") 3998 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))] 3999 "!TARGET_64BIT && reload_completed 4000 && REGNO (operands[0]) == REGNO (operands[1])" 4001 [(set (match_dup 4) (const_int 0))] 4002 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 4003 4004(define_split 4005 [(set (match_operand:DI 0 "nonimmediate_gr_operand") 4006 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))] 4007 "!TARGET_64BIT && reload_completed 4008 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 4009 [(set (match_dup 3) (match_dup 1)) 4010 (set (match_dup 4) (const_int 0))] 4011 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 4012 4013(define_mode_attr kmov_isa 4014 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")]) 4015 4016(define_insn "zero_extend<mode>di2" 4017 [(set (match_operand:DI 0 "register_operand" "=r,*r") 4018 (zero_extend:DI 4019 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))] 4020 "TARGET_64BIT" 4021 "@ 4022 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1} 4023 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}" 4024 [(set_attr "isa" "*,<kmov_isa>") 4025 (set_attr "type" "imovx,mskmov") 4026 (set_attr "mode" "SI,<MODE>")]) 4027 4028(define_expand "zero_extend<mode>si2" 4029 [(set (match_operand:SI 0 "register_operand") 4030 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))] 4031 "" 4032{ 4033 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 4034 { 4035 operands[1] = force_reg (<MODE>mode, operands[1]); 4036 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1])); 4037 DONE; 4038 } 4039}) 4040 4041(define_insn_and_split "zero_extend<mode>si2_and" 4042 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>") 4043 (zero_extend:SI 4044 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m"))) 4045 (clobber (reg:CC FLAGS_REG))] 4046 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 4047 "#" 4048 "&& reload_completed" 4049 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2))) 4050 (clobber (reg:CC FLAGS_REG))])] 4051{ 4052 if (!REG_P (operands[1]) 4053 || REGNO (operands[0]) != REGNO (operands[1])) 4054 { 4055 ix86_expand_clear (operands[0]); 4056 4057 gcc_assert (!TARGET_PARTIAL_REG_STALL); 4058 emit_insn (gen_movstrict<mode> 4059 (gen_lowpart (<MODE>mode, operands[0]), operands[1])); 4060 DONE; 4061 } 4062 4063 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode)); 4064} 4065 [(set_attr "type" "alu1") 4066 (set_attr "mode" "SI")]) 4067 4068(define_insn "*zero_extend<mode>si2" 4069 [(set (match_operand:SI 0 "register_operand" "=r,*r") 4070 (zero_extend:SI 4071 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))] 4072 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" 4073 "@ 4074 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1} 4075 kmov<mskmodesuffix>\t{%1, %0|%0, %1}" 4076 [(set_attr "isa" "*,<kmov_isa>") 4077 (set_attr "type" "imovx,mskmov") 4078 (set_attr "mode" "SI,<MODE>")]) 4079 4080(define_expand "zero_extendqihi2" 4081 [(set (match_operand:HI 0 "register_operand") 4082 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))] 4083 "" 4084{ 4085 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 4086 { 4087 operands[1] = force_reg (QImode, operands[1]); 4088 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1])); 4089 DONE; 4090 } 4091}) 4092 4093(define_insn_and_split "zero_extendqihi2_and" 4094 [(set (match_operand:HI 0 "register_operand" "=r,?&q") 4095 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 4096 (clobber (reg:CC FLAGS_REG))] 4097 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 4098 "#" 4099 "&& reload_completed" 4100 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) 4101 (clobber (reg:CC FLAGS_REG))])] 4102{ 4103 if (!REG_P (operands[1]) 4104 || REGNO (operands[0]) != REGNO (operands[1])) 4105 { 4106 ix86_expand_clear (operands[0]); 4107 4108 gcc_assert (!TARGET_PARTIAL_REG_STALL); 4109 emit_insn (gen_movstrictqi 4110 (gen_lowpart (QImode, operands[0]), operands[1])); 4111 DONE; 4112 } 4113 4114 operands[0] = gen_lowpart (SImode, operands[0]); 4115} 4116 [(set_attr "type" "alu1") 4117 (set_attr "mode" "SI")]) 4118 4119; zero extend to SImode to avoid partial register stalls 4120(define_insn "*zero_extendqihi2" 4121 [(set (match_operand:HI 0 "register_operand" "=r,*r") 4122 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))] 4123 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" 4124 "@ 4125 movz{bl|x}\t{%1, %k0|%k0, %1} 4126 kmovb\t{%1, %k0|%k0, %1}" 4127 [(set_attr "isa" "*,avx512dq") 4128 (set_attr "type" "imovx,mskmov") 4129 (set_attr "mode" "SI,QI")]) 4130 4131(define_insn_and_split "*zext<mode>_doubleword_and" 4132 [(set (match_operand:DI 0 "register_operand" "=&<r>") 4133 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 4134 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 4135 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 4136 "#" 4137 "&& reload_completed && GENERAL_REG_P (operands[0])" 4138 [(set (match_dup 2) (const_int 0))] 4139{ 4140 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]); 4141 4142 emit_move_insn (operands[0], const0_rtx); 4143 4144 gcc_assert (!TARGET_PARTIAL_REG_STALL); 4145 emit_insn (gen_movstrict<mode> 4146 (gen_lowpart (<MODE>mode, operands[0]), operands[1])); 4147}) 4148 4149(define_insn_and_split "*zext<mode>_doubleword" 4150 [(set (match_operand:DI 0 "register_operand" "=r") 4151 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 4152 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 4153 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" 4154 "#" 4155 "&& reload_completed && GENERAL_REG_P (operands[0])" 4156 [(set (match_dup 0) (zero_extend:SI (match_dup 1))) 4157 (set (match_dup 2) (const_int 0))] 4158 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);") 4159 4160(define_insn_and_split "*zextsi_doubleword" 4161 [(set (match_operand:DI 0 "register_operand" "=r") 4162 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))] 4163 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" 4164 "#" 4165 "&& reload_completed && GENERAL_REG_P (operands[0])" 4166 [(set (match_dup 0) (match_dup 1)) 4167 (set (match_dup 2) (const_int 0))] 4168 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);") 4169 4170;; Sign extension instructions 4171 4172(define_expand "extendsidi2" 4173 [(set (match_operand:DI 0 "register_operand") 4174 (sign_extend:DI (match_operand:SI 1 "register_operand")))] 4175 "" 4176{ 4177 if (!TARGET_64BIT) 4178 { 4179 emit_insn (gen_extendsidi2_1 (operands[0], operands[1])); 4180 DONE; 4181 } 4182}) 4183 4184(define_insn "*extendsidi2_rex64" 4185 [(set (match_operand:DI 0 "register_operand" "=*a,r") 4186 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 4187 "TARGET_64BIT" 4188 "@ 4189 {cltq|cdqe} 4190 movs{lq|x}\t{%1, %0|%0, %1}" 4191 [(set_attr "type" "imovx") 4192 (set_attr "mode" "DI") 4193 (set_attr "prefix_0f" "0") 4194 (set_attr "modrm" "0,1")]) 4195 4196(define_insn "extendsidi2_1" 4197 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 4198 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 4199 (clobber (reg:CC FLAGS_REG)) 4200 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 4201 "!TARGET_64BIT" 4202 "#") 4203 4204;; Split the memory case. If the source register doesn't die, it will stay 4205;; this way, if it does die, following peephole2s take care of it. 4206(define_split 4207 [(set (match_operand:DI 0 "memory_operand") 4208 (sign_extend:DI (match_operand:SI 1 "register_operand"))) 4209 (clobber (reg:CC FLAGS_REG)) 4210 (clobber (match_operand:SI 2 "register_operand"))] 4211 "reload_completed" 4212 [(const_int 0)] 4213{ 4214 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 4215 4216 emit_move_insn (operands[3], operands[1]); 4217 4218 /* Generate a cltd if possible and doing so it profitable. */ 4219 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 4220 && REGNO (operands[1]) == AX_REG 4221 && REGNO (operands[2]) == DX_REG) 4222 { 4223 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31))); 4224 } 4225 else 4226 { 4227 emit_move_insn (operands[2], operands[1]); 4228 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31))); 4229 } 4230 emit_move_insn (operands[4], operands[2]); 4231 DONE; 4232}) 4233 4234;; Peepholes for the case where the source register does die, after 4235;; being split with the above splitter. 4236(define_peephole2 4237 [(set (match_operand:SI 0 "memory_operand") 4238 (match_operand:SI 1 "general_reg_operand")) 4239 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1)) 4240 (parallel [(set (match_dup 2) 4241 (ashiftrt:SI (match_dup 2) (const_int 31))) 4242 (clobber (reg:CC FLAGS_REG))]) 4243 (set (match_operand:SI 3 "memory_operand") (match_dup 2))] 4244 "REGNO (operands[1]) != REGNO (operands[2]) 4245 && peep2_reg_dead_p (2, operands[1]) 4246 && peep2_reg_dead_p (4, operands[2]) 4247 && !reg_mentioned_p (operands[2], operands[3])" 4248 [(set (match_dup 0) (match_dup 1)) 4249 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 4250 (clobber (reg:CC FLAGS_REG))]) 4251 (set (match_dup 3) (match_dup 1))]) 4252 4253(define_peephole2 4254 [(set (match_operand:SI 0 "memory_operand") 4255 (match_operand:SI 1 "general_reg_operand")) 4256 (parallel [(set (match_operand:SI 2 "general_reg_operand") 4257 (ashiftrt:SI (match_dup 1) (const_int 31))) 4258 (clobber (reg:CC FLAGS_REG))]) 4259 (set (match_operand:SI 3 "memory_operand") (match_dup 2))] 4260 "/* cltd is shorter than sarl $31, %eax */ 4261 !optimize_function_for_size_p (cfun) 4262 && REGNO (operands[1]) == AX_REG 4263 && REGNO (operands[2]) == DX_REG 4264 && peep2_reg_dead_p (2, operands[1]) 4265 && peep2_reg_dead_p (3, operands[2]) 4266 && !reg_mentioned_p (operands[2], operands[3])" 4267 [(set (match_dup 0) (match_dup 1)) 4268 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 4269 (clobber (reg:CC FLAGS_REG))]) 4270 (set (match_dup 3) (match_dup 1))]) 4271 4272;; Extend to register case. Optimize case where source and destination 4273;; registers match and cases where we can use cltd. 4274(define_split 4275 [(set (match_operand:DI 0 "register_operand") 4276 (sign_extend:DI (match_operand:SI 1 "register_operand"))) 4277 (clobber (reg:CC FLAGS_REG)) 4278 (clobber (match_scratch:SI 2))] 4279 "reload_completed" 4280 [(const_int 0)] 4281{ 4282 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 4283 4284 if (REGNO (operands[3]) != REGNO (operands[1])) 4285 emit_move_insn (operands[3], operands[1]); 4286 4287 /* Generate a cltd if possible and doing so it profitable. */ 4288 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 4289 && REGNO (operands[3]) == AX_REG 4290 && REGNO (operands[4]) == DX_REG) 4291 { 4292 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31))); 4293 DONE; 4294 } 4295 4296 if (REGNO (operands[4]) != REGNO (operands[1])) 4297 emit_move_insn (operands[4], operands[1]); 4298 4299 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31))); 4300 DONE; 4301}) 4302 4303(define_insn "extend<mode>di2" 4304 [(set (match_operand:DI 0 "register_operand" "=r") 4305 (sign_extend:DI 4306 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 4307 "TARGET_64BIT" 4308 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}" 4309 [(set_attr "type" "imovx") 4310 (set_attr "mode" "DI")]) 4311 4312(define_insn "extendhisi2" 4313 [(set (match_operand:SI 0 "register_operand" "=*a,r") 4314 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 4315 "" 4316{ 4317 switch (get_attr_prefix_0f (insn)) 4318 { 4319 case 0: 4320 return "{cwtl|cwde}"; 4321 default: 4322 return "movs{wl|x}\t{%1, %0|%0, %1}"; 4323 } 4324} 4325 [(set_attr "type" "imovx") 4326 (set_attr "mode" "SI") 4327 (set (attr "prefix_0f") 4328 ;; movsx is short decodable while cwtl is vector decoded. 4329 (if_then_else (and (eq_attr "cpu" "!k6") 4330 (eq_attr "alternative" "0")) 4331 (const_string "0") 4332 (const_string "1"))) 4333 (set (attr "znver1_decode") 4334 (if_then_else (eq_attr "prefix_0f" "0") 4335 (const_string "double") 4336 (const_string "direct"))) 4337 (set (attr "modrm") 4338 (if_then_else (eq_attr "prefix_0f" "0") 4339 (const_string "0") 4340 (const_string "1")))]) 4341 4342(define_insn "*extendhisi2_zext" 4343 [(set (match_operand:DI 0 "register_operand" "=*a,r") 4344 (zero_extend:DI 4345 (sign_extend:SI 4346 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 4347 "TARGET_64BIT" 4348{ 4349 switch (get_attr_prefix_0f (insn)) 4350 { 4351 case 0: 4352 return "{cwtl|cwde}"; 4353 default: 4354 return "movs{wl|x}\t{%1, %k0|%k0, %1}"; 4355 } 4356} 4357 [(set_attr "type" "imovx") 4358 (set_attr "mode" "SI") 4359 (set (attr "prefix_0f") 4360 ;; movsx is short decodable while cwtl is vector decoded. 4361 (if_then_else (and (eq_attr "cpu" "!k6") 4362 (eq_attr "alternative" "0")) 4363 (const_string "0") 4364 (const_string "1"))) 4365 (set (attr "modrm") 4366 (if_then_else (eq_attr "prefix_0f" "0") 4367 (const_string "0") 4368 (const_string "1")))]) 4369 4370(define_insn "extendqisi2" 4371 [(set (match_operand:SI 0 "register_operand" "=r") 4372 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 4373 "" 4374 "movs{bl|x}\t{%1, %0|%0, %1}" 4375 [(set_attr "type" "imovx") 4376 (set_attr "mode" "SI")]) 4377 4378(define_insn "*extendqisi2_zext" 4379 [(set (match_operand:DI 0 "register_operand" "=r") 4380 (zero_extend:DI 4381 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 4382 "TARGET_64BIT" 4383 "movs{bl|x}\t{%1, %k0|%k0, %1}" 4384 [(set_attr "type" "imovx") 4385 (set_attr "mode" "SI")]) 4386 4387(define_insn "extendqihi2" 4388 [(set (match_operand:HI 0 "register_operand" "=*a,r") 4389 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 4390 "" 4391{ 4392 switch (get_attr_prefix_0f (insn)) 4393 { 4394 case 0: 4395 return "{cbtw|cbw}"; 4396 default: 4397 return "movs{bw|x}\t{%1, %0|%0, %1}"; 4398 } 4399} 4400 [(set_attr "type" "imovx") 4401 (set_attr "mode" "HI") 4402 (set (attr "prefix_0f") 4403 ;; movsx is short decodable while cwtl is vector decoded. 4404 (if_then_else (and (eq_attr "cpu" "!k6") 4405 (eq_attr "alternative" "0")) 4406 (const_string "0") 4407 (const_string "1"))) 4408 (set (attr "modrm") 4409 (if_then_else (eq_attr "prefix_0f" "0") 4410 (const_string "0") 4411 (const_string "1")))]) 4412 4413;; Conversions between float and double. 4414 4415;; These are all no-ops in the model used for the 80387. 4416;; So just emit moves. 4417 4418;; %%% Kill these when call knows how to work out a DFmode push earlier. 4419(define_split 4420 [(set (match_operand:DF 0 "push_operand") 4421 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))] 4422 "reload_completed" 4423 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 4424 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))]) 4425 4426(define_split 4427 [(set (match_operand:XF 0 "push_operand") 4428 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))] 4429 "reload_completed" 4430 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 4431 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] 4432 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 4433 4434(define_expand "extendsfdf2" 4435 [(set (match_operand:DF 0 "nonimm_ssenomem_operand") 4436 (float_extend:DF (match_operand:SF 1 "general_operand")))] 4437 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4438{ 4439 /* ??? Needed for compress_float_constant since all fp constants 4440 are TARGET_LEGITIMATE_CONSTANT_P. */ 4441 if (CONST_DOUBLE_P (operands[1])) 4442 { 4443 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 4444 && standard_80387_constant_p (operands[1]) > 0) 4445 { 4446 operands[1] = simplify_const_unary_operation 4447 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 4448 emit_move_insn_1 (operands[0], operands[1]); 4449 DONE; 4450 } 4451 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 4452 } 4453}) 4454 4455/* For converting SF(xmm2) to DF(xmm1), use the following code instead of 4456 cvtss2sd: 4457 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs 4458 cvtps2pd xmm2,xmm1 4459 We do the conversion post reload to avoid producing of 128bit spills 4460 that might lead to ICE on 32bit target. The sequence unlikely combine 4461 anyway. */ 4462(define_split 4463 [(set (match_operand:DF 0 "sse_reg_operand") 4464 (float_extend:DF 4465 (match_operand:SF 1 "nonimmediate_operand")))] 4466 "TARGET_USE_VECTOR_FP_CONVERTS 4467 && optimize_insn_for_speed_p () 4468 && reload_completed 4469 && (!EXT_REX_SSE_REG_P (operands[0]) 4470 || TARGET_AVX512VL)" 4471 [(set (match_dup 2) 4472 (float_extend:V2DF 4473 (vec_select:V2SF 4474 (match_dup 3) 4475 (parallel [(const_int 0) (const_int 1)]))))] 4476{ 4477 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode); 4478 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode); 4479 /* Use movss for loading from memory, unpcklps reg, reg for registers. 4480 Try to avoid move when unpacking can be done in source. */ 4481 if (REG_P (operands[1])) 4482 { 4483 /* If it is unsafe to overwrite upper half of source, we need 4484 to move to destination and unpack there. */ 4485 if (REGNO (operands[0]) != REGNO (operands[1]) 4486 || (EXT_REX_SSE_REG_P (operands[1]) 4487 && !TARGET_AVX512VL)) 4488 { 4489 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode); 4490 emit_move_insn (tmp, operands[1]); 4491 } 4492 else 4493 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode); 4494 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow 4495 =v, v, then vbroadcastss will be only needed for AVX512F without 4496 AVX512VL. */ 4497 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3]))) 4498 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3], 4499 operands[3])); 4500 else 4501 { 4502 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode); 4503 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp)); 4504 } 4505 } 4506 else 4507 emit_insn (gen_vec_setv4sf_0 (operands[3], 4508 CONST0_RTX (V4SFmode), operands[1])); 4509}) 4510 4511;; It's more profitable to split and then extend in the same register. 4512(define_peephole2 4513 [(set (match_operand:DF 0 "sse_reg_operand") 4514 (float_extend:DF 4515 (match_operand:SF 1 "memory_operand")))] 4516 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS 4517 && optimize_insn_for_speed_p ()" 4518 [(set (match_dup 2) (match_dup 1)) 4519 (set (match_dup 0) (float_extend:DF (match_dup 2)))] 4520 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);") 4521 4522(define_insn "*extendsfdf2" 4523 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v") 4524 (float_extend:DF 4525 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))] 4526 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4527{ 4528 switch (which_alternative) 4529 { 4530 case 0: 4531 case 1: 4532 return output_387_reg_move (insn, operands); 4533 4534 case 2: 4535 return "%vcvtss2sd\t{%1, %d0|%d0, %1}"; 4536 4537 default: 4538 gcc_unreachable (); 4539 } 4540} 4541 [(set_attr "type" "fmov,fmov,ssecvt") 4542 (set_attr "prefix" "orig,orig,maybe_vex") 4543 (set_attr "mode" "SF,XF,DF") 4544 (set (attr "enabled") 4545 (if_then_else 4546 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH")) 4547 (if_then_else 4548 (eq_attr "alternative" "0,1") 4549 (symbol_ref "TARGET_MIX_SSE_I387") 4550 (symbol_ref "true")) 4551 (if_then_else 4552 (eq_attr "alternative" "0,1") 4553 (symbol_ref "true") 4554 (symbol_ref "false"))))]) 4555 4556(define_expand "extend<mode>xf2" 4557 [(set (match_operand:XF 0 "nonimmediate_operand") 4558 (float_extend:XF (match_operand:MODEF 1 "general_operand")))] 4559 "TARGET_80387" 4560{ 4561 /* ??? Needed for compress_float_constant since all fp constants 4562 are TARGET_LEGITIMATE_CONSTANT_P. */ 4563 if (CONST_DOUBLE_P (operands[1])) 4564 { 4565 if (standard_80387_constant_p (operands[1]) > 0) 4566 { 4567 operands[1] = simplify_const_unary_operation 4568 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode); 4569 emit_move_insn_1 (operands[0], operands[1]); 4570 DONE; 4571 } 4572 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1])); 4573 } 4574}) 4575 4576(define_insn "*extend<mode>xf2_i387" 4577 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 4578 (float_extend:XF 4579 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))] 4580 "TARGET_80387" 4581 "* return output_387_reg_move (insn, operands);" 4582 [(set_attr "type" "fmov") 4583 (set_attr "mode" "<MODE>,XF")]) 4584 4585;; %%% This seems like bad news. 4586;; This cannot output into an f-reg because there is no way to be sure 4587;; of truncating in that case. Otherwise this is just like a simple move 4588;; insn. So we pretend we can output to a reg in order to get better 4589;; register preferencing, but we really use a stack slot. 4590 4591;; Conversion from DFmode to SFmode. 4592 4593(define_expand "truncdfsf2" 4594 [(set (match_operand:SF 0 "nonimmediate_operand") 4595 (float_truncate:SF 4596 (match_operand:DF 1 "nonimmediate_operand")))] 4597 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4598{ 4599 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 4600 ; 4601 else if (flag_unsafe_math_optimizations) 4602 ; 4603 else 4604 { 4605 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP); 4606 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 4607 DONE; 4608 } 4609}) 4610 4611/* For converting DF(xmm2) to SF(xmm1), use the following code instead of 4612 cvtsd2ss: 4613 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs 4614 cvtpd2ps xmm2,xmm1 4615 We do the conversion post reload to avoid producing of 128bit spills 4616 that might lead to ICE on 32bit target. The sequence unlikely combine 4617 anyway. */ 4618(define_split 4619 [(set (match_operand:SF 0 "sse_reg_operand") 4620 (float_truncate:SF 4621 (match_operand:DF 1 "nonimmediate_operand")))] 4622 "TARGET_USE_VECTOR_FP_CONVERTS 4623 && optimize_insn_for_speed_p () 4624 && reload_completed 4625 && (!EXT_REX_SSE_REG_P (operands[0]) 4626 || TARGET_AVX512VL)" 4627 [(set (match_dup 2) 4628 (vec_concat:V4SF 4629 (float_truncate:V2SF 4630 (match_dup 4)) 4631 (match_dup 3)))] 4632{ 4633 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode); 4634 operands[3] = CONST0_RTX (V2SFmode); 4635 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode); 4636 /* Use movsd for loading from memory, unpcklpd for registers. 4637 Try to avoid move when unpacking can be done in source, or SSE3 4638 movddup is available. */ 4639 if (REG_P (operands[1])) 4640 { 4641 if (!TARGET_SSE3 4642 && REGNO (operands[0]) != REGNO (operands[1])) 4643 { 4644 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode); 4645 emit_move_insn (tmp, operands[1]); 4646 operands[1] = tmp; 4647 } 4648 else if (!TARGET_SSE3) 4649 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode); 4650 emit_insn (gen_vec_dupv2df (operands[4], operands[1])); 4651 } 4652 else 4653 emit_insn (gen_vec_concatv2df (operands[4], operands[1], 4654 CONST0_RTX (DFmode))); 4655}) 4656 4657;; It's more profitable to split and then extend in the same register. 4658(define_peephole2 4659 [(set (match_operand:SF 0 "sse_reg_operand") 4660 (float_truncate:SF 4661 (match_operand:DF 1 "memory_operand")))] 4662 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS 4663 && optimize_insn_for_speed_p ()" 4664 [(set (match_dup 2) (match_dup 1)) 4665 (set (match_dup 0) (float_truncate:SF (match_dup 2)))] 4666 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);") 4667 4668(define_expand "truncdfsf2_with_temp" 4669 [(parallel [(set (match_operand:SF 0) 4670 (float_truncate:SF (match_operand:DF 1))) 4671 (clobber (match_operand:SF 2))])]) 4672 4673;; SSE alternative doesn't depend on flag_unsafe_math_optimizations, 4674;; because nothing we do there is unsafe. 4675(define_insn "*truncdfsf_fast_mixed" 4676 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v") 4677 (float_truncate:SF 4678 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))] 4679 "TARGET_SSE2 && TARGET_SSE_MATH" 4680{ 4681 switch (which_alternative) 4682 { 4683 case 0: 4684 return output_387_reg_move (insn, operands); 4685 case 1: 4686 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4687 default: 4688 gcc_unreachable (); 4689 } 4690} 4691 [(set_attr "type" "fmov,ssecvt") 4692 (set_attr "prefix" "orig,maybe_vex") 4693 (set_attr "mode" "SF") 4694 (set (attr "enabled") 4695 (cond [(eq_attr "alternative" "0") 4696 (symbol_ref "TARGET_MIX_SSE_I387 4697 && flag_unsafe_math_optimizations") 4698 ] 4699 (symbol_ref "true")))]) 4700 4701(define_insn "*truncdfsf_fast_i387" 4702 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 4703 (float_truncate:SF 4704 (match_operand:DF 1 "nonimmediate_operand" "f")))] 4705 "TARGET_80387 && flag_unsafe_math_optimizations" 4706 "* return output_387_reg_move (insn, operands);" 4707 [(set_attr "type" "fmov") 4708 (set_attr "mode" "SF")]) 4709 4710(define_insn "*truncdfsf_mixed" 4711 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r") 4712 (float_truncate:SF 4713 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f"))) 4714 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))] 4715 "TARGET_MIX_SSE_I387" 4716{ 4717 switch (which_alternative) 4718 { 4719 case 0: 4720 return output_387_reg_move (insn, operands); 4721 case 1: 4722 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4723 4724 default: 4725 return "#"; 4726 } 4727} 4728 [(set_attr "isa" "*,sse2,*,*,*") 4729 (set_attr "type" "fmov,ssecvt,multi,multi,multi") 4730 (set_attr "unit" "*,*,i387,i387,i387") 4731 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig") 4732 (set_attr "mode" "SF")]) 4733 4734(define_insn "*truncdfsf_i387" 4735 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r") 4736 (float_truncate:SF 4737 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f"))) 4738 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4739 "TARGET_80387" 4740{ 4741 switch (which_alternative) 4742 { 4743 case 0: 4744 return output_387_reg_move (insn, operands); 4745 4746 default: 4747 return "#"; 4748 } 4749} 4750 [(set_attr "type" "fmov,multi,multi,multi") 4751 (set_attr "unit" "*,i387,i387,i387") 4752 (set_attr "mode" "SF")]) 4753 4754(define_insn "*truncdfsf2_i387_1" 4755 [(set (match_operand:SF 0 "memory_operand" "=m") 4756 (float_truncate:SF 4757 (match_operand:DF 1 "register_operand" "f")))] 4758 "TARGET_80387 4759 && !(TARGET_SSE2 && TARGET_SSE_MATH) 4760 && !TARGET_MIX_SSE_I387" 4761 "* return output_387_reg_move (insn, operands);" 4762 [(set_attr "type" "fmov") 4763 (set_attr "mode" "SF")]) 4764 4765(define_split 4766 [(set (match_operand:SF 0 "register_operand") 4767 (float_truncate:SF 4768 (match_operand:DF 1 "fp_register_operand"))) 4769 (clobber (match_operand 2))] 4770 "reload_completed" 4771 [(set (match_dup 2) (match_dup 1)) 4772 (set (match_dup 0) (match_dup 2))] 4773 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));") 4774 4775;; Conversion from XFmode to {SF,DF}mode 4776 4777(define_expand "truncxf<mode>2" 4778 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand") 4779 (float_truncate:MODEF 4780 (match_operand:XF 1 "register_operand"))) 4781 (clobber (match_dup 2))])] 4782 "TARGET_80387" 4783{ 4784 if (flag_unsafe_math_optimizations) 4785 { 4786 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode); 4787 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1])); 4788 if (reg != operands[0]) 4789 emit_move_insn (operands[0], reg); 4790 DONE; 4791 } 4792 else 4793 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4794}) 4795 4796(define_insn "*truncxfsf2_mixed" 4797 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r") 4798 (float_truncate:SF 4799 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4800 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4801 "TARGET_80387" 4802{ 4803 gcc_assert (!which_alternative); 4804 return output_387_reg_move (insn, operands); 4805} 4806 [(set_attr "type" "fmov,multi,multi,multi") 4807 (set_attr "unit" "*,i387,i387,i387") 4808 (set_attr "mode" "SF")]) 4809 4810(define_insn "*truncxfdf2_mixed" 4811 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r") 4812 (float_truncate:DF 4813 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4814 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))] 4815 "TARGET_80387" 4816{ 4817 gcc_assert (!which_alternative); 4818 return output_387_reg_move (insn, operands); 4819} 4820 [(set_attr "isa" "*,*,sse2,*") 4821 (set_attr "type" "fmov,multi,multi,multi") 4822 (set_attr "unit" "*,i387,i387,i387") 4823 (set_attr "mode" "DF")]) 4824 4825(define_insn "truncxf<mode>2_i387_noop" 4826 [(set (match_operand:MODEF 0 "register_operand" "=f") 4827 (float_truncate:MODEF 4828 (match_operand:XF 1 "register_operand" "f")))] 4829 "TARGET_80387 && flag_unsafe_math_optimizations" 4830 "* return output_387_reg_move (insn, operands);" 4831 [(set_attr "type" "fmov") 4832 (set_attr "mode" "<MODE>")]) 4833 4834(define_insn "*truncxf<mode>2_i387" 4835 [(set (match_operand:MODEF 0 "memory_operand" "=m") 4836 (float_truncate:MODEF 4837 (match_operand:XF 1 "register_operand" "f")))] 4838 "TARGET_80387" 4839 "* return output_387_reg_move (insn, operands);" 4840 [(set_attr "type" "fmov") 4841 (set_attr "mode" "<MODE>")]) 4842 4843(define_split 4844 [(set (match_operand:MODEF 0 "register_operand") 4845 (float_truncate:MODEF 4846 (match_operand:XF 1 "register_operand"))) 4847 (clobber (match_operand:MODEF 2 "memory_operand"))] 4848 "TARGET_80387 && reload_completed" 4849 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1))) 4850 (set (match_dup 0) (match_dup 2))]) 4851 4852(define_split 4853 [(set (match_operand:MODEF 0 "memory_operand") 4854 (float_truncate:MODEF 4855 (match_operand:XF 1 "register_operand"))) 4856 (clobber (match_operand:MODEF 2 "memory_operand"))] 4857 "TARGET_80387" 4858 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]) 4859 4860;; Signed conversion to DImode. 4861 4862(define_expand "fix_truncxfdi2" 4863 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand") 4864 (fix:DI (match_operand:XF 1 "register_operand"))) 4865 (clobber (reg:CC FLAGS_REG))])] 4866 "TARGET_80387" 4867{ 4868 if (TARGET_FISTTP) 4869 { 4870 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4871 DONE; 4872 } 4873}) 4874 4875(define_expand "fix_trunc<mode>di2" 4876 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand") 4877 (fix:DI (match_operand:MODEF 1 "register_operand"))) 4878 (clobber (reg:CC FLAGS_REG))])] 4879 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4880{ 4881 if (TARGET_FISTTP 4882 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4883 { 4884 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4885 DONE; 4886 } 4887 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4888 { 4889 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4890 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4891 if (out != operands[0]) 4892 emit_move_insn (operands[0], out); 4893 DONE; 4894 } 4895}) 4896 4897;; Signed conversion to SImode. 4898 4899(define_expand "fix_truncxfsi2" 4900 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 4901 (fix:SI (match_operand:XF 1 "register_operand"))) 4902 (clobber (reg:CC FLAGS_REG))])] 4903 "TARGET_80387" 4904{ 4905 if (TARGET_FISTTP) 4906 { 4907 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4908 DONE; 4909 } 4910}) 4911 4912(define_expand "fix_trunc<mode>si2" 4913 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 4914 (fix:SI (match_operand:MODEF 1 "register_operand"))) 4915 (clobber (reg:CC FLAGS_REG))])] 4916 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4917{ 4918 if (TARGET_FISTTP 4919 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4920 { 4921 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4922 DONE; 4923 } 4924 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4925 { 4926 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4927 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4928 if (out != operands[0]) 4929 emit_move_insn (operands[0], out); 4930 DONE; 4931 } 4932}) 4933 4934;; Signed conversion to HImode. 4935 4936(define_expand "fix_trunc<mode>hi2" 4937 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand") 4938 (fix:HI (match_operand:X87MODEF 1 "register_operand"))) 4939 (clobber (reg:CC FLAGS_REG))])] 4940 "TARGET_80387 4941 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4942{ 4943 if (TARGET_FISTTP) 4944 { 4945 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4946 DONE; 4947 } 4948}) 4949 4950;; Unsigned conversion to SImode. 4951 4952(define_expand "fixuns_trunc<mode>si2" 4953 [(parallel 4954 [(set (match_operand:SI 0 "register_operand") 4955 (unsigned_fix:SI 4956 (match_operand:MODEF 1 "nonimmediate_operand"))) 4957 (use (match_dup 2)) 4958 (clobber (match_scratch:<ssevecmode> 3)) 4959 (clobber (match_scratch:<ssevecmode> 4))])] 4960 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4961{ 4962 machine_mode mode = <MODE>mode; 4963 machine_mode vecmode = <ssevecmode>mode; 4964 REAL_VALUE_TYPE TWO31r; 4965 rtx two31; 4966 4967 if (optimize_insn_for_size_p ()) 4968 FAIL; 4969 4970 real_ldexp (&TWO31r, &dconst1, 31); 4971 two31 = const_double_from_real_value (TWO31r, mode); 4972 two31 = ix86_build_const_vector (vecmode, true, two31); 4973 operands[2] = force_reg (vecmode, two31); 4974}) 4975 4976(define_insn_and_split "*fixuns_trunc<mode>_1" 4977 [(set (match_operand:SI 0 "register_operand" "=&x,&x") 4978 (unsigned_fix:SI 4979 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm"))) 4980 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x")) 4981 (clobber (match_scratch:<ssevecmode> 1 "=x,&x")) 4982 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))] 4983 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH 4984 && optimize_function_for_speed_p (cfun)" 4985 "#" 4986 "&& reload_completed" 4987 [(const_int 0)] 4988{ 4989 ix86_split_convert_uns_si_sse (operands); 4990 DONE; 4991}) 4992 4993;; Unsigned conversion to HImode. 4994;; Without these patterns, we'll try the unsigned SI conversion which 4995;; is complex for SSE, rather than the signed SI conversion, which isn't. 4996 4997(define_expand "fixuns_trunc<mode>hi2" 4998 [(set (match_dup 2) 4999 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand"))) 5000 (set (match_operand:HI 0 "nonimmediate_operand") 5001 (subreg:HI (match_dup 2) 0))] 5002 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 5003 "operands[2] = gen_reg_rtx (SImode);") 5004 5005;; When SSE is available, it is always faster to use it! 5006(define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse" 5007 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 5008 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))] 5009 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) 5010 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 5011 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}" 5012 [(set_attr "type" "sseicvt") 5013 (set_attr "prefix" "maybe_vex") 5014 (set (attr "prefix_rex") 5015 (if_then_else 5016 (match_test "<SWI48:MODE>mode == DImode") 5017 (const_string "1") 5018 (const_string "*"))) 5019 (set_attr "mode" "<MODEF:MODE>") 5020 (set_attr "athlon_decode" "double,vector") 5021 (set_attr "amdfam10_decode" "double,double") 5022 (set_attr "bdver1_decode" "double,double")]) 5023 5024;; Avoid vector decoded forms of the instruction. 5025(define_peephole2 5026 [(match_scratch:MODEF 2 "x") 5027 (set (match_operand:SWI48 0 "register_operand") 5028 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))] 5029 "TARGET_AVOID_VECTOR_DECODE 5030 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) 5031 && optimize_insn_for_speed_p ()" 5032 [(set (match_dup 2) (match_dup 1)) 5033 (set (match_dup 0) (fix:SWI48 (match_dup 2)))]) 5034 5035(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 5036 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 5037 (fix:SWI248x (match_operand 1 "register_operand")))] 5038 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 5039 && TARGET_FISTTP 5040 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 5041 && (TARGET_64BIT || <MODE>mode != DImode)) 5042 && TARGET_SSE_MATH) 5043 && can_create_pseudo_p ()" 5044 "#" 5045 "&& 1" 5046 [(const_int 0)] 5047{ 5048 if (memory_operand (operands[0], VOIDmode)) 5049 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 5050 else 5051 { 5052 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 5053 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 5054 operands[1], 5055 operands[2])); 5056 } 5057 DONE; 5058} 5059 [(set_attr "type" "fisttp") 5060 (set_attr "mode" "<MODE>")]) 5061 5062(define_insn "fix_trunc<mode>_i387_fisttp" 5063 [(set (match_operand:SWI248x 0 "memory_operand" "=m") 5064 (fix:SWI248x (match_operand 1 "register_operand" "f"))) 5065 (clobber (match_scratch:XF 2 "=&1f"))] 5066 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 5067 && TARGET_FISTTP 5068 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 5069 && (TARGET_64BIT || <MODE>mode != DImode)) 5070 && TARGET_SSE_MATH)" 5071 "* return output_fix_trunc (insn, operands, true);" 5072 [(set_attr "type" "fisttp") 5073 (set_attr "mode" "<MODE>")]) 5074 5075(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 5076 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r") 5077 (fix:SWI248x (match_operand 1 "register_operand" "f,f"))) 5078 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m")) 5079 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 5080 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 5081 && TARGET_FISTTP 5082 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 5083 && (TARGET_64BIT || <MODE>mode != DImode)) 5084 && TARGET_SSE_MATH)" 5085 "#" 5086 [(set_attr "type" "fisttp") 5087 (set_attr "mode" "<MODE>")]) 5088 5089(define_split 5090 [(set (match_operand:SWI248x 0 "register_operand") 5091 (fix:SWI248x (match_operand 1 "register_operand"))) 5092 (clobber (match_operand:SWI248x 2 "memory_operand")) 5093 (clobber (match_scratch 3))] 5094 "reload_completed" 5095 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1))) 5096 (clobber (match_dup 3))]) 5097 (set (match_dup 0) (match_dup 2))]) 5098 5099(define_split 5100 [(set (match_operand:SWI248x 0 "memory_operand") 5101 (fix:SWI248x (match_operand 1 "register_operand"))) 5102 (clobber (match_operand:SWI248x 2 "memory_operand")) 5103 (clobber (match_scratch 3))] 5104 "reload_completed" 5105 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1))) 5106 (clobber (match_dup 3))])]) 5107 5108;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 5109;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 5110;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 5111;; clobbering insns can be used. Look at emit_i387_cw_initialization () 5112;; function in i386.c. 5113(define_insn_and_split "*fix_trunc<mode>_i387_1" 5114 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 5115 (fix:SWI248x (match_operand 1 "register_operand"))) 5116 (clobber (reg:CC FLAGS_REG))] 5117 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 5118 && !TARGET_FISTTP 5119 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 5120 && (TARGET_64BIT || <MODE>mode != DImode)) 5121 && can_create_pseudo_p ()" 5122 "#" 5123 "&& 1" 5124 [(const_int 0)] 5125{ 5126 ix86_optimize_mode_switching[I387_TRUNC] = 1; 5127 5128 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 5129 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 5130 if (memory_operand (operands[0], VOIDmode)) 5131 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 5132 operands[2], operands[3])); 5133 else 5134 { 5135 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 5136 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 5137 operands[2], operands[3], 5138 operands[4])); 5139 } 5140 DONE; 5141} 5142 [(set_attr "type" "fistp") 5143 (set_attr "i387_cw" "trunc") 5144 (set_attr "mode" "<MODE>")]) 5145 5146(define_insn "fix_truncdi_i387" 5147 [(set (match_operand:DI 0 "memory_operand" "=m") 5148 (fix:DI (match_operand 1 "register_operand" "f"))) 5149 (use (match_operand:HI 2 "memory_operand" "m")) 5150 (use (match_operand:HI 3 "memory_operand" "m")) 5151 (clobber (match_scratch:XF 4 "=&1f"))] 5152 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 5153 && !TARGET_FISTTP 5154 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 5155 "* return output_fix_trunc (insn, operands, false);" 5156 [(set_attr "type" "fistp") 5157 (set_attr "i387_cw" "trunc") 5158 (set_attr "mode" "DI")]) 5159 5160(define_insn "fix_truncdi_i387_with_temp" 5161 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 5162 (fix:DI (match_operand 1 "register_operand" "f,f"))) 5163 (use (match_operand:HI 2 "memory_operand" "m,m")) 5164 (use (match_operand:HI 3 "memory_operand" "m,m")) 5165 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 5166 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 5167 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 5168 && !TARGET_FISTTP 5169 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 5170 "#" 5171 [(set_attr "type" "fistp") 5172 (set_attr "i387_cw" "trunc") 5173 (set_attr "mode" "DI")]) 5174 5175(define_split 5176 [(set (match_operand:DI 0 "register_operand") 5177 (fix:DI (match_operand 1 "register_operand"))) 5178 (use (match_operand:HI 2 "memory_operand")) 5179 (use (match_operand:HI 3 "memory_operand")) 5180 (clobber (match_operand:DI 4 "memory_operand")) 5181 (clobber (match_scratch 5))] 5182 "reload_completed" 5183 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 5184 (use (match_dup 2)) 5185 (use (match_dup 3)) 5186 (clobber (match_dup 5))]) 5187 (set (match_dup 0) (match_dup 4))]) 5188 5189(define_split 5190 [(set (match_operand:DI 0 "memory_operand") 5191 (fix:DI (match_operand 1 "register_operand"))) 5192 (use (match_operand:HI 2 "memory_operand")) 5193 (use (match_operand:HI 3 "memory_operand")) 5194 (clobber (match_operand:DI 4 "memory_operand")) 5195 (clobber (match_scratch 5))] 5196 "reload_completed" 5197 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 5198 (use (match_dup 2)) 5199 (use (match_dup 3)) 5200 (clobber (match_dup 5))])]) 5201 5202(define_insn "fix_trunc<mode>_i387" 5203 [(set (match_operand:SWI24 0 "memory_operand" "=m") 5204 (fix:SWI24 (match_operand 1 "register_operand" "f"))) 5205 (use (match_operand:HI 2 "memory_operand" "m")) 5206 (use (match_operand:HI 3 "memory_operand" "m"))] 5207 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 5208 && !TARGET_FISTTP 5209 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 5210 "* return output_fix_trunc (insn, operands, false);" 5211 [(set_attr "type" "fistp") 5212 (set_attr "i387_cw" "trunc") 5213 (set_attr "mode" "<MODE>")]) 5214 5215(define_insn "fix_trunc<mode>_i387_with_temp" 5216 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 5217 (fix:SWI24 (match_operand 1 "register_operand" "f,f"))) 5218 (use (match_operand:HI 2 "memory_operand" "m,m")) 5219 (use (match_operand:HI 3 "memory_operand" "m,m")) 5220 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 5221 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 5222 && !TARGET_FISTTP 5223 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 5224 "#" 5225 [(set_attr "type" "fistp") 5226 (set_attr "i387_cw" "trunc") 5227 (set_attr "mode" "<MODE>")]) 5228 5229(define_split 5230 [(set (match_operand:SWI24 0 "register_operand") 5231 (fix:SWI24 (match_operand 1 "register_operand"))) 5232 (use (match_operand:HI 2 "memory_operand")) 5233 (use (match_operand:HI 3 "memory_operand")) 5234 (clobber (match_operand:SWI24 4 "memory_operand"))] 5235 "reload_completed" 5236 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1))) 5237 (use (match_dup 2)) 5238 (use (match_dup 3))]) 5239 (set (match_dup 0) (match_dup 4))]) 5240 5241(define_split 5242 [(set (match_operand:SWI24 0 "memory_operand") 5243 (fix:SWI24 (match_operand 1 "register_operand"))) 5244 (use (match_operand:HI 2 "memory_operand")) 5245 (use (match_operand:HI 3 "memory_operand")) 5246 (clobber (match_operand:SWI24 4 "memory_operand"))] 5247 "reload_completed" 5248 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1))) 5249 (use (match_dup 2)) 5250 (use (match_dup 3))])]) 5251 5252(define_insn "x86_fnstcw_1" 5253 [(set (match_operand:HI 0 "memory_operand" "=m") 5254 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))] 5255 "TARGET_80387" 5256 "fnstcw\t%0" 5257 [(set (attr "length") 5258 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 5259 (set_attr "mode" "HI") 5260 (set_attr "unit" "i387") 5261 (set_attr "bdver1_decode" "vector")]) 5262 5263(define_insn "x86_fldcw_1" 5264 [(set (reg:HI FPCR_REG) 5265 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 5266 "TARGET_80387" 5267 "fldcw\t%0" 5268 [(set (attr "length") 5269 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 5270 (set_attr "mode" "HI") 5271 (set_attr "unit" "i387") 5272 (set_attr "athlon_decode" "vector") 5273 (set_attr "amdfam10_decode" "vector") 5274 (set_attr "bdver1_decode" "vector")]) 5275 5276;; Conversion between fixed point and floating point. 5277 5278;; Even though we only accept memory inputs, the backend _really_ 5279;; wants to be able to do this between registers. Thankfully, LRA 5280;; will fix this up for us during register allocation. 5281 5282(define_insn "floathi<mode>2" 5283 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 5284 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))] 5285 "TARGET_80387 5286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 5287 || TARGET_MIX_SSE_I387)" 5288 "fild%Z1\t%1" 5289 [(set_attr "type" "fmov") 5290 (set_attr "mode" "<MODE>") 5291 (set_attr "znver1_decode" "double") 5292 (set_attr "fp_int_src" "true")]) 5293 5294(define_insn "float<SWI48x:mode>xf2" 5295 [(set (match_operand:XF 0 "register_operand" "=f") 5296 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))] 5297 "TARGET_80387" 5298 "fild%Z1\t%1" 5299 [(set_attr "type" "fmov") 5300 (set_attr "mode" "XF") 5301 (set_attr "znver1_decode" "double") 5302 (set_attr "fp_int_src" "true")]) 5303 5304(define_expand "float<SWI48:mode><MODEF:mode>2" 5305 [(set (match_operand:MODEF 0 "register_operand") 5306 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))] 5307 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)" 5308{ 5309 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 5310 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode)) 5311 { 5312 rtx reg = gen_reg_rtx (XFmode); 5313 rtx (*insn)(rtx, rtx); 5314 5315 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1])); 5316 5317 if (<MODEF:MODE>mode == SFmode) 5318 insn = gen_truncxfsf2; 5319 else if (<MODEF:MODE>mode == DFmode) 5320 insn = gen_truncxfdf2; 5321 else 5322 gcc_unreachable (); 5323 5324 emit_insn (insn (operands[0], reg)); 5325 DONE; 5326 } 5327}) 5328 5329(define_insn "*float<SWI48:mode><MODEF:mode>2_mixed" 5330 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v") 5331 (float:MODEF 5332 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))] 5333 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" 5334 "@ 5335 fild%Z1\t%1 5336 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1} 5337 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}" 5338 [(set_attr "type" "fmov,sseicvt,sseicvt") 5339 (set_attr "prefix" "orig,maybe_vex,maybe_vex") 5340 (set_attr "mode" "<MODEF:MODE>") 5341 (set (attr "prefix_rex") 5342 (if_then_else 5343 (and (eq_attr "prefix" "maybe_vex") 5344 (match_test "<SWI48:MODE>mode == DImode")) 5345 (const_string "1") 5346 (const_string "*"))) 5347 (set_attr "unit" "i387,*,*") 5348 (set_attr "athlon_decode" "*,double,direct") 5349 (set_attr "amdfam10_decode" "*,vector,double") 5350 (set_attr "bdver1_decode" "*,double,direct") 5351 (set_attr "znver1_decode" "double,*,*") 5352 (set_attr "fp_int_src" "true") 5353 (set (attr "enabled") 5354 (cond [(eq_attr "alternative" "0") 5355 (symbol_ref "TARGET_MIX_SSE_I387 5356 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, 5357 <SWI48:MODE>mode)") 5358 ] 5359 (symbol_ref "true"))) 5360 (set (attr "preferred_for_speed") 5361 (cond [(eq_attr "alternative" "1") 5362 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")] 5363 (symbol_ref "true")))]) 5364 5365(define_insn "*float<SWI48x:mode><MODEF:mode>2_i387" 5366 [(set (match_operand:MODEF 0 "register_operand" "=f") 5367 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))] 5368 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)" 5369 "fild%Z1\t%1" 5370 [(set_attr "type" "fmov") 5371 (set_attr "mode" "<MODEF:MODE>") 5372 (set_attr "znver1_decode" "double") 5373 (set_attr "fp_int_src" "true")]) 5374 5375;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory 5376;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs 5377;; alternative in sse2_loadld. 5378(define_split 5379 [(set (match_operand:MODEF 0 "sse_reg_operand") 5380 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))] 5381 "TARGET_SSE2 5382 && TARGET_USE_VECTOR_CONVERTS 5383 && optimize_function_for_speed_p (cfun) 5384 && reload_completed 5385 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC) 5386 && (!EXT_REX_SSE_REG_P (operands[0]) 5387 || TARGET_AVX512VL)" 5388 [(const_int 0)] 5389{ 5390 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode); 5391 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode); 5392 5393 emit_insn (gen_sse2_loadld (operands[4], 5394 CONST0_RTX (V4SImode), operands[1])); 5395 5396 if (<ssevecmode>mode == V4SFmode) 5397 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 5398 else 5399 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 5400 DONE; 5401}) 5402 5403;; Avoid partial SSE register dependency stalls. This splitter should split 5404;; late in the pass sequence (after register rename pass), so allocated 5405;; registers won't change anymore 5406 5407(define_split 5408 [(set (match_operand:MODEF 0 "sse_reg_operand") 5409 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))] 5410 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed 5411 && optimize_function_for_speed_p (cfun) 5412 && (!EXT_REX_SSE_REG_P (operands[0]) 5413 || TARGET_AVX512VL)" 5414 [(set (match_dup 0) 5415 (vec_merge:<MODEF:ssevecmode> 5416 (vec_duplicate:<MODEF:ssevecmode> 5417 (float:MODEF 5418 (match_dup 1))) 5419 (match_dup 0) 5420 (const_int 1)))] 5421{ 5422 const machine_mode vmode = <MODEF:ssevecmode>mode; 5423 5424 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode); 5425 emit_move_insn (operands[0], CONST0_RTX (vmode)); 5426}) 5427 5428;; Break partial reg stall for cvtsd2ss. This splitter should split 5429;; late in the pass sequence (after register rename pass), 5430;; so allocated registers won't change anymore. 5431 5432(define_split 5433 [(set (match_operand:SF 0 "sse_reg_operand") 5434 (float_truncate:SF 5435 (match_operand:DF 1 "nonimmediate_operand")))] 5436 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed 5437 && optimize_function_for_speed_p (cfun) 5438 && (!REG_P (operands[1]) 5439 || REGNO (operands[0]) != REGNO (operands[1])) 5440 && (!EXT_REX_SSE_REG_P (operands[0]) 5441 || TARGET_AVX512VL)" 5442 [(set (match_dup 0) 5443 (vec_merge:V4SF 5444 (vec_duplicate:V4SF 5445 (float_truncate:SF 5446 (match_dup 1))) 5447 (match_dup 0) 5448 (const_int 1)))] 5449{ 5450 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode); 5451 emit_move_insn (operands[0], CONST0_RTX (V4SFmode)); 5452}) 5453 5454;; Break partial reg stall for cvtss2sd. This splitter should split 5455;; late in the pass sequence (after register rename pass), 5456;; so allocated registers won't change anymore. 5457 5458(define_split 5459 [(set (match_operand:DF 0 "sse_reg_operand") 5460 (float_extend:DF 5461 (match_operand:SF 1 "nonimmediate_operand")))] 5462 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed 5463 && optimize_function_for_speed_p (cfun) 5464 && (!REG_P (operands[1]) 5465 || REGNO (operands[0]) != REGNO (operands[1])) 5466 && (!EXT_REX_SSE_REG_P (operands[0]) 5467 || TARGET_AVX512VL)" 5468 [(set (match_dup 0) 5469 (vec_merge:V2DF 5470 (vec_duplicate:V2DF 5471 (float_extend:DF 5472 (match_dup 1))) 5473 (match_dup 0) 5474 (const_int 1)))] 5475{ 5476 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode); 5477 emit_move_insn (operands[0], CONST0_RTX (V2DFmode)); 5478}) 5479 5480;; Avoid store forwarding (partial memory) stall penalty 5481;; by passing DImode value through XMM registers. */ 5482 5483(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm" 5484 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5485 (float:X87MODEF 5486 (match_operand:DI 1 "nonimmediate_operand" "m,?r"))) 5487 (clobber (match_scratch:V4SI 3 "=X,x")) 5488 (clobber (match_scratch:V4SI 4 "=X,x")) 5489 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))] 5490 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5491 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC 5492 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)" 5493 "#" 5494 [(set_attr "type" "multi") 5495 (set_attr "mode" "<X87MODEF:MODE>") 5496 (set_attr "unit" "i387") 5497 (set_attr "fp_int_src" "true")]) 5498 5499(define_split 5500 [(set (match_operand:X87MODEF 0 "fp_register_operand") 5501 (float:X87MODEF (match_operand:DI 1 "register_operand"))) 5502 (clobber (match_scratch:V4SI 3)) 5503 (clobber (match_scratch:V4SI 4)) 5504 (clobber (match_operand:DI 2 "memory_operand"))] 5505 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5506 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC 5507 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5508 && reload_completed" 5509 [(set (match_dup 2) (match_dup 3)) 5510 (set (match_dup 0) (float:X87MODEF (match_dup 2)))] 5511{ 5512 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). 5513 Assemble the 64-bit DImode value in an xmm register. */ 5514 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode), 5515 gen_lowpart (SImode, operands[1]))); 5516 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode), 5517 gen_highpart (SImode, operands[1]))); 5518 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3], 5519 operands[4])); 5520 5521 operands[3] = gen_lowpart (DImode, operands[3]); 5522}) 5523 5524(define_split 5525 [(set (match_operand:X87MODEF 0 "fp_register_operand") 5526 (float:X87MODEF (match_operand:DI 1 "memory_operand"))) 5527 (clobber (match_scratch:V4SI 3)) 5528 (clobber (match_scratch:V4SI 4)) 5529 (clobber (match_operand:DI 2 "memory_operand"))] 5530 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5531 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC 5532 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5533 && reload_completed" 5534 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 5535 5536(define_expand "floatuns<SWI12:mode><MODEF:mode>2" 5537 [(set (match_operand:MODEF 0 "register_operand") 5538 (unsigned_float:MODEF 5539 (match_operand:SWI12 1 "nonimmediate_operand")))] 5540 "!TARGET_64BIT 5541 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" 5542{ 5543 operands[1] = convert_to_mode (SImode, operands[1], 1); 5544 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1])); 5545 DONE; 5546}) 5547 5548;; Avoid store forwarding (partial memory) stall penalty by extending 5549;; SImode value to DImode through XMM register instead of pushing two 5550;; SImode values to stack. Also note that fild loads from memory only. 5551 5552(define_insn_and_split "*floatunssi<mode>2_i387_with_xmm" 5553 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 5554 (unsigned_float:X87MODEF 5555 (match_operand:SI 1 "nonimmediate_operand" "rm"))) 5556 (clobber (match_scratch:DI 3 "=x")) 5557 (clobber (match_operand:DI 2 "memory_operand" "=m"))] 5558 "!TARGET_64BIT 5559 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5560 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC" 5561 "#" 5562 "&& reload_completed" 5563 [(set (match_dup 3) (zero_extend:DI (match_dup 1))) 5564 (set (match_dup 2) (match_dup 3)) 5565 (set (match_dup 0) 5566 (float:X87MODEF (match_dup 2)))] 5567 "" 5568 [(set_attr "type" "multi") 5569 (set_attr "mode" "<MODE>")]) 5570 5571(define_expand "floatunssi<mode>2" 5572 [(parallel 5573 [(set (match_operand:X87MODEF 0 "register_operand") 5574 (unsigned_float:X87MODEF 5575 (match_operand:SI 1 "nonimmediate_operand"))) 5576 (clobber (match_scratch:DI 3)) 5577 (clobber (match_dup 2))])] 5578 "!TARGET_64BIT 5579 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5580 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC) 5581 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 5582{ 5583 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 5584 { 5585 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]); 5586 DONE; 5587 } 5588 else 5589 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 5590}) 5591 5592(define_expand "floatunsdisf2" 5593 [(use (match_operand:SF 0 "register_operand")) 5594 (use (match_operand:DI 1 "nonimmediate_operand"))] 5595 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH" 5596 "x86_emit_floatuns (operands); DONE;") 5597 5598(define_expand "floatunsdidf2" 5599 [(use (match_operand:DF 0 "register_operand")) 5600 (use (match_operand:DI 1 "nonimmediate_operand"))] 5601 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK) 5602 && TARGET_SSE2 && TARGET_SSE_MATH" 5603{ 5604 if (TARGET_64BIT) 5605 x86_emit_floatuns (operands); 5606 else 5607 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]); 5608 DONE; 5609}) 5610 5611;; Load effective address instructions 5612 5613(define_insn_and_split "*lea<mode>" 5614 [(set (match_operand:SWI48 0 "register_operand" "=r") 5615 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))] 5616 "" 5617{ 5618 if (SImode_address_operand (operands[1], VOIDmode)) 5619 { 5620 gcc_assert (TARGET_64BIT); 5621 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 5622 } 5623 else 5624 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"; 5625} 5626 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)" 5627 [(const_int 0)] 5628{ 5629 machine_mode mode = <MODE>mode; 5630 rtx pat; 5631 5632 /* ix86_avoid_lea_for_addr re-recognizes insn and may 5633 change operands[] array behind our back. */ 5634 pat = PATTERN (curr_insn); 5635 5636 operands[0] = SET_DEST (pat); 5637 operands[1] = SET_SRC (pat); 5638 5639 /* Emit all operations in SImode for zero-extended addresses. */ 5640 if (SImode_address_operand (operands[1], VOIDmode)) 5641 mode = SImode; 5642 5643 ix86_split_lea_for_addr (curr_insn, operands, mode); 5644 5645 /* Zero-extend return register to DImode for zero-extended addresses. */ 5646 if (mode != <MODE>mode) 5647 emit_insn (gen_zero_extendsidi2 5648 (operands[0], gen_lowpart (mode, operands[0]))); 5649 5650 DONE; 5651} 5652 [(set_attr "type" "lea") 5653 (set (attr "mode") 5654 (if_then_else 5655 (match_operand 1 "SImode_address_operand") 5656 (const_string "SI") 5657 (const_string "<MODE>")))]) 5658 5659;; Add instructions 5660 5661(define_expand "add<mode>3" 5662 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 5663 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand") 5664 (match_operand:SDWIM 2 "<general_hilo_operand>")))] 5665 "" 5666 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;") 5667 5668(define_insn_and_split "*add<dwi>3_doubleword" 5669 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 5670 (plus:<DWI> 5671 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0") 5672 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" 5673 "ro<di>,r<di>"))) 5674 (clobber (reg:CC FLAGS_REG))] 5675 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)" 5676 "#" 5677 "reload_completed" 5678 [(parallel [(set (reg:CCC FLAGS_REG) 5679 (compare:CCC 5680 (plus:DWIH (match_dup 1) (match_dup 2)) 5681 (match_dup 1))) 5682 (set (match_dup 0) 5683 (plus:DWIH (match_dup 1) (match_dup 2)))]) 5684 (parallel [(set (match_dup 3) 5685 (plus:DWIH 5686 (plus:DWIH 5687 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5688 (match_dup 4)) 5689 (match_dup 5))) 5690 (clobber (reg:CC FLAGS_REG))])] 5691{ 5692 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 5693 if (operands[2] == const0_rtx) 5694 { 5695 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]); 5696 DONE; 5697 } 5698}) 5699 5700(define_insn "*add<mode>_1" 5701 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r") 5702 (plus:SWI48 5703 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") 5704 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le"))) 5705 (clobber (reg:CC FLAGS_REG))] 5706 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5707{ 5708 switch (get_attr_type (insn)) 5709 { 5710 case TYPE_LEA: 5711 return "#"; 5712 5713 case TYPE_INCDEC: 5714 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5715 if (operands[2] == const1_rtx) 5716 return "inc{<imodesuffix>}\t%0"; 5717 else 5718 { 5719 gcc_assert (operands[2] == constm1_rtx); 5720 return "dec{<imodesuffix>}\t%0"; 5721 } 5722 5723 default: 5724 /* For most processors, ADD is faster than LEA. This alternative 5725 was added to use ADD as much as possible. */ 5726 if (which_alternative == 2) 5727 std::swap (operands[1], operands[2]); 5728 5729 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5730 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5731 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5732 5733 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5734 } 5735} 5736 [(set (attr "type") 5737 (cond [(eq_attr "alternative" "3") 5738 (const_string "lea") 5739 (match_operand:SWI48 2 "incdec_operand") 5740 (const_string "incdec") 5741 ] 5742 (const_string "alu"))) 5743 (set (attr "length_immediate") 5744 (if_then_else 5745 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5746 (const_string "1") 5747 (const_string "*"))) 5748 (set_attr "mode" "<MODE>")]) 5749 5750;; It may seem that nonimmediate operand is proper one for operand 1. 5751;; The addsi_1 pattern allows nonimmediate operand at that place and 5752;; we take care in ix86_binary_operator_ok to not allow two memory 5753;; operands so proper swapping will be done in reload. This allow 5754;; patterns constructed from addsi_1 to match. 5755 5756(define_insn "addsi_1_zext" 5757 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 5758 (zero_extend:DI 5759 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") 5760 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) 5761 (clobber (reg:CC FLAGS_REG))] 5762 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5763{ 5764 switch (get_attr_type (insn)) 5765 { 5766 case TYPE_LEA: 5767 return "#"; 5768 5769 case TYPE_INCDEC: 5770 if (operands[2] == const1_rtx) 5771 return "inc{l}\t%k0"; 5772 else 5773 { 5774 gcc_assert (operands[2] == constm1_rtx); 5775 return "dec{l}\t%k0"; 5776 } 5777 5778 default: 5779 /* For most processors, ADD is faster than LEA. This alternative 5780 was added to use ADD as much as possible. */ 5781 if (which_alternative == 1) 5782 std::swap (operands[1], operands[2]); 5783 5784 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5785 return "sub{l}\t{%2, %k0|%k0, %2}"; 5786 5787 return "add{l}\t{%2, %k0|%k0, %2}"; 5788 } 5789} 5790 [(set (attr "type") 5791 (cond [(eq_attr "alternative" "2") 5792 (const_string "lea") 5793 (match_operand:SI 2 "incdec_operand") 5794 (const_string "incdec") 5795 ] 5796 (const_string "alu"))) 5797 (set (attr "length_immediate") 5798 (if_then_else 5799 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5800 (const_string "1") 5801 (const_string "*"))) 5802 (set_attr "mode" "SI")]) 5803 5804(define_insn "*addhi_1" 5805 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp") 5806 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp") 5807 (match_operand:HI 2 "general_operand" "rn,rm,0,ln"))) 5808 (clobber (reg:CC FLAGS_REG))] 5809 "ix86_binary_operator_ok (PLUS, HImode, operands)" 5810{ 5811 switch (get_attr_type (insn)) 5812 { 5813 case TYPE_LEA: 5814 return "#"; 5815 5816 case TYPE_INCDEC: 5817 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5818 if (operands[2] == const1_rtx) 5819 return "inc{w}\t%0"; 5820 else 5821 { 5822 gcc_assert (operands[2] == constm1_rtx); 5823 return "dec{w}\t%0"; 5824 } 5825 5826 default: 5827 /* For most processors, ADD is faster than LEA. This alternative 5828 was added to use ADD as much as possible. */ 5829 if (which_alternative == 2) 5830 std::swap (operands[1], operands[2]); 5831 5832 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5833 if (x86_maybe_negate_const_int (&operands[2], HImode)) 5834 return "sub{w}\t{%2, %0|%0, %2}"; 5835 5836 return "add{w}\t{%2, %0|%0, %2}"; 5837 } 5838} 5839 [(set (attr "type") 5840 (cond [(eq_attr "alternative" "3") 5841 (const_string "lea") 5842 (match_operand:HI 2 "incdec_operand") 5843 (const_string "incdec") 5844 ] 5845 (const_string "alu"))) 5846 (set (attr "length_immediate") 5847 (if_then_else 5848 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5849 (const_string "1") 5850 (const_string "*"))) 5851 (set_attr "mode" "HI,HI,HI,SI")]) 5852 5853(define_insn "*addqi_1" 5854 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp") 5855 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp") 5856 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln"))) 5857 (clobber (reg:CC FLAGS_REG))] 5858 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5859{ 5860 bool widen = (get_attr_mode (insn) != MODE_QI); 5861 5862 switch (get_attr_type (insn)) 5863 { 5864 case TYPE_LEA: 5865 return "#"; 5866 5867 case TYPE_INCDEC: 5868 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5869 if (operands[2] == const1_rtx) 5870 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 5871 else 5872 { 5873 gcc_assert (operands[2] == constm1_rtx); 5874 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 5875 } 5876 5877 default: 5878 /* For most processors, ADD is faster than LEA. These alternatives 5879 were added to use ADD as much as possible. */ 5880 if (which_alternative == 2 || which_alternative == 4) 5881 std::swap (operands[1], operands[2]); 5882 5883 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5884 if (x86_maybe_negate_const_int (&operands[2], QImode)) 5885 { 5886 if (widen) 5887 return "sub{l}\t{%2, %k0|%k0, %2}"; 5888 else 5889 return "sub{b}\t{%2, %0|%0, %2}"; 5890 } 5891 if (widen) 5892 return "add{l}\t{%k2, %k0|%k0, %k2}"; 5893 else 5894 return "add{b}\t{%2, %0|%0, %2}"; 5895 } 5896} 5897 [(set (attr "type") 5898 (cond [(eq_attr "alternative" "5") 5899 (const_string "lea") 5900 (match_operand:QI 2 "incdec_operand") 5901 (const_string "incdec") 5902 ] 5903 (const_string "alu"))) 5904 (set (attr "length_immediate") 5905 (if_then_else 5906 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5907 (const_string "1") 5908 (const_string "*"))) 5909 (set_attr "mode" "QI,QI,QI,SI,SI,SI") 5910 ;; Potential partial reg stall on alternatives 3 and 4. 5911 (set (attr "preferred_for_speed") 5912 (cond [(eq_attr "alternative" "3,4") 5913 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 5914 (symbol_ref "true")))]) 5915 5916(define_insn "*addqi_1_slp" 5917 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 5918 (plus:QI (match_dup 0) 5919 (match_operand:QI 1 "general_operand" "qn,qm"))) 5920 (clobber (reg:CC FLAGS_REG))] 5921 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 5922 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 5923{ 5924 switch (get_attr_type (insn)) 5925 { 5926 case TYPE_INCDEC: 5927 if (operands[1] == const1_rtx) 5928 return "inc{b}\t%0"; 5929 else 5930 { 5931 gcc_assert (operands[1] == constm1_rtx); 5932 return "dec{b}\t%0"; 5933 } 5934 5935 default: 5936 if (x86_maybe_negate_const_int (&operands[1], QImode)) 5937 return "sub{b}\t{%1, %0|%0, %1}"; 5938 5939 return "add{b}\t{%1, %0|%0, %1}"; 5940 } 5941} 5942 [(set (attr "type") 5943 (if_then_else (match_operand:QI 1 "incdec_operand") 5944 (const_string "incdec") 5945 (const_string "alu1"))) 5946 (set (attr "memory") 5947 (if_then_else (match_operand 1 "memory_operand") 5948 (const_string "load") 5949 (const_string "none"))) 5950 (set_attr "mode" "QI")]) 5951 5952;; Split non destructive adds if we cannot use lea. 5953(define_split 5954 [(set (match_operand:SWI48 0 "register_operand") 5955 (plus:SWI48 (match_operand:SWI48 1 "register_operand") 5956 (match_operand:SWI48 2 "x86_64_nonmemory_operand"))) 5957 (clobber (reg:CC FLAGS_REG))] 5958 "reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5959 [(set (match_dup 0) (match_dup 1)) 5960 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2))) 5961 (clobber (reg:CC FLAGS_REG))])]) 5962 5963;; Split non destructive adds if we cannot use lea. 5964(define_split 5965 [(set (match_operand:DI 0 "register_operand") 5966 (zero_extend:DI 5967 (plus:SI (match_operand:SI 1 "register_operand") 5968 (match_operand:SI 2 "x86_64_nonmemory_operand")))) 5969 (clobber (reg:CC FLAGS_REG))] 5970 "TARGET_64BIT 5971 && reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5972 [(set (match_dup 3) (match_dup 1)) 5973 (parallel [(set (match_dup 0) 5974 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2)))) 5975 (clobber (reg:CC FLAGS_REG))])] 5976 "operands[3] = gen_lowpart (SImode, operands[0]);") 5977 5978;; Convert add to the lea pattern to avoid flags dependency. 5979(define_split 5980 [(set (match_operand:SWI 0 "register_operand") 5981 (plus:SWI (match_operand:SWI 1 "register_operand") 5982 (match_operand:SWI 2 "<nonmemory_operand>"))) 5983 (clobber (reg:CC FLAGS_REG))] 5984 "reload_completed && ix86_lea_for_add_ok (insn, operands)" 5985 [(set (match_dup 0) 5986 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))] 5987{ 5988 if (<MODE>mode != <LEAMODE>mode) 5989 { 5990 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]); 5991 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]); 5992 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]); 5993 } 5994}) 5995 5996;; Convert add to the lea pattern to avoid flags dependency. 5997(define_split 5998 [(set (match_operand:DI 0 "register_operand") 5999 (zero_extend:DI 6000 (plus:SI (match_operand:SI 1 "register_operand") 6001 (match_operand:SI 2 "x86_64_nonmemory_operand")))) 6002 (clobber (reg:CC FLAGS_REG))] 6003 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" 6004 [(set (match_dup 0) 6005 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]) 6006 6007(define_insn "*add<mode>_2" 6008 [(set (reg FLAGS_REG) 6009 (compare 6010 (plus:SWI 6011 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") 6012 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0")) 6013 (const_int 0))) 6014 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>") 6015 (plus:SWI (match_dup 1) (match_dup 2)))] 6016 "ix86_match_ccmode (insn, CCGOCmode) 6017 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6018{ 6019 switch (get_attr_type (insn)) 6020 { 6021 case TYPE_INCDEC: 6022 if (operands[2] == const1_rtx) 6023 return "inc{<imodesuffix>}\t%0"; 6024 else 6025 { 6026 gcc_assert (operands[2] == constm1_rtx); 6027 return "dec{<imodesuffix>}\t%0"; 6028 } 6029 6030 default: 6031 if (which_alternative == 2) 6032 std::swap (operands[1], operands[2]); 6033 6034 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6035 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6036 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6037 6038 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6039 } 6040} 6041 [(set (attr "type") 6042 (if_then_else (match_operand:SWI 2 "incdec_operand") 6043 (const_string "incdec") 6044 (const_string "alu"))) 6045 (set (attr "length_immediate") 6046 (if_then_else 6047 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 6048 (const_string "1") 6049 (const_string "*"))) 6050 (set_attr "mode" "<MODE>")]) 6051 6052;; See comment for addsi_1_zext why we do use nonimmediate_operand 6053(define_insn "*addsi_2_zext" 6054 [(set (reg FLAGS_REG) 6055 (compare 6056 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 6057 (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 6058 (const_int 0))) 6059 (set (match_operand:DI 0 "register_operand" "=r,r") 6060 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 6061 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6062 && ix86_binary_operator_ok (PLUS, SImode, operands)" 6063{ 6064 switch (get_attr_type (insn)) 6065 { 6066 case TYPE_INCDEC: 6067 if (operands[2] == const1_rtx) 6068 return "inc{l}\t%k0"; 6069 else 6070 { 6071 gcc_assert (operands[2] == constm1_rtx); 6072 return "dec{l}\t%k0"; 6073 } 6074 6075 default: 6076 if (which_alternative == 1) 6077 std::swap (operands[1], operands[2]); 6078 6079 if (x86_maybe_negate_const_int (&operands[2], SImode)) 6080 return "sub{l}\t{%2, %k0|%k0, %2}"; 6081 6082 return "add{l}\t{%2, %k0|%k0, %2}"; 6083 } 6084} 6085 [(set (attr "type") 6086 (if_then_else (match_operand:SI 2 "incdec_operand") 6087 (const_string "incdec") 6088 (const_string "alu"))) 6089 (set (attr "length_immediate") 6090 (if_then_else 6091 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 6092 (const_string "1") 6093 (const_string "*"))) 6094 (set_attr "mode" "SI")]) 6095 6096(define_insn "*add<mode>_3" 6097 [(set (reg FLAGS_REG) 6098 (compare 6099 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0")) 6100 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>"))) 6101 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 6102 "ix86_match_ccmode (insn, CCZmode) 6103 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6104{ 6105 switch (get_attr_type (insn)) 6106 { 6107 case TYPE_INCDEC: 6108 if (operands[2] == const1_rtx) 6109 return "inc{<imodesuffix>}\t%0"; 6110 else 6111 { 6112 gcc_assert (operands[2] == constm1_rtx); 6113 return "dec{<imodesuffix>}\t%0"; 6114 } 6115 6116 default: 6117 if (which_alternative == 1) 6118 std::swap (operands[1], operands[2]); 6119 6120 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6121 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6122 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6123 6124 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6125 } 6126} 6127 [(set (attr "type") 6128 (if_then_else (match_operand:SWI 2 "incdec_operand") 6129 (const_string "incdec") 6130 (const_string "alu"))) 6131 (set (attr "length_immediate") 6132 (if_then_else 6133 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 6134 (const_string "1") 6135 (const_string "*"))) 6136 (set_attr "mode" "<MODE>")]) 6137 6138;; See comment for addsi_1_zext why we do use nonimmediate_operand 6139(define_insn "*addsi_3_zext" 6140 [(set (reg FLAGS_REG) 6141 (compare 6142 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 6143 (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) 6144 (set (match_operand:DI 0 "register_operand" "=r,r") 6145 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 6146 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 6147 && ix86_binary_operator_ok (PLUS, SImode, operands)" 6148{ 6149 switch (get_attr_type (insn)) 6150 { 6151 case TYPE_INCDEC: 6152 if (operands[2] == const1_rtx) 6153 return "inc{l}\t%k0"; 6154 else 6155 { 6156 gcc_assert (operands[2] == constm1_rtx); 6157 return "dec{l}\t%k0"; 6158 } 6159 6160 default: 6161 if (which_alternative == 1) 6162 std::swap (operands[1], operands[2]); 6163 6164 if (x86_maybe_negate_const_int (&operands[2], SImode)) 6165 return "sub{l}\t{%2, %k0|%k0, %2}"; 6166 6167 return "add{l}\t{%2, %k0|%k0, %2}"; 6168 } 6169} 6170 [(set (attr "type") 6171 (if_then_else (match_operand:SI 2 "incdec_operand") 6172 (const_string "incdec") 6173 (const_string "alu"))) 6174 (set (attr "length_immediate") 6175 (if_then_else 6176 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 6177 (const_string "1") 6178 (const_string "*"))) 6179 (set_attr "mode" "SI")]) 6180 6181; For comparisons against 1, -1 and 128, we may generate better code 6182; by converting cmp to add, inc or dec as done by peephole2. This pattern 6183; is matched then. We can't accept general immediate, because for 6184; case of overflows, the result is messed up. 6185; Also carry flag is reversed compared to cmp, so this conversion is valid 6186; only for comparisons not depending on it. 6187 6188(define_insn "*adddi_4" 6189 [(set (reg FLAGS_REG) 6190 (compare 6191 (match_operand:DI 1 "nonimmediate_operand" "0") 6192 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 6193 (clobber (match_scratch:DI 0 "=rm"))] 6194 "TARGET_64BIT 6195 && ix86_match_ccmode (insn, CCGCmode)" 6196{ 6197 switch (get_attr_type (insn)) 6198 { 6199 case TYPE_INCDEC: 6200 if (operands[2] == constm1_rtx) 6201 return "inc{q}\t%0"; 6202 else 6203 { 6204 gcc_assert (operands[2] == const1_rtx); 6205 return "dec{q}\t%0"; 6206 } 6207 6208 default: 6209 if (x86_maybe_negate_const_int (&operands[2], DImode)) 6210 return "add{q}\t{%2, %0|%0, %2}"; 6211 6212 return "sub{q}\t{%2, %0|%0, %2}"; 6213 } 6214} 6215 [(set (attr "type") 6216 (if_then_else (match_operand:DI 2 "incdec_operand") 6217 (const_string "incdec") 6218 (const_string "alu"))) 6219 (set (attr "length_immediate") 6220 (if_then_else 6221 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 6222 (const_string "1") 6223 (const_string "*"))) 6224 (set_attr "mode" "DI")]) 6225 6226; For comparisons against 1, -1 and 128, we may generate better code 6227; by converting cmp to add, inc or dec as done by peephole2. This pattern 6228; is matched then. We can't accept general immediate, because for 6229; case of overflows, the result is messed up. 6230; Also carry flag is reversed compared to cmp, so this conversion is valid 6231; only for comparisons not depending on it. 6232 6233(define_insn "*add<mode>_4" 6234 [(set (reg FLAGS_REG) 6235 (compare 6236 (match_operand:SWI124 1 "nonimmediate_operand" "0") 6237 (match_operand:SWI124 2 "const_int_operand" "n"))) 6238 (clobber (match_scratch:SWI124 0 "=<r>m"))] 6239 "ix86_match_ccmode (insn, CCGCmode)" 6240{ 6241 switch (get_attr_type (insn)) 6242 { 6243 case TYPE_INCDEC: 6244 if (operands[2] == constm1_rtx) 6245 return "inc{<imodesuffix>}\t%0"; 6246 else 6247 { 6248 gcc_assert (operands[2] == const1_rtx); 6249 return "dec{<imodesuffix>}\t%0"; 6250 } 6251 6252 default: 6253 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6254 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6255 6256 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6257 } 6258} 6259 [(set (attr "type") 6260 (if_then_else (match_operand:<MODE> 2 "incdec_operand") 6261 (const_string "incdec") 6262 (const_string "alu"))) 6263 (set (attr "length_immediate") 6264 (if_then_else 6265 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 6266 (const_string "1") 6267 (const_string "*"))) 6268 (set_attr "mode" "<MODE>")]) 6269 6270(define_insn "*add<mode>_5" 6271 [(set (reg FLAGS_REG) 6272 (compare 6273 (plus:SWI 6274 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>") 6275 (match_operand:SWI 2 "<general_operand>" "<g>,0")) 6276 (const_int 0))) 6277 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 6278 "ix86_match_ccmode (insn, CCGOCmode) 6279 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6280{ 6281 switch (get_attr_type (insn)) 6282 { 6283 case TYPE_INCDEC: 6284 if (operands[2] == const1_rtx) 6285 return "inc{<imodesuffix>}\t%0"; 6286 else 6287 { 6288 gcc_assert (operands[2] == constm1_rtx); 6289 return "dec{<imodesuffix>}\t%0"; 6290 } 6291 6292 default: 6293 if (which_alternative == 1) 6294 std::swap (operands[1], operands[2]); 6295 6296 gcc_assert (rtx_equal_p (operands[0], operands[1])); 6297 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 6298 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 6299 6300 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 6301 } 6302} 6303 [(set (attr "type") 6304 (if_then_else (match_operand:SWI 2 "incdec_operand") 6305 (const_string "incdec") 6306 (const_string "alu"))) 6307 (set (attr "length_immediate") 6308 (if_then_else 6309 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 6310 (const_string "1") 6311 (const_string "*"))) 6312 (set_attr "mode" "<MODE>")]) 6313 6314(define_insn "addqi_ext_1" 6315 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 6316 (const_int 8) 6317 (const_int 8)) 6318 (subreg:SI 6319 (plus:QI 6320 (subreg:QI 6321 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 6322 (const_int 8) 6323 (const_int 8)) 0) 6324 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 6325 (clobber (reg:CC FLAGS_REG))] 6326 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 6327 rtx_equal_p (operands[0], operands[1])" 6328{ 6329 switch (get_attr_type (insn)) 6330 { 6331 case TYPE_INCDEC: 6332 if (operands[2] == const1_rtx) 6333 return "inc{b}\t%h0"; 6334 else 6335 { 6336 gcc_assert (operands[2] == constm1_rtx); 6337 return "dec{b}\t%h0"; 6338 } 6339 6340 default: 6341 return "add{b}\t{%2, %h0|%h0, %2}"; 6342 } 6343} 6344 [(set_attr "isa" "*,nox64") 6345 (set (attr "type") 6346 (if_then_else (match_operand:QI 2 "incdec_operand") 6347 (const_string "incdec") 6348 (const_string "alu"))) 6349 (set_attr "mode" "QI")]) 6350 6351(define_insn "*addqi_ext_2" 6352 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 6353 (const_int 8) 6354 (const_int 8)) 6355 (subreg:SI 6356 (plus:QI 6357 (subreg:QI 6358 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 6359 (const_int 8) 6360 (const_int 8)) 0) 6361 (subreg:QI 6362 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 6363 (const_int 8) 6364 (const_int 8)) 0)) 0)) 6365 (clobber (reg:CC FLAGS_REG))] 6366 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 6367 rtx_equal_p (operands[0], operands[1]) 6368 || rtx_equal_p (operands[0], operands[2])" 6369 "add{b}\t{%h2, %h0|%h0, %h2}" 6370 [(set_attr "type" "alu") 6371 (set_attr "mode" "QI")]) 6372 6373;; Add with jump on overflow. 6374(define_expand "addv<mode>4" 6375 [(parallel [(set (reg:CCO FLAGS_REG) 6376 (eq:CCO (plus:<DWI> 6377 (sign_extend:<DWI> 6378 (match_operand:SWI 1 "nonimmediate_operand")) 6379 (match_dup 4)) 6380 (sign_extend:<DWI> 6381 (plus:SWI (match_dup 1) 6382 (match_operand:SWI 2 6383 "<general_operand>"))))) 6384 (set (match_operand:SWI 0 "register_operand") 6385 (plus:SWI (match_dup 1) (match_dup 2)))]) 6386 (set (pc) (if_then_else 6387 (eq (reg:CCO FLAGS_REG) (const_int 0)) 6388 (label_ref (match_operand 3)) 6389 (pc)))] 6390 "" 6391{ 6392 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands); 6393 if (CONST_INT_P (operands[2])) 6394 operands[4] = operands[2]; 6395 else 6396 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]); 6397}) 6398 6399(define_insn "*addv<mode>4" 6400 [(set (reg:CCO FLAGS_REG) 6401 (eq:CCO (plus:<DWI> 6402 (sign_extend:<DWI> 6403 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) 6404 (sign_extend:<DWI> 6405 (match_operand:SWI 2 "<general_sext_operand>" 6406 "<r>mWe,<r>We"))) 6407 (sign_extend:<DWI> 6408 (plus:SWI (match_dup 1) (match_dup 2))))) 6409 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 6410 (plus:SWI (match_dup 1) (match_dup 2)))] 6411 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6412 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6413 [(set_attr "type" "alu") 6414 (set_attr "mode" "<MODE>")]) 6415 6416(define_insn "*addv<mode>4_1" 6417 [(set (reg:CCO FLAGS_REG) 6418 (eq:CCO (plus:<DWI> 6419 (sign_extend:<DWI> 6420 (match_operand:SWI 1 "nonimmediate_operand" "0")) 6421 (match_operand:<DWI> 3 "const_int_operand" "i")) 6422 (sign_extend:<DWI> 6423 (plus:SWI (match_dup 1) 6424 (match_operand:SWI 2 "x86_64_immediate_operand" 6425 "<i>"))))) 6426 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 6427 (plus:SWI (match_dup 1) (match_dup 2)))] 6428 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands) 6429 && CONST_INT_P (operands[2]) 6430 && INTVAL (operands[2]) == INTVAL (operands[3])" 6431 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6432 [(set_attr "type" "alu") 6433 (set_attr "mode" "<MODE>") 6434 (set (attr "length_immediate") 6435 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 6436 (const_string "1") 6437 (match_test "<MODE_SIZE> == 8") 6438 (const_string "4")] 6439 (const_string "<MODE_SIZE>")))]) 6440 6441(define_expand "uaddv<mode>4" 6442 [(parallel [(set (reg:CCC FLAGS_REG) 6443 (compare:CCC 6444 (plus:SWI 6445 (match_operand:SWI 1 "nonimmediate_operand") 6446 (match_operand:SWI 2 "<general_operand>")) 6447 (match_dup 1))) 6448 (set (match_operand:SWI 0 "register_operand") 6449 (plus:SWI (match_dup 1) (match_dup 2)))]) 6450 (set (pc) (if_then_else 6451 (ltu (reg:CCC FLAGS_REG) (const_int 0)) 6452 (label_ref (match_operand 3)) 6453 (pc)))] 6454 "" 6455 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);") 6456 6457;; The lea patterns for modes less than 32 bits need to be matched by 6458;; several insns converted to real lea by splitters. 6459 6460(define_insn_and_split "*lea<mode>_general_1" 6461 [(set (match_operand:SWI12 0 "register_operand" "=r") 6462 (plus:SWI12 6463 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6464 (match_operand:SWI12 2 "register_operand" "r")) 6465 (match_operand:SWI12 3 "immediate_operand" "i")))] 6466 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6467 "#" 6468 "&& reload_completed" 6469 [(set (match_dup 0) 6470 (plus:SI 6471 (plus:SI (match_dup 1) (match_dup 2)) 6472 (match_dup 3)))] 6473{ 6474 operands[0] = gen_lowpart (SImode, operands[0]); 6475 operands[1] = gen_lowpart (SImode, operands[1]); 6476 operands[2] = gen_lowpart (SImode, operands[2]); 6477 operands[3] = gen_lowpart (SImode, operands[3]); 6478} 6479 [(set_attr "type" "lea") 6480 (set_attr "mode" "SI")]) 6481 6482(define_insn_and_split "*lea<mode>_general_2" 6483 [(set (match_operand:SWI12 0 "register_operand" "=r") 6484 (plus:SWI12 6485 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6486 (match_operand 2 "const248_operand" "n")) 6487 (match_operand:SWI12 3 "nonmemory_operand" "ri")))] 6488 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6489 "#" 6490 "&& reload_completed" 6491 [(set (match_dup 0) 6492 (plus:SI 6493 (mult:SI (match_dup 1) (match_dup 2)) 6494 (match_dup 3)))] 6495{ 6496 operands[0] = gen_lowpart (SImode, operands[0]); 6497 operands[1] = gen_lowpart (SImode, operands[1]); 6498 operands[3] = gen_lowpart (SImode, operands[3]); 6499} 6500 [(set_attr "type" "lea") 6501 (set_attr "mode" "SI")]) 6502 6503(define_insn_and_split "*lea<mode>_general_2b" 6504 [(set (match_operand:SWI12 0 "register_operand" "=r") 6505 (plus:SWI12 6506 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6507 (match_operand 2 "const123_operand" "n")) 6508 (match_operand:SWI12 3 "nonmemory_operand" "ri")))] 6509 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6510 "#" 6511 "&& reload_completed" 6512 [(set (match_dup 0) 6513 (plus:SI 6514 (ashift:SI (match_dup 1) (match_dup 2)) 6515 (match_dup 3)))] 6516{ 6517 operands[0] = gen_lowpart (SImode, operands[0]); 6518 operands[1] = gen_lowpart (SImode, operands[1]); 6519 operands[3] = gen_lowpart (SImode, operands[3]); 6520} 6521 [(set_attr "type" "lea") 6522 (set_attr "mode" "SI")]) 6523 6524(define_insn_and_split "*lea<mode>_general_3" 6525 [(set (match_operand:SWI12 0 "register_operand" "=r") 6526 (plus:SWI12 6527 (plus:SWI12 6528 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6529 (match_operand 2 "const248_operand" "n")) 6530 (match_operand:SWI12 3 "register_operand" "r")) 6531 (match_operand:SWI12 4 "immediate_operand" "i")))] 6532 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6533 "#" 6534 "&& reload_completed" 6535 [(set (match_dup 0) 6536 (plus:SI 6537 (plus:SI 6538 (mult:SI (match_dup 1) (match_dup 2)) 6539 (match_dup 3)) 6540 (match_dup 4)))] 6541{ 6542 operands[0] = gen_lowpart (SImode, operands[0]); 6543 operands[1] = gen_lowpart (SImode, operands[1]); 6544 operands[3] = gen_lowpart (SImode, operands[3]); 6545 operands[4] = gen_lowpart (SImode, operands[4]); 6546} 6547 [(set_attr "type" "lea") 6548 (set_attr "mode" "SI")]) 6549 6550(define_insn_and_split "*lea<mode>_general_3b" 6551 [(set (match_operand:SWI12 0 "register_operand" "=r") 6552 (plus:SWI12 6553 (plus:SWI12 6554 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6555 (match_operand 2 "const123_operand" "n")) 6556 (match_operand:SWI12 3 "register_operand" "r")) 6557 (match_operand:SWI12 4 "immediate_operand" "i")))] 6558 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6559 "#" 6560 "&& reload_completed" 6561 [(set (match_dup 0) 6562 (plus:SI 6563 (plus:SI 6564 (ashift:SI (match_dup 1) (match_dup 2)) 6565 (match_dup 3)) 6566 (match_dup 4)))] 6567{ 6568 operands[0] = gen_lowpart (SImode, operands[0]); 6569 operands[1] = gen_lowpart (SImode, operands[1]); 6570 operands[3] = gen_lowpart (SImode, operands[3]); 6571 operands[4] = gen_lowpart (SImode, operands[4]); 6572} 6573 [(set_attr "type" "lea") 6574 (set_attr "mode" "SI")]) 6575 6576(define_insn_and_split "*lea<mode>_general_4" 6577 [(set (match_operand:SWI12 0 "register_operand" "=r") 6578 (any_or:SWI12 6579 (ashift:SWI12 6580 (match_operand:SWI12 1 "index_register_operand" "l") 6581 (match_operand 2 "const_0_to_3_operand" "n")) 6582 (match_operand 3 "const_int_operand" "n")))] 6583 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6584 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3]) 6585 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))" 6586 "#" 6587 "&& reload_completed" 6588 [(set (match_dup 0) 6589 (plus:SI 6590 (mult:SI (match_dup 1) (match_dup 2)) 6591 (match_dup 3)))] 6592{ 6593 operands[0] = gen_lowpart (SImode, operands[0]); 6594 operands[1] = gen_lowpart (SImode, operands[1]); 6595 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 6596} 6597 [(set_attr "type" "lea") 6598 (set_attr "mode" "SI")]) 6599 6600(define_insn_and_split "*lea<mode>_general_4" 6601 [(set (match_operand:SWI48 0 "register_operand" "=r") 6602 (any_or:SWI48 6603 (ashift:SWI48 6604 (match_operand:SWI48 1 "index_register_operand" "l") 6605 (match_operand 2 "const_0_to_3_operand" "n")) 6606 (match_operand 3 "const_int_operand" "n")))] 6607 "(unsigned HOST_WIDE_INT) INTVAL (operands[3]) 6608 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))" 6609 "#" 6610 "&& reload_completed" 6611 [(set (match_dup 0) 6612 (plus:SWI48 6613 (mult:SWI48 (match_dup 1) (match_dup 2)) 6614 (match_dup 3)))] 6615 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));" 6616 [(set_attr "type" "lea") 6617 (set_attr "mode" "<MODE>")]) 6618 6619;; Subtract instructions 6620 6621(define_expand "sub<mode>3" 6622 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 6623 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand") 6624 (match_operand:SDWIM 2 "<general_hilo_operand>")))] 6625 "" 6626 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;") 6627 6628(define_insn_and_split "*sub<dwi>3_doubleword" 6629 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 6630 (minus:<DWI> 6631 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0") 6632 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" 6633 "ro<di>,r<di>"))) 6634 (clobber (reg:CC FLAGS_REG))] 6635 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6636 "#" 6637 "reload_completed" 6638 [(parallel [(set (reg:CC FLAGS_REG) 6639 (compare:CC (match_dup 1) (match_dup 2))) 6640 (set (match_dup 0) 6641 (minus:DWIH (match_dup 1) (match_dup 2)))]) 6642 (parallel [(set (match_dup 3) 6643 (minus:DWIH 6644 (minus:DWIH 6645 (match_dup 4) 6646 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))) 6647 (match_dup 5))) 6648 (clobber (reg:CC FLAGS_REG))])] 6649{ 6650 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 6651 if (operands[2] == const0_rtx) 6652 { 6653 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]); 6654 DONE; 6655 } 6656}) 6657 6658(define_insn "*sub<mode>_1" 6659 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6660 (minus:SWI 6661 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6662 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6663 (clobber (reg:CC FLAGS_REG))] 6664 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6665 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6666 [(set_attr "type" "alu") 6667 (set_attr "mode" "<MODE>")]) 6668 6669(define_insn "*subsi_1_zext" 6670 [(set (match_operand:DI 0 "register_operand" "=r") 6671 (zero_extend:DI 6672 (minus:SI (match_operand:SI 1 "register_operand" "0") 6673 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6674 (clobber (reg:CC FLAGS_REG))] 6675 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6676 "sub{l}\t{%2, %k0|%k0, %2}" 6677 [(set_attr "type" "alu") 6678 (set_attr "mode" "SI")]) 6679 6680(define_insn "*subqi_1_slp" 6681 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6682 (minus:QI (match_dup 0) 6683 (match_operand:QI 1 "general_operand" "qn,qm"))) 6684 (clobber (reg:CC FLAGS_REG))] 6685 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6686 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 6687 "sub{b}\t{%1, %0|%0, %1}" 6688 [(set_attr "type" "alu1") 6689 (set_attr "mode" "QI")]) 6690 6691(define_insn "*sub<mode>_2" 6692 [(set (reg FLAGS_REG) 6693 (compare 6694 (minus:SWI 6695 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6696 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6697 (const_int 0))) 6698 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6699 (minus:SWI (match_dup 1) (match_dup 2)))] 6700 "ix86_match_ccmode (insn, CCGOCmode) 6701 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6702 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6703 [(set_attr "type" "alu") 6704 (set_attr "mode" "<MODE>")]) 6705 6706(define_insn "*subsi_2_zext" 6707 [(set (reg FLAGS_REG) 6708 (compare 6709 (minus:SI (match_operand:SI 1 "register_operand" "0") 6710 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6711 (const_int 0))) 6712 (set (match_operand:DI 0 "register_operand" "=r") 6713 (zero_extend:DI 6714 (minus:SI (match_dup 1) 6715 (match_dup 2))))] 6716 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6717 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6718 "sub{l}\t{%2, %k0|%k0, %2}" 6719 [(set_attr "type" "alu") 6720 (set_attr "mode" "SI")]) 6721 6722;; Subtract with jump on overflow. 6723(define_expand "subv<mode>4" 6724 [(parallel [(set (reg:CCO FLAGS_REG) 6725 (eq:CCO (minus:<DWI> 6726 (sign_extend:<DWI> 6727 (match_operand:SWI 1 "nonimmediate_operand")) 6728 (match_dup 4)) 6729 (sign_extend:<DWI> 6730 (minus:SWI (match_dup 1) 6731 (match_operand:SWI 2 6732 "<general_operand>"))))) 6733 (set (match_operand:SWI 0 "register_operand") 6734 (minus:SWI (match_dup 1) (match_dup 2)))]) 6735 (set (pc) (if_then_else 6736 (eq (reg:CCO FLAGS_REG) (const_int 0)) 6737 (label_ref (match_operand 3)) 6738 (pc)))] 6739 "" 6740{ 6741 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands); 6742 if (CONST_INT_P (operands[2])) 6743 operands[4] = operands[2]; 6744 else 6745 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]); 6746}) 6747 6748(define_insn "*subv<mode>4" 6749 [(set (reg:CCO FLAGS_REG) 6750 (eq:CCO (minus:<DWI> 6751 (sign_extend:<DWI> 6752 (match_operand:SWI 1 "nonimmediate_operand" "0,0")) 6753 (sign_extend:<DWI> 6754 (match_operand:SWI 2 "<general_sext_operand>" 6755 "<r>We,<r>m"))) 6756 (sign_extend:<DWI> 6757 (minus:SWI (match_dup 1) (match_dup 2))))) 6758 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6759 (minus:SWI (match_dup 1) (match_dup 2)))] 6760 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6761 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6762 [(set_attr "type" "alu") 6763 (set_attr "mode" "<MODE>")]) 6764 6765(define_insn "*subv<mode>4_1" 6766 [(set (reg:CCO FLAGS_REG) 6767 (eq:CCO (minus:<DWI> 6768 (sign_extend:<DWI> 6769 (match_operand:SWI 1 "nonimmediate_operand" "0")) 6770 (match_operand:<DWI> 3 "const_int_operand" "i")) 6771 (sign_extend:<DWI> 6772 (minus:SWI (match_dup 1) 6773 (match_operand:SWI 2 "x86_64_immediate_operand" 6774 "<i>"))))) 6775 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 6776 (minus:SWI (match_dup 1) (match_dup 2)))] 6777 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) 6778 && CONST_INT_P (operands[2]) 6779 && INTVAL (operands[2]) == INTVAL (operands[3])" 6780 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6781 [(set_attr "type" "alu") 6782 (set_attr "mode" "<MODE>") 6783 (set (attr "length_immediate") 6784 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 6785 (const_string "1") 6786 (match_test "<MODE_SIZE> == 8") 6787 (const_string "4")] 6788 (const_string "<MODE_SIZE>")))]) 6789 6790(define_expand "usubv<mode>4" 6791 [(parallel [(set (reg:CC FLAGS_REG) 6792 (compare:CC 6793 (match_operand:SWI 1 "nonimmediate_operand") 6794 (match_operand:SWI 2 "<general_operand>"))) 6795 (set (match_operand:SWI 0 "register_operand") 6796 (minus:SWI (match_dup 1) (match_dup 2)))]) 6797 (set (pc) (if_then_else 6798 (ltu (reg:CC FLAGS_REG) (const_int 0)) 6799 (label_ref (match_operand 3)) 6800 (pc)))] 6801 "" 6802 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);") 6803 6804(define_insn "*sub<mode>_3" 6805 [(set (reg FLAGS_REG) 6806 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6807 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6808 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6809 (minus:SWI (match_dup 1) (match_dup 2)))] 6810 "ix86_match_ccmode (insn, CCmode) 6811 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6812 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6813 [(set_attr "type" "alu") 6814 (set_attr "mode" "<MODE>")]) 6815 6816(define_peephole2 6817 [(parallel 6818 [(set (reg:CC FLAGS_REG) 6819 (compare:CC (match_operand:SWI 0 "general_reg_operand") 6820 (match_operand:SWI 1 "general_gr_operand"))) 6821 (set (match_dup 0) 6822 (minus:SWI (match_dup 0) (match_dup 1)))])] 6823 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0" 6824 [(set (reg:CC FLAGS_REG) 6825 (compare:CC (match_dup 0) (match_dup 1)))]) 6826 6827(define_insn "*subsi_3_zext" 6828 [(set (reg FLAGS_REG) 6829 (compare (match_operand:SI 1 "register_operand" "0") 6830 (match_operand:SI 2 "x86_64_general_operand" "rme"))) 6831 (set (match_operand:DI 0 "register_operand" "=r") 6832 (zero_extend:DI 6833 (minus:SI (match_dup 1) 6834 (match_dup 2))))] 6835 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6836 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6837 "sub{l}\t{%2, %1|%1, %2}" 6838 [(set_attr "type" "alu") 6839 (set_attr "mode" "SI")]) 6840 6841;; Add with carry and subtract with borrow 6842 6843(define_insn "add<mode>3_carry" 6844 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6845 (plus:SWI 6846 (plus:SWI 6847 (match_operator:SWI 4 "ix86_carry_flag_operator" 6848 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6849 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) 6850 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6851 (clobber (reg:CC FLAGS_REG))] 6852 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6853 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6854 [(set_attr "type" "alu") 6855 (set_attr "use_carry" "1") 6856 (set_attr "pent_pair" "pu") 6857 (set_attr "mode" "<MODE>")]) 6858 6859(define_insn "*add<mode>3_carry_0" 6860 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 6861 (plus:SWI 6862 (match_operator:SWI 3 "ix86_carry_flag_operator" 6863 [(match_operand 2 "flags_reg_operand") (const_int 0)]) 6864 (match_operand:SWI 1 "nonimmediate_operand" "0"))) 6865 (clobber (reg:CC FLAGS_REG))] 6866 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)" 6867 "adc{<imodesuffix>}\t{$0, %0|%0, 0}" 6868 [(set_attr "type" "alu") 6869 (set_attr "use_carry" "1") 6870 (set_attr "pent_pair" "pu") 6871 (set_attr "mode" "<MODE>")]) 6872 6873(define_insn "*addsi3_carry_zext" 6874 [(set (match_operand:DI 0 "register_operand" "=r") 6875 (zero_extend:DI 6876 (plus:SI 6877 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator" 6878 [(reg FLAGS_REG) (const_int 0)]) 6879 (match_operand:SI 1 "register_operand" "%0")) 6880 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6881 (clobber (reg:CC FLAGS_REG))] 6882 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6883 "adc{l}\t{%2, %k0|%k0, %2}" 6884 [(set_attr "type" "alu") 6885 (set_attr "use_carry" "1") 6886 (set_attr "pent_pair" "pu") 6887 (set_attr "mode" "SI")]) 6888 6889(define_insn "*addsi3_carry_zext_0" 6890 [(set (match_operand:DI 0 "register_operand" "=r") 6891 (zero_extend:DI 6892 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator" 6893 [(reg FLAGS_REG) (const_int 0)]) 6894 (match_operand:SI 1 "register_operand" "0")))) 6895 (clobber (reg:CC FLAGS_REG))] 6896 "TARGET_64BIT" 6897 "adc{l}\t{$0, %k0|%k0, 0}" 6898 [(set_attr "type" "alu") 6899 (set_attr "use_carry" "1") 6900 (set_attr "pent_pair" "pu") 6901 (set_attr "mode" "SI")]) 6902 6903;; There is no point to generate ADCX instruction. ADC is shorter and faster. 6904 6905(define_insn "addcarry<mode>" 6906 [(set (reg:CCC FLAGS_REG) 6907 (compare:CCC 6908 (zero_extend:<DWI> 6909 (plus:SWI48 6910 (plus:SWI48 6911 (match_operator:SWI48 5 "ix86_carry_flag_operator" 6912 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6913 (match_operand:SWI48 1 "nonimmediate_operand" "%0")) 6914 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))) 6915 (plus:<DWI> 6916 (zero_extend:<DWI> (match_dup 2)) 6917 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 6918 [(match_dup 3) (const_int 0)])))) 6919 (set (match_operand:SWI48 0 "register_operand" "=r") 6920 (plus:SWI48 (plus:SWI48 (match_op_dup 5 6921 [(match_dup 3) (const_int 0)]) 6922 (match_dup 1)) 6923 (match_dup 2)))] 6924 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6925 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6926 [(set_attr "type" "alu") 6927 (set_attr "use_carry" "1") 6928 (set_attr "pent_pair" "pu") 6929 (set_attr "mode" "<MODE>")]) 6930 6931(define_expand "addcarry<mode>_0" 6932 [(parallel 6933 [(set (reg:CCC FLAGS_REG) 6934 (compare:CCC 6935 (plus:SWI48 6936 (match_operand:SWI48 1 "nonimmediate_operand") 6937 (match_operand:SWI48 2 "x86_64_general_operand")) 6938 (match_dup 1))) 6939 (set (match_operand:SWI48 0 "register_operand") 6940 (plus:SWI48 (match_dup 1) (match_dup 2)))])] 6941 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)") 6942 6943(define_insn "sub<mode>3_carry" 6944 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6945 (minus:SWI 6946 (minus:SWI 6947 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6948 (match_operator:SWI 4 "ix86_carry_flag_operator" 6949 [(match_operand 3 "flags_reg_operand") (const_int 0)])) 6950 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6951 (clobber (reg:CC FLAGS_REG))] 6952 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6953 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6954 [(set_attr "type" "alu") 6955 (set_attr "use_carry" "1") 6956 (set_attr "pent_pair" "pu") 6957 (set_attr "mode" "<MODE>")]) 6958 6959(define_insn "*sub<mode>3_carry_0" 6960 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 6961 (minus:SWI 6962 (match_operand:SWI 1 "nonimmediate_operand" "0") 6963 (match_operator:SWI 3 "ix86_carry_flag_operator" 6964 [(match_operand 2 "flags_reg_operand") (const_int 0)]))) 6965 (clobber (reg:CC FLAGS_REG))] 6966 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)" 6967 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}" 6968 [(set_attr "type" "alu") 6969 (set_attr "use_carry" "1") 6970 (set_attr "pent_pair" "pu") 6971 (set_attr "mode" "<MODE>")]) 6972 6973(define_insn "*subsi3_carry_zext" 6974 [(set (match_operand:DI 0 "register_operand" "=r") 6975 (zero_extend:DI 6976 (minus:SI 6977 (minus:SI 6978 (match_operand:SI 1 "register_operand" "0") 6979 (match_operator:SI 3 "ix86_carry_flag_operator" 6980 [(reg FLAGS_REG) (const_int 0)])) 6981 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6982 (clobber (reg:CC FLAGS_REG))] 6983 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6984 "sbb{l}\t{%2, %k0|%k0, %2}" 6985 [(set_attr "type" "alu") 6986 (set_attr "use_carry" "1") 6987 (set_attr "pent_pair" "pu") 6988 (set_attr "mode" "SI")]) 6989 6990(define_insn "*subsi3_carry_zext_0" 6991 [(set (match_operand:DI 0 "register_operand" "=r") 6992 (zero_extend:DI 6993 (minus:SI 6994 (match_operand:SI 1 "register_operand" "0") 6995 (match_operator:SI 2 "ix86_carry_flag_operator" 6996 [(reg FLAGS_REG) (const_int 0)])))) 6997 (clobber (reg:CC FLAGS_REG))] 6998 "TARGET_64BIT" 6999 "sbb{l}\t{$0, %k0|%k0, 0}" 7000 [(set_attr "type" "alu") 7001 (set_attr "use_carry" "1") 7002 (set_attr "pent_pair" "pu") 7003 (set_attr "mode" "SI")]) 7004 7005(define_insn "sub<mode>3_carry_ccc" 7006 [(set (reg:CCC FLAGS_REG) 7007 (compare:CCC 7008 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0")) 7009 (plus:<DWI> 7010 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)) 7011 (zero_extend:<DWI> 7012 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe"))))) 7013 (clobber (match_scratch:DWIH 0 "=r"))] 7014 "" 7015 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 7016 [(set_attr "type" "alu") 7017 (set_attr "mode" "<MODE>")]) 7018 7019(define_insn "*sub<mode>3_carry_ccc_1" 7020 [(set (reg:CCC FLAGS_REG) 7021 (compare:CCC 7022 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0")) 7023 (plus:<DWI> 7024 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)) 7025 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf")))) 7026 (clobber (match_scratch:DWIH 0 "=r"))] 7027 "" 7028{ 7029 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0); 7030 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}"; 7031} 7032 [(set_attr "type" "alu") 7033 (set_attr "mode" "<MODE>")]) 7034 7035;; The sign flag is set from the 7036;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2))) 7037;; result, the overflow flag likewise, but the overflow flag is also 7038;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows. 7039(define_insn "sub<mode>3_carry_ccgz" 7040 [(set (reg:CCGZ FLAGS_REG) 7041 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0") 7042 (match_operand:DWIH 2 "x86_64_general_operand" "rme") 7043 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))] 7044 UNSPEC_SBB)) 7045 (clobber (match_scratch:DWIH 0 "=r"))] 7046 "" 7047 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 7048 [(set_attr "type" "alu") 7049 (set_attr "mode" "<MODE>")]) 7050 7051(define_insn "subborrow<mode>" 7052 [(set (reg:CCC FLAGS_REG) 7053 (compare:CCC 7054 (zero_extend:<DWI> 7055 (match_operand:SWI48 1 "nonimmediate_operand" "0")) 7056 (plus:<DWI> 7057 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 7058 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 7059 (zero_extend:<DWI> 7060 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))) 7061 (set (match_operand:SWI48 0 "register_operand" "=r") 7062 (minus:SWI48 (minus:SWI48 7063 (match_dup 1) 7064 (match_operator:SWI48 5 "ix86_carry_flag_operator" 7065 [(match_dup 3) (const_int 0)])) 7066 (match_dup 2)))] 7067 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 7068 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 7069 [(set_attr "type" "alu") 7070 (set_attr "use_carry" "1") 7071 (set_attr "pent_pair" "pu") 7072 (set_attr "mode" "<MODE>")]) 7073 7074(define_expand "subborrow<mode>_0" 7075 [(parallel 7076 [(set (reg:CC FLAGS_REG) 7077 (compare:CC 7078 (match_operand:SWI48 1 "nonimmediate_operand") 7079 (match_operand:SWI48 2 "<general_operand>"))) 7080 (set (match_operand:SWI48 0 "register_operand") 7081 (minus:SWI48 (match_dup 1) (match_dup 2)))])] 7082 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)") 7083 7084;; Overflow setting add instructions 7085 7086(define_expand "addqi3_cconly_overflow" 7087 [(parallel 7088 [(set (reg:CCC FLAGS_REG) 7089 (compare:CCC 7090 (plus:QI 7091 (match_operand:QI 0 "nonimmediate_operand") 7092 (match_operand:QI 1 "general_operand")) 7093 (match_dup 0))) 7094 (clobber (match_scratch:QI 2))])] 7095 "!(MEM_P (operands[0]) && MEM_P (operands[1]))") 7096 7097(define_insn "*add<mode>3_cconly_overflow_1" 7098 [(set (reg:CCC FLAGS_REG) 7099 (compare:CCC 7100 (plus:SWI 7101 (match_operand:SWI 1 "nonimmediate_operand" "%0") 7102 (match_operand:SWI 2 "<general_operand>" "<g>")) 7103 (match_dup 1))) 7104 (clobber (match_scratch:SWI 0 "=<r>"))] 7105 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7106 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 7107 [(set_attr "type" "alu") 7108 (set_attr "mode" "<MODE>")]) 7109 7110(define_insn "*add<mode>3_cc_overflow_1" 7111 [(set (reg:CCC FLAGS_REG) 7112 (compare:CCC 7113 (plus:SWI 7114 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 7115 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 7116 (match_dup 1))) 7117 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 7118 (plus:SWI (match_dup 1) (match_dup 2)))] 7119 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 7120 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 7121 [(set_attr "type" "alu") 7122 (set_attr "mode" "<MODE>")]) 7123 7124(define_insn "*addsi3_zext_cc_overflow_1" 7125 [(set (reg:CCC FLAGS_REG) 7126 (compare:CCC 7127 (plus:SI 7128 (match_operand:SI 1 "nonimmediate_operand" "%0") 7129 (match_operand:SI 2 "x86_64_general_operand" "rme")) 7130 (match_dup 1))) 7131 (set (match_operand:DI 0 "register_operand" "=r") 7132 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 7133 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 7134 "add{l}\t{%2, %k0|%k0, %2}" 7135 [(set_attr "type" "alu") 7136 (set_attr "mode" "SI")]) 7137 7138(define_insn "*add<mode>3_cconly_overflow_2" 7139 [(set (reg:CCC FLAGS_REG) 7140 (compare:CCC 7141 (plus:SWI 7142 (match_operand:SWI 1 "nonimmediate_operand" "%0") 7143 (match_operand:SWI 2 "<general_operand>" "<g>")) 7144 (match_dup 2))) 7145 (clobber (match_scratch:SWI 0 "=<r>"))] 7146 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7147 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 7148 [(set_attr "type" "alu") 7149 (set_attr "mode" "<MODE>")]) 7150 7151(define_insn "*add<mode>3_cc_overflow_2" 7152 [(set (reg:CCC FLAGS_REG) 7153 (compare:CCC 7154 (plus:SWI 7155 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 7156 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 7157 (match_dup 2))) 7158 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 7159 (plus:SWI (match_dup 1) (match_dup 2)))] 7160 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 7161 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 7162 [(set_attr "type" "alu") 7163 (set_attr "mode" "<MODE>")]) 7164 7165(define_insn "*addsi3_zext_cc_overflow_2" 7166 [(set (reg:CCC FLAGS_REG) 7167 (compare:CCC 7168 (plus:SI 7169 (match_operand:SI 1 "nonimmediate_operand" "%0") 7170 (match_operand:SI 2 "x86_64_general_operand" "rme")) 7171 (match_dup 2))) 7172 (set (match_operand:DI 0 "register_operand" "=r") 7173 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 7174 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 7175 "add{l}\t{%2, %k0|%k0, %2}" 7176 [(set_attr "type" "alu") 7177 (set_attr "mode" "SI")]) 7178 7179;; The patterns that match these are at the end of this file. 7180 7181(define_expand "<plusminus_insn>xf3" 7182 [(set (match_operand:XF 0 "register_operand") 7183 (plusminus:XF 7184 (match_operand:XF 1 "register_operand") 7185 (match_operand:XF 2 "register_operand")))] 7186 "TARGET_80387") 7187 7188(define_expand "<plusminus_insn><mode>3" 7189 [(set (match_operand:MODEF 0 "register_operand") 7190 (plusminus:MODEF 7191 (match_operand:MODEF 1 "register_operand") 7192 (match_operand:MODEF 2 "nonimmediate_operand")))] 7193 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7194 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 7195 7196;; Multiply instructions 7197 7198(define_expand "mul<mode>3" 7199 [(parallel [(set (match_operand:SWIM248 0 "register_operand") 7200 (mult:SWIM248 7201 (match_operand:SWIM248 1 "register_operand") 7202 (match_operand:SWIM248 2 "<general_operand>"))) 7203 (clobber (reg:CC FLAGS_REG))])]) 7204 7205(define_expand "mulqi3" 7206 [(parallel [(set (match_operand:QI 0 "register_operand") 7207 (mult:QI 7208 (match_operand:QI 1 "register_operand") 7209 (match_operand:QI 2 "nonimmediate_operand"))) 7210 (clobber (reg:CC FLAGS_REG))])] 7211 "TARGET_QIMODE_MATH") 7212 7213;; On AMDFAM10 7214;; IMUL reg32/64, reg32/64, imm8 Direct 7215;; IMUL reg32/64, mem32/64, imm8 VectorPath 7216;; IMUL reg32/64, reg32/64, imm32 Direct 7217;; IMUL reg32/64, mem32/64, imm32 VectorPath 7218;; IMUL reg32/64, reg32/64 Direct 7219;; IMUL reg32/64, mem32/64 Direct 7220;; 7221;; On BDVER1, all above IMULs use DirectPath 7222;; 7223;; On AMDFAM10 7224;; IMUL reg16, reg16, imm8 VectorPath 7225;; IMUL reg16, mem16, imm8 VectorPath 7226;; IMUL reg16, reg16, imm16 VectorPath 7227;; IMUL reg16, mem16, imm16 VectorPath 7228;; IMUL reg16, reg16 Direct 7229;; IMUL reg16, mem16 Direct 7230;; 7231;; On BDVER1, all HI MULs use DoublePath 7232 7233(define_insn "*mul<mode>3_1" 7234 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r") 7235 (mult:SWIM248 7236 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0") 7237 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr"))) 7238 (clobber (reg:CC FLAGS_REG))] 7239 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7240 "@ 7241 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 7242 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 7243 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 7244 [(set_attr "type" "imul") 7245 (set_attr "prefix_0f" "0,0,1") 7246 (set (attr "athlon_decode") 7247 (cond [(eq_attr "cpu" "athlon") 7248 (const_string "vector") 7249 (eq_attr "alternative" "1") 7250 (const_string "vector") 7251 (and (eq_attr "alternative" "2") 7252 (ior (match_test "<MODE>mode == HImode") 7253 (match_operand 1 "memory_operand"))) 7254 (const_string "vector")] 7255 (const_string "direct"))) 7256 (set (attr "amdfam10_decode") 7257 (cond [(and (eq_attr "alternative" "0,1") 7258 (ior (match_test "<MODE>mode == HImode") 7259 (match_operand 1 "memory_operand"))) 7260 (const_string "vector")] 7261 (const_string "direct"))) 7262 (set (attr "bdver1_decode") 7263 (if_then_else 7264 (match_test "<MODE>mode == HImode") 7265 (const_string "double") 7266 (const_string "direct"))) 7267 (set_attr "mode" "<MODE>")]) 7268 7269(define_insn "*mulsi3_1_zext" 7270 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 7271 (zero_extend:DI 7272 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 7273 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) 7274 (clobber (reg:CC FLAGS_REG))] 7275 "TARGET_64BIT 7276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7277 "@ 7278 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 7279 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 7280 imul{l}\t{%2, %k0|%k0, %2}" 7281 [(set_attr "type" "imul") 7282 (set_attr "prefix_0f" "0,0,1") 7283 (set (attr "athlon_decode") 7284 (cond [(eq_attr "cpu" "athlon") 7285 (const_string "vector") 7286 (eq_attr "alternative" "1") 7287 (const_string "vector") 7288 (and (eq_attr "alternative" "2") 7289 (match_operand 1 "memory_operand")) 7290 (const_string "vector")] 7291 (const_string "direct"))) 7292 (set (attr "amdfam10_decode") 7293 (cond [(and (eq_attr "alternative" "0,1") 7294 (match_operand 1 "memory_operand")) 7295 (const_string "vector")] 7296 (const_string "direct"))) 7297 (set_attr "bdver1_decode" "direct") 7298 (set_attr "mode" "SI")]) 7299 7300;;On AMDFAM10 and BDVER1 7301;; MUL reg8 Direct 7302;; MUL mem8 Direct 7303 7304(define_insn "*mulqi3_1" 7305 [(set (match_operand:QI 0 "register_operand" "=a") 7306 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 7307 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7308 (clobber (reg:CC FLAGS_REG))] 7309 "TARGET_QIMODE_MATH 7310 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7311 "mul{b}\t%2" 7312 [(set_attr "type" "imul") 7313 (set_attr "length_immediate" "0") 7314 (set (attr "athlon_decode") 7315 (if_then_else (eq_attr "cpu" "athlon") 7316 (const_string "vector") 7317 (const_string "direct"))) 7318 (set_attr "amdfam10_decode" "direct") 7319 (set_attr "bdver1_decode" "direct") 7320 (set_attr "mode" "QI")]) 7321 7322;; Multiply with jump on overflow. 7323(define_expand "mulv<mode>4" 7324 [(parallel [(set (reg:CCO FLAGS_REG) 7325 (eq:CCO (mult:<DWI> 7326 (sign_extend:<DWI> 7327 (match_operand:SWI248 1 "register_operand")) 7328 (match_dup 4)) 7329 (sign_extend:<DWI> 7330 (mult:SWI248 (match_dup 1) 7331 (match_operand:SWI248 2 7332 "<general_operand>"))))) 7333 (set (match_operand:SWI248 0 "register_operand") 7334 (mult:SWI248 (match_dup 1) (match_dup 2)))]) 7335 (set (pc) (if_then_else 7336 (eq (reg:CCO FLAGS_REG) (const_int 0)) 7337 (label_ref (match_operand 3)) 7338 (pc)))] 7339 "" 7340{ 7341 if (CONST_INT_P (operands[2])) 7342 operands[4] = operands[2]; 7343 else 7344 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]); 7345}) 7346 7347(define_insn "*mulv<mode>4" 7348 [(set (reg:CCO FLAGS_REG) 7349 (eq:CCO (mult:<DWI> 7350 (sign_extend:<DWI> 7351 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0")) 7352 (sign_extend:<DWI> 7353 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr"))) 7354 (sign_extend:<DWI> 7355 (mult:SWI48 (match_dup 1) (match_dup 2))))) 7356 (set (match_operand:SWI48 0 "register_operand" "=r,r") 7357 (mult:SWI48 (match_dup 1) (match_dup 2)))] 7358 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7359 "@ 7360 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 7361 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 7362 [(set_attr "type" "imul") 7363 (set_attr "prefix_0f" "0,1") 7364 (set (attr "athlon_decode") 7365 (cond [(eq_attr "cpu" "athlon") 7366 (const_string "vector") 7367 (eq_attr "alternative" "0") 7368 (const_string "vector") 7369 (and (eq_attr "alternative" "1") 7370 (match_operand 1 "memory_operand")) 7371 (const_string "vector")] 7372 (const_string "direct"))) 7373 (set (attr "amdfam10_decode") 7374 (cond [(and (eq_attr "alternative" "1") 7375 (match_operand 1 "memory_operand")) 7376 (const_string "vector")] 7377 (const_string "direct"))) 7378 (set_attr "bdver1_decode" "direct") 7379 (set_attr "mode" "<MODE>")]) 7380 7381(define_insn "*mulvhi4" 7382 [(set (reg:CCO FLAGS_REG) 7383 (eq:CCO (mult:SI 7384 (sign_extend:SI 7385 (match_operand:HI 1 "nonimmediate_operand" "%0")) 7386 (sign_extend:SI 7387 (match_operand:HI 2 "nonimmediate_operand" "mr"))) 7388 (sign_extend:SI 7389 (mult:HI (match_dup 1) (match_dup 2))))) 7390 (set (match_operand:HI 0 "register_operand" "=r") 7391 (mult:HI (match_dup 1) (match_dup 2)))] 7392 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7393 "imul{w}\t{%2, %0|%0, %2}" 7394 [(set_attr "type" "imul") 7395 (set_attr "prefix_0f" "1") 7396 (set_attr "athlon_decode" "vector") 7397 (set_attr "amdfam10_decode" "direct") 7398 (set_attr "bdver1_decode" "double") 7399 (set_attr "mode" "HI")]) 7400 7401(define_insn "*mulv<mode>4_1" 7402 [(set (reg:CCO FLAGS_REG) 7403 (eq:CCO (mult:<DWI> 7404 (sign_extend:<DWI> 7405 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm")) 7406 (match_operand:<DWI> 3 "const_int_operand" "K,i")) 7407 (sign_extend:<DWI> 7408 (mult:SWI248 (match_dup 1) 7409 (match_operand:SWI248 2 7410 "<immediate_operand>" "K,<i>"))))) 7411 (set (match_operand:SWI248 0 "register_operand" "=r,r") 7412 (mult:SWI248 (match_dup 1) (match_dup 2)))] 7413 "!(MEM_P (operands[1]) && MEM_P (operands[2])) 7414 && CONST_INT_P (operands[2]) 7415 && INTVAL (operands[2]) == INTVAL (operands[3])" 7416 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" 7417 [(set_attr "type" "imul") 7418 (set (attr "prefix_0f") 7419 (if_then_else 7420 (match_test "<MODE>mode == HImode") 7421 (const_string "0") 7422 (const_string "*"))) 7423 (set (attr "athlon_decode") 7424 (cond [(eq_attr "cpu" "athlon") 7425 (const_string "vector") 7426 (eq_attr "alternative" "1") 7427 (const_string "vector")] 7428 (const_string "direct"))) 7429 (set (attr "amdfam10_decode") 7430 (cond [(ior (match_test "<MODE>mode == HImode") 7431 (match_operand 1 "memory_operand")) 7432 (const_string "vector")] 7433 (const_string "direct"))) 7434 (set (attr "bdver1_decode") 7435 (if_then_else 7436 (match_test "<MODE>mode == HImode") 7437 (const_string "double") 7438 (const_string "direct"))) 7439 (set_attr "mode" "<MODE>") 7440 (set (attr "length_immediate") 7441 (cond [(eq_attr "alternative" "0") 7442 (const_string "1") 7443 (match_test "<MODE_SIZE> == 8") 7444 (const_string "4")] 7445 (const_string "<MODE_SIZE>")))]) 7446 7447(define_expand "umulv<mode>4" 7448 [(parallel [(set (reg:CCO FLAGS_REG) 7449 (eq:CCO (mult:<DWI> 7450 (zero_extend:<DWI> 7451 (match_operand:SWI248 1 7452 "nonimmediate_operand")) 7453 (zero_extend:<DWI> 7454 (match_operand:SWI248 2 7455 "nonimmediate_operand"))) 7456 (zero_extend:<DWI> 7457 (mult:SWI248 (match_dup 1) (match_dup 2))))) 7458 (set (match_operand:SWI248 0 "register_operand") 7459 (mult:SWI248 (match_dup 1) (match_dup 2))) 7460 (clobber (match_scratch:SWI248 4))]) 7461 (set (pc) (if_then_else 7462 (eq (reg:CCO FLAGS_REG) (const_int 0)) 7463 (label_ref (match_operand 3)) 7464 (pc)))] 7465 "" 7466{ 7467 if (MEM_P (operands[1]) && MEM_P (operands[2])) 7468 operands[1] = force_reg (<MODE>mode, operands[1]); 7469}) 7470 7471(define_insn "*umulv<mode>4" 7472 [(set (reg:CCO FLAGS_REG) 7473 (eq:CCO (mult:<DWI> 7474 (zero_extend:<DWI> 7475 (match_operand:SWI248 1 "nonimmediate_operand" "%0")) 7476 (zero_extend:<DWI> 7477 (match_operand:SWI248 2 "nonimmediate_operand" "rm"))) 7478 (zero_extend:<DWI> 7479 (mult:SWI248 (match_dup 1) (match_dup 2))))) 7480 (set (match_operand:SWI248 0 "register_operand" "=a") 7481 (mult:SWI248 (match_dup 1) (match_dup 2))) 7482 (clobber (match_scratch:SWI248 3 "=d"))] 7483 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7484 "mul{<imodesuffix>}\t%2" 7485 [(set_attr "type" "imul") 7486 (set_attr "length_immediate" "0") 7487 (set (attr "athlon_decode") 7488 (if_then_else (eq_attr "cpu" "athlon") 7489 (const_string "vector") 7490 (const_string "double"))) 7491 (set_attr "amdfam10_decode" "double") 7492 (set_attr "bdver1_decode" "direct") 7493 (set_attr "mode" "<MODE>")]) 7494 7495(define_expand "<u>mulvqi4" 7496 [(parallel [(set (reg:CCO FLAGS_REG) 7497 (eq:CCO (mult:HI 7498 (any_extend:HI 7499 (match_operand:QI 1 "nonimmediate_operand")) 7500 (any_extend:HI 7501 (match_operand:QI 2 "nonimmediate_operand"))) 7502 (any_extend:HI 7503 (mult:QI (match_dup 1) (match_dup 2))))) 7504 (set (match_operand:QI 0 "register_operand") 7505 (mult:QI (match_dup 1) (match_dup 2)))]) 7506 (set (pc) (if_then_else 7507 (eq (reg:CCO FLAGS_REG) (const_int 0)) 7508 (label_ref (match_operand 3)) 7509 (pc)))] 7510 "TARGET_QIMODE_MATH" 7511{ 7512 if (MEM_P (operands[1]) && MEM_P (operands[2])) 7513 operands[1] = force_reg (QImode, operands[1]); 7514}) 7515 7516(define_insn "*<u>mulvqi4" 7517 [(set (reg:CCO FLAGS_REG) 7518 (eq:CCO (mult:HI 7519 (any_extend:HI 7520 (match_operand:QI 1 "nonimmediate_operand" "%0")) 7521 (any_extend:HI 7522 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7523 (any_extend:HI 7524 (mult:QI (match_dup 1) (match_dup 2))))) 7525 (set (match_operand:QI 0 "register_operand" "=a") 7526 (mult:QI (match_dup 1) (match_dup 2)))] 7527 "TARGET_QIMODE_MATH 7528 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7529 "<sgnprefix>mul{b}\t%2" 7530 [(set_attr "type" "imul") 7531 (set_attr "length_immediate" "0") 7532 (set (attr "athlon_decode") 7533 (if_then_else (eq_attr "cpu" "athlon") 7534 (const_string "vector") 7535 (const_string "direct"))) 7536 (set_attr "amdfam10_decode" "direct") 7537 (set_attr "bdver1_decode" "direct") 7538 (set_attr "mode" "QI")]) 7539 7540(define_expand "<u>mul<mode><dwi>3" 7541 [(parallel [(set (match_operand:<DWI> 0 "register_operand") 7542 (mult:<DWI> 7543 (any_extend:<DWI> 7544 (match_operand:DWIH 1 "nonimmediate_operand")) 7545 (any_extend:<DWI> 7546 (match_operand:DWIH 2 "register_operand")))) 7547 (clobber (reg:CC FLAGS_REG))])]) 7548 7549(define_expand "<u>mulqihi3" 7550 [(parallel [(set (match_operand:HI 0 "register_operand") 7551 (mult:HI 7552 (any_extend:HI 7553 (match_operand:QI 1 "nonimmediate_operand")) 7554 (any_extend:HI 7555 (match_operand:QI 2 "register_operand")))) 7556 (clobber (reg:CC FLAGS_REG))])] 7557 "TARGET_QIMODE_MATH") 7558 7559(define_insn "*bmi2_umul<mode><dwi>3_1" 7560 [(set (match_operand:DWIH 0 "register_operand" "=r") 7561 (mult:DWIH 7562 (match_operand:DWIH 2 "nonimmediate_operand" "%d") 7563 (match_operand:DWIH 3 "nonimmediate_operand" "rm"))) 7564 (set (match_operand:DWIH 1 "register_operand" "=r") 7565 (truncate:DWIH 7566 (lshiftrt:<DWI> 7567 (mult:<DWI> (zero_extend:<DWI> (match_dup 2)) 7568 (zero_extend:<DWI> (match_dup 3))) 7569 (match_operand:QI 4 "const_int_operand" "n"))))] 7570 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT 7571 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7572 "mulx\t{%3, %0, %1|%1, %0, %3}" 7573 [(set_attr "type" "imulx") 7574 (set_attr "prefix" "vex") 7575 (set_attr "mode" "<MODE>")]) 7576 7577(define_insn "*umul<mode><dwi>3_1" 7578 [(set (match_operand:<DWI> 0 "register_operand" "=r,A") 7579 (mult:<DWI> 7580 (zero_extend:<DWI> 7581 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0")) 7582 (zero_extend:<DWI> 7583 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm")))) 7584 (clobber (reg:CC FLAGS_REG))] 7585 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7586 "@ 7587 # 7588 mul{<imodesuffix>}\t%2" 7589 [(set_attr "isa" "bmi2,*") 7590 (set_attr "type" "imulx,imul") 7591 (set_attr "length_immediate" "*,0") 7592 (set (attr "athlon_decode") 7593 (cond [(eq_attr "alternative" "1") 7594 (if_then_else (eq_attr "cpu" "athlon") 7595 (const_string "vector") 7596 (const_string "double"))] 7597 (const_string "*"))) 7598 (set_attr "amdfam10_decode" "*,double") 7599 (set_attr "bdver1_decode" "*,direct") 7600 (set_attr "prefix" "vex,orig") 7601 (set_attr "mode" "<MODE>")]) 7602 7603;; Convert mul to the mulx pattern to avoid flags dependency. 7604(define_split 7605 [(set (match_operand:<DWI> 0 "register_operand") 7606 (mult:<DWI> 7607 (zero_extend:<DWI> 7608 (match_operand:DWIH 1 "register_operand")) 7609 (zero_extend:<DWI> 7610 (match_operand:DWIH 2 "nonimmediate_operand")))) 7611 (clobber (reg:CC FLAGS_REG))] 7612 "TARGET_BMI2 && reload_completed 7613 && REGNO (operands[1]) == DX_REG" 7614 [(parallel [(set (match_dup 3) 7615 (mult:DWIH (match_dup 1) (match_dup 2))) 7616 (set (match_dup 4) 7617 (truncate:DWIH 7618 (lshiftrt:<DWI> 7619 (mult:<DWI> (zero_extend:<DWI> (match_dup 1)) 7620 (zero_extend:<DWI> (match_dup 2))) 7621 (match_dup 5))))])] 7622{ 7623 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]); 7624 7625 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); 7626}) 7627 7628(define_insn "*mul<mode><dwi>3_1" 7629 [(set (match_operand:<DWI> 0 "register_operand" "=A") 7630 (mult:<DWI> 7631 (sign_extend:<DWI> 7632 (match_operand:DWIH 1 "nonimmediate_operand" "%0")) 7633 (sign_extend:<DWI> 7634 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))) 7635 (clobber (reg:CC FLAGS_REG))] 7636 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7637 "imul{<imodesuffix>}\t%2" 7638 [(set_attr "type" "imul") 7639 (set_attr "length_immediate" "0") 7640 (set (attr "athlon_decode") 7641 (if_then_else (eq_attr "cpu" "athlon") 7642 (const_string "vector") 7643 (const_string "double"))) 7644 (set_attr "amdfam10_decode" "double") 7645 (set_attr "bdver1_decode" "direct") 7646 (set_attr "mode" "<MODE>")]) 7647 7648(define_insn "*<u>mulqihi3_1" 7649 [(set (match_operand:HI 0 "register_operand" "=a") 7650 (mult:HI 7651 (any_extend:HI 7652 (match_operand:QI 1 "nonimmediate_operand" "%0")) 7653 (any_extend:HI 7654 (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7655 (clobber (reg:CC FLAGS_REG))] 7656 "TARGET_QIMODE_MATH 7657 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7658 "<sgnprefix>mul{b}\t%2" 7659 [(set_attr "type" "imul") 7660 (set_attr "length_immediate" "0") 7661 (set (attr "athlon_decode") 7662 (if_then_else (eq_attr "cpu" "athlon") 7663 (const_string "vector") 7664 (const_string "direct"))) 7665 (set_attr "amdfam10_decode" "direct") 7666 (set_attr "bdver1_decode" "direct") 7667 (set_attr "mode" "QI")]) 7668 7669(define_expand "<s>mul<mode>3_highpart" 7670 [(parallel [(set (match_operand:SWI48 0 "register_operand") 7671 (truncate:SWI48 7672 (lshiftrt:<DWI> 7673 (mult:<DWI> 7674 (any_extend:<DWI> 7675 (match_operand:SWI48 1 "nonimmediate_operand")) 7676 (any_extend:<DWI> 7677 (match_operand:SWI48 2 "register_operand"))) 7678 (match_dup 3)))) 7679 (clobber (match_scratch:SWI48 4)) 7680 (clobber (reg:CC FLAGS_REG))])] 7681 "" 7682 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 7683 7684(define_insn "*<s>muldi3_highpart_1" 7685 [(set (match_operand:DI 0 "register_operand" "=d") 7686 (truncate:DI 7687 (lshiftrt:TI 7688 (mult:TI 7689 (any_extend:TI 7690 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7691 (any_extend:TI 7692 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7693 (const_int 64)))) 7694 (clobber (match_scratch:DI 3 "=1")) 7695 (clobber (reg:CC FLAGS_REG))] 7696 "TARGET_64BIT 7697 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7698 "<sgnprefix>mul{q}\t%2" 7699 [(set_attr "type" "imul") 7700 (set_attr "length_immediate" "0") 7701 (set (attr "athlon_decode") 7702 (if_then_else (eq_attr "cpu" "athlon") 7703 (const_string "vector") 7704 (const_string "double"))) 7705 (set_attr "amdfam10_decode" "double") 7706 (set_attr "bdver1_decode" "direct") 7707 (set_attr "mode" "DI")]) 7708 7709(define_insn "*<s>mulsi3_highpart_zext" 7710 [(set (match_operand:DI 0 "register_operand" "=d") 7711 (zero_extend:DI (truncate:SI 7712 (lshiftrt:DI 7713 (mult:DI (any_extend:DI 7714 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7715 (any_extend:DI 7716 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7717 (const_int 32))))) 7718 (clobber (match_scratch:SI 3 "=1")) 7719 (clobber (reg:CC FLAGS_REG))] 7720 "TARGET_64BIT 7721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7722 "<sgnprefix>mul{l}\t%2" 7723 [(set_attr "type" "imul") 7724 (set_attr "length_immediate" "0") 7725 (set (attr "athlon_decode") 7726 (if_then_else (eq_attr "cpu" "athlon") 7727 (const_string "vector") 7728 (const_string "double"))) 7729 (set_attr "amdfam10_decode" "double") 7730 (set_attr "bdver1_decode" "direct") 7731 (set_attr "mode" "SI")]) 7732 7733(define_insn "*<s>mulsi3_highpart_1" 7734 [(set (match_operand:SI 0 "register_operand" "=d") 7735 (truncate:SI 7736 (lshiftrt:DI 7737 (mult:DI 7738 (any_extend:DI 7739 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7740 (any_extend:DI 7741 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7742 (const_int 32)))) 7743 (clobber (match_scratch:SI 3 "=1")) 7744 (clobber (reg:CC FLAGS_REG))] 7745 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7746 "<sgnprefix>mul{l}\t%2" 7747 [(set_attr "type" "imul") 7748 (set_attr "length_immediate" "0") 7749 (set (attr "athlon_decode") 7750 (if_then_else (eq_attr "cpu" "athlon") 7751 (const_string "vector") 7752 (const_string "double"))) 7753 (set_attr "amdfam10_decode" "double") 7754 (set_attr "bdver1_decode" "direct") 7755 (set_attr "mode" "SI")]) 7756 7757;; The patterns that match these are at the end of this file. 7758 7759(define_expand "mulxf3" 7760 [(set (match_operand:XF 0 "register_operand") 7761 (mult:XF (match_operand:XF 1 "register_operand") 7762 (match_operand:XF 2 "register_operand")))] 7763 "TARGET_80387") 7764 7765(define_expand "mul<mode>3" 7766 [(set (match_operand:MODEF 0 "register_operand") 7767 (mult:MODEF (match_operand:MODEF 1 "register_operand") 7768 (match_operand:MODEF 2 "nonimmediate_operand")))] 7769 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7770 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 7771 7772;; Divide instructions 7773 7774;; The patterns that match these are at the end of this file. 7775 7776(define_expand "divxf3" 7777 [(set (match_operand:XF 0 "register_operand") 7778 (div:XF (match_operand:XF 1 "register_operand") 7779 (match_operand:XF 2 "register_operand")))] 7780 "TARGET_80387") 7781 7782(define_expand "div<mode>3" 7783 [(set (match_operand:MODEF 0 "register_operand") 7784 (div:MODEF (match_operand:MODEF 1 "register_operand") 7785 (match_operand:MODEF 2 "nonimmediate_operand")))] 7786 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7787 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 7788{ 7789 if (<MODE>mode == SFmode 7790 && TARGET_SSE && TARGET_SSE_MATH 7791 && TARGET_RECIP_DIV 7792 && optimize_insn_for_speed_p () 7793 && flag_finite_math_only && !flag_trapping_math 7794 && flag_unsafe_math_optimizations) 7795 { 7796 ix86_emit_swdivsf (operands[0], operands[1], 7797 operands[2], SFmode); 7798 DONE; 7799 } 7800}) 7801 7802;; Divmod instructions. 7803 7804(define_expand "divmod<mode>4" 7805 [(parallel [(set (match_operand:SWIM248 0 "register_operand") 7806 (div:SWIM248 7807 (match_operand:SWIM248 1 "register_operand") 7808 (match_operand:SWIM248 2 "nonimmediate_operand"))) 7809 (set (match_operand:SWIM248 3 "register_operand") 7810 (mod:SWIM248 (match_dup 1) (match_dup 2))) 7811 (clobber (reg:CC FLAGS_REG))])]) 7812 7813;; Split with 8bit unsigned divide: 7814;; if (dividend an divisor are in [0-255]) 7815;; use 8bit unsigned integer divide 7816;; else 7817;; use original integer divide 7818(define_split 7819 [(set (match_operand:SWI48 0 "register_operand") 7820 (div:SWI48 (match_operand:SWI48 2 "register_operand") 7821 (match_operand:SWI48 3 "nonimmediate_operand"))) 7822 (set (match_operand:SWI48 1 "register_operand") 7823 (mod:SWI48 (match_dup 2) (match_dup 3))) 7824 (clobber (reg:CC FLAGS_REG))] 7825 "TARGET_USE_8BIT_IDIV 7826 && TARGET_QIMODE_MATH 7827 && can_create_pseudo_p () 7828 && !optimize_insn_for_size_p ()" 7829 [(const_int 0)] 7830 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;") 7831 7832(define_split 7833 [(set (match_operand:DI 0 "register_operand") 7834 (zero_extend:DI 7835 (div:SI (match_operand:SI 2 "register_operand") 7836 (match_operand:SI 3 "nonimmediate_operand")))) 7837 (set (match_operand:SI 1 "register_operand") 7838 (mod:SI (match_dup 2) (match_dup 3))) 7839 (clobber (reg:CC FLAGS_REG))] 7840 "TARGET_USE_8BIT_IDIV 7841 && TARGET_QIMODE_MATH 7842 && can_create_pseudo_p () 7843 && !optimize_insn_for_size_p ()" 7844 [(const_int 0)] 7845 "ix86_split_idivmod (SImode, operands, true); DONE;") 7846 7847(define_split 7848 [(set (match_operand:DI 1 "register_operand") 7849 (zero_extend:DI 7850 (mod:SI (match_operand:SI 2 "register_operand") 7851 (match_operand:SI 3 "nonimmediate_operand")))) 7852 (set (match_operand:SI 0 "register_operand") 7853 (div:SI (match_dup 2) (match_dup 3))) 7854 (clobber (reg:CC FLAGS_REG))] 7855 "TARGET_USE_8BIT_IDIV 7856 && TARGET_QIMODE_MATH 7857 && can_create_pseudo_p () 7858 && !optimize_insn_for_size_p ()" 7859 [(const_int 0)] 7860 "ix86_split_idivmod (SImode, operands, true); DONE;") 7861 7862(define_insn_and_split "divmod<mode>4_1" 7863 [(set (match_operand:SWI48 0 "register_operand" "=a") 7864 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7865 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7866 (set (match_operand:SWI48 1 "register_operand" "=&d") 7867 (mod:SWI48 (match_dup 2) (match_dup 3))) 7868 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7869 (clobber (reg:CC FLAGS_REG))] 7870 "" 7871 "#" 7872 "reload_completed" 7873 [(parallel [(set (match_dup 1) 7874 (ashiftrt:SWI48 (match_dup 4) (match_dup 5))) 7875 (clobber (reg:CC FLAGS_REG))]) 7876 (parallel [(set (match_dup 0) 7877 (div:SWI48 (match_dup 2) (match_dup 3))) 7878 (set (match_dup 1) 7879 (mod:SWI48 (match_dup 2) (match_dup 3))) 7880 (use (match_dup 1)) 7881 (clobber (reg:CC FLAGS_REG))])] 7882{ 7883 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7884 7885 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 7886 operands[4] = operands[2]; 7887 else 7888 { 7889 /* Avoid use of cltd in favor of a mov+shift. */ 7890 emit_move_insn (operands[1], operands[2]); 7891 operands[4] = operands[1]; 7892 } 7893} 7894 [(set_attr "type" "multi") 7895 (set_attr "mode" "<MODE>")]) 7896 7897(define_insn_and_split "divmodsi4_zext_1" 7898 [(set (match_operand:DI 0 "register_operand" "=a") 7899 (zero_extend:DI 7900 (div:SI (match_operand:SI 2 "register_operand" "0") 7901 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 7902 (set (match_operand:SI 1 "register_operand" "=&d") 7903 (mod:SI (match_dup 2) (match_dup 3))) 7904 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7905 (clobber (reg:CC FLAGS_REG))] 7906 "TARGET_64BIT" 7907 "#" 7908 "reload_completed" 7909 [(parallel [(set (match_dup 1) 7910 (ashiftrt:SI (match_dup 4) (match_dup 5))) 7911 (clobber (reg:CC FLAGS_REG))]) 7912 (parallel [(set (match_dup 0) 7913 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3)))) 7914 (set (match_dup 1) 7915 (mod:SI (match_dup 2) (match_dup 3))) 7916 (use (match_dup 1)) 7917 (clobber (reg:CC FLAGS_REG))])] 7918{ 7919 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1); 7920 7921 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 7922 operands[4] = operands[2]; 7923 else 7924 { 7925 /* Avoid use of cltd in favor of a mov+shift. */ 7926 emit_move_insn (operands[1], operands[2]); 7927 operands[4] = operands[1]; 7928 } 7929} 7930 [(set_attr "type" "multi") 7931 (set_attr "mode" "SI")]) 7932 7933(define_insn_and_split "divmodsi4_zext_2" 7934 [(set (match_operand:DI 1 "register_operand" "=&d") 7935 (zero_extend:DI 7936 (mod:SI (match_operand:SI 2 "register_operand" "0") 7937 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 7938 (set (match_operand:SI 0 "register_operand" "=a") 7939 (div:SI (match_dup 2) (match_dup 3))) 7940 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7941 (clobber (reg:CC FLAGS_REG))] 7942 "TARGET_64BIT" 7943 "#" 7944 "reload_completed" 7945 [(parallel [(set (match_dup 6) 7946 (ashiftrt:SI (match_dup 4) (match_dup 5))) 7947 (clobber (reg:CC FLAGS_REG))]) 7948 (parallel [(set (match_dup 1) 7949 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3)))) 7950 (set (match_dup 0) 7951 (div:SI (match_dup 2) (match_dup 3))) 7952 (use (match_dup 6)) 7953 (clobber (reg:CC FLAGS_REG))])] 7954{ 7955 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1); 7956 operands[6] = gen_lowpart (SImode, operands[1]); 7957 7958 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 7959 operands[4] = operands[2]; 7960 else 7961 { 7962 /* Avoid use of cltd in favor of a mov+shift. */ 7963 emit_move_insn (operands[6], operands[2]); 7964 operands[4] = operands[6]; 7965 } 7966} 7967 [(set_attr "type" "multi") 7968 (set_attr "mode" "SI")]) 7969 7970(define_insn_and_split "*divmod<mode>4" 7971 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7972 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7973 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7974 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7975 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7976 (clobber (reg:CC FLAGS_REG))] 7977 "" 7978 "#" 7979 "reload_completed" 7980 [(parallel [(set (match_dup 1) 7981 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5))) 7982 (clobber (reg:CC FLAGS_REG))]) 7983 (parallel [(set (match_dup 0) 7984 (div:SWIM248 (match_dup 2) (match_dup 3))) 7985 (set (match_dup 1) 7986 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7987 (use (match_dup 1)) 7988 (clobber (reg:CC FLAGS_REG))])] 7989{ 7990 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7991 7992 if (<MODE>mode != HImode 7993 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)) 7994 operands[4] = operands[2]; 7995 else 7996 { 7997 /* Avoid use of cltd in favor of a mov+shift. */ 7998 emit_move_insn (operands[1], operands[2]); 7999 operands[4] = operands[1]; 8000 } 8001} 8002 [(set_attr "type" "multi") 8003 (set_attr "mode" "<MODE>")]) 8004 8005(define_insn_and_split "*divmodsi4_zext_1" 8006 [(set (match_operand:DI 0 "register_operand" "=a") 8007 (zero_extend:DI 8008 (div:SI (match_operand:SI 2 "register_operand" "0") 8009 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8010 (set (match_operand:SI 1 "register_operand" "=&d") 8011 (mod:SI (match_dup 2) (match_dup 3))) 8012 (clobber (reg:CC FLAGS_REG))] 8013 "TARGET_64BIT" 8014 "#" 8015 "reload_completed" 8016 [(parallel [(set (match_dup 1) 8017 (ashiftrt:SI (match_dup 4) (match_dup 5))) 8018 (clobber (reg:CC FLAGS_REG))]) 8019 (parallel [(set (match_dup 0) 8020 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3)))) 8021 (set (match_dup 1) 8022 (mod:SI (match_dup 2) (match_dup 3))) 8023 (use (match_dup 1)) 8024 (clobber (reg:CC FLAGS_REG))])] 8025{ 8026 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1); 8027 8028 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 8029 operands[4] = operands[2]; 8030 else 8031 { 8032 /* Avoid use of cltd in favor of a mov+shift. */ 8033 emit_move_insn (operands[1], operands[2]); 8034 operands[4] = operands[1]; 8035 } 8036} 8037 [(set_attr "type" "multi") 8038 (set_attr "mode" "SI")]) 8039 8040(define_insn_and_split "*divmodsi4_zext_2" 8041 [(set (match_operand:DI 1 "register_operand" "=&d") 8042 (zero_extend:DI 8043 (mod:SI (match_operand:SI 2 "register_operand" "0") 8044 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8045 (set (match_operand:SI 0 "register_operand" "=a") 8046 (div:SI (match_dup 2) (match_dup 3))) 8047 (clobber (reg:CC FLAGS_REG))] 8048 "TARGET_64BIT" 8049 "#" 8050 "reload_completed" 8051 [(parallel [(set (match_dup 6) 8052 (ashiftrt:SI (match_dup 4) (match_dup 5))) 8053 (clobber (reg:CC FLAGS_REG))]) 8054 (parallel [(set (match_dup 1) 8055 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3)))) 8056 (set (match_dup 0) 8057 (div:SI (match_dup 2) (match_dup 3))) 8058 (use (match_dup 6)) 8059 (clobber (reg:CC FLAGS_REG))])] 8060{ 8061 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1); 8062 operands[6] = gen_lowpart (SImode, operands[1]); 8063 8064 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 8065 operands[4] = operands[2]; 8066 else 8067 { 8068 /* Avoid use of cltd in favor of a mov+shift. */ 8069 emit_move_insn (operands[6], operands[2]); 8070 operands[4] = operands[6]; 8071 } 8072} 8073 [(set_attr "type" "multi") 8074 (set_attr "mode" "SI")]) 8075 8076(define_insn "*divmod<mode>4_noext" 8077 [(set (match_operand:SWIM248 0 "register_operand" "=a") 8078 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 8079 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 8080 (set (match_operand:SWIM248 1 "register_operand" "=d") 8081 (mod:SWIM248 (match_dup 2) (match_dup 3))) 8082 (use (match_operand:SWIM248 4 "register_operand" "1")) 8083 (clobber (reg:CC FLAGS_REG))] 8084 "" 8085 "idiv{<imodesuffix>}\t%3" 8086 [(set_attr "type" "idiv") 8087 (set_attr "mode" "<MODE>")]) 8088 8089(define_insn "*divmodsi4_noext_zext_1" 8090 [(set (match_operand:DI 0 "register_operand" "=a") 8091 (zero_extend:DI 8092 (div:SI (match_operand:SI 2 "register_operand" "0") 8093 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8094 (set (match_operand:SI 1 "register_operand" "=d") 8095 (mod:SI (match_dup 2) (match_dup 3))) 8096 (use (match_operand:SI 4 "register_operand" "1")) 8097 (clobber (reg:CC FLAGS_REG))] 8098 "TARGET_64BIT" 8099 "idiv{l}\t%3" 8100 [(set_attr "type" "idiv") 8101 (set_attr "mode" "SI")]) 8102 8103(define_insn "*divmodsi4_noext_zext_2" 8104 [(set (match_operand:DI 1 "register_operand" "=d") 8105 (zero_extend:DI 8106 (mod:SI (match_operand:SI 2 "register_operand" "0") 8107 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8108 (set (match_operand:SI 0 "register_operand" "=a") 8109 (div:SI (match_dup 2) (match_dup 3))) 8110 (use (match_operand:SI 4 "register_operand" "1")) 8111 (clobber (reg:CC FLAGS_REG))] 8112 "TARGET_64BIT" 8113 "idiv{l}\t%3" 8114 [(set_attr "type" "idiv") 8115 (set_attr "mode" "SI")]) 8116 8117(define_expand "divmodqi4" 8118 [(parallel [(set (match_operand:QI 0 "register_operand") 8119 (div:QI 8120 (match_operand:QI 1 "register_operand") 8121 (match_operand:QI 2 "nonimmediate_operand"))) 8122 (set (match_operand:QI 3 "register_operand") 8123 (mod:QI (match_dup 1) (match_dup 2))) 8124 (clobber (reg:CC FLAGS_REG))])] 8125 "TARGET_QIMODE_MATH" 8126{ 8127 rtx div, mod; 8128 rtx tmp0, tmp1; 8129 8130 tmp0 = gen_reg_rtx (HImode); 8131 tmp1 = gen_reg_rtx (HImode); 8132 8133 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */ 8134 emit_insn (gen_extendqihi2 (tmp1, operands[1])); 8135 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2])); 8136 8137 /* Extract remainder from AH. */ 8138 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8)); 8139 tmp1 = lowpart_subreg (QImode, tmp1, SImode); 8140 rtx_insn *insn = emit_move_insn (operands[3], tmp1); 8141 8142 mod = gen_rtx_MOD (QImode, operands[1], operands[2]); 8143 set_unique_reg_note (insn, REG_EQUAL, mod); 8144 8145 /* Extract quotient from AL. */ 8146 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 8147 8148 div = gen_rtx_DIV (QImode, operands[1], operands[2]); 8149 set_unique_reg_note (insn, REG_EQUAL, div); 8150 8151 DONE; 8152}) 8153 8154;; Divide AX by r/m8, with result stored in 8155;; AL <- Quotient 8156;; AH <- Remainder 8157;; Change div/mod to HImode and extend the second argument to HImode 8158;; so that mode of div/mod matches with mode of arguments. Otherwise 8159;; combine may fail. 8160(define_insn "divmodhiqi3" 8161 [(set (match_operand:HI 0 "register_operand" "=a") 8162 (ior:HI 8163 (ashift:HI 8164 (zero_extend:HI 8165 (truncate:QI 8166 (mod:HI (match_operand:HI 1 "register_operand" "0") 8167 (sign_extend:HI 8168 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 8169 (const_int 8)) 8170 (zero_extend:HI 8171 (truncate:QI 8172 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2))))))) 8173 (clobber (reg:CC FLAGS_REG))] 8174 "TARGET_QIMODE_MATH" 8175 "idiv{b}\t%2" 8176 [(set_attr "type" "idiv") 8177 (set_attr "mode" "QI")]) 8178 8179(define_expand "udivmod<mode>4" 8180 [(parallel [(set (match_operand:SWIM248 0 "register_operand") 8181 (udiv:SWIM248 8182 (match_operand:SWIM248 1 "register_operand") 8183 (match_operand:SWIM248 2 "nonimmediate_operand"))) 8184 (set (match_operand:SWIM248 3 "register_operand") 8185 (umod:SWIM248 (match_dup 1) (match_dup 2))) 8186 (clobber (reg:CC FLAGS_REG))])]) 8187 8188;; Split with 8bit unsigned divide: 8189;; if (dividend an divisor are in [0-255]) 8190;; use 8bit unsigned integer divide 8191;; else 8192;; use original integer divide 8193(define_split 8194 [(set (match_operand:SWI48 0 "register_operand") 8195 (udiv:SWI48 (match_operand:SWI48 2 "register_operand") 8196 (match_operand:SWI48 3 "nonimmediate_operand"))) 8197 (set (match_operand:SWI48 1 "register_operand") 8198 (umod:SWI48 (match_dup 2) (match_dup 3))) 8199 (clobber (reg:CC FLAGS_REG))] 8200 "TARGET_USE_8BIT_IDIV 8201 && TARGET_QIMODE_MATH 8202 && can_create_pseudo_p () 8203 && !optimize_insn_for_size_p ()" 8204 [(const_int 0)] 8205 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;") 8206 8207(define_split 8208 [(set (match_operand:DI 0 "register_operand") 8209 (zero_extend:DI 8210 (udiv:SI (match_operand:SI 2 "register_operand") 8211 (match_operand:SI 3 "nonimmediate_operand")))) 8212 (set (match_operand:SI 1 "register_operand") 8213 (umod:SI (match_dup 2) (match_dup 3))) 8214 (clobber (reg:CC FLAGS_REG))] 8215 "TARGET_64BIT 8216 && TARGET_USE_8BIT_IDIV 8217 && TARGET_QIMODE_MATH 8218 && can_create_pseudo_p () 8219 && !optimize_insn_for_size_p ()" 8220 [(const_int 0)] 8221 "ix86_split_idivmod (SImode, operands, false); DONE;") 8222 8223(define_split 8224 [(set (match_operand:DI 1 "register_operand") 8225 (zero_extend:DI 8226 (umod:SI (match_operand:SI 2 "register_operand") 8227 (match_operand:SI 3 "nonimmediate_operand")))) 8228 (set (match_operand:SI 0 "register_operand") 8229 (udiv:SI (match_dup 2) (match_dup 3))) 8230 (clobber (reg:CC FLAGS_REG))] 8231 "TARGET_64BIT 8232 && TARGET_USE_8BIT_IDIV 8233 && TARGET_QIMODE_MATH 8234 && can_create_pseudo_p () 8235 && !optimize_insn_for_size_p ()" 8236 [(const_int 0)] 8237 "ix86_split_idivmod (SImode, operands, false); DONE;") 8238 8239(define_insn_and_split "udivmod<mode>4_1" 8240 [(set (match_operand:SWI48 0 "register_operand" "=a") 8241 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 8242 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 8243 (set (match_operand:SWI48 1 "register_operand" "=&d") 8244 (umod:SWI48 (match_dup 2) (match_dup 3))) 8245 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8246 (clobber (reg:CC FLAGS_REG))] 8247 "" 8248 "#" 8249 "reload_completed" 8250 [(set (match_dup 1) (const_int 0)) 8251 (parallel [(set (match_dup 0) 8252 (udiv:SWI48 (match_dup 2) (match_dup 3))) 8253 (set (match_dup 1) 8254 (umod:SWI48 (match_dup 2) (match_dup 3))) 8255 (use (match_dup 1)) 8256 (clobber (reg:CC FLAGS_REG))])] 8257 "" 8258 [(set_attr "type" "multi") 8259 (set_attr "mode" "<MODE>")]) 8260 8261(define_insn_and_split "udivmodsi4_zext_1" 8262 [(set (match_operand:DI 0 "register_operand" "=a") 8263 (zero_extend:DI 8264 (udiv:SI (match_operand:SI 2 "register_operand" "0") 8265 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8266 (set (match_operand:SI 1 "register_operand" "=&d") 8267 (umod:SI (match_dup 2) (match_dup 3))) 8268 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8269 (clobber (reg:CC FLAGS_REG))] 8270 "TARGET_64BIT" 8271 "#" 8272 "reload_completed" 8273 [(set (match_dup 1) (const_int 0)) 8274 (parallel [(set (match_dup 0) 8275 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) 8276 (set (match_dup 1) 8277 (umod:SI (match_dup 2) (match_dup 3))) 8278 (use (match_dup 1)) 8279 (clobber (reg:CC FLAGS_REG))])] 8280 "" 8281 [(set_attr "type" "multi") 8282 (set_attr "mode" "SI")]) 8283 8284(define_insn_and_split "udivmodsi4_zext_2" 8285 [(set (match_operand:DI 1 "register_operand" "=&d") 8286 (zero_extend:DI 8287 (umod:SI (match_operand:SI 2 "register_operand" "0") 8288 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8289 (set (match_operand:SI 0 "register_operand" "=a") 8290 (udiv:SI (match_dup 2) (match_dup 3))) 8291 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8292 (clobber (reg:CC FLAGS_REG))] 8293 "TARGET_64BIT" 8294 "#" 8295 "reload_completed" 8296 [(set (match_dup 4) (const_int 0)) 8297 (parallel [(set (match_dup 1) 8298 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) 8299 (set (match_dup 0) 8300 (udiv:SI (match_dup 2) (match_dup 3))) 8301 (use (match_dup 4)) 8302 (clobber (reg:CC FLAGS_REG))])] 8303 "operands[4] = gen_lowpart (SImode, operands[1]);" 8304 [(set_attr "type" "multi") 8305 (set_attr "mode" "SI")]) 8306 8307(define_insn_and_split "*udivmod<mode>4" 8308 [(set (match_operand:SWIM248 0 "register_operand" "=a") 8309 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 8310 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 8311 (set (match_operand:SWIM248 1 "register_operand" "=&d") 8312 (umod:SWIM248 (match_dup 2) (match_dup 3))) 8313 (clobber (reg:CC FLAGS_REG))] 8314 "" 8315 "#" 8316 "reload_completed" 8317 [(set (match_dup 1) (const_int 0)) 8318 (parallel [(set (match_dup 0) 8319 (udiv:SWIM248 (match_dup 2) (match_dup 3))) 8320 (set (match_dup 1) 8321 (umod:SWIM248 (match_dup 2) (match_dup 3))) 8322 (use (match_dup 1)) 8323 (clobber (reg:CC FLAGS_REG))])] 8324 "" 8325 [(set_attr "type" "multi") 8326 (set_attr "mode" "<MODE>")]) 8327 8328(define_insn_and_split "*udivmodsi4_zext_1" 8329 [(set (match_operand:DI 0 "register_operand" "=a") 8330 (zero_extend:DI 8331 (udiv:SI (match_operand:SI 2 "register_operand" "0") 8332 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8333 (set (match_operand:SI 1 "register_operand" "=&d") 8334 (umod:SI (match_dup 2) (match_dup 3))) 8335 (clobber (reg:CC FLAGS_REG))] 8336 "TARGET_64BIT" 8337 "#" 8338 "reload_completed" 8339 [(set (match_dup 1) (const_int 0)) 8340 (parallel [(set (match_dup 0) 8341 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) 8342 (set (match_dup 1) 8343 (umod:SI (match_dup 2) (match_dup 3))) 8344 (use (match_dup 1)) 8345 (clobber (reg:CC FLAGS_REG))])] 8346 "" 8347 [(set_attr "type" "multi") 8348 (set_attr "mode" "SI")]) 8349 8350(define_insn_and_split "*udivmodsi4_zext_2" 8351 [(set (match_operand:DI 1 "register_operand" "=&d") 8352 (zero_extend:DI 8353 (umod:SI (match_operand:SI 2 "register_operand" "0") 8354 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8355 (set (match_operand:SI 0 "register_operand" "=a") 8356 (udiv:SI (match_dup 2) (match_dup 3))) 8357 (clobber (reg:CC FLAGS_REG))] 8358 "TARGET_64BIT" 8359 "#" 8360 "reload_completed" 8361 [(set (match_dup 4) (const_int 0)) 8362 (parallel [(set (match_dup 1) 8363 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) 8364 (set (match_dup 0) 8365 (udiv:SI (match_dup 2) (match_dup 3))) 8366 (use (match_dup 4)) 8367 (clobber (reg:CC FLAGS_REG))])] 8368 "operands[4] = gen_lowpart (SImode, operands[1]);" 8369 [(set_attr "type" "multi") 8370 (set_attr "mode" "SI")]) 8371 8372;; Optimize division or modulo by constant power of 2, if the constant 8373;; materializes only after expansion. 8374(define_insn_and_split "*udivmod<mode>4_pow2" 8375 [(set (match_operand:SWI48 0 "register_operand" "=r") 8376 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 8377 (match_operand:SWI48 3 "const_int_operand" "n"))) 8378 (set (match_operand:SWI48 1 "register_operand" "=r") 8379 (umod:SWI48 (match_dup 2) (match_dup 3))) 8380 (clobber (reg:CC FLAGS_REG))] 8381 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) 8382 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" 8383 "#" 8384 "&& 1" 8385 [(set (match_dup 1) (match_dup 2)) 8386 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4))) 8387 (clobber (reg:CC FLAGS_REG))]) 8388 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5))) 8389 (clobber (reg:CC FLAGS_REG))])] 8390{ 8391 int v = exact_log2 (UINTVAL (operands[3])); 8392 operands[4] = GEN_INT (v); 8393 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); 8394} 8395 [(set_attr "type" "multi") 8396 (set_attr "mode" "<MODE>")]) 8397 8398(define_insn_and_split "*udivmodsi4_pow2_zext_1" 8399 [(set (match_operand:DI 0 "register_operand" "=r") 8400 (zero_extend:DI 8401 (udiv:SI (match_operand:SI 2 "register_operand" "0") 8402 (match_operand:SI 3 "const_int_operand" "n")))) 8403 (set (match_operand:SI 1 "register_operand" "=r") 8404 (umod:SI (match_dup 2) (match_dup 3))) 8405 (clobber (reg:CC FLAGS_REG))] 8406 "TARGET_64BIT 8407 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) 8408 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" 8409 "#" 8410 "&& 1" 8411 [(set (match_dup 1) (match_dup 2)) 8412 (parallel [(set (match_dup 0) 8413 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4)))) 8414 (clobber (reg:CC FLAGS_REG))]) 8415 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5))) 8416 (clobber (reg:CC FLAGS_REG))])] 8417{ 8418 int v = exact_log2 (UINTVAL (operands[3])); 8419 operands[4] = GEN_INT (v); 8420 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); 8421} 8422 [(set_attr "type" "multi") 8423 (set_attr "mode" "SI")]) 8424 8425(define_insn_and_split "*udivmodsi4_pow2_zext_2" 8426 [(set (match_operand:DI 1 "register_operand" "=r") 8427 (zero_extend:DI 8428 (umod:SI (match_operand:SI 2 "register_operand" "0") 8429 (match_operand:SI 3 "const_int_operand" "n")))) 8430 (set (match_operand:SI 0 "register_operand" "=r") 8431 (umod:SI (match_dup 2) (match_dup 3))) 8432 (clobber (reg:CC FLAGS_REG))] 8433 "TARGET_64BIT 8434 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) 8435 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" 8436 "#" 8437 "&& 1" 8438 [(set (match_dup 1) (match_dup 2)) 8439 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4))) 8440 (clobber (reg:CC FLAGS_REG))]) 8441 (parallel [(set (match_dup 1) 8442 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5)))) 8443 (clobber (reg:CC FLAGS_REG))])] 8444{ 8445 int v = exact_log2 (UINTVAL (operands[3])); 8446 operands[4] = GEN_INT (v); 8447 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); 8448} 8449 [(set_attr "type" "multi") 8450 (set_attr "mode" "SI")]) 8451 8452(define_insn "*udivmod<mode>4_noext" 8453 [(set (match_operand:SWIM248 0 "register_operand" "=a") 8454 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 8455 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 8456 (set (match_operand:SWIM248 1 "register_operand" "=d") 8457 (umod:SWIM248 (match_dup 2) (match_dup 3))) 8458 (use (match_operand:SWIM248 4 "register_operand" "1")) 8459 (clobber (reg:CC FLAGS_REG))] 8460 "" 8461 "div{<imodesuffix>}\t%3" 8462 [(set_attr "type" "idiv") 8463 (set_attr "mode" "<MODE>")]) 8464 8465(define_insn "*udivmodsi4_noext_zext_1" 8466 [(set (match_operand:DI 0 "register_operand" "=a") 8467 (zero_extend:DI 8468 (udiv:SI (match_operand:SI 2 "register_operand" "0") 8469 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8470 (set (match_operand:SI 1 "register_operand" "=d") 8471 (umod:SI (match_dup 2) (match_dup 3))) 8472 (use (match_operand:SI 4 "register_operand" "1")) 8473 (clobber (reg:CC FLAGS_REG))] 8474 "TARGET_64BIT" 8475 "div{l}\t%3" 8476 [(set_attr "type" "idiv") 8477 (set_attr "mode" "SI")]) 8478 8479(define_insn "*udivmodsi4_noext_zext_2" 8480 [(set (match_operand:DI 1 "register_operand" "=d") 8481 (zero_extend:DI 8482 (umod:SI (match_operand:SI 2 "register_operand" "0") 8483 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8484 (set (match_operand:SI 0 "register_operand" "=a") 8485 (udiv:SI (match_dup 2) (match_dup 3))) 8486 (use (match_operand:SI 4 "register_operand" "1")) 8487 (clobber (reg:CC FLAGS_REG))] 8488 "TARGET_64BIT" 8489 "div{l}\t%3" 8490 [(set_attr "type" "idiv") 8491 (set_attr "mode" "SI")]) 8492 8493(define_expand "udivmodqi4" 8494 [(parallel [(set (match_operand:QI 0 "register_operand") 8495 (udiv:QI 8496 (match_operand:QI 1 "register_operand") 8497 (match_operand:QI 2 "nonimmediate_operand"))) 8498 (set (match_operand:QI 3 "register_operand") 8499 (umod:QI (match_dup 1) (match_dup 2))) 8500 (clobber (reg:CC FLAGS_REG))])] 8501 "TARGET_QIMODE_MATH" 8502{ 8503 rtx div, mod; 8504 rtx tmp0, tmp1; 8505 8506 tmp0 = gen_reg_rtx (HImode); 8507 tmp1 = gen_reg_rtx (HImode); 8508 8509 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */ 8510 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1])); 8511 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2])); 8512 8513 /* Extract remainder from AH. */ 8514 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8)); 8515 tmp1 = lowpart_subreg (QImode, tmp1, SImode); 8516 rtx_insn *insn = emit_move_insn (operands[3], tmp1); 8517 8518 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]); 8519 set_unique_reg_note (insn, REG_EQUAL, mod); 8520 8521 /* Extract quotient from AL. */ 8522 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 8523 8524 div = gen_rtx_UDIV (QImode, operands[1], operands[2]); 8525 set_unique_reg_note (insn, REG_EQUAL, div); 8526 8527 DONE; 8528}) 8529 8530(define_insn "udivmodhiqi3" 8531 [(set (match_operand:HI 0 "register_operand" "=a") 8532 (ior:HI 8533 (ashift:HI 8534 (zero_extend:HI 8535 (truncate:QI 8536 (mod:HI (match_operand:HI 1 "register_operand" "0") 8537 (zero_extend:HI 8538 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 8539 (const_int 8)) 8540 (zero_extend:HI 8541 (truncate:QI 8542 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2))))))) 8543 (clobber (reg:CC FLAGS_REG))] 8544 "TARGET_QIMODE_MATH" 8545 "div{b}\t%2" 8546 [(set_attr "type" "idiv") 8547 (set_attr "mode" "QI")]) 8548 8549;; We cannot use div/idiv for double division, because it causes 8550;; "division by zero" on the overflow and that's not what we expect 8551;; from truncate. Because true (non truncating) double division is 8552;; never generated, we can't create this insn anyway. 8553; 8554;(define_insn "" 8555; [(set (match_operand:SI 0 "register_operand" "=a") 8556; (truncate:SI 8557; (udiv:DI (match_operand:DI 1 "register_operand" "A") 8558; (zero_extend:DI 8559; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 8560; (set (match_operand:SI 3 "register_operand" "=d") 8561; (truncate:SI 8562; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 8563; (clobber (reg:CC FLAGS_REG))] 8564; "" 8565; "div{l}\t{%2, %0|%0, %2}" 8566; [(set_attr "type" "idiv")]) 8567 8568;;- Logical AND instructions 8569 8570;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 8571;; Note that this excludes ah. 8572 8573(define_expand "testsi_ccno_1" 8574 [(set (reg:CCNO FLAGS_REG) 8575 (compare:CCNO 8576 (and:SI (match_operand:SI 0 "nonimmediate_operand") 8577 (match_operand:SI 1 "x86_64_nonmemory_operand")) 8578 (const_int 0)))]) 8579 8580(define_expand "testqi_ccz_1" 8581 [(set (reg:CCZ FLAGS_REG) 8582 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand") 8583 (match_operand:QI 1 "nonmemory_operand")) 8584 (const_int 0)))]) 8585 8586(define_expand "testdi_ccno_1" 8587 [(set (reg:CCNO FLAGS_REG) 8588 (compare:CCNO 8589 (and:DI (match_operand:DI 0 "nonimmediate_operand") 8590 (match_operand:DI 1 "x86_64_szext_general_operand")) 8591 (const_int 0)))] 8592 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))") 8593 8594(define_insn "*testdi_1" 8595 [(set (reg FLAGS_REG) 8596 (compare 8597 (and:DI 8598 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 8599 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 8600 (const_int 0)))] 8601 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8602 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8603 "@ 8604 test{l}\t{%k1, %k0|%k0, %k1} 8605 test{l}\t{%k1, %k0|%k0, %k1} 8606 test{q}\t{%1, %0|%0, %1} 8607 test{q}\t{%1, %0|%0, %1} 8608 test{q}\t{%1, %0|%0, %1}" 8609 [(set_attr "type" "test") 8610 (set_attr "modrm" "0,1,0,1,1") 8611 (set_attr "mode" "SI,SI,DI,DI,DI")]) 8612 8613(define_insn "*testqi_1_maybe_si" 8614 [(set (reg FLAGS_REG) 8615 (compare 8616 (and:QI 8617 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 8618 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 8619 (const_int 0)))] 8620 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 8621 && ix86_match_ccmode (insn, 8622 CONST_INT_P (operands[1]) 8623 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 8624{ 8625 if (which_alternative == 3) 8626 { 8627 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0) 8628 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 8629 return "test{l}\t{%1, %k0|%k0, %1}"; 8630 } 8631 return "test{b}\t{%1, %0|%0, %1}"; 8632} 8633 [(set_attr "type" "test") 8634 (set_attr "modrm" "0,1,1,1") 8635 (set_attr "mode" "QI,QI,QI,SI") 8636 (set_attr "pent_pair" "uv,np,uv,np")]) 8637 8638(define_insn "*test<mode>_1" 8639 [(set (reg FLAGS_REG) 8640 (compare 8641 (and:SWI124 8642 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m") 8643 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>")) 8644 (const_int 0)))] 8645 "ix86_match_ccmode (insn, CCNOmode) 8646 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8647 "test{<imodesuffix>}\t{%1, %0|%0, %1}" 8648 [(set_attr "type" "test") 8649 (set_attr "modrm" "0,1,1") 8650 (set_attr "mode" "<MODE>") 8651 (set_attr "pent_pair" "uv,np,uv")]) 8652 8653(define_expand "testqi_ext_1_ccno" 8654 [(set (reg:CCNO FLAGS_REG) 8655 (compare:CCNO 8656 (and:QI 8657 (subreg:QI 8658 (zero_extract:SI (match_operand 0 "ext_register_operand") 8659 (const_int 8) 8660 (const_int 8)) 0) 8661 (match_operand 1 "const_int_operand")) 8662 (const_int 0)))]) 8663 8664(define_insn "*testqi_ext_1" 8665 [(set (reg FLAGS_REG) 8666 (compare 8667 (and:QI 8668 (subreg:QI 8669 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q") 8670 (const_int 8) 8671 (const_int 8)) 0) 8672 (match_operand:QI 1 "general_operand" "QnBc,m")) 8673 (const_int 0)))] 8674 "ix86_match_ccmode (insn, CCNOmode)" 8675 "test{b}\t{%1, %h0|%h0, %1}" 8676 [(set_attr "isa" "*,nox64") 8677 (set_attr "type" "test") 8678 (set_attr "mode" "QI")]) 8679 8680(define_insn "*testqi_ext_2" 8681 [(set (reg FLAGS_REG) 8682 (compare 8683 (and:QI 8684 (subreg:QI 8685 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q") 8686 (const_int 8) 8687 (const_int 8)) 0) 8688 (subreg:QI 8689 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 8690 (const_int 8) 8691 (const_int 8)) 0)) 8692 (const_int 0)))] 8693 "ix86_match_ccmode (insn, CCNOmode)" 8694 "test{b}\t{%h1, %h0|%h0, %h1}" 8695 [(set_attr "type" "test") 8696 (set_attr "mode" "QI")]) 8697 8698;; Combine likes to form bit extractions for some tests. Humor it. 8699(define_insn_and_split "*testqi_ext_3" 8700 [(set (match_operand 0 "flags_reg_operand") 8701 (match_operator 1 "compare_operator" 8702 [(zero_extract:SWI248 8703 (match_operand 2 "nonimmediate_operand" "rm") 8704 (match_operand 3 "const_int_operand" "n") 8705 (match_operand 4 "const_int_operand" "n")) 8706 (const_int 0)]))] 8707 "ix86_match_ccmode (insn, CCNOmode) 8708 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode) 8709 || GET_MODE (operands[2]) == SImode 8710 || GET_MODE (operands[2]) == HImode 8711 || GET_MODE (operands[2]) == QImode) 8712 /* Ensure that resulting mask is zero or sign extended operand. */ 8713 && INTVAL (operands[4]) >= 0 8714 && ((INTVAL (operands[3]) > 0 8715 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32) 8716 || (<MODE>mode == DImode 8717 && INTVAL (operands[3]) > 32 8718 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))" 8719 "#" 8720 "&& 1" 8721 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 8722{ 8723 rtx val = operands[2]; 8724 HOST_WIDE_INT len = INTVAL (operands[3]); 8725 HOST_WIDE_INT pos = INTVAL (operands[4]); 8726 machine_mode mode = GET_MODE (val); 8727 8728 if (SUBREG_P (val)) 8729 { 8730 machine_mode submode = GET_MODE (SUBREG_REG (val)); 8731 8732 /* Narrow paradoxical subregs to prevent partial register stalls. */ 8733 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode) 8734 && GET_MODE_CLASS (submode) == MODE_INT) 8735 { 8736 val = SUBREG_REG (val); 8737 mode = submode; 8738 } 8739 } 8740 8741 /* Small HImode tests can be converted to QImode. */ 8742 if (register_operand (val, HImode) && pos + len <= 8) 8743 { 8744 val = gen_lowpart (QImode, val); 8745 mode = QImode; 8746 } 8747 8748 gcc_assert (pos + len <= GET_MODE_PRECISION (mode)); 8749 8750 wide_int mask 8751 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode)); 8752 8753 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode)); 8754}) 8755 8756;; Convert HImode/SImode test instructions with immediate to QImode ones. 8757;; i386 does not allow to encode test with 8bit sign extended immediate, so 8758;; this is relatively important trick. 8759;; Do the conversion only post-reload to avoid limiting of the register class 8760;; to QI regs. 8761(define_split 8762 [(set (match_operand 0 "flags_reg_operand") 8763 (match_operator 1 "compare_operator" 8764 [(and (match_operand 2 "QIreg_operand") 8765 (match_operand 3 "const_int_operand")) 8766 (const_int 0)]))] 8767 "reload_completed 8768 && GET_MODE (operands[2]) != QImode 8769 && ((ix86_match_ccmode (insn, CCZmode) 8770 && !(INTVAL (operands[3]) & ~(255 << 8))) 8771 || (ix86_match_ccmode (insn, CCNOmode) 8772 && !(INTVAL (operands[3]) & ~(127 << 8))))" 8773 [(set (match_dup 0) 8774 (match_op_dup 1 8775 [(and:QI 8776 (subreg:QI 8777 (zero_extract:SI (match_dup 2) 8778 (const_int 8) 8779 (const_int 8)) 0) 8780 (match_dup 3)) 8781 (const_int 0)]))] 8782{ 8783 operands[2] = gen_lowpart (SImode, operands[2]); 8784 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode); 8785}) 8786 8787(define_split 8788 [(set (match_operand 0 "flags_reg_operand") 8789 (match_operator 1 "compare_operator" 8790 [(and (match_operand 2 "nonimmediate_operand") 8791 (match_operand 3 "const_int_operand")) 8792 (const_int 0)]))] 8793 "reload_completed 8794 && GET_MODE (operands[2]) != QImode 8795 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 8796 && ((ix86_match_ccmode (insn, CCZmode) 8797 && !(INTVAL (operands[3]) & ~255)) 8798 || (ix86_match_ccmode (insn, CCNOmode) 8799 && !(INTVAL (operands[3]) & ~127)))" 8800 [(set (match_dup 0) 8801 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 8802 (const_int 0)]))] 8803{ 8804 operands[2] = gen_lowpart (QImode, operands[2]); 8805 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode); 8806}) 8807 8808;; %%% This used to optimize known byte-wide and operations to memory, 8809;; and sometimes to QImode registers. If this is considered useful, 8810;; it should be done with splitters. 8811 8812(define_expand "and<mode>3" 8813 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand") 8814 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand") 8815 (match_operand:SWIM1248x 2 "<general_szext_operand>")))] 8816 "" 8817{ 8818 machine_mode mode = <MODE>mode; 8819 rtx (*insn) (rtx, rtx); 8820 8821 if (CONST_INT_P (operands[2]) && REG_P (operands[0])) 8822 { 8823 HOST_WIDE_INT ival = INTVAL (operands[2]); 8824 8825 if (ival == (HOST_WIDE_INT) 0xffffffff) 8826 mode = SImode; 8827 else if (ival == 0xffff) 8828 mode = HImode; 8829 else if (ival == 0xff) 8830 mode = QImode; 8831 } 8832 8833 if (mode == <MODE>mode) 8834 { 8835 ix86_expand_binary_operator (AND, <MODE>mode, operands); 8836 DONE; 8837 } 8838 8839 if (<MODE>mode == DImode) 8840 insn = (mode == SImode) 8841 ? gen_zero_extendsidi2 8842 : (mode == HImode) 8843 ? gen_zero_extendhidi2 8844 : gen_zero_extendqidi2; 8845 else if (<MODE>mode == SImode) 8846 insn = (mode == HImode) 8847 ? gen_zero_extendhisi2 8848 : gen_zero_extendqisi2; 8849 else if (<MODE>mode == HImode) 8850 insn = gen_zero_extendqihi2; 8851 else 8852 gcc_unreachable (); 8853 8854 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1]))); 8855 DONE; 8856}) 8857 8858(define_insn_and_split "*anddi3_doubleword" 8859 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 8860 (and:DI 8861 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 8862 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm"))) 8863 (clobber (reg:CC FLAGS_REG))] 8864 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 8865 && ix86_binary_operator_ok (AND, DImode, operands)" 8866 "#" 8867 "&& reload_completed" 8868 [(const_int 0)] 8869{ 8870 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); 8871 if (operands[2] == const0_rtx) 8872 { 8873 operands[1] = const0_rtx; 8874 ix86_expand_move (SImode, &operands[0]); 8875 } 8876 else if (operands[2] != constm1_rtx) 8877 ix86_expand_binary_operator (AND, SImode, &operands[0]); 8878 else if (operands[5] == constm1_rtx) 8879 emit_note (NOTE_INSN_DELETED); 8880 if (operands[5] == const0_rtx) 8881 { 8882 operands[4] = const0_rtx; 8883 ix86_expand_move (SImode, &operands[3]); 8884 } 8885 else if (operands[5] != constm1_rtx) 8886 ix86_expand_binary_operator (AND, SImode, &operands[3]); 8887 DONE; 8888}) 8889 8890(define_insn "*anddi_1" 8891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 8892 (and:DI 8893 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 8894 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L"))) 8895 (clobber (reg:CC FLAGS_REG))] 8896 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 8897 "@ 8898 and{l}\t{%k2, %k0|%k0, %k2} 8899 and{q}\t{%2, %0|%0, %2} 8900 and{q}\t{%2, %0|%0, %2} 8901 #" 8902 [(set_attr "type" "alu,alu,alu,imovx") 8903 (set_attr "length_immediate" "*,*,*,0") 8904 (set (attr "prefix_rex") 8905 (if_then_else 8906 (and (eq_attr "type" "imovx") 8907 (and (match_test "INTVAL (operands[2]) == 0xff") 8908 (match_operand 1 "ext_QIreg_operand"))) 8909 (const_string "1") 8910 (const_string "*"))) 8911 (set_attr "mode" "SI,DI,DI,SI")]) 8912 8913(define_insn_and_split "*anddi_1_btr" 8914 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 8915 (and:DI 8916 (match_operand:DI 1 "nonimmediate_operand" "%0") 8917 (match_operand:DI 2 "const_int_operand" "n"))) 8918 (clobber (reg:CC FLAGS_REG))] 8919 "TARGET_64BIT && TARGET_USE_BT 8920 && ix86_binary_operator_ok (AND, DImode, operands) 8921 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)" 8922 "#" 8923 "&& reload_completed" 8924 [(parallel [(set (zero_extract:DI (match_dup 0) 8925 (const_int 1) 8926 (match_dup 3)) 8927 (const_int 0)) 8928 (clobber (reg:CC FLAGS_REG))])] 8929 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));" 8930 [(set_attr "type" "alu1") 8931 (set_attr "prefix_0f" "1") 8932 (set_attr "znver1_decode" "double") 8933 (set_attr "mode" "DI")]) 8934 8935;; Turn *anddi_1 into *andsi_1_zext if possible. 8936(define_split 8937 [(set (match_operand:DI 0 "register_operand") 8938 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0) 8939 (match_operand:DI 2 "x86_64_zext_immediate_operand"))) 8940 (clobber (reg:CC FLAGS_REG))] 8941 "TARGET_64BIT" 8942 [(parallel [(set (match_dup 0) 8943 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2)))) 8944 (clobber (reg:CC FLAGS_REG))])] 8945{ 8946 if (GET_CODE (operands[2]) == SYMBOL_REF 8947 || GET_CODE (operands[2]) == LABEL_REF) 8948 { 8949 operands[2] = shallow_copy_rtx (operands[2]); 8950 PUT_MODE (operands[2], SImode); 8951 } 8952 else 8953 operands[2] = gen_lowpart (SImode, operands[2]); 8954}) 8955 8956;; See comment for addsi_1_zext why we do use nonimmediate_operand 8957(define_insn "*andsi_1_zext" 8958 [(set (match_operand:DI 0 "register_operand" "=r") 8959 (zero_extend:DI 8960 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8961 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 8962 (clobber (reg:CC FLAGS_REG))] 8963 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 8964 "and{l}\t{%2, %k0|%k0, %2}" 8965 [(set_attr "type" "alu") 8966 (set_attr "mode" "SI")]) 8967 8968(define_insn "*and<mode>_1" 8969 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya") 8970 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm") 8971 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L"))) 8972 (clobber (reg:CC FLAGS_REG))] 8973 "ix86_binary_operator_ok (AND, <MODE>mode, operands)" 8974 "@ 8975 and{<imodesuffix>}\t{%2, %0|%0, %2} 8976 and{<imodesuffix>}\t{%2, %0|%0, %2} 8977 #" 8978 [(set_attr "type" "alu,alu,imovx") 8979 (set_attr "length_immediate" "*,*,0") 8980 (set (attr "prefix_rex") 8981 (if_then_else 8982 (and (eq_attr "type" "imovx") 8983 (and (match_test "INTVAL (operands[2]) == 0xff") 8984 (match_operand 1 "ext_QIreg_operand"))) 8985 (const_string "1") 8986 (const_string "*"))) 8987 (set_attr "mode" "<MODE>,<MODE>,SI")]) 8988 8989(define_insn "*andqi_1" 8990 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 8991 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8992 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 8993 (clobber (reg:CC FLAGS_REG))] 8994 "ix86_binary_operator_ok (AND, QImode, operands)" 8995 "@ 8996 and{b}\t{%2, %0|%0, %2} 8997 and{b}\t{%2, %0|%0, %2} 8998 and{l}\t{%k2, %k0|%k0, %k2}" 8999 [(set_attr "type" "alu") 9000 (set_attr "mode" "QI,QI,SI") 9001 ;; Potential partial reg stall on alternative 2. 9002 (set (attr "preferred_for_speed") 9003 (cond [(eq_attr "alternative" "2") 9004 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 9005 (symbol_ref "true")))]) 9006 9007(define_insn "*andqi_1_slp" 9008 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 9009 (and:QI (match_dup 0) 9010 (match_operand:QI 1 "general_operand" "qn,qmn"))) 9011 (clobber (reg:CC FLAGS_REG))] 9012 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9013 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9014 "and{b}\t{%1, %0|%0, %1}" 9015 [(set_attr "type" "alu1") 9016 (set_attr "mode" "QI")]) 9017 9018(define_split 9019 [(set (match_operand:SWI248 0 "register_operand") 9020 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand") 9021 (match_operand:SWI248 2 "const_int_operand"))) 9022 (clobber (reg:CC FLAGS_REG))] 9023 "reload_completed 9024 && (!REG_P (operands[1]) 9025 || REGNO (operands[0]) != REGNO (operands[1]))" 9026 [(const_int 0)] 9027{ 9028 HOST_WIDE_INT ival = INTVAL (operands[2]); 9029 machine_mode mode; 9030 rtx (*insn) (rtx, rtx); 9031 9032 if (ival == (HOST_WIDE_INT) 0xffffffff) 9033 mode = SImode; 9034 else if (ival == 0xffff) 9035 mode = HImode; 9036 else 9037 { 9038 gcc_assert (ival == 0xff); 9039 mode = QImode; 9040 } 9041 9042 if (<MODE>mode == DImode) 9043 insn = (mode == SImode) 9044 ? gen_zero_extendsidi2 9045 : (mode == HImode) 9046 ? gen_zero_extendhidi2 9047 : gen_zero_extendqidi2; 9048 else 9049 { 9050 if (<MODE>mode != SImode) 9051 /* Zero extend to SImode to avoid partial register stalls. */ 9052 operands[0] = gen_lowpart (SImode, operands[0]); 9053 9054 insn = (mode == HImode) 9055 ? gen_zero_extendhisi2 9056 : gen_zero_extendqisi2; 9057 } 9058 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1]))); 9059 DONE; 9060}) 9061 9062(define_split 9063 [(set (match_operand:SWI48 0 "register_operand") 9064 (and:SWI48 (match_dup 0) 9065 (const_int -65536))) 9066 (clobber (reg:CC FLAGS_REG))] 9067 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL) 9068 || optimize_function_for_size_p (cfun)" 9069 [(set (strict_low_part (match_dup 1)) (const_int 0))] 9070 "operands[1] = gen_lowpart (HImode, operands[0]);") 9071 9072(define_split 9073 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9074 (and:SWI248 (match_dup 0) 9075 (const_int -256))) 9076 (clobber (reg:CC FLAGS_REG))] 9077 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9078 && reload_completed" 9079 [(set (strict_low_part (match_dup 1)) (const_int 0))] 9080 "operands[1] = gen_lowpart (QImode, operands[0]);") 9081 9082(define_split 9083 [(set (match_operand:SWI248 0 "QIreg_operand") 9084 (and:SWI248 (match_dup 0) 9085 (const_int -65281))) 9086 (clobber (reg:CC FLAGS_REG))] 9087 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9088 && reload_completed" 9089 [(parallel 9090 [(set (zero_extract:SI (match_dup 0) 9091 (const_int 8) 9092 (const_int 8)) 9093 (subreg:SI 9094 (xor:QI 9095 (subreg:QI 9096 (zero_extract:SI (match_dup 0) 9097 (const_int 8) 9098 (const_int 8)) 0) 9099 (subreg:QI 9100 (zero_extract:SI (match_dup 0) 9101 (const_int 8) 9102 (const_int 8)) 0)) 0)) 9103 (clobber (reg:CC FLAGS_REG))])] 9104 "operands[0] = gen_lowpart (SImode, operands[0]);") 9105 9106(define_insn "*anddi_2" 9107 [(set (reg FLAGS_REG) 9108 (compare 9109 (and:DI 9110 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 9111 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 9112 (const_int 0))) 9113 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 9114 (and:DI (match_dup 1) (match_dup 2)))] 9115 "TARGET_64BIT 9116 && ix86_match_ccmode 9117 (insn, 9118 /* If we are going to emit andl instead of andq, and the operands[2] 9119 constant might have the SImode sign bit set, make sure the sign 9120 flag isn't tested, because the instruction will set the sign flag 9121 based on bit 31 rather than bit 63. If it isn't CONST_INT, 9122 conservatively assume it might have bit 31 set. */ 9123 (satisfies_constraint_Z (operands[2]) 9124 && (!CONST_INT_P (operands[2]) 9125 || val_signbit_known_set_p (SImode, INTVAL (operands[2])))) 9126 ? CCZmode : CCNOmode) 9127 && ix86_binary_operator_ok (AND, DImode, operands)" 9128 "@ 9129 and{l}\t{%k2, %k0|%k0, %k2} 9130 and{q}\t{%2, %0|%0, %2} 9131 and{q}\t{%2, %0|%0, %2}" 9132 [(set_attr "type" "alu") 9133 (set_attr "mode" "SI,DI,DI")]) 9134 9135;; See comment for addsi_1_zext why we do use nonimmediate_operand 9136(define_insn "*andsi_2_zext" 9137 [(set (reg FLAGS_REG) 9138 (compare (and:SI 9139 (match_operand:SI 1 "nonimmediate_operand" "%0") 9140 (match_operand:SI 2 "x86_64_general_operand" "rme")) 9141 (const_int 0))) 9142 (set (match_operand:DI 0 "register_operand" "=r") 9143 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 9144 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9145 && ix86_binary_operator_ok (AND, SImode, operands)" 9146 "and{l}\t{%2, %k0|%k0, %2}" 9147 [(set_attr "type" "alu") 9148 (set_attr "mode" "SI")]) 9149 9150(define_insn "*andqi_2_maybe_si" 9151 [(set (reg FLAGS_REG) 9152 (compare (and:QI 9153 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9154 (match_operand:QI 2 "general_operand" "qmn,qn,n")) 9155 (const_int 0))) 9156 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 9157 (and:QI (match_dup 1) (match_dup 2)))] 9158 "ix86_binary_operator_ok (AND, QImode, operands) 9159 && ix86_match_ccmode (insn, 9160 CONST_INT_P (operands[2]) 9161 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 9162{ 9163 if (which_alternative == 2) 9164 { 9165 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 9166 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 9167 return "and{l}\t{%2, %k0|%k0, %2}"; 9168 } 9169 return "and{b}\t{%2, %0|%0, %2}"; 9170} 9171 [(set_attr "type" "alu") 9172 (set_attr "mode" "QI,QI,SI")]) 9173 9174(define_insn "*and<mode>_2" 9175 [(set (reg FLAGS_REG) 9176 (compare (and:SWI124 9177 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") 9178 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>")) 9179 (const_int 0))) 9180 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m") 9181 (and:SWI124 (match_dup 1) (match_dup 2)))] 9182 "ix86_match_ccmode (insn, CCNOmode) 9183 && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 9184 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 9185 [(set_attr "type" "alu") 9186 (set_attr "mode" "<MODE>")]) 9187 9188(define_insn "*andqi_2_slp" 9189 [(set (reg FLAGS_REG) 9190 (compare (and:QI 9191 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9192 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) 9193 (const_int 0))) 9194 (set (strict_low_part (match_dup 0)) 9195 (and:QI (match_dup 0) (match_dup 1)))] 9196 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9197 && ix86_match_ccmode (insn, CCNOmode) 9198 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9199 "and{b}\t{%1, %0|%0, %1}" 9200 [(set_attr "type" "alu1") 9201 (set_attr "mode" "QI")]) 9202 9203(define_insn "andqi_ext_1" 9204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9205 (const_int 8) 9206 (const_int 8)) 9207 (subreg:SI 9208 (and:QI 9209 (subreg:QI 9210 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9211 (const_int 8) 9212 (const_int 8)) 0) 9213 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 9214 (clobber (reg:CC FLAGS_REG))] 9215 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9216 rtx_equal_p (operands[0], operands[1])" 9217 "and{b}\t{%2, %h0|%h0, %2}" 9218 [(set_attr "isa" "*,nox64") 9219 (set_attr "type" "alu") 9220 (set_attr "mode" "QI")]) 9221 9222;; Generated by peephole translating test to and. This shows up 9223;; often in fp comparisons. 9224(define_insn "*andqi_ext_1_cc" 9225 [(set (reg FLAGS_REG) 9226 (compare 9227 (and:QI 9228 (subreg:QI 9229 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9230 (const_int 8) 9231 (const_int 8)) 0) 9232 (match_operand:QI 2 "general_operand" "QnBc,m")) 9233 (const_int 0))) 9234 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9235 (const_int 8) 9236 (const_int 8)) 9237 (subreg:SI 9238 (and:QI 9239 (subreg:QI 9240 (zero_extract:SI (match_dup 1) 9241 (const_int 8) 9242 (const_int 8)) 0) 9243 (match_dup 2)) 0))] 9244 "ix86_match_ccmode (insn, CCNOmode) 9245 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9246 && rtx_equal_p (operands[0], operands[1])" 9247 "and{b}\t{%2, %h0|%h0, %2}" 9248 [(set_attr "isa" "*,nox64") 9249 (set_attr "type" "alu") 9250 (set_attr "mode" "QI")]) 9251 9252(define_insn "*andqi_ext_2" 9253 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 9254 (const_int 8) 9255 (const_int 8)) 9256 (subreg:SI 9257 (and:QI 9258 (subreg:QI 9259 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 9260 (const_int 8) 9261 (const_int 8)) 0) 9262 (subreg:QI 9263 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9264 (const_int 8) 9265 (const_int 8)) 0)) 0)) 9266 (clobber (reg:CC FLAGS_REG))] 9267 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9268 rtx_equal_p (operands[0], operands[1]) 9269 || rtx_equal_p (operands[0], operands[2])" 9270 "and{b}\t{%h2, %h0|%h0, %h2}" 9271 [(set_attr "type" "alu") 9272 (set_attr "mode" "QI")]) 9273 9274;; Convert wide AND instructions with immediate operand to shorter QImode 9275;; equivalents when possible. 9276;; Don't do the splitting with memory operands, since it introduces risk 9277;; of memory mismatch stalls. We may want to do the splitting for optimizing 9278;; for size, but that can (should?) be handled by generic code instead. 9279(define_split 9280 [(set (match_operand:SWI248 0 "QIreg_operand") 9281 (and:SWI248 (match_operand:SWI248 1 "register_operand") 9282 (match_operand:SWI248 2 "const_int_operand"))) 9283 (clobber (reg:CC FLAGS_REG))] 9284 "reload_completed 9285 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9286 && !(~INTVAL (operands[2]) & ~(255 << 8))" 9287 [(parallel 9288 [(set (zero_extract:SI (match_dup 0) 9289 (const_int 8) 9290 (const_int 8)) 9291 (subreg:SI 9292 (and:QI 9293 (subreg:QI 9294 (zero_extract:SI (match_dup 1) 9295 (const_int 8) 9296 (const_int 8)) 0) 9297 (match_dup 2)) 0)) 9298 (clobber (reg:CC FLAGS_REG))])] 9299{ 9300 operands[0] = gen_lowpart (SImode, operands[0]); 9301 operands[1] = gen_lowpart (SImode, operands[1]); 9302 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode); 9303}) 9304 9305;; Since AND can be encoded with sign extended immediate, this is only 9306;; profitable when 7th bit is not set. 9307(define_split 9308 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9309 (and:SWI248 (match_operand:SWI248 1 "general_operand") 9310 (match_operand:SWI248 2 "const_int_operand"))) 9311 (clobber (reg:CC FLAGS_REG))] 9312 "reload_completed 9313 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9314 && !(~INTVAL (operands[2]) & ~255) 9315 && !(INTVAL (operands[2]) & 128)" 9316 [(parallel [(set (strict_low_part (match_dup 0)) 9317 (and:QI (match_dup 1) 9318 (match_dup 2))) 9319 (clobber (reg:CC FLAGS_REG))])] 9320{ 9321 operands[0] = gen_lowpart (QImode, operands[0]); 9322 operands[1] = gen_lowpart (QImode, operands[1]); 9323 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 9324}) 9325 9326(define_insn "*andndi3_doubleword" 9327 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r") 9328 (and:DI 9329 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0")) 9330 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm"))) 9331 (clobber (reg:CC FLAGS_REG))] 9332 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" 9333 "#" 9334 [(set_attr "isa" "bmi,bmi,bmi,*")]) 9335 9336(define_split 9337 [(set (match_operand:DI 0 "register_operand") 9338 (and:DI 9339 (not:DI (match_operand:DI 1 "register_operand")) 9340 (match_operand:DI 2 "nonimmediate_operand"))) 9341 (clobber (reg:CC FLAGS_REG))] 9342 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2 9343 && reload_completed" 9344 [(parallel [(set (match_dup 0) 9345 (and:SI (not:SI (match_dup 1)) (match_dup 2))) 9346 (clobber (reg:CC FLAGS_REG))]) 9347 (parallel [(set (match_dup 3) 9348 (and:SI (not:SI (match_dup 4)) (match_dup 5))) 9349 (clobber (reg:CC FLAGS_REG))])] 9350 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);") 9351 9352(define_split 9353 [(set (match_operand:DI 0 "register_operand") 9354 (and:DI 9355 (not:DI (match_dup 0)) 9356 (match_operand:DI 1 "nonimmediate_operand"))) 9357 (clobber (reg:CC FLAGS_REG))] 9358 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2 9359 && reload_completed" 9360 [(set (match_dup 0) (not:SI (match_dup 0))) 9361 (parallel [(set (match_dup 0) 9362 (and:SI (match_dup 0) (match_dup 1))) 9363 (clobber (reg:CC FLAGS_REG))]) 9364 (set (match_dup 2) (not:SI (match_dup 2))) 9365 (parallel [(set (match_dup 2) 9366 (and:SI (match_dup 2) (match_dup 3))) 9367 (clobber (reg:CC FLAGS_REG))])] 9368 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);") 9369 9370(define_insn "*andn<mode>_1" 9371 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 9372 (and:SWI48 9373 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r")) 9374 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))) 9375 (clobber (reg:CC FLAGS_REG))] 9376 "TARGET_BMI" 9377 "andn\t{%2, %1, %0|%0, %1, %2}" 9378 [(set_attr "type" "bitmanip") 9379 (set_attr "btver2_decode" "direct, double") 9380 (set_attr "mode" "<MODE>")]) 9381 9382(define_insn "*andn<mode>_1" 9383 [(set (match_operand:SWI12 0 "register_operand" "=r") 9384 (and:SWI12 9385 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r")) 9386 (match_operand:SWI12 2 "register_operand" "r"))) 9387 (clobber (reg:CC FLAGS_REG))] 9388 "TARGET_BMI" 9389 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}" 9390 [(set_attr "type" "bitmanip") 9391 (set_attr "btver2_decode" "direct") 9392 (set_attr "mode" "SI")]) 9393 9394(define_insn "*andn_<mode>_ccno" 9395 [(set (reg FLAGS_REG) 9396 (compare 9397 (and:SWI48 9398 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r")) 9399 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")) 9400 (const_int 0))) 9401 (clobber (match_scratch:SWI48 0 "=r,r"))] 9402 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)" 9403 "andn\t{%2, %1, %0|%0, %1, %2}" 9404 [(set_attr "type" "bitmanip") 9405 (set_attr "btver2_decode" "direct, double") 9406 (set_attr "mode" "<MODE>")]) 9407 9408;; Logical inclusive and exclusive OR instructions 9409 9410;; %%% This used to optimize known byte-wide and operations to memory. 9411;; If this is considered useful, it should be done with splitters. 9412 9413(define_expand "<code><mode>3" 9414 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand") 9415 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand") 9416 (match_operand:SWIM1248x 2 "<general_operand>")))] 9417 "" 9418 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 9419 9420(define_insn_and_split "*<code>di3_doubleword" 9421 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 9422 (any_or:DI 9423 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 9424 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm"))) 9425 (clobber (reg:CC FLAGS_REG))] 9426 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 9427 && ix86_binary_operator_ok (<CODE>, DImode, operands)" 9428 "#" 9429 "&& reload_completed" 9430 [(const_int 0)] 9431{ 9432 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); 9433 if (operands[2] == constm1_rtx) 9434 { 9435 if (<CODE> == IOR) 9436 { 9437 operands[1] = constm1_rtx; 9438 ix86_expand_move (SImode, &operands[0]); 9439 } 9440 else 9441 ix86_expand_unary_operator (NOT, SImode, &operands[0]); 9442 } 9443 else if (operands[2] != const0_rtx) 9444 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]); 9445 else if (operands[5] == const0_rtx) 9446 emit_note (NOTE_INSN_DELETED); 9447 if (operands[5] == constm1_rtx) 9448 { 9449 if (<CODE> == IOR) 9450 { 9451 operands[4] = constm1_rtx; 9452 ix86_expand_move (SImode, &operands[3]); 9453 } 9454 else 9455 ix86_expand_unary_operator (NOT, SImode, &operands[3]); 9456 } 9457 else if (operands[5] != const0_rtx) 9458 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]); 9459 DONE; 9460}) 9461 9462(define_insn "*<code><mode>_1" 9463 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm") 9464 (any_or:SWI248 9465 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0") 9466 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>"))) 9467 (clobber (reg:CC FLAGS_REG))] 9468 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9469 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9470 [(set_attr "type" "alu") 9471 (set_attr "mode" "<MODE>")]) 9472 9473(define_insn_and_split "*iordi_1_bts" 9474 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9475 (ior:DI 9476 (match_operand:DI 1 "nonimmediate_operand" "%0") 9477 (match_operand:DI 2 "const_int_operand" "n"))) 9478 (clobber (reg:CC FLAGS_REG))] 9479 "TARGET_64BIT && TARGET_USE_BT 9480 && ix86_binary_operator_ok (IOR, DImode, operands) 9481 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)" 9482 "#" 9483 "&& reload_completed" 9484 [(parallel [(set (zero_extract:DI (match_dup 0) 9485 (const_int 1) 9486 (match_dup 3)) 9487 (const_int 1)) 9488 (clobber (reg:CC FLAGS_REG))])] 9489 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));" 9490 [(set_attr "type" "alu1") 9491 (set_attr "prefix_0f" "1") 9492 (set_attr "znver1_decode" "double") 9493 (set_attr "mode" "DI")]) 9494 9495(define_insn_and_split "*xordi_1_btc" 9496 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9497 (xor:DI 9498 (match_operand:DI 1 "nonimmediate_operand" "%0") 9499 (match_operand:DI 2 "const_int_operand" "n"))) 9500 (clobber (reg:CC FLAGS_REG))] 9501 "TARGET_64BIT && TARGET_USE_BT 9502 && ix86_binary_operator_ok (XOR, DImode, operands) 9503 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)" 9504 "#" 9505 "&& reload_completed" 9506 [(parallel [(set (zero_extract:DI (match_dup 0) 9507 (const_int 1) 9508 (match_dup 3)) 9509 (not:DI (zero_extract:DI (match_dup 0) 9510 (const_int 1) 9511 (match_dup 3)))) 9512 (clobber (reg:CC FLAGS_REG))])] 9513 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));" 9514 [(set_attr "type" "alu1") 9515 (set_attr "prefix_0f" "1") 9516 (set_attr "znver1_decode" "double") 9517 (set_attr "mode" "DI")]) 9518 9519;; See comment for addsi_1_zext why we do use nonimmediate_operand 9520(define_insn "*<code>si_1_zext" 9521 [(set (match_operand:DI 0 "register_operand" "=r") 9522 (zero_extend:DI 9523 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9524 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 9525 (clobber (reg:CC FLAGS_REG))] 9526 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9527 "<logic>{l}\t{%2, %k0|%k0, %2}" 9528 [(set_attr "type" "alu") 9529 (set_attr "mode" "SI")]) 9530 9531(define_insn "*<code>si_1_zext_imm" 9532 [(set (match_operand:DI 0 "register_operand" "=r") 9533 (any_or:DI 9534 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 9535 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 9536 (clobber (reg:CC FLAGS_REG))] 9537 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9538 "<logic>{l}\t{%2, %k0|%k0, %2}" 9539 [(set_attr "type" "alu") 9540 (set_attr "mode" "SI")]) 9541 9542(define_insn "*<code>qi_1" 9543 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 9544 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9545 (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) 9546 (clobber (reg:CC FLAGS_REG))] 9547 "ix86_binary_operator_ok (<CODE>, QImode, operands)" 9548 "@ 9549 <logic>{b}\t{%2, %0|%0, %2} 9550 <logic>{b}\t{%2, %0|%0, %2} 9551 <logic>{l}\t{%k2, %k0|%k0, %k2}" 9552 [(set_attr "type" "alu") 9553 (set_attr "mode" "QI,QI,SI") 9554 ;; Potential partial reg stall on alternative 2. 9555 (set (attr "preferred_for_speed") 9556 (cond [(eq_attr "alternative" "2") 9557 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 9558 (symbol_ref "true")))]) 9559 9560(define_insn "*<code>qi_1_slp" 9561 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 9562 (any_or:QI (match_dup 0) 9563 (match_operand:QI 1 "general_operand" "qmn,qn"))) 9564 (clobber (reg:CC FLAGS_REG))] 9565 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9566 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9567 "<logic>{b}\t{%1, %0|%0, %1}" 9568 [(set_attr "type" "alu1") 9569 (set_attr "mode" "QI")]) 9570 9571(define_insn "*<code><mode>_2" 9572 [(set (reg FLAGS_REG) 9573 (compare (any_or:SWI 9574 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 9575 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")) 9576 (const_int 0))) 9577 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 9578 (any_or:SWI (match_dup 1) (match_dup 2)))] 9579 "ix86_match_ccmode (insn, CCNOmode) 9580 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9581 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9582 [(set_attr "type" "alu") 9583 (set_attr "mode" "<MODE>")]) 9584 9585;; See comment for addsi_1_zext why we do use nonimmediate_operand 9586;; ??? Special case for immediate operand is missing - it is tricky. 9587(define_insn "*<code>si_2_zext" 9588 [(set (reg FLAGS_REG) 9589 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9590 (match_operand:SI 2 "x86_64_general_operand" "rme")) 9591 (const_int 0))) 9592 (set (match_operand:DI 0 "register_operand" "=r") 9593 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] 9594 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9595 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9596 "<logic>{l}\t{%2, %k0|%k0, %2}" 9597 [(set_attr "type" "alu") 9598 (set_attr "mode" "SI")]) 9599 9600(define_insn "*<code>si_2_zext_imm" 9601 [(set (reg FLAGS_REG) 9602 (compare (any_or:SI 9603 (match_operand:SI 1 "nonimmediate_operand" "%0") 9604 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z")) 9605 (const_int 0))) 9606 (set (match_operand:DI 0 "register_operand" "=r") 9607 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 9608 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9609 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9610 "<logic>{l}\t{%2, %k0|%k0, %2}" 9611 [(set_attr "type" "alu") 9612 (set_attr "mode" "SI")]) 9613 9614(define_insn "*<code>qi_2_slp" 9615 [(set (reg FLAGS_REG) 9616 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9617 (match_operand:QI 1 "general_operand" "qmn,qn")) 9618 (const_int 0))) 9619 (set (strict_low_part (match_dup 0)) 9620 (any_or:QI (match_dup 0) (match_dup 1)))] 9621 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9622 && ix86_match_ccmode (insn, CCNOmode) 9623 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9624 "<logic>{b}\t{%1, %0|%0, %1}" 9625 [(set_attr "type" "alu1") 9626 (set_attr "mode" "QI")]) 9627 9628(define_insn "*<code><mode>_3" 9629 [(set (reg FLAGS_REG) 9630 (compare (any_or:SWI 9631 (match_operand:SWI 1 "nonimmediate_operand" "%0") 9632 (match_operand:SWI 2 "<general_operand>" "<g>")) 9633 (const_int 0))) 9634 (clobber (match_scratch:SWI 0 "=<r>"))] 9635 "ix86_match_ccmode (insn, CCNOmode) 9636 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 9637 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9638 [(set_attr "type" "alu") 9639 (set_attr "mode" "<MODE>")]) 9640 9641(define_insn "*<code>qi_ext_1" 9642 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9643 (const_int 8) 9644 (const_int 8)) 9645 (subreg:SI 9646 (any_or:QI 9647 (subreg:QI 9648 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9649 (const_int 8) 9650 (const_int 8)) 0) 9651 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 9652 (clobber (reg:CC FLAGS_REG))] 9653 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9654 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9655 && rtx_equal_p (operands[0], operands[1])" 9656 "<logic>{b}\t{%2, %h0|%h0, %2}" 9657 [(set_attr "isa" "*,nox64") 9658 (set_attr "type" "alu") 9659 (set_attr "mode" "QI")]) 9660 9661(define_insn "*<code>qi_ext_2" 9662 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 9663 (const_int 8) 9664 (const_int 8)) 9665 (subreg:SI 9666 (any_or:QI 9667 (subreg:QI 9668 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 9669 (const_int 8) 9670 (const_int 8)) 0) 9671 (subreg:QI 9672 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9673 (const_int 8) 9674 (const_int 8)) 0)) 0)) 9675 (clobber (reg:CC FLAGS_REG))] 9676 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9677 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9678 && (rtx_equal_p (operands[0], operands[1]) 9679 || rtx_equal_p (operands[0], operands[2]))" 9680 "<logic>{b}\t{%h2, %h0|%h0, %h2}" 9681 [(set_attr "type" "alu") 9682 (set_attr "mode" "QI")]) 9683 9684;; Convert wide OR instructions with immediate operand to shorter QImode 9685;; equivalents when possible. 9686;; Don't do the splitting with memory operands, since it introduces risk 9687;; of memory mismatch stalls. We may want to do the splitting for optimizing 9688;; for size, but that can (should?) be handled by generic code instead. 9689(define_split 9690 [(set (match_operand:SWI248 0 "QIreg_operand") 9691 (any_or:SWI248 (match_operand:SWI248 1 "register_operand") 9692 (match_operand:SWI248 2 "const_int_operand"))) 9693 (clobber (reg:CC FLAGS_REG))] 9694 "reload_completed 9695 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9696 && !(INTVAL (operands[2]) & ~(255 << 8))" 9697 [(parallel 9698 [(set (zero_extract:SI (match_dup 0) 9699 (const_int 8) 9700 (const_int 8)) 9701 (subreg:SI 9702 (any_or:QI 9703 (subreg:QI 9704 (zero_extract:SI (match_dup 1) 9705 (const_int 8) 9706 (const_int 8)) 0) 9707 (match_dup 2)) 0)) 9708 (clobber (reg:CC FLAGS_REG))])] 9709{ 9710 operands[0] = gen_lowpart (SImode, operands[0]); 9711 operands[1] = gen_lowpart (SImode, operands[1]); 9712 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode); 9713}) 9714 9715;; Since OR can be encoded with sign extended immediate, this is only 9716;; profitable when 7th bit is set. 9717(define_split 9718 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9719 (any_or:SWI248 (match_operand:SWI248 1 "general_operand") 9720 (match_operand:SWI248 2 "const_int_operand"))) 9721 (clobber (reg:CC FLAGS_REG))] 9722 "reload_completed 9723 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9724 && !(INTVAL (operands[2]) & ~255) 9725 && (INTVAL (operands[2]) & 128)" 9726 [(parallel [(set (strict_low_part (match_dup 0)) 9727 (any_or:QI (match_dup 1) 9728 (match_dup 2))) 9729 (clobber (reg:CC FLAGS_REG))])] 9730{ 9731 operands[0] = gen_lowpart (QImode, operands[0]); 9732 operands[1] = gen_lowpart (QImode, operands[1]); 9733 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 9734}) 9735 9736(define_expand "xorqi_ext_1_cc" 9737 [(parallel [ 9738 (set (reg:CCNO FLAGS_REG) 9739 (compare:CCNO 9740 (xor:QI 9741 (subreg:QI 9742 (zero_extract:SI (match_operand 1 "ext_register_operand") 9743 (const_int 8) 9744 (const_int 8)) 0) 9745 (match_operand 2 "const_int_operand")) 9746 (const_int 0))) 9747 (set (zero_extract:SI (match_operand 0 "ext_register_operand") 9748 (const_int 8) 9749 (const_int 8)) 9750 (subreg:SI 9751 (xor:QI 9752 (subreg:QI 9753 (zero_extract:SI (match_dup 1) 9754 (const_int 8) 9755 (const_int 8)) 0) 9756 (match_dup 2)) 0))])]) 9757 9758(define_insn "*xorqi_ext_1_cc" 9759 [(set (reg FLAGS_REG) 9760 (compare 9761 (xor:QI 9762 (subreg:QI 9763 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9764 (const_int 8) 9765 (const_int 8)) 0) 9766 (match_operand:QI 2 "general_operand" "QnBc,m")) 9767 (const_int 0))) 9768 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9769 (const_int 8) 9770 (const_int 8)) 9771 (subreg:SI 9772 (xor:QI 9773 (subreg:QI 9774 (zero_extract:SI (match_dup 1) 9775 (const_int 8) 9776 (const_int 8)) 0) 9777 (match_dup 2)) 0))] 9778 "ix86_match_ccmode (insn, CCNOmode) 9779 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9780 && rtx_equal_p (operands[0], operands[1])" 9781 "xor{b}\t{%2, %h0|%h0, %2}" 9782 [(set_attr "isa" "*,nox64") 9783 (set_attr "type" "alu") 9784 (set_attr "mode" "QI")]) 9785 9786;; Negation instructions 9787 9788(define_expand "neg<mode>2" 9789 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 9790 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))] 9791 "" 9792 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;") 9793 9794(define_insn_and_split "*neg<dwi>2_doubleword" 9795 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 9796 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0"))) 9797 (clobber (reg:CC FLAGS_REG))] 9798 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)" 9799 "#" 9800 "reload_completed" 9801 [(parallel 9802 [(set (reg:CCZ FLAGS_REG) 9803 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0))) 9804 (set (match_dup 0) (neg:DWIH (match_dup 1)))]) 9805 (parallel 9806 [(set (match_dup 2) 9807 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 9808 (match_dup 3)) 9809 (const_int 0))) 9810 (clobber (reg:CC FLAGS_REG))]) 9811 (parallel 9812 [(set (match_dup 2) 9813 (neg:DWIH (match_dup 2))) 9814 (clobber (reg:CC FLAGS_REG))])] 9815 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);") 9816 9817(define_insn "*neg<mode>2_1" 9818 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9819 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) 9820 (clobber (reg:CC FLAGS_REG))] 9821 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 9822 "neg{<imodesuffix>}\t%0" 9823 [(set_attr "type" "negnot") 9824 (set_attr "mode" "<MODE>")]) 9825 9826;; Combine is quite creative about this pattern. 9827(define_insn "*negsi2_1_zext" 9828 [(set (match_operand:DI 0 "register_operand" "=r") 9829 (lshiftrt:DI 9830 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 9831 (const_int 32))) 9832 (const_int 32))) 9833 (clobber (reg:CC FLAGS_REG))] 9834 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9835 "neg{l}\t%k0" 9836 [(set_attr "type" "negnot") 9837 (set_attr "mode" "SI")]) 9838 9839;; The problem with neg is that it does not perform (compare x 0), 9840;; it really performs (compare 0 x), which leaves us with the zero 9841;; flag being the only useful item. 9842 9843(define_insn "*neg<mode>2_cmpz" 9844 [(set (reg:CCZ FLAGS_REG) 9845 (compare:CCZ 9846 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 9847 (const_int 0))) 9848 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9849 (neg:SWI (match_dup 1)))] 9850 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 9851 "neg{<imodesuffix>}\t%0" 9852 [(set_attr "type" "negnot") 9853 (set_attr "mode" "<MODE>")]) 9854 9855(define_insn "*negsi2_cmpz_zext" 9856 [(set (reg:CCZ FLAGS_REG) 9857 (compare:CCZ 9858 (lshiftrt:DI 9859 (neg:DI (ashift:DI 9860 (match_operand:DI 1 "register_operand" "0") 9861 (const_int 32))) 9862 (const_int 32)) 9863 (const_int 0))) 9864 (set (match_operand:DI 0 "register_operand" "=r") 9865 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 9866 (const_int 32))) 9867 (const_int 32)))] 9868 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9869 "neg{l}\t%k0" 9870 [(set_attr "type" "negnot") 9871 (set_attr "mode" "SI")]) 9872 9873;; Negate with jump on overflow. 9874(define_expand "negv<mode>3" 9875 [(parallel [(set (reg:CCO FLAGS_REG) 9876 (ne:CCO (match_operand:SWI 1 "register_operand") 9877 (match_dup 3))) 9878 (set (match_operand:SWI 0 "register_operand") 9879 (neg:SWI (match_dup 1)))]) 9880 (set (pc) (if_then_else 9881 (eq (reg:CCO FLAGS_REG) (const_int 0)) 9882 (label_ref (match_operand 2)) 9883 (pc)))] 9884 "" 9885{ 9886 operands[3] 9887 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1), 9888 <MODE>mode); 9889}) 9890 9891(define_insn "*negv<mode>3" 9892 [(set (reg:CCO FLAGS_REG) 9893 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") 9894 (match_operand:SWI 2 "const_int_operand"))) 9895 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9896 (neg:SWI (match_dup 1)))] 9897 "ix86_unary_operator_ok (NEG, <MODE>mode, operands) 9898 && mode_signbit_p (<MODE>mode, operands[2])" 9899 "neg{<imodesuffix>}\t%0" 9900 [(set_attr "type" "negnot") 9901 (set_attr "mode" "<MODE>")]) 9902 9903;; Changing of sign for FP values is doable using integer unit too. 9904 9905(define_expand "<code><mode>2" 9906 [(set (match_operand:X87MODEF 0 "register_operand") 9907 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))] 9908 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 9909 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 9910 9911(define_insn "*absneg<mode>2" 9912 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r") 9913 (match_operator:MODEF 3 "absneg_operator" 9914 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")])) 9915 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X")) 9916 (clobber (reg:CC FLAGS_REG))] 9917 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 9918 "#" 9919 [(set (attr "enabled") 9920 (if_then_else 9921 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 9922 (if_then_else 9923 (eq_attr "alternative" "2") 9924 (symbol_ref "TARGET_MIX_SSE_I387") 9925 (symbol_ref "true")) 9926 (if_then_else 9927 (eq_attr "alternative" "2,3") 9928 (symbol_ref "true") 9929 (symbol_ref "false"))))]) 9930 9931(define_insn "*absnegxf2_i387" 9932 [(set (match_operand:XF 0 "register_operand" "=f,!r") 9933 (match_operator:XF 3 "absneg_operator" 9934 [(match_operand:XF 1 "register_operand" "0,0")])) 9935 (use (match_operand 2)) 9936 (clobber (reg:CC FLAGS_REG))] 9937 "TARGET_80387" 9938 "#") 9939 9940(define_expand "<code>tf2" 9941 [(set (match_operand:TF 0 "register_operand") 9942 (absneg:TF (match_operand:TF 1 "register_operand")))] 9943 "TARGET_SSE" 9944 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") 9945 9946(define_insn "*absnegtf2_sse" 9947 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv") 9948 (match_operator:TF 3 "absneg_operator" 9949 [(match_operand:TF 1 "register_operand" "0,Yv")])) 9950 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0")) 9951 (clobber (reg:CC FLAGS_REG))] 9952 "TARGET_SSE" 9953 "#") 9954 9955;; Splitters for fp abs and neg. 9956 9957(define_split 9958 [(set (match_operand 0 "fp_register_operand") 9959 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9960 (use (match_operand 2)) 9961 (clobber (reg:CC FLAGS_REG))] 9962 "reload_completed" 9963 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 9964 9965(define_split 9966 [(set (match_operand 0 "sse_reg_operand") 9967 (match_operator 3 "absneg_operator" 9968 [(match_operand 1 "register_operand")])) 9969 (use (match_operand 2 "nonimmediate_operand")) 9970 (clobber (reg:CC FLAGS_REG))] 9971 "reload_completed" 9972 [(set (match_dup 0) (match_dup 3))] 9973{ 9974 machine_mode mode = GET_MODE (operands[0]); 9975 machine_mode vmode = GET_MODE (operands[2]); 9976 rtx tmp; 9977 9978 operands[0] = lowpart_subreg (vmode, operands[0], mode); 9979 operands[1] = lowpart_subreg (vmode, operands[1], mode); 9980 if (operands_match_p (operands[0], operands[2])) 9981 std::swap (operands[1], operands[2]); 9982 if (GET_CODE (operands[3]) == ABS) 9983 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 9984 else 9985 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 9986 operands[3] = tmp; 9987}) 9988 9989(define_split 9990 [(set (match_operand:SF 0 "general_reg_operand") 9991 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 9992 (use (match_operand:V4SF 2)) 9993 (clobber (reg:CC FLAGS_REG))] 9994 "reload_completed" 9995 [(parallel [(set (match_dup 0) (match_dup 1)) 9996 (clobber (reg:CC FLAGS_REG))])] 9997{ 9998 rtx tmp; 9999 operands[0] = gen_lowpart (SImode, operands[0]); 10000 if (GET_CODE (operands[1]) == ABS) 10001 { 10002 tmp = gen_int_mode (0x7fffffff, SImode); 10003 tmp = gen_rtx_AND (SImode, operands[0], tmp); 10004 } 10005 else 10006 { 10007 tmp = gen_int_mode (0x80000000, SImode); 10008 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10009 } 10010 operands[1] = tmp; 10011}) 10012 10013(define_split 10014 [(set (match_operand:DF 0 "general_reg_operand") 10015 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 10016 (use (match_operand 2)) 10017 (clobber (reg:CC FLAGS_REG))] 10018 "reload_completed" 10019 [(parallel [(set (match_dup 0) (match_dup 1)) 10020 (clobber (reg:CC FLAGS_REG))])] 10021{ 10022 rtx tmp; 10023 if (TARGET_64BIT) 10024 { 10025 tmp = gen_lowpart (DImode, operands[0]); 10026 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 10027 operands[0] = tmp; 10028 10029 if (GET_CODE (operands[1]) == ABS) 10030 tmp = const0_rtx; 10031 else 10032 tmp = gen_rtx_NOT (DImode, tmp); 10033 } 10034 else 10035 { 10036 operands[0] = gen_highpart (SImode, operands[0]); 10037 if (GET_CODE (operands[1]) == ABS) 10038 { 10039 tmp = gen_int_mode (0x7fffffff, SImode); 10040 tmp = gen_rtx_AND (SImode, operands[0], tmp); 10041 } 10042 else 10043 { 10044 tmp = gen_int_mode (0x80000000, SImode); 10045 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10046 } 10047 } 10048 operands[1] = tmp; 10049}) 10050 10051(define_split 10052 [(set (match_operand:XF 0 "general_reg_operand") 10053 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 10054 (use (match_operand 2)) 10055 (clobber (reg:CC FLAGS_REG))] 10056 "reload_completed" 10057 [(parallel [(set (match_dup 0) (match_dup 1)) 10058 (clobber (reg:CC FLAGS_REG))])] 10059{ 10060 rtx tmp; 10061 operands[0] = gen_rtx_REG (SImode, 10062 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2)); 10063 if (GET_CODE (operands[1]) == ABS) 10064 { 10065 tmp = GEN_INT (0x7fff); 10066 tmp = gen_rtx_AND (SImode, operands[0], tmp); 10067 } 10068 else 10069 { 10070 tmp = GEN_INT (0x8000); 10071 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10072 } 10073 operands[1] = tmp; 10074}) 10075 10076;; Conditionalize these after reload. If they match before reload, we 10077;; lose the clobber and ability to use integer instructions. 10078 10079(define_insn "*<code><mode>2_1" 10080 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 10081 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] 10082 "TARGET_80387 10083 && (reload_completed 10084 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 10085 "f<absneg_mnemonic>" 10086 [(set_attr "type" "fsgn") 10087 (set_attr "mode" "<MODE>")]) 10088 10089(define_insn "*<code>extendsfdf2" 10090 [(set (match_operand:DF 0 "register_operand" "=f") 10091 (absneg:DF (float_extend:DF 10092 (match_operand:SF 1 "register_operand" "0"))))] 10093 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 10094 "f<absneg_mnemonic>" 10095 [(set_attr "type" "fsgn") 10096 (set_attr "mode" "DF")]) 10097 10098(define_insn "*<code>extendsfxf2" 10099 [(set (match_operand:XF 0 "register_operand" "=f") 10100 (absneg:XF (float_extend:XF 10101 (match_operand:SF 1 "register_operand" "0"))))] 10102 "TARGET_80387" 10103 "f<absneg_mnemonic>" 10104 [(set_attr "type" "fsgn") 10105 (set_attr "mode" "XF")]) 10106 10107(define_insn "*<code>extenddfxf2" 10108 [(set (match_operand:XF 0 "register_operand" "=f") 10109 (absneg:XF (float_extend:XF 10110 (match_operand:DF 1 "register_operand" "0"))))] 10111 "TARGET_80387" 10112 "f<absneg_mnemonic>" 10113 [(set_attr "type" "fsgn") 10114 (set_attr "mode" "XF")]) 10115 10116;; Copysign instructions 10117 10118(define_mode_iterator CSGNMODE [SF DF TF]) 10119(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) 10120 10121(define_expand "copysign<mode>3" 10122 [(match_operand:CSGNMODE 0 "register_operand") 10123 (match_operand:CSGNMODE 1 "nonmemory_operand") 10124 (match_operand:CSGNMODE 2 "register_operand")] 10125 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10126 || (TARGET_SSE && (<MODE>mode == TFmode))" 10127 "ix86_expand_copysign (operands); DONE;") 10128 10129(define_insn_and_split "copysign<mode>3_const" 10130 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv") 10131 (unspec:CSGNMODE 10132 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC") 10133 (match_operand:CSGNMODE 2 "register_operand" "0") 10134 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")] 10135 UNSPEC_COPYSIGN))] 10136 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10137 || (TARGET_SSE && (<MODE>mode == TFmode))" 10138 "#" 10139 "&& reload_completed" 10140 [(const_int 0)] 10141 "ix86_split_copysign_const (operands); DONE;") 10142 10143(define_insn "copysign<mode>3_var" 10144 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv") 10145 (unspec:CSGNMODE 10146 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv") 10147 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv") 10148 (match_operand:<CSGNVMODE> 4 10149 "nonimmediate_operand" "X,Yvm,Yvm,0,0") 10150 (match_operand:<CSGNVMODE> 5 10151 "nonimmediate_operand" "0,Yvm,1,Yvm,1")] 10152 UNSPEC_COPYSIGN)) 10153 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))] 10154 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10155 || (TARGET_SSE && (<MODE>mode == TFmode))" 10156 "#") 10157 10158(define_split 10159 [(set (match_operand:CSGNMODE 0 "register_operand") 10160 (unspec:CSGNMODE 10161 [(match_operand:CSGNMODE 2 "register_operand") 10162 (match_operand:CSGNMODE 3 "register_operand") 10163 (match_operand:<CSGNVMODE> 4) 10164 (match_operand:<CSGNVMODE> 5)] 10165 UNSPEC_COPYSIGN)) 10166 (clobber (match_scratch:<CSGNVMODE> 1))] 10167 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10168 || (TARGET_SSE && (<MODE>mode == TFmode))) 10169 && reload_completed" 10170 [(const_int 0)] 10171 "ix86_split_copysign_var (operands); DONE;") 10172 10173;; One complement instructions 10174 10175(define_expand "one_cmpl<mode>2" 10176 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand") 10177 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))] 10178 "" 10179 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") 10180 10181(define_insn_and_split "*one_cmpldi2_doubleword" 10182 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10183 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] 10184 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 10185 && ix86_unary_operator_ok (NOT, DImode, operands)" 10186 "#" 10187 "&& reload_completed" 10188 [(set (match_dup 0) 10189 (not:SI (match_dup 1))) 10190 (set (match_dup 2) 10191 (not:SI (match_dup 3)))] 10192 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);") 10193 10194(define_insn "*one_cmpl<mode>2_1" 10195 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") 10196 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))] 10197 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 10198 "not{<imodesuffix>}\t%0" 10199 [(set_attr "type" "negnot") 10200 (set_attr "mode" "<MODE>")]) 10201 10202;; ??? Currently never generated - xor is used instead. 10203(define_insn "*one_cmplsi2_1_zext" 10204 [(set (match_operand:DI 0 "register_operand" "=r") 10205 (zero_extend:DI 10206 (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10207 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10208 "not{l}\t%k0" 10209 [(set_attr "type" "negnot") 10210 (set_attr "mode" "SI")]) 10211 10212(define_insn "*one_cmplqi2_1" 10213 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10214 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10215 "ix86_unary_operator_ok (NOT, QImode, operands)" 10216 "@ 10217 not{b}\t%0 10218 not{l}\t%k0" 10219 [(set_attr "type" "negnot") 10220 (set_attr "mode" "QI,SI") 10221 ;; Potential partial reg stall on alternative 1. 10222 (set (attr "preferred_for_speed") 10223 (cond [(eq_attr "alternative" "1") 10224 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 10225 (symbol_ref "true")))]) 10226 10227(define_insn "*one_cmpl<mode>2_2" 10228 [(set (reg FLAGS_REG) 10229 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 10230 (const_int 0))) 10231 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10232 (not:SWI (match_dup 1)))] 10233 "ix86_match_ccmode (insn, CCNOmode) 10234 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 10235 "#" 10236 [(set_attr "type" "alu1") 10237 (set_attr "mode" "<MODE>")]) 10238 10239(define_split 10240 [(set (match_operand 0 "flags_reg_operand") 10241 (match_operator 2 "compare_operator" 10242 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand")) 10243 (const_int 0)])) 10244 (set (match_operand:SWI 1 "nonimmediate_operand") 10245 (not:SWI (match_dup 3)))] 10246 "ix86_match_ccmode (insn, CCNOmode)" 10247 [(parallel [(set (match_dup 0) 10248 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1)) 10249 (const_int 0)])) 10250 (set (match_dup 1) 10251 (xor:SWI (match_dup 3) (const_int -1)))])]) 10252 10253;; ??? Currently never generated - xor is used instead. 10254(define_insn "*one_cmplsi2_2_zext" 10255 [(set (reg FLAGS_REG) 10256 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10257 (const_int 0))) 10258 (set (match_operand:DI 0 "register_operand" "=r") 10259 (zero_extend:DI (not:SI (match_dup 1))))] 10260 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10261 && ix86_unary_operator_ok (NOT, SImode, operands)" 10262 "#" 10263 [(set_attr "type" "alu1") 10264 (set_attr "mode" "SI")]) 10265 10266(define_split 10267 [(set (match_operand 0 "flags_reg_operand") 10268 (match_operator 2 "compare_operator" 10269 [(not:SI (match_operand:SI 3 "register_operand")) 10270 (const_int 0)])) 10271 (set (match_operand:DI 1 "register_operand") 10272 (zero_extend:DI (not:SI (match_dup 3))))] 10273 "ix86_match_ccmode (insn, CCNOmode)" 10274 [(parallel [(set (match_dup 0) 10275 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10276 (const_int 0)])) 10277 (set (match_dup 1) 10278 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]) 10279 10280;; Shift instructions 10281 10282;; DImode shifts are implemented using the i386 "shift double" opcode, 10283;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10284;; is variable, then the count is in %cl and the "imm" operand is dropped 10285;; from the assembler input. 10286;; 10287;; This instruction shifts the target reg/mem as usual, but instead of 10288;; shifting in zeros, bits are shifted in from reg operand. If the insn 10289;; is a left shift double, bits are taken from the high order bits of 10290;; reg, else if the insn is a shift right double, bits are taken from the 10291;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10292;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10293;; 10294;; Since sh[lr]d does not change the `reg' operand, that is done 10295;; separately, making all shifts emit pairs of shift double and normal 10296;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10297;; support a 63 bit shift, each shift where the count is in a reg expands 10298;; to a pair of shifts, a branch, a shift by 32 and a label. 10299;; 10300;; If the shift count is a constant, we need never emit more than one 10301;; shift pair, instead using moves and sign extension for counts greater 10302;; than 31. 10303 10304(define_expand "ashl<mode>3" 10305 [(set (match_operand:SDWIM 0 "<shift_operand>") 10306 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>") 10307 (match_operand:QI 2 "nonmemory_operand")))] 10308 "" 10309 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") 10310 10311(define_insn "*ashl<mode>3_doubleword" 10312 [(set (match_operand:DWI 0 "register_operand" "=&r") 10313 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n") 10314 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 10315 (clobber (reg:CC FLAGS_REG))] 10316 "" 10317 "#" 10318 [(set_attr "type" "multi")]) 10319 10320(define_split 10321 [(set (match_operand:DWI 0 "register_operand") 10322 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand") 10323 (match_operand:QI 2 "nonmemory_operand"))) 10324 (clobber (reg:CC FLAGS_REG))] 10325 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 10326 [(const_int 0)] 10327 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;") 10328 10329;; By default we don't ask for a scratch register, because when DWImode 10330;; values are manipulated, registers are already at a premium. But if 10331;; we have one handy, we won't turn it away. 10332 10333(define_peephole2 10334 [(match_scratch:DWIH 3 "r") 10335 (parallel [(set (match_operand:<DWI> 0 "register_operand") 10336 (ashift:<DWI> 10337 (match_operand:<DWI> 1 "nonmemory_operand") 10338 (match_operand:QI 2 "nonmemory_operand"))) 10339 (clobber (reg:CC FLAGS_REG))]) 10340 (match_dup 3)] 10341 "TARGET_CMOVE" 10342 [(const_int 0)] 10343 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;") 10344 10345(define_insn "x86_64_shld" 10346 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 10347 (ior:DI (ashift:DI (match_dup 0) 10348 (match_operand:QI 2 "nonmemory_operand" "Jc")) 10349 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 10350 (minus:QI (const_int 64) (match_dup 2))))) 10351 (clobber (reg:CC FLAGS_REG))] 10352 "TARGET_64BIT" 10353 "shld{q}\t{%s2%1, %0|%0, %1, %2}" 10354 [(set_attr "type" "ishift") 10355 (set_attr "prefix_0f" "1") 10356 (set_attr "mode" "DI") 10357 (set_attr "athlon_decode" "vector") 10358 (set_attr "amdfam10_decode" "vector") 10359 (set_attr "bdver1_decode" "vector")]) 10360 10361(define_insn "x86_shld" 10362 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 10363 (ior:SI (ashift:SI (match_dup 0) 10364 (match_operand:QI 2 "nonmemory_operand" "Ic")) 10365 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 10366 (minus:QI (const_int 32) (match_dup 2))))) 10367 (clobber (reg:CC FLAGS_REG))] 10368 "" 10369 "shld{l}\t{%s2%1, %0|%0, %1, %2}" 10370 [(set_attr "type" "ishift") 10371 (set_attr "prefix_0f" "1") 10372 (set_attr "mode" "SI") 10373 (set_attr "pent_pair" "np") 10374 (set_attr "athlon_decode" "vector") 10375 (set_attr "amdfam10_decode" "vector") 10376 (set_attr "bdver1_decode" "vector")]) 10377 10378(define_expand "x86_shift<mode>_adj_1" 10379 [(set (reg:CCZ FLAGS_REG) 10380 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand") 10381 (match_dup 4)) 10382 (const_int 0))) 10383 (set (match_operand:SWI48 0 "register_operand") 10384 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10385 (match_operand:SWI48 1 "register_operand") 10386 (match_dup 0))) 10387 (set (match_dup 1) 10388 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10389 (match_operand:SWI48 3 "register_operand") 10390 (match_dup 1)))] 10391 "TARGET_CMOVE" 10392 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 10393 10394(define_expand "x86_shift<mode>_adj_2" 10395 [(use (match_operand:SWI48 0 "register_operand")) 10396 (use (match_operand:SWI48 1 "register_operand")) 10397 (use (match_operand:QI 2 "register_operand"))] 10398 "" 10399{ 10400 rtx_code_label *label = gen_label_rtx (); 10401 rtx tmp; 10402 10403 emit_insn (gen_testqi_ccz_1 (operands[2], 10404 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 10405 10406 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10407 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10408 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10409 gen_rtx_LABEL_REF (VOIDmode, label), 10410 pc_rtx); 10411 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 10412 JUMP_LABEL (tmp) = label; 10413 10414 emit_move_insn (operands[0], operands[1]); 10415 ix86_expand_clear (operands[1]); 10416 10417 emit_label (label); 10418 LABEL_NUSES (label) = 1; 10419 10420 DONE; 10421}) 10422 10423;; Avoid useless masking of count operand. 10424(define_insn_and_split "*ashl<mode>3_mask" 10425 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10426 (ashift:SWI48 10427 (match_operand:SWI48 1 "nonimmediate_operand") 10428 (subreg:QI 10429 (and:SI 10430 (match_operand:SI 2 "register_operand" "c,r") 10431 (match_operand:SI 3 "const_int_operand")) 0))) 10432 (clobber (reg:CC FLAGS_REG))] 10433 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 10434 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10435 == GET_MODE_BITSIZE (<MODE>mode)-1 10436 && can_create_pseudo_p ()" 10437 "#" 10438 "&& 1" 10439 [(parallel 10440 [(set (match_dup 0) 10441 (ashift:SWI48 (match_dup 1) 10442 (match_dup 2))) 10443 (clobber (reg:CC FLAGS_REG))])] 10444 "operands[2] = gen_lowpart (QImode, operands[2]);" 10445 [(set_attr "isa" "*,bmi2")]) 10446 10447(define_insn_and_split "*ashl<mode>3_mask_1" 10448 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10449 (ashift:SWI48 10450 (match_operand:SWI48 1 "nonimmediate_operand") 10451 (and:QI 10452 (match_operand:QI 2 "register_operand" "c,r") 10453 (match_operand:QI 3 "const_int_operand")))) 10454 (clobber (reg:CC FLAGS_REG))] 10455 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 10456 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10457 == GET_MODE_BITSIZE (<MODE>mode)-1 10458 && can_create_pseudo_p ()" 10459 "#" 10460 "&& 1" 10461 [(parallel 10462 [(set (match_dup 0) 10463 (ashift:SWI48 (match_dup 1) 10464 (match_dup 2))) 10465 (clobber (reg:CC FLAGS_REG))])] 10466 "" 10467 [(set_attr "isa" "*,bmi2")]) 10468 10469(define_insn "*bmi2_ashl<mode>3_1" 10470 [(set (match_operand:SWI48 0 "register_operand" "=r") 10471 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10472 (match_operand:SWI48 2 "register_operand" "r")))] 10473 "TARGET_BMI2" 10474 "shlx\t{%2, %1, %0|%0, %1, %2}" 10475 [(set_attr "type" "ishiftx") 10476 (set_attr "mode" "<MODE>")]) 10477 10478(define_insn "*ashl<mode>3_1" 10479 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") 10480 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm") 10481 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r"))) 10482 (clobber (reg:CC FLAGS_REG))] 10483 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 10484{ 10485 switch (get_attr_type (insn)) 10486 { 10487 case TYPE_LEA: 10488 case TYPE_ISHIFTX: 10489 return "#"; 10490 10491 case TYPE_ALU: 10492 gcc_assert (operands[2] == const1_rtx); 10493 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10494 return "add{<imodesuffix>}\t%0, %0"; 10495 10496 default: 10497 if (operands[2] == const1_rtx 10498 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10499 return "sal{<imodesuffix>}\t%0"; 10500 else 10501 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10502 } 10503} 10504 [(set_attr "isa" "*,*,bmi2") 10505 (set (attr "type") 10506 (cond [(eq_attr "alternative" "1") 10507 (const_string "lea") 10508 (eq_attr "alternative" "2") 10509 (const_string "ishiftx") 10510 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10511 (match_operand 0 "register_operand")) 10512 (match_operand 2 "const1_operand")) 10513 (const_string "alu") 10514 ] 10515 (const_string "ishift"))) 10516 (set (attr "length_immediate") 10517 (if_then_else 10518 (ior (eq_attr "type" "alu") 10519 (and (eq_attr "type" "ishift") 10520 (and (match_operand 2 "const1_operand") 10521 (ior (match_test "TARGET_SHIFT1") 10522 (match_test "optimize_function_for_size_p (cfun)"))))) 10523 (const_string "0") 10524 (const_string "*"))) 10525 (set_attr "mode" "<MODE>")]) 10526 10527;; Convert shift to the shiftx pattern to avoid flags dependency. 10528(define_split 10529 [(set (match_operand:SWI48 0 "register_operand") 10530 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 10531 (match_operand:QI 2 "register_operand"))) 10532 (clobber (reg:CC FLAGS_REG))] 10533 "TARGET_BMI2 && reload_completed" 10534 [(set (match_dup 0) 10535 (ashift:SWI48 (match_dup 1) (match_dup 2)))] 10536 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 10537 10538(define_insn "*bmi2_ashlsi3_1_zext" 10539 [(set (match_operand:DI 0 "register_operand" "=r") 10540 (zero_extend:DI 10541 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10542 (match_operand:SI 2 "register_operand" "r"))))] 10543 "TARGET_64BIT && TARGET_BMI2" 10544 "shlx\t{%2, %1, %k0|%k0, %1, %2}" 10545 [(set_attr "type" "ishiftx") 10546 (set_attr "mode" "SI")]) 10547 10548(define_insn "*ashlsi3_1_zext" 10549 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 10550 (zero_extend:DI 10551 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm") 10552 (match_operand:QI 2 "nonmemory_operand" "cI,M,r")))) 10553 (clobber (reg:CC FLAGS_REG))] 10554 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10555{ 10556 switch (get_attr_type (insn)) 10557 { 10558 case TYPE_LEA: 10559 case TYPE_ISHIFTX: 10560 return "#"; 10561 10562 case TYPE_ALU: 10563 gcc_assert (operands[2] == const1_rtx); 10564 return "add{l}\t%k0, %k0"; 10565 10566 default: 10567 if (operands[2] == const1_rtx 10568 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10569 return "sal{l}\t%k0"; 10570 else 10571 return "sal{l}\t{%2, %k0|%k0, %2}"; 10572 } 10573} 10574 [(set_attr "isa" "*,*,bmi2") 10575 (set (attr "type") 10576 (cond [(eq_attr "alternative" "1") 10577 (const_string "lea") 10578 (eq_attr "alternative" "2") 10579 (const_string "ishiftx") 10580 (and (match_test "TARGET_DOUBLE_WITH_ADD") 10581 (match_operand 2 "const1_operand")) 10582 (const_string "alu") 10583 ] 10584 (const_string "ishift"))) 10585 (set (attr "length_immediate") 10586 (if_then_else 10587 (ior (eq_attr "type" "alu") 10588 (and (eq_attr "type" "ishift") 10589 (and (match_operand 2 "const1_operand") 10590 (ior (match_test "TARGET_SHIFT1") 10591 (match_test "optimize_function_for_size_p (cfun)"))))) 10592 (const_string "0") 10593 (const_string "*"))) 10594 (set_attr "mode" "SI")]) 10595 10596;; Convert shift to the shiftx pattern to avoid flags dependency. 10597(define_split 10598 [(set (match_operand:DI 0 "register_operand") 10599 (zero_extend:DI 10600 (ashift:SI (match_operand:SI 1 "nonimmediate_operand") 10601 (match_operand:QI 2 "register_operand")))) 10602 (clobber (reg:CC FLAGS_REG))] 10603 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10604 [(set (match_dup 0) 10605 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10606 "operands[2] = gen_lowpart (SImode, operands[2]);") 10607 10608(define_insn "*ashlhi3_1" 10609 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") 10610 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10611 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10612 (clobber (reg:CC FLAGS_REG))] 10613 "ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10614{ 10615 switch (get_attr_type (insn)) 10616 { 10617 case TYPE_LEA: 10618 return "#"; 10619 10620 case TYPE_ALU: 10621 gcc_assert (operands[2] == const1_rtx); 10622 return "add{w}\t%0, %0"; 10623 10624 default: 10625 if (operands[2] == const1_rtx 10626 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10627 return "sal{w}\t%0"; 10628 else 10629 return "sal{w}\t{%2, %0|%0, %2}"; 10630 } 10631} 10632 [(set (attr "type") 10633 (cond [(eq_attr "alternative" "1") 10634 (const_string "lea") 10635 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10636 (match_operand 0 "register_operand")) 10637 (match_operand 2 "const1_operand")) 10638 (const_string "alu") 10639 ] 10640 (const_string "ishift"))) 10641 (set (attr "length_immediate") 10642 (if_then_else 10643 (ior (eq_attr "type" "alu") 10644 (and (eq_attr "type" "ishift") 10645 (and (match_operand 2 "const1_operand") 10646 (ior (match_test "TARGET_SHIFT1") 10647 (match_test "optimize_function_for_size_p (cfun)"))))) 10648 (const_string "0") 10649 (const_string "*"))) 10650 (set_attr "mode" "HI,SI")]) 10651 10652(define_insn "*ashlqi3_1" 10653 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") 10654 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 10655 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 10656 (clobber (reg:CC FLAGS_REG))] 10657 "ix86_binary_operator_ok (ASHIFT, QImode, operands)" 10658{ 10659 switch (get_attr_type (insn)) 10660 { 10661 case TYPE_LEA: 10662 return "#"; 10663 10664 case TYPE_ALU: 10665 gcc_assert (operands[2] == const1_rtx); 10666 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1]))) 10667 return "add{l}\t%k0, %k0"; 10668 else 10669 return "add{b}\t%0, %0"; 10670 10671 default: 10672 if (operands[2] == const1_rtx 10673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10674 { 10675 if (get_attr_mode (insn) == MODE_SI) 10676 return "sal{l}\t%k0"; 10677 else 10678 return "sal{b}\t%0"; 10679 } 10680 else 10681 { 10682 if (get_attr_mode (insn) == MODE_SI) 10683 return "sal{l}\t{%2, %k0|%k0, %2}"; 10684 else 10685 return "sal{b}\t{%2, %0|%0, %2}"; 10686 } 10687 } 10688} 10689 [(set (attr "type") 10690 (cond [(eq_attr "alternative" "2") 10691 (const_string "lea") 10692 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10693 (match_operand 0 "register_operand")) 10694 (match_operand 2 "const1_operand")) 10695 (const_string "alu") 10696 ] 10697 (const_string "ishift"))) 10698 (set (attr "length_immediate") 10699 (if_then_else 10700 (ior (eq_attr "type" "alu") 10701 (and (eq_attr "type" "ishift") 10702 (and (match_operand 2 "const1_operand") 10703 (ior (match_test "TARGET_SHIFT1") 10704 (match_test "optimize_function_for_size_p (cfun)"))))) 10705 (const_string "0") 10706 (const_string "*"))) 10707 (set_attr "mode" "QI,SI,SI") 10708 ;; Potential partial reg stall on alternative 1. 10709 (set (attr "preferred_for_speed") 10710 (cond [(eq_attr "alternative" "1") 10711 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 10712 (symbol_ref "true")))]) 10713 10714(define_insn "*ashlqi3_1_slp" 10715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10716 (ashift:QI (match_dup 0) 10717 (match_operand:QI 1 "nonmemory_operand" "cI"))) 10718 (clobber (reg:CC FLAGS_REG))] 10719 "(optimize_function_for_size_p (cfun) 10720 || !TARGET_PARTIAL_FLAG_REG_STALL 10721 || (operands[1] == const1_rtx 10722 && (TARGET_SHIFT1 10723 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10724{ 10725 switch (get_attr_type (insn)) 10726 { 10727 case TYPE_ALU1: 10728 gcc_assert (operands[1] == const1_rtx); 10729 return "add{b}\t%0, %0"; 10730 10731 default: 10732 if (operands[1] == const1_rtx 10733 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10734 return "sal{b}\t%0"; 10735 else 10736 return "sal{b}\t{%1, %0|%0, %1}"; 10737 } 10738} 10739 [(set (attr "type") 10740 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10741 (match_operand 0 "register_operand")) 10742 (match_operand 1 "const1_operand")) 10743 (const_string "alu1") 10744 ] 10745 (const_string "ishift1"))) 10746 (set (attr "length_immediate") 10747 (if_then_else 10748 (ior (eq_attr "type" "alu1") 10749 (and (eq_attr "type" "ishift1") 10750 (and (match_operand 1 "const1_operand") 10751 (ior (match_test "TARGET_SHIFT1") 10752 (match_test "optimize_function_for_size_p (cfun)"))))) 10753 (const_string "0") 10754 (const_string "*"))) 10755 (set_attr "mode" "QI")]) 10756 10757;; Convert ashift to the lea pattern to avoid flags dependency. 10758(define_split 10759 [(set (match_operand:SWI 0 "register_operand") 10760 (ashift:SWI (match_operand:SWI 1 "index_register_operand") 10761 (match_operand 2 "const_0_to_3_operand"))) 10762 (clobber (reg:CC FLAGS_REG))] 10763 "reload_completed 10764 && REGNO (operands[0]) != REGNO (operands[1])" 10765 [(set (match_dup 0) 10766 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))] 10767{ 10768 if (<MODE>mode != <LEAMODE>mode) 10769 { 10770 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]); 10771 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]); 10772 } 10773 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10774}) 10775 10776;; Convert ashift to the lea pattern to avoid flags dependency. 10777(define_split 10778 [(set (match_operand:DI 0 "register_operand") 10779 (zero_extend:DI 10780 (ashift:SI (match_operand:SI 1 "index_register_operand") 10781 (match_operand 2 "const_0_to_3_operand")))) 10782 (clobber (reg:CC FLAGS_REG))] 10783 "TARGET_64BIT && reload_completed 10784 && REGNO (operands[0]) != REGNO (operands[1])" 10785 [(set (match_dup 0) 10786 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))] 10787{ 10788 operands[1] = gen_lowpart (SImode, operands[1]); 10789 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10790}) 10791 10792;; This pattern can't accept a variable shift count, since shifts by 10793;; zero don't affect the flags. We assume that shifts by constant 10794;; zero are optimized away. 10795(define_insn "*ashl<mode>3_cmp" 10796 [(set (reg FLAGS_REG) 10797 (compare 10798 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") 10799 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10800 (const_int 0))) 10801 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10802 (ashift:SWI (match_dup 1) (match_dup 2)))] 10803 "(optimize_function_for_size_p (cfun) 10804 || !TARGET_PARTIAL_FLAG_REG_STALL 10805 || (operands[2] == const1_rtx 10806 && (TARGET_SHIFT1 10807 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) 10808 && ix86_match_ccmode (insn, CCGOCmode) 10809 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 10810{ 10811 switch (get_attr_type (insn)) 10812 { 10813 case TYPE_ALU: 10814 gcc_assert (operands[2] == const1_rtx); 10815 return "add{<imodesuffix>}\t%0, %0"; 10816 10817 default: 10818 if (operands[2] == const1_rtx 10819 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10820 return "sal{<imodesuffix>}\t%0"; 10821 else 10822 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10823 } 10824} 10825 [(set (attr "type") 10826 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10827 (match_operand 0 "register_operand")) 10828 (match_operand 2 "const1_operand")) 10829 (const_string "alu") 10830 ] 10831 (const_string "ishift"))) 10832 (set (attr "length_immediate") 10833 (if_then_else 10834 (ior (eq_attr "type" "alu") 10835 (and (eq_attr "type" "ishift") 10836 (and (match_operand 2 "const1_operand") 10837 (ior (match_test "TARGET_SHIFT1") 10838 (match_test "optimize_function_for_size_p (cfun)"))))) 10839 (const_string "0") 10840 (const_string "*"))) 10841 (set_attr "mode" "<MODE>")]) 10842 10843(define_insn "*ashlsi3_cmp_zext" 10844 [(set (reg FLAGS_REG) 10845 (compare 10846 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10847 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10848 (const_int 0))) 10849 (set (match_operand:DI 0 "register_operand" "=r") 10850 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10851 "TARGET_64BIT 10852 && (optimize_function_for_size_p (cfun) 10853 || !TARGET_PARTIAL_FLAG_REG_STALL 10854 || (operands[2] == const1_rtx 10855 && (TARGET_SHIFT1 10856 || TARGET_DOUBLE_WITH_ADD))) 10857 && ix86_match_ccmode (insn, CCGOCmode) 10858 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10859{ 10860 switch (get_attr_type (insn)) 10861 { 10862 case TYPE_ALU: 10863 gcc_assert (operands[2] == const1_rtx); 10864 return "add{l}\t%k0, %k0"; 10865 10866 default: 10867 if (operands[2] == const1_rtx 10868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10869 return "sal{l}\t%k0"; 10870 else 10871 return "sal{l}\t{%2, %k0|%k0, %2}"; 10872 } 10873} 10874 [(set (attr "type") 10875 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 10876 (match_operand 2 "const1_operand")) 10877 (const_string "alu") 10878 ] 10879 (const_string "ishift"))) 10880 (set (attr "length_immediate") 10881 (if_then_else 10882 (ior (eq_attr "type" "alu") 10883 (and (eq_attr "type" "ishift") 10884 (and (match_operand 2 "const1_operand") 10885 (ior (match_test "TARGET_SHIFT1") 10886 (match_test "optimize_function_for_size_p (cfun)"))))) 10887 (const_string "0") 10888 (const_string "*"))) 10889 (set_attr "mode" "SI")]) 10890 10891(define_insn "*ashl<mode>3_cconly" 10892 [(set (reg FLAGS_REG) 10893 (compare 10894 (ashift:SWI (match_operand:SWI 1 "register_operand" "0") 10895 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10896 (const_int 0))) 10897 (clobber (match_scratch:SWI 0 "=<r>"))] 10898 "(optimize_function_for_size_p (cfun) 10899 || !TARGET_PARTIAL_FLAG_REG_STALL 10900 || (operands[2] == const1_rtx 10901 && (TARGET_SHIFT1 10902 || TARGET_DOUBLE_WITH_ADD))) 10903 && ix86_match_ccmode (insn, CCGOCmode)" 10904{ 10905 switch (get_attr_type (insn)) 10906 { 10907 case TYPE_ALU: 10908 gcc_assert (operands[2] == const1_rtx); 10909 return "add{<imodesuffix>}\t%0, %0"; 10910 10911 default: 10912 if (operands[2] == const1_rtx 10913 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10914 return "sal{<imodesuffix>}\t%0"; 10915 else 10916 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10917 } 10918} 10919 [(set (attr "type") 10920 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10921 (match_operand 0 "register_operand")) 10922 (match_operand 2 "const1_operand")) 10923 (const_string "alu") 10924 ] 10925 (const_string "ishift"))) 10926 (set (attr "length_immediate") 10927 (if_then_else 10928 (ior (eq_attr "type" "alu") 10929 (and (eq_attr "type" "ishift") 10930 (and (match_operand 2 "const1_operand") 10931 (ior (match_test "TARGET_SHIFT1") 10932 (match_test "optimize_function_for_size_p (cfun)"))))) 10933 (const_string "0") 10934 (const_string "*"))) 10935 (set_attr "mode" "<MODE>")]) 10936 10937;; See comment above `ashl<mode>3' about how this works. 10938 10939(define_expand "<shift_insn><mode>3" 10940 [(set (match_operand:SDWIM 0 "<shift_operand>") 10941 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>") 10942 (match_operand:QI 2 "nonmemory_operand")))] 10943 "" 10944 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 10945 10946;; Avoid useless masking of count operand. 10947(define_insn_and_split "*<shift_insn><mode>3_mask" 10948 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10949 (any_shiftrt:SWI48 10950 (match_operand:SWI48 1 "nonimmediate_operand") 10951 (subreg:QI 10952 (and:SI 10953 (match_operand:SI 2 "register_operand" "c,r") 10954 (match_operand:SI 3 "const_int_operand")) 0))) 10955 (clobber (reg:CC FLAGS_REG))] 10956 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10957 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10958 == GET_MODE_BITSIZE (<MODE>mode)-1 10959 && can_create_pseudo_p ()" 10960 "#" 10961 "&& 1" 10962 [(parallel 10963 [(set (match_dup 0) 10964 (any_shiftrt:SWI48 (match_dup 1) 10965 (match_dup 2))) 10966 (clobber (reg:CC FLAGS_REG))])] 10967 "operands[2] = gen_lowpart (QImode, operands[2]);" 10968 [(set_attr "isa" "*,bmi2")]) 10969 10970(define_insn_and_split "*<shift_insn><mode>3_mask_1" 10971 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10972 (any_shiftrt:SWI48 10973 (match_operand:SWI48 1 "nonimmediate_operand") 10974 (and:QI 10975 (match_operand:QI 2 "register_operand" "c,r") 10976 (match_operand:QI 3 "const_int_operand")))) 10977 (clobber (reg:CC FLAGS_REG))] 10978 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10979 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10980 == GET_MODE_BITSIZE (<MODE>mode)-1 10981 && can_create_pseudo_p ()" 10982 "#" 10983 "&& 1" 10984 [(parallel 10985 [(set (match_dup 0) 10986 (any_shiftrt:SWI48 (match_dup 1) 10987 (match_dup 2))) 10988 (clobber (reg:CC FLAGS_REG))])] 10989 "" 10990 [(set_attr "isa" "*,bmi2")]) 10991 10992(define_insn_and_split "*<shift_insn><mode>3_doubleword" 10993 [(set (match_operand:DWI 0 "register_operand" "=&r") 10994 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") 10995 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 10996 (clobber (reg:CC FLAGS_REG))] 10997 "" 10998 "#" 10999 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 11000 [(const_int 0)] 11001 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;" 11002 [(set_attr "type" "multi")]) 11003 11004;; By default we don't ask for a scratch register, because when DWImode 11005;; values are manipulated, registers are already at a premium. But if 11006;; we have one handy, we won't turn it away. 11007 11008(define_peephole2 11009 [(match_scratch:DWIH 3 "r") 11010 (parallel [(set (match_operand:<DWI> 0 "register_operand") 11011 (any_shiftrt:<DWI> 11012 (match_operand:<DWI> 1 "register_operand") 11013 (match_operand:QI 2 "nonmemory_operand"))) 11014 (clobber (reg:CC FLAGS_REG))]) 11015 (match_dup 3)] 11016 "TARGET_CMOVE" 11017 [(const_int 0)] 11018 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;") 11019 11020(define_insn "x86_64_shrd" 11021 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 11022 (ior:DI (lshiftrt:DI (match_dup 0) 11023 (match_operand:QI 2 "nonmemory_operand" "Jc")) 11024 (ashift:DI (match_operand:DI 1 "register_operand" "r") 11025 (minus:QI (const_int 64) (match_dup 2))))) 11026 (clobber (reg:CC FLAGS_REG))] 11027 "TARGET_64BIT" 11028 "shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11029 [(set_attr "type" "ishift") 11030 (set_attr "prefix_0f" "1") 11031 (set_attr "mode" "DI") 11032 (set_attr "athlon_decode" "vector") 11033 (set_attr "amdfam10_decode" "vector") 11034 (set_attr "bdver1_decode" "vector")]) 11035 11036(define_insn "x86_shrd" 11037 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 11038 (ior:SI (lshiftrt:SI (match_dup 0) 11039 (match_operand:QI 2 "nonmemory_operand" "Ic")) 11040 (ashift:SI (match_operand:SI 1 "register_operand" "r") 11041 (minus:QI (const_int 32) (match_dup 2))))) 11042 (clobber (reg:CC FLAGS_REG))] 11043 "" 11044 "shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11045 [(set_attr "type" "ishift") 11046 (set_attr "prefix_0f" "1") 11047 (set_attr "mode" "SI") 11048 (set_attr "pent_pair" "np") 11049 (set_attr "athlon_decode" "vector") 11050 (set_attr "amdfam10_decode" "vector") 11051 (set_attr "bdver1_decode" "vector")]) 11052 11053(define_insn "ashrdi3_cvt" 11054 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 11055 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 11056 (match_operand:QI 2 "const_int_operand"))) 11057 (clobber (reg:CC FLAGS_REG))] 11058 "TARGET_64BIT && INTVAL (operands[2]) == 63 11059 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11060 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11061 "@ 11062 {cqto|cqo} 11063 sar{q}\t{%2, %0|%0, %2}" 11064 [(set_attr "type" "imovx,ishift") 11065 (set_attr "prefix_0f" "0,*") 11066 (set_attr "length_immediate" "0,*") 11067 (set_attr "modrm" "0,1") 11068 (set_attr "mode" "DI")]) 11069 11070(define_insn "*ashrsi3_cvt_zext" 11071 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11072 (zero_extend:DI 11073 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11074 (match_operand:QI 2 "const_int_operand")))) 11075 (clobber (reg:CC FLAGS_REG))] 11076 "TARGET_64BIT && INTVAL (operands[2]) == 31 11077 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11078 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11079 "@ 11080 {cltd|cdq} 11081 sar{l}\t{%2, %k0|%k0, %2}" 11082 [(set_attr "type" "imovx,ishift") 11083 (set_attr "prefix_0f" "0,*") 11084 (set_attr "length_immediate" "0,*") 11085 (set_attr "modrm" "0,1") 11086 (set_attr "mode" "SI")]) 11087 11088(define_insn "ashrsi3_cvt" 11089 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 11090 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 11091 (match_operand:QI 2 "const_int_operand"))) 11092 (clobber (reg:CC FLAGS_REG))] 11093 "INTVAL (operands[2]) == 31 11094 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11095 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11096 "@ 11097 {cltd|cdq} 11098 sar{l}\t{%2, %0|%0, %2}" 11099 [(set_attr "type" "imovx,ishift") 11100 (set_attr "prefix_0f" "0,*") 11101 (set_attr "length_immediate" "0,*") 11102 (set_attr "modrm" "0,1") 11103 (set_attr "mode" "SI")]) 11104 11105(define_expand "x86_shift<mode>_adj_3" 11106 [(use (match_operand:SWI48 0 "register_operand")) 11107 (use (match_operand:SWI48 1 "register_operand")) 11108 (use (match_operand:QI 2 "register_operand"))] 11109 "" 11110{ 11111 rtx_code_label *label = gen_label_rtx (); 11112 rtx tmp; 11113 11114 emit_insn (gen_testqi_ccz_1 (operands[2], 11115 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 11116 11117 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11118 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11119 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11120 gen_rtx_LABEL_REF (VOIDmode, label), 11121 pc_rtx); 11122 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 11123 JUMP_LABEL (tmp) = label; 11124 11125 emit_move_insn (operands[0], operands[1]); 11126 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1], 11127 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1))); 11128 emit_label (label); 11129 LABEL_NUSES (label) = 1; 11130 11131 DONE; 11132}) 11133 11134(define_insn "*bmi2_<shift_insn><mode>3_1" 11135 [(set (match_operand:SWI48 0 "register_operand" "=r") 11136 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 11137 (match_operand:SWI48 2 "register_operand" "r")))] 11138 "TARGET_BMI2" 11139 "<shift>x\t{%2, %1, %0|%0, %1, %2}" 11140 [(set_attr "type" "ishiftx") 11141 (set_attr "mode" "<MODE>")]) 11142 11143(define_insn "*<shift_insn><mode>3_1" 11144 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 11145 (any_shiftrt:SWI48 11146 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 11147 (match_operand:QI 2 "nonmemory_operand" "c<S>,r"))) 11148 (clobber (reg:CC FLAGS_REG))] 11149 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11150{ 11151 switch (get_attr_type (insn)) 11152 { 11153 case TYPE_ISHIFTX: 11154 return "#"; 11155 11156 default: 11157 if (operands[2] == const1_rtx 11158 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11159 return "<shift>{<imodesuffix>}\t%0"; 11160 else 11161 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11162 } 11163} 11164 [(set_attr "isa" "*,bmi2") 11165 (set_attr "type" "ishift,ishiftx") 11166 (set (attr "length_immediate") 11167 (if_then_else 11168 (and (match_operand 2 "const1_operand") 11169 (ior (match_test "TARGET_SHIFT1") 11170 (match_test "optimize_function_for_size_p (cfun)"))) 11171 (const_string "0") 11172 (const_string "*"))) 11173 (set_attr "mode" "<MODE>")]) 11174 11175;; Convert shift to the shiftx pattern to avoid flags dependency. 11176(define_split 11177 [(set (match_operand:SWI48 0 "register_operand") 11178 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11179 (match_operand:QI 2 "register_operand"))) 11180 (clobber (reg:CC FLAGS_REG))] 11181 "TARGET_BMI2 && reload_completed" 11182 [(set (match_dup 0) 11183 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))] 11184 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 11185 11186(define_insn "*bmi2_<shift_insn>si3_1_zext" 11187 [(set (match_operand:DI 0 "register_operand" "=r") 11188 (zero_extend:DI 11189 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 11190 (match_operand:SI 2 "register_operand" "r"))))] 11191 "TARGET_64BIT && TARGET_BMI2" 11192 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}" 11193 [(set_attr "type" "ishiftx") 11194 (set_attr "mode" "SI")]) 11195 11196(define_insn "*<shift_insn>si3_1_zext" 11197 [(set (match_operand:DI 0 "register_operand" "=r,r") 11198 (zero_extend:DI 11199 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 11200 (match_operand:QI 2 "nonmemory_operand" "cI,r")))) 11201 (clobber (reg:CC FLAGS_REG))] 11202 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11203{ 11204 switch (get_attr_type (insn)) 11205 { 11206 case TYPE_ISHIFTX: 11207 return "#"; 11208 11209 default: 11210 if (operands[2] == const1_rtx 11211 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11212 return "<shift>{l}\t%k0"; 11213 else 11214 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 11215 } 11216} 11217 [(set_attr "isa" "*,bmi2") 11218 (set_attr "type" "ishift,ishiftx") 11219 (set (attr "length_immediate") 11220 (if_then_else 11221 (and (match_operand 2 "const1_operand") 11222 (ior (match_test "TARGET_SHIFT1") 11223 (match_test "optimize_function_for_size_p (cfun)"))) 11224 (const_string "0") 11225 (const_string "*"))) 11226 (set_attr "mode" "SI")]) 11227 11228;; Convert shift to the shiftx pattern to avoid flags dependency. 11229(define_split 11230 [(set (match_operand:DI 0 "register_operand") 11231 (zero_extend:DI 11232 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand") 11233 (match_operand:QI 2 "register_operand")))) 11234 (clobber (reg:CC FLAGS_REG))] 11235 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11236 [(set (match_dup 0) 11237 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 11238 "operands[2] = gen_lowpart (SImode, operands[2]);") 11239 11240(define_insn "*<shift_insn><mode>3_1" 11241 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 11242 (any_shiftrt:SWI12 11243 (match_operand:SWI12 1 "nonimmediate_operand" "0") 11244 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 11245 (clobber (reg:CC FLAGS_REG))] 11246 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11247{ 11248 if (operands[2] == const1_rtx 11249 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11250 return "<shift>{<imodesuffix>}\t%0"; 11251 else 11252 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11253} 11254 [(set_attr "type" "ishift") 11255 (set (attr "length_immediate") 11256 (if_then_else 11257 (and (match_operand 2 "const1_operand") 11258 (ior (match_test "TARGET_SHIFT1") 11259 (match_test "optimize_function_for_size_p (cfun)"))) 11260 (const_string "0") 11261 (const_string "*"))) 11262 (set_attr "mode" "<MODE>")]) 11263 11264(define_insn "*<shift_insn>qi3_1_slp" 11265 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11266 (any_shiftrt:QI (match_dup 0) 11267 (match_operand:QI 1 "nonmemory_operand" "cI"))) 11268 (clobber (reg:CC FLAGS_REG))] 11269 "(optimize_function_for_size_p (cfun) 11270 || !TARGET_PARTIAL_REG_STALL 11271 || (operands[1] == const1_rtx 11272 && TARGET_SHIFT1))" 11273{ 11274 if (operands[1] == const1_rtx 11275 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11276 return "<shift>{b}\t%0"; 11277 else 11278 return "<shift>{b}\t{%1, %0|%0, %1}"; 11279} 11280 [(set_attr "type" "ishift1") 11281 (set (attr "length_immediate") 11282 (if_then_else 11283 (and (match_operand 1 "const1_operand") 11284 (ior (match_test "TARGET_SHIFT1") 11285 (match_test "optimize_function_for_size_p (cfun)"))) 11286 (const_string "0") 11287 (const_string "*"))) 11288 (set_attr "mode" "QI")]) 11289 11290;; This pattern can't accept a variable shift count, since shifts by 11291;; zero don't affect the flags. We assume that shifts by constant 11292;; zero are optimized away. 11293(define_insn "*<shift_insn><mode>3_cmp" 11294 [(set (reg FLAGS_REG) 11295 (compare 11296 (any_shiftrt:SWI 11297 (match_operand:SWI 1 "nonimmediate_operand" "0") 11298 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11299 (const_int 0))) 11300 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 11301 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] 11302 "(optimize_function_for_size_p (cfun) 11303 || !TARGET_PARTIAL_FLAG_REG_STALL 11304 || (operands[2] == const1_rtx 11305 && TARGET_SHIFT1)) 11306 && ix86_match_ccmode (insn, CCGOCmode) 11307 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11308{ 11309 if (operands[2] == const1_rtx 11310 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11311 return "<shift>{<imodesuffix>}\t%0"; 11312 else 11313 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11314} 11315 [(set_attr "type" "ishift") 11316 (set (attr "length_immediate") 11317 (if_then_else 11318 (and (match_operand 2 "const1_operand") 11319 (ior (match_test "TARGET_SHIFT1") 11320 (match_test "optimize_function_for_size_p (cfun)"))) 11321 (const_string "0") 11322 (const_string "*"))) 11323 (set_attr "mode" "<MODE>")]) 11324 11325(define_insn "*<shift_insn>si3_cmp_zext" 11326 [(set (reg FLAGS_REG) 11327 (compare 11328 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") 11329 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11330 (const_int 0))) 11331 (set (match_operand:DI 0 "register_operand" "=r") 11332 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 11333 "TARGET_64BIT 11334 && (optimize_function_for_size_p (cfun) 11335 || !TARGET_PARTIAL_FLAG_REG_STALL 11336 || (operands[2] == const1_rtx 11337 && TARGET_SHIFT1)) 11338 && ix86_match_ccmode (insn, CCGOCmode) 11339 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11340{ 11341 if (operands[2] == const1_rtx 11342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11343 return "<shift>{l}\t%k0"; 11344 else 11345 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 11346} 11347 [(set_attr "type" "ishift") 11348 (set (attr "length_immediate") 11349 (if_then_else 11350 (and (match_operand 2 "const1_operand") 11351 (ior (match_test "TARGET_SHIFT1") 11352 (match_test "optimize_function_for_size_p (cfun)"))) 11353 (const_string "0") 11354 (const_string "*"))) 11355 (set_attr "mode" "SI")]) 11356 11357(define_insn "*<shift_insn><mode>3_cconly" 11358 [(set (reg FLAGS_REG) 11359 (compare 11360 (any_shiftrt:SWI 11361 (match_operand:SWI 1 "register_operand" "0") 11362 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11363 (const_int 0))) 11364 (clobber (match_scratch:SWI 0 "=<r>"))] 11365 "(optimize_function_for_size_p (cfun) 11366 || !TARGET_PARTIAL_FLAG_REG_STALL 11367 || (operands[2] == const1_rtx 11368 && TARGET_SHIFT1)) 11369 && ix86_match_ccmode (insn, CCGOCmode)" 11370{ 11371 if (operands[2] == const1_rtx 11372 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11373 return "<shift>{<imodesuffix>}\t%0"; 11374 else 11375 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11376} 11377 [(set_attr "type" "ishift") 11378 (set (attr "length_immediate") 11379 (if_then_else 11380 (and (match_operand 2 "const1_operand") 11381 (ior (match_test "TARGET_SHIFT1") 11382 (match_test "optimize_function_for_size_p (cfun)"))) 11383 (const_string "0") 11384 (const_string "*"))) 11385 (set_attr "mode" "<MODE>")]) 11386 11387;; Rotate instructions 11388 11389(define_expand "<rotate_insn>ti3" 11390 [(set (match_operand:TI 0 "register_operand") 11391 (any_rotate:TI (match_operand:TI 1 "register_operand") 11392 (match_operand:QI 2 "nonmemory_operand")))] 11393 "TARGET_64BIT" 11394{ 11395 if (const_1_to_63_operand (operands[2], VOIDmode)) 11396 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword 11397 (operands[0], operands[1], operands[2])); 11398 else 11399 FAIL; 11400 11401 DONE; 11402}) 11403 11404(define_expand "<rotate_insn>di3" 11405 [(set (match_operand:DI 0 "shiftdi_operand") 11406 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand") 11407 (match_operand:QI 2 "nonmemory_operand")))] 11408 "" 11409{ 11410 if (TARGET_64BIT) 11411 ix86_expand_binary_operator (<CODE>, DImode, operands); 11412 else if (const_1_to_31_operand (operands[2], VOIDmode)) 11413 emit_insn (gen_ix86_<rotate_insn>di3_doubleword 11414 (operands[0], operands[1], operands[2])); 11415 else 11416 FAIL; 11417 11418 DONE; 11419}) 11420 11421(define_expand "<rotate_insn><mode>3" 11422 [(set (match_operand:SWIM124 0 "nonimmediate_operand") 11423 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand") 11424 (match_operand:QI 2 "nonmemory_operand")))] 11425 "" 11426 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 11427 11428;; Avoid useless masking of count operand. 11429(define_insn_and_split "*<rotate_insn><mode>3_mask" 11430 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11431 (any_rotate:SWI48 11432 (match_operand:SWI48 1 "nonimmediate_operand") 11433 (subreg:QI 11434 (and:SI 11435 (match_operand:SI 2 "register_operand" "c") 11436 (match_operand:SI 3 "const_int_operand")) 0))) 11437 (clobber (reg:CC FLAGS_REG))] 11438 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11439 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11440 == GET_MODE_BITSIZE (<MODE>mode)-1 11441 && can_create_pseudo_p ()" 11442 "#" 11443 "&& 1" 11444 [(parallel 11445 [(set (match_dup 0) 11446 (any_rotate:SWI48 (match_dup 1) 11447 (match_dup 2))) 11448 (clobber (reg:CC FLAGS_REG))])] 11449 "operands[2] = gen_lowpart (QImode, operands[2]);") 11450 11451(define_insn_and_split "*<rotate_insn><mode>3_mask_1" 11452 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11453 (any_rotate:SWI48 11454 (match_operand:SWI48 1 "nonimmediate_operand") 11455 (and:QI 11456 (match_operand:QI 2 "register_operand" "c") 11457 (match_operand:QI 3 "const_int_operand")))) 11458 (clobber (reg:CC FLAGS_REG))] 11459 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11460 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11461 == GET_MODE_BITSIZE (<MODE>mode)-1 11462 && can_create_pseudo_p ()" 11463 "#" 11464 "&& 1" 11465 [(parallel 11466 [(set (match_dup 0) 11467 (any_rotate:SWI48 (match_dup 1) 11468 (match_dup 2))) 11469 (clobber (reg:CC FLAGS_REG))])]) 11470 11471;; Implement rotation using two double-precision 11472;; shift instructions and a scratch register. 11473 11474(define_insn_and_split "ix86_rotl<dwi>3_doubleword" 11475 [(set (match_operand:<DWI> 0 "register_operand" "=r") 11476 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 11477 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 11478 (clobber (reg:CC FLAGS_REG)) 11479 (clobber (match_scratch:DWIH 3 "=&r"))] 11480 "" 11481 "#" 11482 "reload_completed" 11483 [(set (match_dup 3) (match_dup 4)) 11484 (parallel 11485 [(set (match_dup 4) 11486 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) 11487 (lshiftrt:DWIH (match_dup 5) 11488 (minus:QI (match_dup 6) (match_dup 2))))) 11489 (clobber (reg:CC FLAGS_REG))]) 11490 (parallel 11491 [(set (match_dup 5) 11492 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) 11493 (lshiftrt:DWIH (match_dup 3) 11494 (minus:QI (match_dup 6) (match_dup 2))))) 11495 (clobber (reg:CC FLAGS_REG))])] 11496{ 11497 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 11498 11499 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 11500}) 11501 11502(define_insn_and_split "ix86_rotr<dwi>3_doubleword" 11503 [(set (match_operand:<DWI> 0 "register_operand" "=r") 11504 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 11505 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 11506 (clobber (reg:CC FLAGS_REG)) 11507 (clobber (match_scratch:DWIH 3 "=&r"))] 11508 "" 11509 "#" 11510 "reload_completed" 11511 [(set (match_dup 3) (match_dup 4)) 11512 (parallel 11513 [(set (match_dup 4) 11514 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) 11515 (ashift:DWIH (match_dup 5) 11516 (minus:QI (match_dup 6) (match_dup 2))))) 11517 (clobber (reg:CC FLAGS_REG))]) 11518 (parallel 11519 [(set (match_dup 5) 11520 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2)) 11521 (ashift:DWIH (match_dup 3) 11522 (minus:QI (match_dup 6) (match_dup 2))))) 11523 (clobber (reg:CC FLAGS_REG))])] 11524{ 11525 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 11526 11527 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 11528}) 11529 11530(define_mode_attr rorx_immediate_operand 11531 [(SI "const_0_to_31_operand") 11532 (DI "const_0_to_63_operand")]) 11533 11534(define_insn "*bmi2_rorx<mode>3_1" 11535 [(set (match_operand:SWI48 0 "register_operand" "=r") 11536 (rotatert:SWI48 11537 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 11538 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))] 11539 "TARGET_BMI2" 11540 "rorx\t{%2, %1, %0|%0, %1, %2}" 11541 [(set_attr "type" "rotatex") 11542 (set_attr "mode" "<MODE>")]) 11543 11544(define_insn "*<rotate_insn><mode>3_1" 11545 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 11546 (any_rotate:SWI48 11547 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 11548 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>"))) 11549 (clobber (reg:CC FLAGS_REG))] 11550 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11551{ 11552 switch (get_attr_type (insn)) 11553 { 11554 case TYPE_ROTATEX: 11555 return "#"; 11556 11557 default: 11558 if (operands[2] == const1_rtx 11559 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11560 return "<rotate>{<imodesuffix>}\t%0"; 11561 else 11562 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11563 } 11564} 11565 [(set_attr "isa" "*,bmi2") 11566 (set_attr "type" "rotate,rotatex") 11567 (set (attr "length_immediate") 11568 (if_then_else 11569 (and (eq_attr "type" "rotate") 11570 (and (match_operand 2 "const1_operand") 11571 (ior (match_test "TARGET_SHIFT1") 11572 (match_test "optimize_function_for_size_p (cfun)")))) 11573 (const_string "0") 11574 (const_string "*"))) 11575 (set_attr "mode" "<MODE>")]) 11576 11577;; Convert rotate to the rotatex pattern to avoid flags dependency. 11578(define_split 11579 [(set (match_operand:SWI48 0 "register_operand") 11580 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11581 (match_operand:QI 2 "const_int_operand"))) 11582 (clobber (reg:CC FLAGS_REG))] 11583 "TARGET_BMI2 && reload_completed" 11584 [(set (match_dup 0) 11585 (rotatert:SWI48 (match_dup 1) (match_dup 2)))] 11586{ 11587 int bitsize = GET_MODE_BITSIZE (<MODE>mode); 11588 11589 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize); 11590}) 11591 11592(define_split 11593 [(set (match_operand:SWI48 0 "register_operand") 11594 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11595 (match_operand:QI 2 "const_int_operand"))) 11596 (clobber (reg:CC FLAGS_REG))] 11597 "TARGET_BMI2 && reload_completed" 11598 [(set (match_dup 0) 11599 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]) 11600 11601(define_insn "*bmi2_rorxsi3_1_zext" 11602 [(set (match_operand:DI 0 "register_operand" "=r") 11603 (zero_extend:DI 11604 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 11605 (match_operand:QI 2 "const_0_to_31_operand" "I"))))] 11606 "TARGET_64BIT && TARGET_BMI2" 11607 "rorx\t{%2, %1, %k0|%k0, %1, %2}" 11608 [(set_attr "type" "rotatex") 11609 (set_attr "mode" "SI")]) 11610 11611(define_insn "*<rotate_insn>si3_1_zext" 11612 [(set (match_operand:DI 0 "register_operand" "=r,r") 11613 (zero_extend:DI 11614 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 11615 (match_operand:QI 2 "nonmemory_operand" "cI,I")))) 11616 (clobber (reg:CC FLAGS_REG))] 11617 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11618{ 11619 switch (get_attr_type (insn)) 11620 { 11621 case TYPE_ROTATEX: 11622 return "#"; 11623 11624 default: 11625 if (operands[2] == const1_rtx 11626 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11627 return "<rotate>{l}\t%k0"; 11628 else 11629 return "<rotate>{l}\t{%2, %k0|%k0, %2}"; 11630 } 11631} 11632 [(set_attr "isa" "*,bmi2") 11633 (set_attr "type" "rotate,rotatex") 11634 (set (attr "length_immediate") 11635 (if_then_else 11636 (and (eq_attr "type" "rotate") 11637 (and (match_operand 2 "const1_operand") 11638 (ior (match_test "TARGET_SHIFT1") 11639 (match_test "optimize_function_for_size_p (cfun)")))) 11640 (const_string "0") 11641 (const_string "*"))) 11642 (set_attr "mode" "SI")]) 11643 11644;; Convert rotate to the rotatex pattern to avoid flags dependency. 11645(define_split 11646 [(set (match_operand:DI 0 "register_operand") 11647 (zero_extend:DI 11648 (rotate:SI (match_operand:SI 1 "nonimmediate_operand") 11649 (match_operand:QI 2 "const_int_operand")))) 11650 (clobber (reg:CC FLAGS_REG))] 11651 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11652 [(set (match_dup 0) 11653 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))] 11654{ 11655 int bitsize = GET_MODE_BITSIZE (SImode); 11656 11657 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize); 11658}) 11659 11660(define_split 11661 [(set (match_operand:DI 0 "register_operand") 11662 (zero_extend:DI 11663 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand") 11664 (match_operand:QI 2 "const_int_operand")))) 11665 (clobber (reg:CC FLAGS_REG))] 11666 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11667 [(set (match_dup 0) 11668 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) 11669 11670(define_insn "*<rotate_insn><mode>3_1" 11671 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 11672 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0") 11673 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 11674 (clobber (reg:CC FLAGS_REG))] 11675 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11676{ 11677 if (operands[2] == const1_rtx 11678 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11679 return "<rotate>{<imodesuffix>}\t%0"; 11680 else 11681 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11682} 11683 [(set_attr "type" "rotate") 11684 (set (attr "length_immediate") 11685 (if_then_else 11686 (and (match_operand 2 "const1_operand") 11687 (ior (match_test "TARGET_SHIFT1") 11688 (match_test "optimize_function_for_size_p (cfun)"))) 11689 (const_string "0") 11690 (const_string "*"))) 11691 (set_attr "mode" "<MODE>")]) 11692 11693(define_insn "*<rotate_insn>qi3_1_slp" 11694 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11695 (any_rotate:QI (match_dup 0) 11696 (match_operand:QI 1 "nonmemory_operand" "cI"))) 11697 (clobber (reg:CC FLAGS_REG))] 11698 "(optimize_function_for_size_p (cfun) 11699 || !TARGET_PARTIAL_REG_STALL 11700 || (operands[1] == const1_rtx 11701 && TARGET_SHIFT1))" 11702{ 11703 if (operands[1] == const1_rtx 11704 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11705 return "<rotate>{b}\t%0"; 11706 else 11707 return "<rotate>{b}\t{%1, %0|%0, %1}"; 11708} 11709 [(set_attr "type" "rotate1") 11710 (set (attr "length_immediate") 11711 (if_then_else 11712 (and (match_operand 1 "const1_operand") 11713 (ior (match_test "TARGET_SHIFT1") 11714 (match_test "optimize_function_for_size_p (cfun)"))) 11715 (const_string "0") 11716 (const_string "*"))) 11717 (set_attr "mode" "QI")]) 11718 11719(define_split 11720 [(set (match_operand:HI 0 "QIreg_operand") 11721 (any_rotate:HI (match_dup 0) (const_int 8))) 11722 (clobber (reg:CC FLAGS_REG))] 11723 "reload_completed 11724 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" 11725 [(parallel [(set (strict_low_part (match_dup 0)) 11726 (bswap:HI (match_dup 0))) 11727 (clobber (reg:CC FLAGS_REG))])]) 11728 11729;; Bit set / bit test instructions 11730 11731;; %%% bts, btr, btc 11732 11733;; These instructions are *slow* when applied to memory. 11734 11735(define_code_attr btsc [(ior "bts") (xor "btc")]) 11736 11737(define_insn "*<btsc><mode>" 11738 [(set (match_operand:SWI48 0 "register_operand" "=r") 11739 (any_or:SWI48 11740 (ashift:SWI48 (const_int 1) 11741 (match_operand:QI 2 "register_operand" "r")) 11742 (match_operand:SWI48 1 "register_operand" "0"))) 11743 (clobber (reg:CC FLAGS_REG))] 11744 "TARGET_USE_BT" 11745 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}" 11746 [(set_attr "type" "alu1") 11747 (set_attr "prefix_0f" "1") 11748 (set_attr "znver1_decode" "double") 11749 (set_attr "mode" "<MODE>")]) 11750 11751;; Avoid useless masking of count operand. 11752(define_insn_and_split "*<btsc><mode>_mask" 11753 [(set (match_operand:SWI48 0 "register_operand") 11754 (any_or:SWI48 11755 (ashift:SWI48 11756 (const_int 1) 11757 (subreg:QI 11758 (and:SI 11759 (match_operand:SI 1 "register_operand") 11760 (match_operand:SI 2 "const_int_operand")) 0)) 11761 (match_operand:SWI48 3 "register_operand"))) 11762 (clobber (reg:CC FLAGS_REG))] 11763 "TARGET_USE_BT 11764 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11765 == GET_MODE_BITSIZE (<MODE>mode)-1 11766 && can_create_pseudo_p ()" 11767 "#" 11768 "&& 1" 11769 [(parallel 11770 [(set (match_dup 0) 11771 (any_or:SWI48 11772 (ashift:SWI48 (const_int 1) 11773 (match_dup 1)) 11774 (match_dup 3))) 11775 (clobber (reg:CC FLAGS_REG))])] 11776 "operands[1] = gen_lowpart (QImode, operands[1]);") 11777 11778(define_insn_and_split "*<btsc><mode>_mask_1" 11779 [(set (match_operand:SWI48 0 "register_operand") 11780 (any_or:SWI48 11781 (ashift:SWI48 11782 (const_int 1) 11783 (and:QI 11784 (match_operand:QI 1 "register_operand") 11785 (match_operand:QI 2 "const_int_operand"))) 11786 (match_operand:SWI48 3 "register_operand"))) 11787 (clobber (reg:CC FLAGS_REG))] 11788 "TARGET_USE_BT 11789 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11790 == GET_MODE_BITSIZE (<MODE>mode)-1 11791 && can_create_pseudo_p ()" 11792 "#" 11793 "&& 1" 11794 [(parallel 11795 [(set (match_dup 0) 11796 (any_or:SWI48 11797 (ashift:SWI48 (const_int 1) 11798 (match_dup 1)) 11799 (match_dup 3))) 11800 (clobber (reg:CC FLAGS_REG))])]) 11801 11802(define_insn "*btr<mode>" 11803 [(set (match_operand:SWI48 0 "register_operand" "=r") 11804 (and:SWI48 11805 (rotate:SWI48 (const_int -2) 11806 (match_operand:QI 2 "register_operand" "r")) 11807 (match_operand:SWI48 1 "register_operand" "0"))) 11808 (clobber (reg:CC FLAGS_REG))] 11809 "TARGET_USE_BT" 11810 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}" 11811 [(set_attr "type" "alu1") 11812 (set_attr "prefix_0f" "1") 11813 (set_attr "znver1_decode" "double") 11814 (set_attr "mode" "<MODE>")]) 11815 11816;; Avoid useless masking of count operand. 11817(define_insn_and_split "*btr<mode>_mask" 11818 [(set (match_operand:SWI48 0 "register_operand") 11819 (and:SWI48 11820 (rotate:SWI48 11821 (const_int -2) 11822 (subreg:QI 11823 (and:SI 11824 (match_operand:SI 1 "register_operand") 11825 (match_operand:SI 2 "const_int_operand")) 0)) 11826 (match_operand:SWI48 3 "register_operand"))) 11827 (clobber (reg:CC FLAGS_REG))] 11828 "TARGET_USE_BT 11829 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11830 == GET_MODE_BITSIZE (<MODE>mode)-1 11831 && can_create_pseudo_p ()" 11832 "#" 11833 "&& 1" 11834 [(parallel 11835 [(set (match_dup 0) 11836 (and:SWI48 11837 (rotate:SWI48 (const_int -2) 11838 (match_dup 1)) 11839 (match_dup 3))) 11840 (clobber (reg:CC FLAGS_REG))])] 11841 "operands[1] = gen_lowpart (QImode, operands[1]);") 11842 11843(define_insn_and_split "*btr<mode>_mask_1" 11844 [(set (match_operand:SWI48 0 "register_operand") 11845 (and:SWI48 11846 (rotate:SWI48 11847 (const_int -2) 11848 (and:QI 11849 (match_operand:QI 1 "register_operand") 11850 (match_operand:QI 2 "const_int_operand"))) 11851 (match_operand:SWI48 3 "register_operand"))) 11852 (clobber (reg:CC FLAGS_REG))] 11853 "TARGET_USE_BT 11854 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11855 == GET_MODE_BITSIZE (<MODE>mode)-1 11856 && can_create_pseudo_p ()" 11857 "#" 11858 "&& 1" 11859 [(parallel 11860 [(set (match_dup 0) 11861 (and:SWI48 11862 (rotate:SWI48 (const_int -2) 11863 (match_dup 1)) 11864 (match_dup 3))) 11865 (clobber (reg:CC FLAGS_REG))])]) 11866 11867;; These instructions are never faster than the corresponding 11868;; and/ior/xor operations when using immediate operand, so with 11869;; 32-bit there's no point. But in 64-bit, we can't hold the 11870;; relevant immediates within the instruction itself, so operating 11871;; on bits in the high 32-bits of a register becomes easier. 11872;; 11873;; These are slow on Nocona, but fast on Athlon64. We do require the use 11874;; of btrq and btcq for corner cases of post-reload expansion of absdf and 11875;; negdf respectively, so they can never be disabled entirely. 11876 11877(define_insn "*btsq_imm" 11878 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11879 (const_int 1) 11880 (match_operand 1 "const_0_to_63_operand" "J")) 11881 (const_int 1)) 11882 (clobber (reg:CC FLAGS_REG))] 11883 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11884 "bts{q}\t{%1, %0|%0, %1}" 11885 [(set_attr "type" "alu1") 11886 (set_attr "prefix_0f" "1") 11887 (set_attr "znver1_decode" "double") 11888 (set_attr "mode" "DI")]) 11889 11890(define_insn "*btrq_imm" 11891 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11892 (const_int 1) 11893 (match_operand 1 "const_0_to_63_operand" "J")) 11894 (const_int 0)) 11895 (clobber (reg:CC FLAGS_REG))] 11896 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11897 "btr{q}\t{%1, %0|%0, %1}" 11898 [(set_attr "type" "alu1") 11899 (set_attr "prefix_0f" "1") 11900 (set_attr "znver1_decode" "double") 11901 (set_attr "mode" "DI")]) 11902 11903(define_insn "*btcq_imm" 11904 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11905 (const_int 1) 11906 (match_operand 1 "const_0_to_63_operand" "J")) 11907 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 11908 (clobber (reg:CC FLAGS_REG))] 11909 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11910 "btc{q}\t{%1, %0|%0, %1}" 11911 [(set_attr "type" "alu1") 11912 (set_attr "prefix_0f" "1") 11913 (set_attr "znver1_decode" "double") 11914 (set_attr "mode" "DI")]) 11915 11916;; Allow Nocona to avoid these instructions if a register is available. 11917 11918(define_peephole2 11919 [(match_scratch:DI 2 "r") 11920 (parallel [(set (zero_extract:DI 11921 (match_operand:DI 0 "nonimmediate_operand") 11922 (const_int 1) 11923 (match_operand 1 "const_0_to_63_operand")) 11924 (const_int 1)) 11925 (clobber (reg:CC FLAGS_REG))])] 11926 "TARGET_64BIT && !TARGET_USE_BT" 11927 [(parallel [(set (match_dup 0) 11928 (ior:DI (match_dup 0) (match_dup 3))) 11929 (clobber (reg:CC FLAGS_REG))])] 11930{ 11931 int i = INTVAL (operands[1]); 11932 11933 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); 11934 11935 if (!x86_64_immediate_operand (operands[3], DImode)) 11936 { 11937 emit_move_insn (operands[2], operands[3]); 11938 operands[3] = operands[2]; 11939 } 11940}) 11941 11942(define_peephole2 11943 [(match_scratch:DI 2 "r") 11944 (parallel [(set (zero_extract:DI 11945 (match_operand:DI 0 "nonimmediate_operand") 11946 (const_int 1) 11947 (match_operand 1 "const_0_to_63_operand")) 11948 (const_int 0)) 11949 (clobber (reg:CC FLAGS_REG))])] 11950 "TARGET_64BIT && !TARGET_USE_BT" 11951 [(parallel [(set (match_dup 0) 11952 (and:DI (match_dup 0) (match_dup 3))) 11953 (clobber (reg:CC FLAGS_REG))])] 11954{ 11955 int i = INTVAL (operands[1]); 11956 11957 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode); 11958 11959 if (!x86_64_immediate_operand (operands[3], DImode)) 11960 { 11961 emit_move_insn (operands[2], operands[3]); 11962 operands[3] = operands[2]; 11963 } 11964}) 11965 11966(define_peephole2 11967 [(match_scratch:DI 2 "r") 11968 (parallel [(set (zero_extract:DI 11969 (match_operand:DI 0 "nonimmediate_operand") 11970 (const_int 1) 11971 (match_operand 1 "const_0_to_63_operand")) 11972 (not:DI (zero_extract:DI 11973 (match_dup 0) (const_int 1) (match_dup 1)))) 11974 (clobber (reg:CC FLAGS_REG))])] 11975 "TARGET_64BIT && !TARGET_USE_BT" 11976 [(parallel [(set (match_dup 0) 11977 (xor:DI (match_dup 0) (match_dup 3))) 11978 (clobber (reg:CC FLAGS_REG))])] 11979{ 11980 int i = INTVAL (operands[1]); 11981 11982 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); 11983 11984 if (!x86_64_immediate_operand (operands[3], DImode)) 11985 { 11986 emit_move_insn (operands[2], operands[3]); 11987 operands[3] = operands[2]; 11988 } 11989}) 11990 11991;; %%% bt 11992 11993(define_insn "*bt<mode>" 11994 [(set (reg:CCC FLAGS_REG) 11995 (compare:CCC 11996 (zero_extract:SWI48 11997 (match_operand:SWI48 0 "nonimmediate_operand" "r,m") 11998 (const_int 1) 11999 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>")) 12000 (const_int 0)))] 12001 "" 12002{ 12003 switch (get_attr_mode (insn)) 12004 { 12005 case MODE_SI: 12006 return "bt{l}\t{%1, %k0|%k0, %1}"; 12007 12008 case MODE_DI: 12009 return "bt{q}\t{%q1, %0|%0, %q1}"; 12010 12011 default: 12012 gcc_unreachable (); 12013 } 12014} 12015 [(set_attr "type" "alu1") 12016 (set_attr "prefix_0f" "1") 12017 (set (attr "mode") 12018 (if_then_else 12019 (and (match_test "CONST_INT_P (operands[1])") 12020 (match_test "INTVAL (operands[1]) < 32")) 12021 (const_string "SI") 12022 (const_string "<MODE>")))]) 12023 12024(define_insn_and_split "*jcc_bt<mode>" 12025 [(set (pc) 12026 (if_then_else (match_operator 0 "bt_comparison_operator" 12027 [(zero_extract:SWI48 12028 (match_operand:SWI48 1 "nonimmediate_operand") 12029 (const_int 1) 12030 (match_operand:SI 2 "nonmemory_operand")) 12031 (const_int 0)]) 12032 (label_ref (match_operand 3)) 12033 (pc))) 12034 (clobber (reg:CC FLAGS_REG))] 12035 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12036 && (CONST_INT_P (operands[2]) 12037 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode) 12038 && INTVAL (operands[2]) 12039 >= (optimize_function_for_size_p (cfun) ? 8 : 32)) 12040 : !memory_operand (operands[1], <MODE>mode)) 12041 && can_create_pseudo_p ()" 12042 "#" 12043 "&& 1" 12044 [(set (reg:CCC FLAGS_REG) 12045 (compare:CCC 12046 (zero_extract:SWI48 12047 (match_dup 1) 12048 (const_int 1) 12049 (match_dup 2)) 12050 (const_int 0))) 12051 (set (pc) 12052 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12053 (label_ref (match_dup 3)) 12054 (pc)))] 12055{ 12056 operands[0] = shallow_copy_rtx (operands[0]); 12057 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12058}) 12059 12060(define_insn_and_split "*jcc_bt<mode>_1" 12061 [(set (pc) 12062 (if_then_else (match_operator 0 "bt_comparison_operator" 12063 [(zero_extract:SWI48 12064 (match_operand:SWI48 1 "register_operand") 12065 (const_int 1) 12066 (zero_extend:SI 12067 (match_operand:QI 2 "register_operand"))) 12068 (const_int 0)]) 12069 (label_ref (match_operand 3)) 12070 (pc))) 12071 (clobber (reg:CC FLAGS_REG))] 12072 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12073 && can_create_pseudo_p ()" 12074 "#" 12075 "&& 1" 12076 [(set (reg:CCC FLAGS_REG) 12077 (compare:CCC 12078 (zero_extract:SWI48 12079 (match_dup 1) 12080 (const_int 1) 12081 (match_dup 2)) 12082 (const_int 0))) 12083 (set (pc) 12084 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12085 (label_ref (match_dup 3)) 12086 (pc)))] 12087{ 12088 operands[2] = lowpart_subreg (SImode, operands[2], QImode); 12089 operands[0] = shallow_copy_rtx (operands[0]); 12090 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12091}) 12092 12093;; Avoid useless masking of bit offset operand. 12094(define_insn_and_split "*jcc_bt<mode>_mask" 12095 [(set (pc) 12096 (if_then_else (match_operator 0 "bt_comparison_operator" 12097 [(zero_extract:SWI48 12098 (match_operand:SWI48 1 "register_operand") 12099 (const_int 1) 12100 (and:SI 12101 (match_operand:SI 2 "register_operand") 12102 (match_operand 3 "const_int_operand")))]) 12103 (label_ref (match_operand 4)) 12104 (pc))) 12105 (clobber (reg:CC FLAGS_REG))] 12106 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12107 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 12108 == GET_MODE_BITSIZE (<MODE>mode)-1 12109 && can_create_pseudo_p ()" 12110 "#" 12111 "&& 1" 12112 [(set (reg:CCC FLAGS_REG) 12113 (compare:CCC 12114 (zero_extract:SWI48 12115 (match_dup 1) 12116 (const_int 1) 12117 (match_dup 2)) 12118 (const_int 0))) 12119 (set (pc) 12120 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12121 (label_ref (match_dup 4)) 12122 (pc)))] 12123{ 12124 operands[0] = shallow_copy_rtx (operands[0]); 12125 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12126}) 12127 12128;; Store-flag instructions. 12129 12130;; For all sCOND expanders, also expand the compare or test insn that 12131;; generates cc0. Generate an equality comparison if `seq' or `sne'. 12132 12133(define_insn_and_split "*setcc_di_1" 12134 [(set (match_operand:DI 0 "register_operand" "=q") 12135 (match_operator:DI 1 "ix86_comparison_operator" 12136 [(reg FLAGS_REG) (const_int 0)]))] 12137 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL" 12138 "#" 12139 "&& reload_completed" 12140 [(set (match_dup 2) (match_dup 1)) 12141 (set (match_dup 0) (zero_extend:DI (match_dup 2)))] 12142{ 12143 operands[1] = shallow_copy_rtx (operands[1]); 12144 PUT_MODE (operands[1], QImode); 12145 operands[2] = gen_lowpart (QImode, operands[0]); 12146}) 12147 12148(define_insn_and_split "*setcc_si_1_and" 12149 [(set (match_operand:SI 0 "register_operand" "=q") 12150 (match_operator:SI 1 "ix86_comparison_operator" 12151 [(reg FLAGS_REG) (const_int 0)])) 12152 (clobber (reg:CC FLAGS_REG))] 12153 "!TARGET_PARTIAL_REG_STALL 12154 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 12155 "#" 12156 "&& reload_completed" 12157 [(set (match_dup 2) (match_dup 1)) 12158 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) 12159 (clobber (reg:CC FLAGS_REG))])] 12160{ 12161 operands[1] = shallow_copy_rtx (operands[1]); 12162 PUT_MODE (operands[1], QImode); 12163 operands[2] = gen_lowpart (QImode, operands[0]); 12164}) 12165 12166(define_insn_and_split "*setcc_si_1_movzbl" 12167 [(set (match_operand:SI 0 "register_operand" "=q") 12168 (match_operator:SI 1 "ix86_comparison_operator" 12169 [(reg FLAGS_REG) (const_int 0)]))] 12170 "!TARGET_PARTIAL_REG_STALL 12171 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 12172 "#" 12173 "&& reload_completed" 12174 [(set (match_dup 2) (match_dup 1)) 12175 (set (match_dup 0) (zero_extend:SI (match_dup 2)))] 12176{ 12177 operands[1] = shallow_copy_rtx (operands[1]); 12178 PUT_MODE (operands[1], QImode); 12179 operands[2] = gen_lowpart (QImode, operands[0]); 12180}) 12181 12182(define_insn "*setcc_qi" 12183 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12184 (match_operator:QI 1 "ix86_comparison_operator" 12185 [(reg FLAGS_REG) (const_int 0)]))] 12186 "" 12187 "set%C1\t%0" 12188 [(set_attr "type" "setcc") 12189 (set_attr "mode" "QI")]) 12190 12191(define_insn "*setcc_qi_slp" 12192 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12193 (match_operator:QI 1 "ix86_comparison_operator" 12194 [(reg FLAGS_REG) (const_int 0)]))] 12195 "" 12196 "set%C1\t%0" 12197 [(set_attr "type" "setcc") 12198 (set_attr "mode" "QI")]) 12199 12200;; In general it is not safe to assume too much about CCmode registers, 12201;; so simplify-rtx stops when it sees a second one. Under certain 12202;; conditions this is safe on x86, so help combine not create 12203;; 12204;; seta %al 12205;; testb %al, %al 12206;; sete %al 12207 12208(define_split 12209 [(set (match_operand:QI 0 "nonimmediate_operand") 12210 (ne:QI (match_operator 1 "ix86_comparison_operator" 12211 [(reg FLAGS_REG) (const_int 0)]) 12212 (const_int 0)))] 12213 "" 12214 [(set (match_dup 0) (match_dup 1))] 12215{ 12216 operands[1] = shallow_copy_rtx (operands[1]); 12217 PUT_MODE (operands[1], QImode); 12218}) 12219 12220(define_split 12221 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) 12222 (ne:QI (match_operator 1 "ix86_comparison_operator" 12223 [(reg FLAGS_REG) (const_int 0)]) 12224 (const_int 0)))] 12225 "" 12226 [(set (match_dup 0) (match_dup 1))] 12227{ 12228 operands[1] = shallow_copy_rtx (operands[1]); 12229 PUT_MODE (operands[1], QImode); 12230}) 12231 12232(define_split 12233 [(set (match_operand:QI 0 "nonimmediate_operand") 12234 (eq:QI (match_operator 1 "ix86_comparison_operator" 12235 [(reg FLAGS_REG) (const_int 0)]) 12236 (const_int 0)))] 12237 "" 12238 [(set (match_dup 0) (match_dup 1))] 12239{ 12240 operands[1] = shallow_copy_rtx (operands[1]); 12241 PUT_MODE (operands[1], QImode); 12242 PUT_CODE (operands[1], 12243 ix86_reverse_condition (GET_CODE (operands[1]), 12244 GET_MODE (XEXP (operands[1], 0)))); 12245 12246 /* Make sure that (a) the CCmode we have for the flags is strong 12247 enough for the reversed compare or (b) we have a valid FP compare. */ 12248 if (! ix86_comparison_operator (operands[1], VOIDmode)) 12249 FAIL; 12250}) 12251 12252(define_split 12253 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) 12254 (eq:QI (match_operator 1 "ix86_comparison_operator" 12255 [(reg FLAGS_REG) (const_int 0)]) 12256 (const_int 0)))] 12257 "" 12258 [(set (match_dup 0) (match_dup 1))] 12259{ 12260 operands[1] = shallow_copy_rtx (operands[1]); 12261 PUT_MODE (operands[1], QImode); 12262 PUT_CODE (operands[1], 12263 ix86_reverse_condition (GET_CODE (operands[1]), 12264 GET_MODE (XEXP (operands[1], 0)))); 12265 12266 /* Make sure that (a) the CCmode we have for the flags is strong 12267 enough for the reversed compare or (b) we have a valid FP compare. */ 12268 if (! ix86_comparison_operator (operands[1], VOIDmode)) 12269 FAIL; 12270}) 12271 12272;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 12273;; subsequent logical operations are used to imitate conditional moves. 12274;; 0xffffffff is NaN, but not in normalized form, so we can't represent 12275;; it directly. 12276 12277(define_insn "setcc_<mode>_sse" 12278 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 12279 (match_operator:MODEF 3 "sse_comparison_operator" 12280 [(match_operand:MODEF 1 "register_operand" "0,x") 12281 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 12282 "SSE_FLOAT_MODE_P (<MODE>mode)" 12283 "@ 12284 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2} 12285 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 12286 [(set_attr "isa" "noavx,avx") 12287 (set_attr "type" "ssecmp") 12288 (set_attr "length_immediate" "1") 12289 (set_attr "prefix" "orig,vex") 12290 (set_attr "mode" "<MODE>")]) 12291 12292;; Basic conditional jump instructions. 12293;; We ignore the overflow flag for signed branch instructions. 12294 12295(define_insn "*jcc" 12296 [(set (pc) 12297 (if_then_else (match_operator 1 "ix86_comparison_operator" 12298 [(reg FLAGS_REG) (const_int 0)]) 12299 (label_ref (match_operand 0)) 12300 (pc)))] 12301 "" 12302 "%!%+j%C1\t%l0" 12303 [(set_attr "type" "ibr") 12304 (set_attr "modrm" "0") 12305 (set (attr "length") 12306 (if_then_else 12307 (and (ge (minus (match_dup 0) (pc)) 12308 (const_int -126)) 12309 (lt (minus (match_dup 0) (pc)) 12310 (const_int 128))) 12311 (const_int 2) 12312 (const_int 6))) 12313 (set_attr "maybe_prefix_bnd" "1")]) 12314 12315;; In general it is not safe to assume too much about CCmode registers, 12316;; so simplify-rtx stops when it sees a second one. Under certain 12317;; conditions this is safe on x86, so help combine not create 12318;; 12319;; seta %al 12320;; testb %al, %al 12321;; je Lfoo 12322 12323(define_split 12324 [(set (pc) 12325 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 12326 [(reg FLAGS_REG) (const_int 0)]) 12327 (const_int 0)) 12328 (label_ref (match_operand 1)) 12329 (pc)))] 12330 "" 12331 [(set (pc) 12332 (if_then_else (match_dup 0) 12333 (label_ref (match_dup 1)) 12334 (pc)))] 12335{ 12336 operands[0] = shallow_copy_rtx (operands[0]); 12337 PUT_MODE (operands[0], VOIDmode); 12338}) 12339 12340(define_split 12341 [(set (pc) 12342 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 12343 [(reg FLAGS_REG) (const_int 0)]) 12344 (const_int 0)) 12345 (label_ref (match_operand 1)) 12346 (pc)))] 12347 "" 12348 [(set (pc) 12349 (if_then_else (match_dup 0) 12350 (label_ref (match_dup 1)) 12351 (pc)))] 12352{ 12353 operands[0] = shallow_copy_rtx (operands[0]); 12354 PUT_MODE (operands[0], VOIDmode); 12355 PUT_CODE (operands[0], 12356 ix86_reverse_condition (GET_CODE (operands[0]), 12357 GET_MODE (XEXP (operands[0], 0)))); 12358 12359 /* Make sure that (a) the CCmode we have for the flags is strong 12360 enough for the reversed compare or (b) we have a valid FP compare. */ 12361 if (! ix86_comparison_operator (operands[0], VOIDmode)) 12362 FAIL; 12363}) 12364 12365;; Unconditional and other jump instructions 12366 12367(define_insn "jump" 12368 [(set (pc) 12369 (label_ref (match_operand 0)))] 12370 "" 12371 "%!jmp\t%l0" 12372 [(set_attr "type" "ibr") 12373 (set_attr "modrm" "0") 12374 (set (attr "length") 12375 (if_then_else 12376 (and (ge (minus (match_dup 0) (pc)) 12377 (const_int -126)) 12378 (lt (minus (match_dup 0) (pc)) 12379 (const_int 128))) 12380 (const_int 2) 12381 (const_int 5))) 12382 (set_attr "maybe_prefix_bnd" "1")]) 12383 12384(define_expand "indirect_jump" 12385 [(set (pc) (match_operand 0 "indirect_branch_operand"))] 12386 "" 12387{ 12388 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) 12389 operands[0] = convert_memory_address (word_mode, operands[0]); 12390 cfun->machine->has_local_indirect_jump = true; 12391}) 12392 12393(define_insn "*indirect_jump" 12394 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] 12395 "" 12396 "* return ix86_output_indirect_jmp (operands[0]);" 12397 [(set (attr "type") 12398 (if_then_else (match_test "(cfun->machine->indirect_branch_type 12399 != indirect_branch_keep)") 12400 (const_string "multi") 12401 (const_string "ibr"))) 12402 (set_attr "length_immediate" "0") 12403 (set_attr "maybe_prefix_bnd" "1")]) 12404 12405(define_expand "tablejump" 12406 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand")) 12407 (use (label_ref (match_operand 1)))])] 12408 "" 12409{ 12410 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 12411 relative. Convert the relative address to an absolute address. */ 12412 if (flag_pic) 12413 { 12414 rtx op0, op1; 12415 enum rtx_code code; 12416 12417 /* We can't use @GOTOFF for text labels on VxWorks; 12418 see gotoff_operand. */ 12419 if (TARGET_64BIT || TARGET_VXWORKS_RTP) 12420 { 12421 code = PLUS; 12422 op0 = operands[0]; 12423 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 12424 } 12425 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 12426 { 12427 code = PLUS; 12428 op0 = operands[0]; 12429 op1 = pic_offset_table_rtx; 12430 } 12431 else 12432 { 12433 code = MINUS; 12434 op0 = pic_offset_table_rtx; 12435 op1 = operands[0]; 12436 } 12437 12438 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 12439 OPTAB_DIRECT); 12440 } 12441 12442 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) 12443 operands[0] = convert_memory_address (word_mode, operands[0]); 12444 cfun->machine->has_local_indirect_jump = true; 12445}) 12446 12447(define_insn "*tablejump_1" 12448 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) 12449 (use (label_ref (match_operand 1)))] 12450 "" 12451 "* return ix86_output_indirect_jmp (operands[0]);" 12452 [(set (attr "type") 12453 (if_then_else (match_test "(cfun->machine->indirect_branch_type 12454 != indirect_branch_keep)") 12455 (const_string "multi") 12456 (const_string "ibr"))) 12457 (set_attr "length_immediate" "0") 12458 (set_attr "maybe_prefix_bnd" "1")]) 12459 12460;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 12461 12462(define_peephole2 12463 [(set (reg FLAGS_REG) (match_operand 0)) 12464 (set (match_operand:QI 1 "register_operand") 12465 (match_operator:QI 2 "ix86_comparison_operator" 12466 [(reg FLAGS_REG) (const_int 0)])) 12467 (set (match_operand 3 "any_QIreg_operand") 12468 (zero_extend (match_dup 1)))] 12469 "(peep2_reg_dead_p (3, operands[1]) 12470 || operands_match_p (operands[1], operands[3])) 12471 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12472 && peep2_regno_dead_p (0, FLAGS_REG)" 12473 [(set (match_dup 4) (match_dup 0)) 12474 (set (strict_low_part (match_dup 5)) 12475 (match_dup 2))] 12476{ 12477 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12478 operands[5] = gen_lowpart (QImode, operands[3]); 12479 ix86_expand_clear (operands[3]); 12480}) 12481 12482(define_peephole2 12483 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 12484 (match_operand 4)]) 12485 (set (match_operand:QI 1 "register_operand") 12486 (match_operator:QI 2 "ix86_comparison_operator" 12487 [(reg FLAGS_REG) (const_int 0)])) 12488 (set (match_operand 3 "any_QIreg_operand") 12489 (zero_extend (match_dup 1)))] 12490 "(peep2_reg_dead_p (3, operands[1]) 12491 || operands_match_p (operands[1], operands[3])) 12492 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12493 && ! reg_overlap_mentioned_p (operands[3], operands[4]) 12494 && ! reg_set_p (operands[3], operands[4]) 12495 && peep2_regno_dead_p (0, FLAGS_REG)" 12496 [(parallel [(set (match_dup 5) (match_dup 0)) 12497 (match_dup 4)]) 12498 (set (strict_low_part (match_dup 6)) 12499 (match_dup 2))] 12500{ 12501 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12502 operands[6] = gen_lowpart (QImode, operands[3]); 12503 ix86_expand_clear (operands[3]); 12504}) 12505 12506(define_peephole2 12507 [(set (reg FLAGS_REG) (match_operand 0)) 12508 (parallel [(set (reg FLAGS_REG) (match_operand 1)) 12509 (match_operand 5)]) 12510 (set (match_operand:QI 2 "register_operand") 12511 (match_operator:QI 3 "ix86_comparison_operator" 12512 [(reg FLAGS_REG) (const_int 0)])) 12513 (set (match_operand 4 "any_QIreg_operand") 12514 (zero_extend (match_dup 2)))] 12515 "(peep2_reg_dead_p (4, operands[2]) 12516 || operands_match_p (operands[2], operands[4])) 12517 && ! reg_overlap_mentioned_p (operands[4], operands[0]) 12518 && ! reg_overlap_mentioned_p (operands[4], operands[1]) 12519 && ! reg_overlap_mentioned_p (operands[4], operands[5]) 12520 && ! reg_set_p (operands[4], operands[5]) 12521 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) 12522 && peep2_regno_dead_p (0, FLAGS_REG)" 12523 [(set (match_dup 6) (match_dup 0)) 12524 (parallel [(set (match_dup 7) (match_dup 1)) 12525 (match_dup 5)]) 12526 (set (strict_low_part (match_dup 8)) 12527 (match_dup 3))] 12528{ 12529 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12530 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); 12531 operands[8] = gen_lowpart (QImode, operands[4]); 12532 ix86_expand_clear (operands[4]); 12533}) 12534 12535;; Similar, but match zero extend with andsi3. 12536 12537(define_peephole2 12538 [(set (reg FLAGS_REG) (match_operand 0)) 12539 (set (match_operand:QI 1 "register_operand") 12540 (match_operator:QI 2 "ix86_comparison_operator" 12541 [(reg FLAGS_REG) (const_int 0)])) 12542 (parallel [(set (match_operand:SI 3 "any_QIreg_operand") 12543 (and:SI (match_dup 3) (const_int 255))) 12544 (clobber (reg:CC FLAGS_REG))])] 12545 "REGNO (operands[1]) == REGNO (operands[3]) 12546 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12547 && peep2_regno_dead_p (0, FLAGS_REG)" 12548 [(set (match_dup 4) (match_dup 0)) 12549 (set (strict_low_part (match_dup 5)) 12550 (match_dup 2))] 12551{ 12552 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12553 operands[5] = gen_lowpart (QImode, operands[3]); 12554 ix86_expand_clear (operands[3]); 12555}) 12556 12557(define_peephole2 12558 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 12559 (match_operand 4)]) 12560 (set (match_operand:QI 1 "register_operand") 12561 (match_operator:QI 2 "ix86_comparison_operator" 12562 [(reg FLAGS_REG) (const_int 0)])) 12563 (parallel [(set (match_operand 3 "any_QIreg_operand") 12564 (zero_extend (match_dup 1))) 12565 (clobber (reg:CC FLAGS_REG))])] 12566 "(peep2_reg_dead_p (3, operands[1]) 12567 || operands_match_p (operands[1], operands[3])) 12568 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12569 && ! reg_overlap_mentioned_p (operands[3], operands[4]) 12570 && ! reg_set_p (operands[3], operands[4]) 12571 && peep2_regno_dead_p (0, FLAGS_REG)" 12572 [(parallel [(set (match_dup 5) (match_dup 0)) 12573 (match_dup 4)]) 12574 (set (strict_low_part (match_dup 6)) 12575 (match_dup 2))] 12576{ 12577 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12578 operands[6] = gen_lowpart (QImode, operands[3]); 12579 ix86_expand_clear (operands[3]); 12580}) 12581 12582(define_peephole2 12583 [(set (reg FLAGS_REG) (match_operand 0)) 12584 (parallel [(set (reg FLAGS_REG) (match_operand 1)) 12585 (match_operand 5)]) 12586 (set (match_operand:QI 2 "register_operand") 12587 (match_operator:QI 3 "ix86_comparison_operator" 12588 [(reg FLAGS_REG) (const_int 0)])) 12589 (parallel [(set (match_operand 4 "any_QIreg_operand") 12590 (zero_extend (match_dup 2))) 12591 (clobber (reg:CC FLAGS_REG))])] 12592 "(peep2_reg_dead_p (4, operands[2]) 12593 || operands_match_p (operands[2], operands[4])) 12594 && ! reg_overlap_mentioned_p (operands[4], operands[0]) 12595 && ! reg_overlap_mentioned_p (operands[4], operands[1]) 12596 && ! reg_overlap_mentioned_p (operands[4], operands[5]) 12597 && ! reg_set_p (operands[4], operands[5]) 12598 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) 12599 && peep2_regno_dead_p (0, FLAGS_REG)" 12600 [(set (match_dup 6) (match_dup 0)) 12601 (parallel [(set (match_dup 7) (match_dup 1)) 12602 (match_dup 5)]) 12603 (set (strict_low_part (match_dup 8)) 12604 (match_dup 3))] 12605{ 12606 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12607 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); 12608 operands[8] = gen_lowpart (QImode, operands[4]); 12609 ix86_expand_clear (operands[4]); 12610}) 12611 12612;; Call instructions. 12613 12614;; The predicates normally associated with named expanders are not properly 12615;; checked for calls. This is a bug in the generic code, but it isn't that 12616;; easy to fix. Ignore it for now and be prepared to fix things up. 12617 12618;; P6 processors will jump to the address after the decrement when %esp 12619;; is used as a call operand, so they will execute return address as a code. 12620;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 12621 12622;; Register constraint for call instruction. 12623(define_mode_attr c [(SI "l") (DI "r")]) 12624 12625;; Call subroutine returning no value. 12626 12627(define_expand "call" 12628 [(call (match_operand:QI 0) 12629 (match_operand 1)) 12630 (use (match_operand 2))] 12631 "" 12632{ 12633 ix86_expand_call (NULL, operands[0], operands[1], 12634 operands[2], NULL, false); 12635 DONE; 12636}) 12637 12638(define_expand "sibcall" 12639 [(call (match_operand:QI 0) 12640 (match_operand 1)) 12641 (use (match_operand 2))] 12642 "" 12643{ 12644 ix86_expand_call (NULL, operands[0], operands[1], 12645 operands[2], NULL, true); 12646 DONE; 12647}) 12648 12649(define_insn "*call" 12650 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz")) 12651 (match_operand 1))] 12652 "!SIBLING_CALL_P (insn)" 12653 "* return ix86_output_call_insn (insn, operands[0]);" 12654 [(set_attr "type" "call")]) 12655 12656;; This covers both call and sibcall since only GOT slot is allowed. 12657(define_insn "*call_got_x32" 12658 [(call (mem:QI (zero_extend:DI 12659 (match_operand:SI 0 "GOT_memory_operand" "Bg"))) 12660 (match_operand 1))] 12661 "TARGET_X32" 12662{ 12663 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0)); 12664 return ix86_output_call_insn (insn, fnaddr); 12665} 12666 [(set_attr "type" "call")]) 12667 12668;; Since sibcall never returns, we can only use call-clobbered register 12669;; as GOT base. 12670(define_insn "*sibcall_GOT_32" 12671 [(call (mem:QI 12672 (mem:SI (plus:SI 12673 (match_operand:SI 0 "register_no_elim_operand" "U") 12674 (match_operand:SI 1 "GOT32_symbol_operand")))) 12675 (match_operand 2))] 12676 "!TARGET_MACHO 12677 && !TARGET_64BIT 12678 && !TARGET_INDIRECT_BRANCH_REGISTER 12679 && SIBLING_CALL_P (insn)" 12680{ 12681 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]); 12682 fnaddr = gen_const_mem (SImode, fnaddr); 12683 return ix86_output_call_insn (insn, fnaddr); 12684} 12685 [(set_attr "type" "call")]) 12686 12687(define_insn "*sibcall" 12688 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz")) 12689 (match_operand 1))] 12690 "SIBLING_CALL_P (insn)" 12691 "* return ix86_output_call_insn (insn, operands[0]);" 12692 [(set_attr "type" "call")]) 12693 12694(define_insn "*sibcall_memory" 12695 [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) 12696 (match_operand 1)) 12697 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12698 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" 12699 "* return ix86_output_call_insn (insn, operands[0]);" 12700 [(set_attr "type" "call")]) 12701 12702(define_peephole2 12703 [(set (match_operand:W 0 "register_operand") 12704 (match_operand:W 1 "memory_operand")) 12705 (call (mem:QI (match_dup 0)) 12706 (match_operand 3))] 12707 "!TARGET_X32 12708 && !TARGET_INDIRECT_BRANCH_REGISTER 12709 && SIBLING_CALL_P (peep2_next_insn (1)) 12710 && !reg_mentioned_p (operands[0], 12711 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12712 [(parallel [(call (mem:QI (match_dup 1)) 12713 (match_dup 3)) 12714 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12715 12716(define_peephole2 12717 [(set (match_operand:W 0 "register_operand") 12718 (match_operand:W 1 "memory_operand")) 12719 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12720 (call (mem:QI (match_dup 0)) 12721 (match_operand 3))] 12722 "!TARGET_X32 12723 && !TARGET_INDIRECT_BRANCH_REGISTER 12724 && SIBLING_CALL_P (peep2_next_insn (2)) 12725 && !reg_mentioned_p (operands[0], 12726 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12727 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12728 (parallel [(call (mem:QI (match_dup 1)) 12729 (match_dup 3)) 12730 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12731 12732(define_expand "call_pop" 12733 [(parallel [(call (match_operand:QI 0) 12734 (match_operand:SI 1)) 12735 (set (reg:SI SP_REG) 12736 (plus:SI (reg:SI SP_REG) 12737 (match_operand:SI 3)))])] 12738 "!TARGET_64BIT" 12739{ 12740 ix86_expand_call (NULL, operands[0], operands[1], 12741 operands[2], operands[3], false); 12742 DONE; 12743}) 12744 12745(define_insn "*call_pop" 12746 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) 12747 (match_operand 1)) 12748 (set (reg:SI SP_REG) 12749 (plus:SI (reg:SI SP_REG) 12750 (match_operand:SI 2 "immediate_operand" "i")))] 12751 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 12752 "* return ix86_output_call_insn (insn, operands[0]);" 12753 [(set_attr "type" "call")]) 12754 12755(define_insn "*sibcall_pop" 12756 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz")) 12757 (match_operand 1)) 12758 (set (reg:SI SP_REG) 12759 (plus:SI (reg:SI SP_REG) 12760 (match_operand:SI 2 "immediate_operand" "i")))] 12761 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 12762 "* return ix86_output_call_insn (insn, operands[0]);" 12763 [(set_attr "type" "call")]) 12764 12765(define_insn "*sibcall_pop_memory" 12766 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) 12767 (match_operand 1)) 12768 (set (reg:SI SP_REG) 12769 (plus:SI (reg:SI SP_REG) 12770 (match_operand:SI 2 "immediate_operand" "i"))) 12771 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12772 "!TARGET_64BIT" 12773 "* return ix86_output_call_insn (insn, operands[0]);" 12774 [(set_attr "type" "call")]) 12775 12776(define_peephole2 12777 [(set (match_operand:SI 0 "register_operand") 12778 (match_operand:SI 1 "memory_operand")) 12779 (parallel [(call (mem:QI (match_dup 0)) 12780 (match_operand 3)) 12781 (set (reg:SI SP_REG) 12782 (plus:SI (reg:SI SP_REG) 12783 (match_operand:SI 4 "immediate_operand")))])] 12784 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 12785 && !reg_mentioned_p (operands[0], 12786 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12787 [(parallel [(call (mem:QI (match_dup 1)) 12788 (match_dup 3)) 12789 (set (reg:SI SP_REG) 12790 (plus:SI (reg:SI SP_REG) 12791 (match_dup 4))) 12792 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12793 12794(define_peephole2 12795 [(set (match_operand:SI 0 "register_operand") 12796 (match_operand:SI 1 "memory_operand")) 12797 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12798 (parallel [(call (mem:QI (match_dup 0)) 12799 (match_operand 3)) 12800 (set (reg:SI SP_REG) 12801 (plus:SI (reg:SI SP_REG) 12802 (match_operand:SI 4 "immediate_operand")))])] 12803 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 12804 && !reg_mentioned_p (operands[0], 12805 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12806 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12807 (parallel [(call (mem:QI (match_dup 1)) 12808 (match_dup 3)) 12809 (set (reg:SI SP_REG) 12810 (plus:SI (reg:SI SP_REG) 12811 (match_dup 4))) 12812 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12813 12814;; Combining simple memory jump instruction 12815 12816(define_peephole2 12817 [(set (match_operand:W 0 "register_operand") 12818 (match_operand:W 1 "memory_operand")) 12819 (set (pc) (match_dup 0))] 12820 "!TARGET_X32 12821 && !TARGET_INDIRECT_BRANCH_REGISTER 12822 && peep2_reg_dead_p (2, operands[0])" 12823 [(set (pc) (match_dup 1))]) 12824 12825;; Call subroutine, returning value in operand 0 12826 12827(define_expand "call_value" 12828 [(set (match_operand 0) 12829 (call (match_operand:QI 1) 12830 (match_operand 2))) 12831 (use (match_operand 3))] 12832 "" 12833{ 12834 ix86_expand_call (operands[0], operands[1], operands[2], 12835 operands[3], NULL, false); 12836 DONE; 12837}) 12838 12839(define_expand "sibcall_value" 12840 [(set (match_operand 0) 12841 (call (match_operand:QI 1) 12842 (match_operand 2))) 12843 (use (match_operand 3))] 12844 "" 12845{ 12846 ix86_expand_call (operands[0], operands[1], operands[2], 12847 operands[3], NULL, true); 12848 DONE; 12849}) 12850 12851(define_insn "*call_value" 12852 [(set (match_operand 0) 12853 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz")) 12854 (match_operand 2)))] 12855 "!SIBLING_CALL_P (insn)" 12856 "* return ix86_output_call_insn (insn, operands[1]);" 12857 [(set_attr "type" "callv")]) 12858 12859;; This covers both call and sibcall since only GOT slot is allowed. 12860(define_insn "*call_value_got_x32" 12861 [(set (match_operand 0) 12862 (call (mem:QI 12863 (zero_extend:DI 12864 (match_operand:SI 1 "GOT_memory_operand" "Bg"))) 12865 (match_operand 2)))] 12866 "TARGET_X32" 12867{ 12868 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0)); 12869 return ix86_output_call_insn (insn, fnaddr); 12870} 12871 [(set_attr "type" "callv")]) 12872 12873;; Since sibcall never returns, we can only use call-clobbered register 12874;; as GOT base. 12875(define_insn "*sibcall_value_GOT_32" 12876 [(set (match_operand 0) 12877 (call (mem:QI 12878 (mem:SI (plus:SI 12879 (match_operand:SI 1 "register_no_elim_operand" "U") 12880 (match_operand:SI 2 "GOT32_symbol_operand")))) 12881 (match_operand 3)))] 12882 "!TARGET_MACHO 12883 && !TARGET_64BIT 12884 && !TARGET_INDIRECT_BRANCH_REGISTER 12885 && SIBLING_CALL_P (insn)" 12886{ 12887 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]); 12888 fnaddr = gen_const_mem (SImode, fnaddr); 12889 return ix86_output_call_insn (insn, fnaddr); 12890} 12891 [(set_attr "type" "callv")]) 12892 12893(define_insn "*sibcall_value" 12894 [(set (match_operand 0) 12895 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz")) 12896 (match_operand 2)))] 12897 "SIBLING_CALL_P (insn)" 12898 "* return ix86_output_call_insn (insn, operands[1]);" 12899 [(set_attr "type" "callv")]) 12900 12901(define_insn "*sibcall_value_memory" 12902 [(set (match_operand 0) 12903 (call (mem:QI (match_operand:W 1 "memory_operand" "m")) 12904 (match_operand 2))) 12905 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12906 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" 12907 "* return ix86_output_call_insn (insn, operands[1]);" 12908 [(set_attr "type" "callv")]) 12909 12910(define_peephole2 12911 [(set (match_operand:W 0 "register_operand") 12912 (match_operand:W 1 "memory_operand")) 12913 (set (match_operand 2) 12914 (call (mem:QI (match_dup 0)) 12915 (match_operand 3)))] 12916 "!TARGET_X32 12917 && !TARGET_INDIRECT_BRANCH_REGISTER 12918 && SIBLING_CALL_P (peep2_next_insn (1)) 12919 && !reg_mentioned_p (operands[0], 12920 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12921 [(parallel [(set (match_dup 2) 12922 (call (mem:QI (match_dup 1)) 12923 (match_dup 3))) 12924 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12925 12926(define_peephole2 12927 [(set (match_operand:W 0 "register_operand") 12928 (match_operand:W 1 "memory_operand")) 12929 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12930 (set (match_operand 2) 12931 (call (mem:QI (match_dup 0)) 12932 (match_operand 3)))] 12933 "!TARGET_X32 12934 && !TARGET_INDIRECT_BRANCH_REGISTER 12935 && SIBLING_CALL_P (peep2_next_insn (2)) 12936 && !reg_mentioned_p (operands[0], 12937 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12938 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12939 (parallel [(set (match_dup 2) 12940 (call (mem:QI (match_dup 1)) 12941 (match_dup 3))) 12942 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12943 12944(define_expand "call_value_pop" 12945 [(parallel [(set (match_operand 0) 12946 (call (match_operand:QI 1) 12947 (match_operand:SI 2))) 12948 (set (reg:SI SP_REG) 12949 (plus:SI (reg:SI SP_REG) 12950 (match_operand:SI 4)))])] 12951 "!TARGET_64BIT" 12952{ 12953 ix86_expand_call (operands[0], operands[1], operands[2], 12954 operands[3], operands[4], false); 12955 DONE; 12956}) 12957 12958(define_insn "*call_value_pop" 12959 [(set (match_operand 0) 12960 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) 12961 (match_operand 2))) 12962 (set (reg:SI SP_REG) 12963 (plus:SI (reg:SI SP_REG) 12964 (match_operand:SI 3 "immediate_operand" "i")))] 12965 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 12966 "* return ix86_output_call_insn (insn, operands[1]);" 12967 [(set_attr "type" "callv")]) 12968 12969(define_insn "*sibcall_value_pop" 12970 [(set (match_operand 0) 12971 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz")) 12972 (match_operand 2))) 12973 (set (reg:SI SP_REG) 12974 (plus:SI (reg:SI SP_REG) 12975 (match_operand:SI 3 "immediate_operand" "i")))] 12976 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 12977 "* return ix86_output_call_insn (insn, operands[1]);" 12978 [(set_attr "type" "callv")]) 12979 12980(define_insn "*sibcall_value_pop_memory" 12981 [(set (match_operand 0) 12982 (call (mem:QI (match_operand:SI 1 "memory_operand" "m")) 12983 (match_operand 2))) 12984 (set (reg:SI SP_REG) 12985 (plus:SI (reg:SI SP_REG) 12986 (match_operand:SI 3 "immediate_operand" "i"))) 12987 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12988 "!TARGET_64BIT" 12989 "* return ix86_output_call_insn (insn, operands[1]);" 12990 [(set_attr "type" "callv")]) 12991 12992(define_peephole2 12993 [(set (match_operand:SI 0 "register_operand") 12994 (match_operand:SI 1 "memory_operand")) 12995 (parallel [(set (match_operand 2) 12996 (call (mem:QI (match_dup 0)) 12997 (match_operand 3))) 12998 (set (reg:SI SP_REG) 12999 (plus:SI (reg:SI SP_REG) 13000 (match_operand:SI 4 "immediate_operand")))])] 13001 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 13002 && !reg_mentioned_p (operands[0], 13003 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 13004 [(parallel [(set (match_dup 2) 13005 (call (mem:QI (match_dup 1)) 13006 (match_dup 3))) 13007 (set (reg:SI SP_REG) 13008 (plus:SI (reg:SI SP_REG) 13009 (match_dup 4))) 13010 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13011 13012(define_peephole2 13013 [(set (match_operand:SI 0 "register_operand") 13014 (match_operand:SI 1 "memory_operand")) 13015 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13016 (parallel [(set (match_operand 2) 13017 (call (mem:QI (match_dup 0)) 13018 (match_operand 3))) 13019 (set (reg:SI SP_REG) 13020 (plus:SI (reg:SI SP_REG) 13021 (match_operand:SI 4 "immediate_operand")))])] 13022 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 13023 && !reg_mentioned_p (operands[0], 13024 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 13025 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13026 (parallel [(set (match_dup 2) 13027 (call (mem:QI (match_dup 1)) 13028 (match_dup 3))) 13029 (set (reg:SI SP_REG) 13030 (plus:SI (reg:SI SP_REG) 13031 (match_dup 4))) 13032 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13033 13034;; Call subroutine returning any type. 13035 13036(define_expand "untyped_call" 13037 [(parallel [(call (match_operand 0) 13038 (const_int 0)) 13039 (match_operand 1) 13040 (match_operand 2)])] 13041 "" 13042{ 13043 int i; 13044 13045 /* In order to give reg-stack an easier job in validating two 13046 coprocessor registers as containing a possible return value, 13047 simply pretend the untyped call returns a complex long double 13048 value. 13049 13050 We can't use SSE_REGPARM_MAX here since callee is unprototyped 13051 and should have the default ABI. */ 13052 13053 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 13054 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 13055 operands[0], const0_rtx, 13056 GEN_INT ((TARGET_64BIT 13057 ? (ix86_abi == SYSV_ABI 13058 ? X86_64_SSE_REGPARM_MAX 13059 : X86_64_MS_SSE_REGPARM_MAX) 13060 : X86_32_SSE_REGPARM_MAX) 13061 - 1), 13062 NULL, false); 13063 13064 for (i = 0; i < XVECLEN (operands[2], 0); i++) 13065 { 13066 rtx set = XVECEXP (operands[2], 0, i); 13067 emit_move_insn (SET_DEST (set), SET_SRC (set)); 13068 } 13069 13070 /* The optimizer does not know that the call sets the function value 13071 registers we stored in the result block. We avoid problems by 13072 claiming that all hard registers are used and clobbered at this 13073 point. */ 13074 emit_insn (gen_blockage ()); 13075 13076 DONE; 13077}) 13078 13079;; Prologue and epilogue instructions 13080 13081;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 13082;; all of memory. This blocks insns from being moved across this point. 13083 13084(define_insn "blockage" 13085 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 13086 "" 13087 "" 13088 [(set_attr "length" "0")]) 13089 13090;; Do not schedule instructions accessing memory across this point. 13091 13092(define_expand "memory_blockage" 13093 [(set (match_dup 0) 13094 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 13095 "" 13096{ 13097 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 13098 MEM_VOLATILE_P (operands[0]) = 1; 13099}) 13100 13101(define_insn "*memory_blockage" 13102 [(set (match_operand:BLK 0) 13103 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 13104 "" 13105 "" 13106 [(set_attr "length" "0")]) 13107 13108;; As USE insns aren't meaningful after reload, this is used instead 13109;; to prevent deleting instructions setting registers for PIC code 13110(define_insn "prologue_use" 13111 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)] 13112 "" 13113 "" 13114 [(set_attr "length" "0")]) 13115 13116;; Insn emitted into the body of a function to return from a function. 13117;; This is only done if the function's epilogue is known to be simple. 13118;; See comments for ix86_can_use_return_insn_p in i386.c. 13119 13120(define_expand "return" 13121 [(simple_return)] 13122 "ix86_can_use_return_insn_p ()" 13123{ 13124 if (crtl->args.pops_args) 13125 { 13126 rtx popc = GEN_INT (crtl->args.pops_args); 13127 emit_jump_insn (gen_simple_return_pop_internal (popc)); 13128 DONE; 13129 } 13130}) 13131 13132;; We need to disable this for TARGET_SEH, as otherwise 13133;; shrink-wrapped prologue gets enabled too. This might exceed 13134;; the maximum size of prologue in unwind information. 13135;; Also disallow shrink-wrapping if using stack slot to pass the 13136;; static chain pointer - the first instruction has to be pushl %esi 13137;; and it can't be moved around, as we use alternate entry points 13138;; in that case. 13139 13140(define_expand "simple_return" 13141 [(simple_return)] 13142 "!TARGET_SEH && !ix86_static_chain_on_stack" 13143{ 13144 if (crtl->args.pops_args) 13145 { 13146 rtx popc = GEN_INT (crtl->args.pops_args); 13147 emit_jump_insn (gen_simple_return_pop_internal (popc)); 13148 DONE; 13149 } 13150}) 13151 13152(define_insn "simple_return_internal" 13153 [(simple_return)] 13154 "reload_completed" 13155 "* return ix86_output_function_return (false);" 13156 [(set_attr "length" "1") 13157 (set_attr "atom_unit" "jeu") 13158 (set_attr "length_immediate" "0") 13159 (set_attr "modrm" "0") 13160 (set_attr "maybe_prefix_bnd" "1")]) 13161 13162(define_insn "interrupt_return" 13163 [(simple_return) 13164 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)] 13165 "reload_completed" 13166{ 13167 return TARGET_64BIT ? "iretq" : "iret"; 13168}) 13169 13170;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 13171;; instruction Athlon and K8 have. 13172 13173(define_insn "simple_return_internal_long" 13174 [(simple_return) 13175 (unspec [(const_int 0)] UNSPEC_REP)] 13176 "reload_completed" 13177 "* return ix86_output_function_return (true);" 13178 [(set_attr "length" "2") 13179 (set_attr "atom_unit" "jeu") 13180 (set_attr "length_immediate" "0") 13181 (set_attr "prefix_rep" "1") 13182 (set_attr "modrm" "0")]) 13183 13184(define_insn_and_split "simple_return_pop_internal" 13185 [(simple_return) 13186 (use (match_operand:SI 0 "const_int_operand"))] 13187 "reload_completed" 13188 "%!ret\t%0" 13189 "&& cfun->machine->function_return_type != indirect_branch_keep" 13190 [(const_int 0)] 13191 "ix86_split_simple_return_pop_internal (operands[0]); DONE;" 13192 [(set_attr "length" "3") 13193 (set_attr "atom_unit" "jeu") 13194 (set_attr "length_immediate" "2") 13195 (set_attr "modrm" "0") 13196 (set_attr "maybe_prefix_bnd" "1")]) 13197 13198(define_insn "simple_return_indirect_internal" 13199 [(simple_return) 13200 (use (match_operand 0 "register_operand" "r"))] 13201 "reload_completed" 13202 "* return ix86_output_indirect_function_return (operands[0]);" 13203 [(set (attr "type") 13204 (if_then_else (match_test "(cfun->machine->indirect_branch_type 13205 != indirect_branch_keep)") 13206 (const_string "multi") 13207 (const_string "ibr"))) 13208 (set_attr "length_immediate" "0") 13209 (set_attr "maybe_prefix_bnd" "1")]) 13210 13211(define_insn "nop" 13212 [(const_int 0)] 13213 "" 13214 "nop" 13215 [(set_attr "length" "1") 13216 (set_attr "length_immediate" "0") 13217 (set_attr "modrm" "0")]) 13218 13219;; Generate nops. Operand 0 is the number of nops, up to 8. 13220(define_insn "nops" 13221 [(unspec_volatile [(match_operand 0 "const_int_operand")] 13222 UNSPECV_NOPS)] 13223 "reload_completed" 13224{ 13225 int num = INTVAL (operands[0]); 13226 13227 gcc_assert (IN_RANGE (num, 1, 8)); 13228 13229 while (num--) 13230 fputs ("\tnop\n", asm_out_file); 13231 13232 return ""; 13233} 13234 [(set (attr "length") (symbol_ref "INTVAL (operands[0])")) 13235 (set_attr "length_immediate" "0") 13236 (set_attr "modrm" "0")]) 13237 13238;; Pad to 16-byte boundary, max skip in op0. Used to avoid 13239;; branch prediction penalty for the third jump in a 16-byte 13240;; block on K8. 13241 13242(define_insn "pad" 13243 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)] 13244 "" 13245{ 13246#ifdef ASM_OUTPUT_MAX_SKIP_PAD 13247 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); 13248#else 13249 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 13250 The align insn is used to avoid 3 jump instructions in the row to improve 13251 branch prediction and the benefits hardly outweigh the cost of extra 8 13252 nops on the average inserted by full alignment pseudo operation. */ 13253#endif 13254 return ""; 13255} 13256 [(set_attr "length" "16")]) 13257 13258(define_expand "prologue" 13259 [(const_int 0)] 13260 "" 13261 "ix86_expand_prologue (); DONE;") 13262 13263(define_expand "set_got" 13264 [(parallel 13265 [(set (match_operand:SI 0 "register_operand") 13266 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 13267 (clobber (reg:CC FLAGS_REG))])] 13268 "!TARGET_64BIT" 13269{ 13270 if (flag_pic && !TARGET_VXWORKS_RTP) 13271 ix86_pc_thunk_call_expanded = true; 13272}) 13273 13274(define_insn "*set_got" 13275 [(set (match_operand:SI 0 "register_operand" "=r") 13276 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 13277 (clobber (reg:CC FLAGS_REG))] 13278 "!TARGET_64BIT" 13279 "* return output_set_got (operands[0], NULL_RTX);" 13280 [(set_attr "type" "multi") 13281 (set_attr "length" "12")]) 13282 13283(define_expand "set_got_labelled" 13284 [(parallel 13285 [(set (match_operand:SI 0 "register_operand") 13286 (unspec:SI [(label_ref (match_operand 1))] 13287 UNSPEC_SET_GOT)) 13288 (clobber (reg:CC FLAGS_REG))])] 13289 "!TARGET_64BIT" 13290{ 13291 if (flag_pic && !TARGET_VXWORKS_RTP) 13292 ix86_pc_thunk_call_expanded = true; 13293}) 13294 13295(define_insn "*set_got_labelled" 13296 [(set (match_operand:SI 0 "register_operand" "=r") 13297 (unspec:SI [(label_ref (match_operand 1))] 13298 UNSPEC_SET_GOT)) 13299 (clobber (reg:CC FLAGS_REG))] 13300 "!TARGET_64BIT" 13301 "* return output_set_got (operands[0], operands[1]);" 13302 [(set_attr "type" "multi") 13303 (set_attr "length" "12")]) 13304 13305(define_insn "set_got_rex64" 13306 [(set (match_operand:DI 0 "register_operand" "=r") 13307 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 13308 "TARGET_64BIT" 13309 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" 13310 [(set_attr "type" "lea") 13311 (set_attr "length_address" "4") 13312 (set_attr "modrm_class" "unknown") 13313 (set_attr "mode" "DI")]) 13314 13315(define_insn "set_rip_rex64" 13316 [(set (match_operand:DI 0 "register_operand" "=r") 13317 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))] 13318 "TARGET_64BIT" 13319 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" 13320 [(set_attr "type" "lea") 13321 (set_attr "length_address" "4") 13322 (set_attr "mode" "DI")]) 13323 13324(define_insn "set_got_offset_rex64" 13325 [(set (match_operand:DI 0 "register_operand" "=r") 13326 (unspec:DI 13327 [(label_ref (match_operand 1))] 13328 UNSPEC_SET_GOT_OFFSET))] 13329 "TARGET_LP64" 13330 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" 13331 [(set_attr "type" "imov") 13332 (set_attr "length_immediate" "0") 13333 (set_attr "length_address" "8") 13334 (set_attr "mode" "DI")]) 13335 13336(define_expand "epilogue" 13337 [(const_int 0)] 13338 "" 13339 "ix86_expand_epilogue (1); DONE;") 13340 13341(define_expand "sibcall_epilogue" 13342 [(const_int 0)] 13343 "" 13344 "ix86_expand_epilogue (0); DONE;") 13345 13346(define_expand "eh_return" 13347 [(use (match_operand 0 "register_operand"))] 13348 "" 13349{ 13350 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 13351 13352 /* Tricky bit: we write the address of the handler to which we will 13353 be returning into someone else's stack frame, one word below the 13354 stack address we wish to restore. */ 13355 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 13356 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD); 13357 /* Return address is always in word_mode. */ 13358 tmp = gen_rtx_MEM (word_mode, tmp); 13359 if (GET_MODE (ra) != word_mode) 13360 ra = convert_to_mode (word_mode, ra, 1); 13361 emit_move_insn (tmp, ra); 13362 13363 emit_jump_insn (gen_eh_return_internal ()); 13364 emit_barrier (); 13365 DONE; 13366}) 13367 13368(define_insn_and_split "eh_return_internal" 13369 [(eh_return)] 13370 "" 13371 "#" 13372 "epilogue_completed" 13373 [(const_int 0)] 13374 "ix86_expand_epilogue (2); DONE;") 13375 13376(define_insn "leave" 13377 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 13378 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 13379 (clobber (mem:BLK (scratch)))] 13380 "!TARGET_64BIT" 13381 "leave" 13382 [(set_attr "type" "leave")]) 13383 13384(define_insn "leave_rex64" 13385 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 13386 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 13387 (clobber (mem:BLK (scratch)))] 13388 "TARGET_64BIT" 13389 "leave" 13390 [(set_attr "type" "leave")]) 13391 13392;; Handle -fsplit-stack. 13393 13394(define_expand "split_stack_prologue" 13395 [(const_int 0)] 13396 "" 13397{ 13398 ix86_expand_split_stack_prologue (); 13399 DONE; 13400}) 13401 13402;; In order to support the call/return predictor, we use a return 13403;; instruction which the middle-end doesn't see. 13404(define_insn "split_stack_return" 13405 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] 13406 UNSPECV_SPLIT_STACK_RETURN)] 13407 "" 13408{ 13409 if (operands[0] == const0_rtx) 13410 return "ret"; 13411 else 13412 return "ret\t%0"; 13413} 13414 [(set_attr "atom_unit" "jeu") 13415 (set_attr "modrm" "0") 13416 (set (attr "length") 13417 (if_then_else (match_operand:SI 0 "const0_operand") 13418 (const_int 1) 13419 (const_int 3))) 13420 (set (attr "length_immediate") 13421 (if_then_else (match_operand:SI 0 "const0_operand") 13422 (const_int 0) 13423 (const_int 2)))]) 13424 13425;; If there are operand 0 bytes available on the stack, jump to 13426;; operand 1. 13427 13428(define_expand "split_stack_space_check" 13429 [(set (pc) (if_then_else 13430 (ltu (minus (reg SP_REG) 13431 (match_operand 0 "register_operand")) 13432 (match_dup 2)) 13433 (label_ref (match_operand 1)) 13434 (pc)))] 13435 "" 13436{ 13437 rtx reg = gen_reg_rtx (Pmode); 13438 13439 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0])); 13440 13441 operands[2] = ix86_split_stack_guard (); 13442 ix86_expand_branch (GEU, reg, operands[2], operands[1]); 13443 13444 DONE; 13445}) 13446 13447;; Bit manipulation instructions. 13448 13449(define_expand "ffs<mode>2" 13450 [(set (match_dup 2) (const_int -1)) 13451 (parallel [(set (match_dup 3) (match_dup 4)) 13452 (set (match_operand:SWI48 0 "register_operand") 13453 (ctz:SWI48 13454 (match_operand:SWI48 1 "nonimmediate_operand")))]) 13455 (set (match_dup 0) (if_then_else:SWI48 13456 (eq (match_dup 3) (const_int 0)) 13457 (match_dup 2) 13458 (match_dup 0))) 13459 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) 13460 (clobber (reg:CC FLAGS_REG))])] 13461 "" 13462{ 13463 machine_mode flags_mode; 13464 13465 if (<MODE>mode == SImode && !TARGET_CMOVE) 13466 { 13467 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); 13468 DONE; 13469 } 13470 13471 flags_mode = TARGET_BMI ? CCCmode : CCZmode; 13472 13473 operands[2] = gen_reg_rtx (<MODE>mode); 13474 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG); 13475 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 13476}) 13477 13478(define_insn_and_split "ffssi2_no_cmove" 13479 [(set (match_operand:SI 0 "register_operand" "=r") 13480 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 13481 (clobber (match_scratch:SI 2 "=&q")) 13482 (clobber (reg:CC FLAGS_REG))] 13483 "!TARGET_CMOVE" 13484 "#" 13485 "&& reload_completed" 13486 [(parallel [(set (match_dup 4) (match_dup 5)) 13487 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 13488 (set (strict_low_part (match_dup 3)) 13489 (eq:QI (match_dup 4) (const_int 0))) 13490 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 13491 (clobber (reg:CC FLAGS_REG))]) 13492 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 13493 (clobber (reg:CC FLAGS_REG))]) 13494 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 13495 (clobber (reg:CC FLAGS_REG))])] 13496{ 13497 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode; 13498 13499 operands[3] = gen_lowpart (QImode, operands[2]); 13500 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG); 13501 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 13502 13503 ix86_expand_clear (operands[2]); 13504}) 13505 13506(define_insn_and_split "*tzcnt<mode>_1" 13507 [(set (reg:CCC FLAGS_REG) 13508 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13509 (const_int 0))) 13510 (set (match_operand:SWI48 0 "register_operand" "=r") 13511 (ctz:SWI48 (match_dup 1)))] 13512 "TARGET_BMI" 13513 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13514 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13515 && optimize_function_for_speed_p (cfun) 13516 && !reg_mentioned_p (operands[0], operands[1])" 13517 [(parallel 13518 [(set (reg:CCC FLAGS_REG) 13519 (compare:CCC (match_dup 1) (const_int 0))) 13520 (set (match_dup 0) 13521 (ctz:SWI48 (match_dup 1))) 13522 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] 13523 "ix86_expand_clear (operands[0]);" 13524 [(set_attr "type" "alu1") 13525 (set_attr "prefix_0f" "1") 13526 (set_attr "prefix_rep" "1") 13527 (set_attr "btver2_decode" "double") 13528 (set_attr "mode" "<MODE>")]) 13529 13530; False dependency happens when destination is only updated by tzcnt, 13531; lzcnt or popcnt. There is no false dependency when destination is 13532; also used in source. 13533(define_insn "*tzcnt<mode>_1_falsedep" 13534 [(set (reg:CCC FLAGS_REG) 13535 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13536 (const_int 0))) 13537 (set (match_operand:SWI48 0 "register_operand" "=r") 13538 (ctz:SWI48 (match_dup 1))) 13539 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13540 UNSPEC_INSN_FALSE_DEP)] 13541 "TARGET_BMI" 13542 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13543 [(set_attr "type" "alu1") 13544 (set_attr "prefix_0f" "1") 13545 (set_attr "prefix_rep" "1") 13546 (set_attr "btver2_decode" "double") 13547 (set_attr "mode" "<MODE>")]) 13548 13549(define_insn "*bsf<mode>_1" 13550 [(set (reg:CCZ FLAGS_REG) 13551 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13552 (const_int 0))) 13553 (set (match_operand:SWI48 0 "register_operand" "=r") 13554 (ctz:SWI48 (match_dup 1)))] 13555 "" 13556 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" 13557 [(set_attr "type" "alu1") 13558 (set_attr "prefix_0f" "1") 13559 (set_attr "btver2_decode" "double") 13560 (set_attr "znver1_decode" "vector") 13561 (set_attr "mode" "<MODE>")]) 13562 13563(define_insn_and_split "ctz<mode>2" 13564 [(set (match_operand:SWI48 0 "register_operand" "=r") 13565 (ctz:SWI48 13566 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13567 (clobber (reg:CC FLAGS_REG))] 13568 "" 13569{ 13570 if (TARGET_BMI) 13571 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13572 else if (optimize_function_for_size_p (cfun)) 13573 ; 13574 else if (TARGET_GENERIC) 13575 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 13576 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13577 13578 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13579} 13580 "(TARGET_BMI || TARGET_GENERIC) 13581 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13582 && optimize_function_for_speed_p (cfun) 13583 && !reg_mentioned_p (operands[0], operands[1])" 13584 [(parallel 13585 [(set (match_dup 0) 13586 (ctz:SWI48 (match_dup 1))) 13587 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13588 (clobber (reg:CC FLAGS_REG))])] 13589 "ix86_expand_clear (operands[0]);" 13590 [(set_attr "type" "alu1") 13591 (set_attr "prefix_0f" "1") 13592 (set (attr "prefix_rep") 13593 (if_then_else 13594 (ior (match_test "TARGET_BMI") 13595 (and (not (match_test "optimize_function_for_size_p (cfun)")) 13596 (match_test "TARGET_GENERIC"))) 13597 (const_string "1") 13598 (const_string "0"))) 13599 (set_attr "mode" "<MODE>")]) 13600 13601; False dependency happens when destination is only updated by tzcnt, 13602; lzcnt or popcnt. There is no false dependency when destination is 13603; also used in source. 13604(define_insn "*ctz<mode>2_falsedep" 13605 [(set (match_operand:SWI48 0 "register_operand" "=r") 13606 (ctz:SWI48 13607 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13608 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13609 UNSPEC_INSN_FALSE_DEP) 13610 (clobber (reg:CC FLAGS_REG))] 13611 "" 13612{ 13613 if (TARGET_BMI) 13614 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13615 else if (TARGET_GENERIC) 13616 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 13617 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13618 else 13619 gcc_unreachable (); 13620} 13621 [(set_attr "type" "alu1") 13622 (set_attr "prefix_0f" "1") 13623 (set_attr "prefix_rep" "1") 13624 (set_attr "mode" "<MODE>")]) 13625 13626(define_insn "bsr_rex64" 13627 [(set (match_operand:DI 0 "register_operand" "=r") 13628 (minus:DI (const_int 63) 13629 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 13630 (clobber (reg:CC FLAGS_REG))] 13631 "TARGET_64BIT" 13632 "bsr{q}\t{%1, %0|%0, %1}" 13633 [(set_attr "type" "alu1") 13634 (set_attr "prefix_0f" "1") 13635 (set_attr "znver1_decode" "vector") 13636 (set_attr "mode" "DI")]) 13637 13638(define_insn "bsr" 13639 [(set (match_operand:SI 0 "register_operand" "=r") 13640 (minus:SI (const_int 31) 13641 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 13642 (clobber (reg:CC FLAGS_REG))] 13643 "" 13644 "bsr{l}\t{%1, %0|%0, %1}" 13645 [(set_attr "type" "alu1") 13646 (set_attr "prefix_0f" "1") 13647 (set_attr "znver1_decode" "vector") 13648 (set_attr "mode" "SI")]) 13649 13650(define_insn "*bsrhi" 13651 [(set (match_operand:HI 0 "register_operand" "=r") 13652 (minus:HI (const_int 15) 13653 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 13654 (clobber (reg:CC FLAGS_REG))] 13655 "" 13656 "bsr{w}\t{%1, %0|%0, %1}" 13657 [(set_attr "type" "alu1") 13658 (set_attr "prefix_0f" "1") 13659 (set_attr "znver1_decode" "vector") 13660 (set_attr "mode" "HI")]) 13661 13662(define_expand "clz<mode>2" 13663 [(parallel 13664 [(set (match_operand:SWI48 0 "register_operand") 13665 (minus:SWI48 13666 (match_dup 2) 13667 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")))) 13668 (clobber (reg:CC FLAGS_REG))]) 13669 (parallel 13670 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2))) 13671 (clobber (reg:CC FLAGS_REG))])] 13672 "" 13673{ 13674 if (TARGET_LZCNT) 13675 { 13676 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1])); 13677 DONE; 13678 } 13679 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 13680}) 13681 13682(define_insn_and_split "clz<mode>2_lzcnt" 13683 [(set (match_operand:SWI48 0 "register_operand" "=r") 13684 (clz:SWI48 13685 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13686 (clobber (reg:CC FLAGS_REG))] 13687 "TARGET_LZCNT" 13688 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 13689 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13690 && optimize_function_for_speed_p (cfun) 13691 && !reg_mentioned_p (operands[0], operands[1])" 13692 [(parallel 13693 [(set (match_dup 0) 13694 (clz:SWI48 (match_dup 1))) 13695 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13696 (clobber (reg:CC FLAGS_REG))])] 13697 "ix86_expand_clear (operands[0]);" 13698 [(set_attr "prefix_rep" "1") 13699 (set_attr "type" "bitmanip") 13700 (set_attr "mode" "<MODE>")]) 13701 13702; False dependency happens when destination is only updated by tzcnt, 13703; lzcnt or popcnt. There is no false dependency when destination is 13704; also used in source. 13705(define_insn "*clz<mode>2_lzcnt_falsedep" 13706 [(set (match_operand:SWI48 0 "register_operand" "=r") 13707 (clz:SWI48 13708 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13709 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13710 UNSPEC_INSN_FALSE_DEP) 13711 (clobber (reg:CC FLAGS_REG))] 13712 "TARGET_LZCNT" 13713 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 13714 [(set_attr "prefix_rep" "1") 13715 (set_attr "type" "bitmanip") 13716 (set_attr "mode" "<MODE>")]) 13717 13718(define_int_iterator LT_ZCNT 13719 [(UNSPEC_TZCNT "TARGET_BMI") 13720 (UNSPEC_LZCNT "TARGET_LZCNT")]) 13721 13722(define_int_attr lt_zcnt 13723 [(UNSPEC_TZCNT "tzcnt") 13724 (UNSPEC_LZCNT "lzcnt")]) 13725 13726(define_int_attr lt_zcnt_type 13727 [(UNSPEC_TZCNT "alu1") 13728 (UNSPEC_LZCNT "bitmanip")]) 13729 13730;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version 13731;; provides operand size as output when source operand is zero. 13732 13733(define_insn_and_split "<lt_zcnt>_<mode>" 13734 [(set (match_operand:SWI48 0 "register_operand" "=r") 13735 (unspec:SWI48 13736 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13737 (clobber (reg:CC FLAGS_REG))] 13738 "" 13739 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" 13740 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13741 && optimize_function_for_speed_p (cfun) 13742 && !reg_mentioned_p (operands[0], operands[1])" 13743 [(parallel 13744 [(set (match_dup 0) 13745 (unspec:SWI48 [(match_dup 1)] LT_ZCNT)) 13746 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13747 (clobber (reg:CC FLAGS_REG))])] 13748 "ix86_expand_clear (operands[0]);" 13749 [(set_attr "type" "<lt_zcnt_type>") 13750 (set_attr "prefix_0f" "1") 13751 (set_attr "prefix_rep" "1") 13752 (set_attr "mode" "<MODE>")]) 13753 13754; False dependency happens when destination is only updated by tzcnt, 13755; lzcnt or popcnt. There is no false dependency when destination is 13756; also used in source. 13757(define_insn "*<lt_zcnt>_<mode>_falsedep" 13758 [(set (match_operand:SWI48 0 "register_operand" "=r") 13759 (unspec:SWI48 13760 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13761 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13762 UNSPEC_INSN_FALSE_DEP) 13763 (clobber (reg:CC FLAGS_REG))] 13764 "" 13765 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" 13766 [(set_attr "type" "<lt_zcnt_type>") 13767 (set_attr "prefix_0f" "1") 13768 (set_attr "prefix_rep" "1") 13769 (set_attr "mode" "<MODE>")]) 13770 13771(define_insn "<lt_zcnt>_hi" 13772 [(set (match_operand:HI 0 "register_operand" "=r") 13773 (unspec:HI 13774 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13775 (clobber (reg:CC FLAGS_REG))] 13776 "" 13777 "<lt_zcnt>{w}\t{%1, %0|%0, %1}" 13778 [(set_attr "type" "<lt_zcnt_type>") 13779 (set_attr "prefix_0f" "1") 13780 (set_attr "prefix_rep" "1") 13781 (set_attr "mode" "HI")]) 13782 13783;; BMI instructions. 13784 13785(define_insn "bmi_bextr_<mode>" 13786 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 13787 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 13788 (match_operand:SWI48 2 "register_operand" "r,r")] 13789 UNSPEC_BEXTR)) 13790 (clobber (reg:CC FLAGS_REG))] 13791 "TARGET_BMI" 13792 "bextr\t{%2, %1, %0|%0, %1, %2}" 13793 [(set_attr "type" "bitmanip") 13794 (set_attr "btver2_decode" "direct, double") 13795 (set_attr "mode" "<MODE>")]) 13796 13797(define_insn "*bmi_bextr_<mode>_ccz" 13798 [(set (reg:CCZ FLAGS_REG) 13799 (compare:CCZ 13800 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 13801 (match_operand:SWI48 2 "register_operand" "r,r")] 13802 UNSPEC_BEXTR) 13803 (const_int 0))) 13804 (clobber (match_scratch:SWI48 0 "=r,r"))] 13805 "TARGET_BMI" 13806 "bextr\t{%2, %1, %0|%0, %1, %2}" 13807 [(set_attr "type" "bitmanip") 13808 (set_attr "btver2_decode" "direct, double") 13809 (set_attr "mode" "<MODE>")]) 13810 13811(define_insn "*bmi_blsi_<mode>" 13812 [(set (match_operand:SWI48 0 "register_operand" "=r") 13813 (and:SWI48 13814 (neg:SWI48 13815 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 13816 (match_dup 1))) 13817 (clobber (reg:CC FLAGS_REG))] 13818 "TARGET_BMI" 13819 "blsi\t{%1, %0|%0, %1}" 13820 [(set_attr "type" "bitmanip") 13821 (set_attr "btver2_decode" "double") 13822 (set_attr "mode" "<MODE>")]) 13823 13824(define_insn "*bmi_blsmsk_<mode>" 13825 [(set (match_operand:SWI48 0 "register_operand" "=r") 13826 (xor:SWI48 13827 (plus:SWI48 13828 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13829 (const_int -1)) 13830 (match_dup 1))) 13831 (clobber (reg:CC FLAGS_REG))] 13832 "TARGET_BMI" 13833 "blsmsk\t{%1, %0|%0, %1}" 13834 [(set_attr "type" "bitmanip") 13835 (set_attr "btver2_decode" "double") 13836 (set_attr "mode" "<MODE>")]) 13837 13838(define_insn "*bmi_blsr_<mode>" 13839 [(set (match_operand:SWI48 0 "register_operand" "=r") 13840 (and:SWI48 13841 (plus:SWI48 13842 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13843 (const_int -1)) 13844 (match_dup 1))) 13845 (clobber (reg:CC FLAGS_REG))] 13846 "TARGET_BMI" 13847 "blsr\t{%1, %0|%0, %1}" 13848 [(set_attr "type" "bitmanip") 13849 (set_attr "btver2_decode" "double") 13850 (set_attr "mode" "<MODE>")]) 13851 13852(define_insn "*bmi_blsr_<mode>_cmp" 13853 [(set (reg:CCZ FLAGS_REG) 13854 (compare:CCZ 13855 (and:SWI48 13856 (plus:SWI48 13857 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13858 (const_int -1)) 13859 (match_dup 1)) 13860 (const_int 0))) 13861 (set (match_operand:SWI48 0 "register_operand" "=r") 13862 (and:SWI48 13863 (plus:SWI48 13864 (match_dup 1) 13865 (const_int -1)) 13866 (match_dup 1)))] 13867 "TARGET_BMI" 13868 "blsr\t{%1, %0|%0, %1}" 13869 [(set_attr "type" "bitmanip") 13870 (set_attr "btver2_decode" "double") 13871 (set_attr "mode" "<MODE>")]) 13872 13873(define_insn "*bmi_blsr_<mode>_ccz" 13874 [(set (reg:CCZ FLAGS_REG) 13875 (compare:CCZ 13876 (and:SWI48 13877 (plus:SWI48 13878 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13879 (const_int -1)) 13880 (match_dup 1)) 13881 (const_int 0))) 13882 (clobber (match_scratch:SWI48 0 "=r"))] 13883 "TARGET_BMI" 13884 "blsr\t{%1, %0|%0, %1}" 13885 [(set_attr "type" "bitmanip") 13886 (set_attr "btver2_decode" "double") 13887 (set_attr "mode" "<MODE>")]) 13888 13889;; BMI2 instructions. 13890(define_expand "bmi2_bzhi_<mode>3" 13891 [(parallel 13892 [(set (match_operand:SWI48 0 "register_operand") 13893 (zero_extract:SWI48 13894 (match_operand:SWI48 1 "nonimmediate_operand") 13895 (umin:SWI48 13896 (and:SWI48 (match_operand:SWI48 2 "register_operand") 13897 (const_int 255)) 13898 (match_dup 3)) 13899 (const_int 0))) 13900 (clobber (reg:CC FLAGS_REG))])] 13901 "TARGET_BMI2" 13902 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);") 13903 13904(define_insn "*bmi2_bzhi_<mode>3" 13905 [(set (match_operand:SWI48 0 "register_operand" "=r") 13906 (zero_extract:SWI48 13907 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13908 (umin:SWI48 13909 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r") 13910 (const_int 255)) 13911 (match_operand:SWI48 3 "const_int_operand" "n")) 13912 (const_int 0))) 13913 (clobber (reg:CC FLAGS_REG))] 13914 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13915 "bzhi\t{%2, %1, %0|%0, %1, %2}" 13916 [(set_attr "type" "bitmanip") 13917 (set_attr "prefix" "vex") 13918 (set_attr "mode" "<MODE>")]) 13919 13920(define_insn "*bmi2_bzhi_<mode>3_1" 13921 [(set (match_operand:SWI48 0 "register_operand" "=r") 13922 (zero_extract:SWI48 13923 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13924 (umin:SWI48 13925 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r")) 13926 (match_operand:SWI48 3 "const_int_operand" "n")) 13927 (const_int 0))) 13928 (clobber (reg:CC FLAGS_REG))] 13929 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13930 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 13931 [(set_attr "type" "bitmanip") 13932 (set_attr "prefix" "vex") 13933 (set_attr "mode" "<MODE>")]) 13934 13935(define_insn "*bmi2_bzhi_<mode>3_1_ccz" 13936 [(set (reg:CCZ FLAGS_REG) 13937 (compare:CCZ 13938 (zero_extract:SWI48 13939 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13940 (umin:SWI48 13941 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r")) 13942 (match_operand:SWI48 3 "const_int_operand" "n")) 13943 (const_int 0)) 13944 (const_int 0))) 13945 (clobber (match_scratch:SWI48 0 "=r"))] 13946 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13947 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 13948 [(set_attr "type" "bitmanip") 13949 (set_attr "prefix" "vex") 13950 (set_attr "mode" "<MODE>")]) 13951 13952(define_insn "bmi2_pdep_<mode>3" 13953 [(set (match_operand:SWI48 0 "register_operand" "=r") 13954 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 13955 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 13956 UNSPEC_PDEP))] 13957 "TARGET_BMI2" 13958 "pdep\t{%2, %1, %0|%0, %1, %2}" 13959 [(set_attr "type" "bitmanip") 13960 (set_attr "prefix" "vex") 13961 (set_attr "mode" "<MODE>")]) 13962 13963(define_insn "bmi2_pext_<mode>3" 13964 [(set (match_operand:SWI48 0 "register_operand" "=r") 13965 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 13966 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 13967 UNSPEC_PEXT))] 13968 "TARGET_BMI2" 13969 "pext\t{%2, %1, %0|%0, %1, %2}" 13970 [(set_attr "type" "bitmanip") 13971 (set_attr "prefix" "vex") 13972 (set_attr "mode" "<MODE>")]) 13973 13974;; TBM instructions. 13975(define_insn "tbm_bextri_<mode>" 13976 [(set (match_operand:SWI48 0 "register_operand" "=r") 13977 (zero_extract:SWI48 13978 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13979 (match_operand 2 "const_0_to_255_operand" "N") 13980 (match_operand 3 "const_0_to_255_operand" "N"))) 13981 (clobber (reg:CC FLAGS_REG))] 13982 "TARGET_TBM" 13983{ 13984 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); 13985 return "bextr\t{%2, %1, %0|%0, %1, %2}"; 13986} 13987 [(set_attr "type" "bitmanip") 13988 (set_attr "mode" "<MODE>")]) 13989 13990(define_insn "*tbm_blcfill_<mode>" 13991 [(set (match_operand:SWI48 0 "register_operand" "=r") 13992 (and:SWI48 13993 (plus:SWI48 13994 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13995 (const_int 1)) 13996 (match_dup 1))) 13997 (clobber (reg:CC FLAGS_REG))] 13998 "TARGET_TBM" 13999 "blcfill\t{%1, %0|%0, %1}" 14000 [(set_attr "type" "bitmanip") 14001 (set_attr "mode" "<MODE>")]) 14002 14003(define_insn "*tbm_blci_<mode>" 14004 [(set (match_operand:SWI48 0 "register_operand" "=r") 14005 (ior:SWI48 14006 (not:SWI48 14007 (plus:SWI48 14008 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14009 (const_int 1))) 14010 (match_dup 1))) 14011 (clobber (reg:CC FLAGS_REG))] 14012 "TARGET_TBM" 14013 "blci\t{%1, %0|%0, %1}" 14014 [(set_attr "type" "bitmanip") 14015 (set_attr "mode" "<MODE>")]) 14016 14017(define_insn "*tbm_blcic_<mode>" 14018 [(set (match_operand:SWI48 0 "register_operand" "=r") 14019 (and:SWI48 14020 (plus:SWI48 14021 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14022 (const_int 1)) 14023 (not:SWI48 14024 (match_dup 1)))) 14025 (clobber (reg:CC FLAGS_REG))] 14026 "TARGET_TBM" 14027 "blcic\t{%1, %0|%0, %1}" 14028 [(set_attr "type" "bitmanip") 14029 (set_attr "mode" "<MODE>")]) 14030 14031(define_insn "*tbm_blcmsk_<mode>" 14032 [(set (match_operand:SWI48 0 "register_operand" "=r") 14033 (xor:SWI48 14034 (plus:SWI48 14035 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14036 (const_int 1)) 14037 (match_dup 1))) 14038 (clobber (reg:CC FLAGS_REG))] 14039 "TARGET_TBM" 14040 "blcmsk\t{%1, %0|%0, %1}" 14041 [(set_attr "type" "bitmanip") 14042 (set_attr "mode" "<MODE>")]) 14043 14044(define_insn "*tbm_blcs_<mode>" 14045 [(set (match_operand:SWI48 0 "register_operand" "=r") 14046 (ior:SWI48 14047 (plus:SWI48 14048 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14049 (const_int 1)) 14050 (match_dup 1))) 14051 (clobber (reg:CC FLAGS_REG))] 14052 "TARGET_TBM" 14053 "blcs\t{%1, %0|%0, %1}" 14054 [(set_attr "type" "bitmanip") 14055 (set_attr "mode" "<MODE>")]) 14056 14057(define_insn "*tbm_blsfill_<mode>" 14058 [(set (match_operand:SWI48 0 "register_operand" "=r") 14059 (ior:SWI48 14060 (plus:SWI48 14061 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14062 (const_int -1)) 14063 (match_dup 1))) 14064 (clobber (reg:CC FLAGS_REG))] 14065 "TARGET_TBM" 14066 "blsfill\t{%1, %0|%0, %1}" 14067 [(set_attr "type" "bitmanip") 14068 (set_attr "mode" "<MODE>")]) 14069 14070(define_insn "*tbm_blsic_<mode>" 14071 [(set (match_operand:SWI48 0 "register_operand" "=r") 14072 (ior:SWI48 14073 (plus:SWI48 14074 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14075 (const_int -1)) 14076 (not:SWI48 14077 (match_dup 1)))) 14078 (clobber (reg:CC FLAGS_REG))] 14079 "TARGET_TBM" 14080 "blsic\t{%1, %0|%0, %1}" 14081 [(set_attr "type" "bitmanip") 14082 (set_attr "mode" "<MODE>")]) 14083 14084(define_insn "*tbm_t1mskc_<mode>" 14085 [(set (match_operand:SWI48 0 "register_operand" "=r") 14086 (ior:SWI48 14087 (plus:SWI48 14088 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14089 (const_int 1)) 14090 (not:SWI48 14091 (match_dup 1)))) 14092 (clobber (reg:CC FLAGS_REG))] 14093 "TARGET_TBM" 14094 "t1mskc\t{%1, %0|%0, %1}" 14095 [(set_attr "type" "bitmanip") 14096 (set_attr "mode" "<MODE>")]) 14097 14098(define_insn "*tbm_tzmsk_<mode>" 14099 [(set (match_operand:SWI48 0 "register_operand" "=r") 14100 (and:SWI48 14101 (plus:SWI48 14102 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14103 (const_int -1)) 14104 (not:SWI48 14105 (match_dup 1)))) 14106 (clobber (reg:CC FLAGS_REG))] 14107 "TARGET_TBM" 14108 "tzmsk\t{%1, %0|%0, %1}" 14109 [(set_attr "type" "bitmanip") 14110 (set_attr "mode" "<MODE>")]) 14111 14112(define_insn_and_split "popcount<mode>2" 14113 [(set (match_operand:SWI48 0 "register_operand" "=r") 14114 (popcount:SWI48 14115 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14116 (clobber (reg:CC FLAGS_REG))] 14117 "TARGET_POPCNT" 14118{ 14119#if TARGET_MACHO 14120 return "popcnt\t{%1, %0|%0, %1}"; 14121#else 14122 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 14123#endif 14124} 14125 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 14126 && optimize_function_for_speed_p (cfun) 14127 && !reg_mentioned_p (operands[0], operands[1])" 14128 [(parallel 14129 [(set (match_dup 0) 14130 (popcount:SWI48 (match_dup 1))) 14131 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 14132 (clobber (reg:CC FLAGS_REG))])] 14133 "ix86_expand_clear (operands[0]);" 14134 [(set_attr "prefix_rep" "1") 14135 (set_attr "type" "bitmanip") 14136 (set_attr "mode" "<MODE>")]) 14137 14138; False dependency happens when destination is only updated by tzcnt, 14139; lzcnt or popcnt. There is no false dependency when destination is 14140; also used in source. 14141(define_insn "*popcount<mode>2_falsedep" 14142 [(set (match_operand:SWI48 0 "register_operand" "=r") 14143 (popcount:SWI48 14144 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14145 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 14146 UNSPEC_INSN_FALSE_DEP) 14147 (clobber (reg:CC FLAGS_REG))] 14148 "TARGET_POPCNT" 14149{ 14150#if TARGET_MACHO 14151 return "popcnt\t{%1, %0|%0, %1}"; 14152#else 14153 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 14154#endif 14155} 14156 [(set_attr "prefix_rep" "1") 14157 (set_attr "type" "bitmanip") 14158 (set_attr "mode" "<MODE>")]) 14159 14160(define_insn_and_split "*popcounthi2_1" 14161 [(set (match_operand:SI 0 "register_operand") 14162 (popcount:SI 14163 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))) 14164 (clobber (reg:CC FLAGS_REG))] 14165 "TARGET_POPCNT 14166 && can_create_pseudo_p ()" 14167 "#" 14168 "&& 1" 14169 [(const_int 0)] 14170{ 14171 rtx tmp = gen_reg_rtx (HImode); 14172 14173 emit_insn (gen_popcounthi2 (tmp, operands[1])); 14174 emit_insn (gen_zero_extendhisi2 (operands[0], tmp)); 14175 DONE; 14176}) 14177 14178(define_insn "popcounthi2" 14179 [(set (match_operand:HI 0 "register_operand" "=r") 14180 (popcount:HI 14181 (match_operand:HI 1 "nonimmediate_operand" "rm"))) 14182 (clobber (reg:CC FLAGS_REG))] 14183 "TARGET_POPCNT" 14184{ 14185#if TARGET_MACHO 14186 return "popcnt\t{%1, %0|%0, %1}"; 14187#else 14188 return "popcnt{w}\t{%1, %0|%0, %1}"; 14189#endif 14190} 14191 [(set_attr "prefix_rep" "1") 14192 (set_attr "type" "bitmanip") 14193 (set_attr "mode" "HI")]) 14194 14195(define_expand "bswapdi2" 14196 [(set (match_operand:DI 0 "register_operand") 14197 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))] 14198 "TARGET_64BIT" 14199{ 14200 if (!TARGET_MOVBE) 14201 operands[1] = force_reg (DImode, operands[1]); 14202}) 14203 14204(define_expand "bswapsi2" 14205 [(set (match_operand:SI 0 "register_operand") 14206 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))] 14207 "" 14208{ 14209 if (TARGET_MOVBE) 14210 ; 14211 else if (TARGET_BSWAP) 14212 operands[1] = force_reg (SImode, operands[1]); 14213 else 14214 { 14215 rtx x = operands[0]; 14216 14217 emit_move_insn (x, operands[1]); 14218 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 14219 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 14220 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 14221 DONE; 14222 } 14223}) 14224 14225(define_insn "*bswap<mode>2_movbe" 14226 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") 14227 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] 14228 "TARGET_MOVBE 14229 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 14230 "@ 14231 bswap\t%0 14232 movbe{<imodesuffix>}\t{%1, %0|%0, %1} 14233 movbe{<imodesuffix>}\t{%1, %0|%0, %1}" 14234 [(set_attr "type" "bitmanip,imov,imov") 14235 (set_attr "modrm" "0,1,1") 14236 (set_attr "prefix_0f" "*,1,1") 14237 (set_attr "prefix_extra" "*,1,1") 14238 (set_attr "mode" "<MODE>")]) 14239 14240(define_insn "*bswap<mode>2" 14241 [(set (match_operand:SWI48 0 "register_operand" "=r") 14242 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] 14243 "TARGET_BSWAP" 14244 "bswap\t%0" 14245 [(set_attr "type" "bitmanip") 14246 (set_attr "modrm" "0") 14247 (set_attr "mode" "<MODE>")]) 14248 14249(define_expand "bswaphi2" 14250 [(set (match_operand:HI 0 "register_operand") 14251 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))] 14252 "TARGET_MOVBE") 14253 14254(define_insn "*bswaphi2_movbe" 14255 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m") 14256 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))] 14257 "TARGET_MOVBE 14258 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 14259 "@ 14260 xchg{b}\t{%h0, %b0|%b0, %h0} 14261 movbe{w}\t{%1, %0|%0, %1} 14262 movbe{w}\t{%1, %0|%0, %1}" 14263 [(set_attr "type" "imov") 14264 (set_attr "modrm" "*,1,1") 14265 (set_attr "prefix_0f" "*,1,1") 14266 (set_attr "prefix_extra" "*,1,1") 14267 (set_attr "pent_pair" "np,*,*") 14268 (set_attr "athlon_decode" "vector,*,*") 14269 (set_attr "amdfam10_decode" "double,*,*") 14270 (set_attr "bdver1_decode" "double,*,*") 14271 (set_attr "mode" "QI,HI,HI")]) 14272 14273(define_peephole2 14274 [(set (match_operand:HI 0 "general_reg_operand") 14275 (bswap:HI (match_dup 0)))] 14276 "TARGET_MOVBE 14277 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)) 14278 && peep2_regno_dead_p (0, FLAGS_REG)" 14279 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8))) 14280 (clobber (reg:CC FLAGS_REG))])]) 14281 14282(define_insn "bswaphi_lowpart" 14283 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) 14284 (bswap:HI (match_dup 0))) 14285 (clobber (reg:CC FLAGS_REG))] 14286 "" 14287 "@ 14288 xchg{b}\t{%h0, %b0|%b0, %h0} 14289 rol{w}\t{$8, %0|%0, 8}" 14290 [(set (attr "preferred_for_size") 14291 (cond [(eq_attr "alternative" "0") 14292 (symbol_ref "true")] 14293 (symbol_ref "false"))) 14294 (set (attr "preferred_for_speed") 14295 (cond [(eq_attr "alternative" "0") 14296 (symbol_ref "TARGET_USE_XCHGB")] 14297 (symbol_ref "!TARGET_USE_XCHGB"))) 14298 (set_attr "length" "2,4") 14299 (set_attr "mode" "QI,HI")]) 14300 14301(define_expand "paritydi2" 14302 [(set (match_operand:DI 0 "register_operand") 14303 (parity:DI (match_operand:DI 1 "register_operand")))] 14304 "! TARGET_POPCNT" 14305{ 14306 rtx scratch = gen_reg_rtx (QImode); 14307 14308 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, 14309 NULL_RTX, operands[1])); 14310 14311 ix86_expand_setcc (scratch, ORDERED, 14312 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 14313 14314 if (TARGET_64BIT) 14315 emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); 14316 else 14317 { 14318 rtx tmp = gen_reg_rtx (SImode); 14319 14320 emit_insn (gen_zero_extendqisi2 (tmp, scratch)); 14321 emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); 14322 } 14323 DONE; 14324}) 14325 14326(define_expand "paritysi2" 14327 [(set (match_operand:SI 0 "register_operand") 14328 (parity:SI (match_operand:SI 1 "register_operand")))] 14329 "! TARGET_POPCNT" 14330{ 14331 rtx scratch = gen_reg_rtx (QImode); 14332 14333 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); 14334 14335 ix86_expand_setcc (scratch, ORDERED, 14336 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 14337 14338 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 14339 DONE; 14340}) 14341 14342(define_insn_and_split "paritydi2_cmp" 14343 [(set (reg:CC FLAGS_REG) 14344 (unspec:CC [(match_operand:DI 3 "register_operand" "0")] 14345 UNSPEC_PARITY)) 14346 (clobber (match_scratch:DI 0 "=r")) 14347 (clobber (match_scratch:SI 1 "=&r")) 14348 (clobber (match_scratch:HI 2 "=Q"))] 14349 "! TARGET_POPCNT" 14350 "#" 14351 "&& reload_completed" 14352 [(parallel 14353 [(set (match_dup 1) 14354 (xor:SI (match_dup 1) (match_dup 4))) 14355 (clobber (reg:CC FLAGS_REG))]) 14356 (parallel 14357 [(set (reg:CC FLAGS_REG) 14358 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 14359 (clobber (match_dup 1)) 14360 (clobber (match_dup 2))])] 14361{ 14362 operands[4] = gen_lowpart (SImode, operands[3]); 14363 14364 if (TARGET_64BIT) 14365 { 14366 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); 14367 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); 14368 } 14369 else 14370 operands[1] = gen_highpart (SImode, operands[3]); 14371}) 14372 14373(define_insn_and_split "paritysi2_cmp" 14374 [(set (reg:CC FLAGS_REG) 14375 (unspec:CC [(match_operand:SI 2 "register_operand" "0")] 14376 UNSPEC_PARITY)) 14377 (clobber (match_scratch:SI 0 "=r")) 14378 (clobber (match_scratch:HI 1 "=&Q"))] 14379 "! TARGET_POPCNT" 14380 "#" 14381 "&& reload_completed" 14382 [(parallel 14383 [(set (match_dup 1) 14384 (xor:HI (match_dup 1) (match_dup 3))) 14385 (clobber (reg:CC FLAGS_REG))]) 14386 (parallel 14387 [(set (reg:CC FLAGS_REG) 14388 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 14389 (clobber (match_dup 1))])] 14390{ 14391 operands[3] = gen_lowpart (HImode, operands[2]); 14392 14393 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); 14394 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); 14395}) 14396 14397(define_insn "*parityhi2_cmp" 14398 [(set (reg:CC FLAGS_REG) 14399 (unspec:CC [(match_operand:HI 1 "register_operand" "0")] 14400 UNSPEC_PARITY)) 14401 (clobber (match_scratch:HI 0 "=Q"))] 14402 "! TARGET_POPCNT" 14403 "xor{b}\t{%h0, %b0|%b0, %h0}" 14404 [(set_attr "length" "2") 14405 (set_attr "mode" "HI")]) 14406 14407 14408;; Thread-local storage patterns for ELF. 14409;; 14410;; Note that these code sequences must appear exactly as shown 14411;; in order to allow linker relaxation. 14412 14413(define_insn "*tls_global_dynamic_32_gnu" 14414 [(set (match_operand:SI 0 "register_operand" "=a") 14415 (unspec:SI 14416 [(match_operand:SI 1 "register_operand" "Yb") 14417 (match_operand 2 "tls_symbolic_operand") 14418 (match_operand 3 "constant_call_address_operand" "Bz") 14419 (reg:SI SP_REG)] 14420 UNSPEC_TLS_GD)) 14421 (clobber (match_scratch:SI 4 "=d")) 14422 (clobber (match_scratch:SI 5 "=c")) 14423 (clobber (reg:CC FLAGS_REG))] 14424 "!TARGET_64BIT && TARGET_GNU_TLS" 14425{ 14426 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14427 output_asm_insn 14428 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); 14429 else 14430 output_asm_insn 14431 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands); 14432 if (TARGET_SUN_TLS) 14433#ifdef HAVE_AS_IX86_TLSGDPLT 14434 return "call\t%a2@tlsgdplt"; 14435#else 14436 return "call\t%p3@plt"; 14437#endif 14438 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14439 return "call\t%P3"; 14440 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}"; 14441} 14442 [(set_attr "type" "multi") 14443 (set_attr "length" "12")]) 14444 14445(define_expand "tls_global_dynamic_32" 14446 [(parallel 14447 [(set (match_operand:SI 0 "register_operand") 14448 (unspec:SI [(match_operand:SI 2 "register_operand") 14449 (match_operand 1 "tls_symbolic_operand") 14450 (match_operand 3 "constant_call_address_operand") 14451 (reg:SI SP_REG)] 14452 UNSPEC_TLS_GD)) 14453 (clobber (match_scratch:SI 4)) 14454 (clobber (match_scratch:SI 5)) 14455 (clobber (reg:CC FLAGS_REG))])] 14456 "" 14457 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14458 14459(define_insn "*tls_global_dynamic_64_<mode>" 14460 [(set (match_operand:P 0 "register_operand" "=a") 14461 (call:P 14462 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz")) 14463 (match_operand 3))) 14464 (unspec:P [(match_operand 1 "tls_symbolic_operand") 14465 (reg:P SP_REG)] 14466 UNSPEC_TLS_GD)] 14467 "TARGET_64BIT" 14468{ 14469 if (!TARGET_X32) 14470 fputs (ASM_BYTE "0x66\n", asm_out_file); 14471 output_asm_insn 14472 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 14473 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14474 fputs (ASM_SHORT "0x6666\n", asm_out_file); 14475 else 14476 fputs (ASM_BYTE "0x66\n", asm_out_file); 14477 fputs ("\trex64\n", asm_out_file); 14478 if (TARGET_SUN_TLS) 14479 return "call\t%p2@plt"; 14480 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14481 return "call\t%P2"; 14482 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}"; 14483} 14484 [(set_attr "type" "multi") 14485 (set (attr "length") 14486 (symbol_ref "TARGET_X32 ? 15 : 16"))]) 14487 14488(define_insn "*tls_global_dynamic_64_largepic" 14489 [(set (match_operand:DI 0 "register_operand" "=a") 14490 (call:DI 14491 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b") 14492 (match_operand:DI 3 "immediate_operand" "i"))) 14493 (match_operand 4))) 14494 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 14495 (reg:DI SP_REG)] 14496 UNSPEC_TLS_GD)] 14497 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 14498 && GET_CODE (operands[3]) == CONST 14499 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC 14500 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF" 14501{ 14502 output_asm_insn 14503 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 14504 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands); 14505 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands); 14506 return "call\t{*%%rax|rax}"; 14507} 14508 [(set_attr "type" "multi") 14509 (set_attr "length" "22")]) 14510 14511(define_expand "tls_global_dynamic_64_<mode>" 14512 [(parallel 14513 [(set (match_operand:P 0 "register_operand") 14514 (call:P 14515 (mem:QI (match_operand 2)) 14516 (const_int 0))) 14517 (unspec:P [(match_operand 1 "tls_symbolic_operand") 14518 (reg:P SP_REG)] 14519 UNSPEC_TLS_GD)])] 14520 "TARGET_64BIT" 14521 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14522 14523(define_insn "*tls_local_dynamic_base_32_gnu" 14524 [(set (match_operand:SI 0 "register_operand" "=a") 14525 (unspec:SI 14526 [(match_operand:SI 1 "register_operand" "Yb") 14527 (match_operand 2 "constant_call_address_operand" "Bz") 14528 (reg:SI SP_REG)] 14529 UNSPEC_TLS_LD_BASE)) 14530 (clobber (match_scratch:SI 3 "=d")) 14531 (clobber (match_scratch:SI 4 "=c")) 14532 (clobber (reg:CC FLAGS_REG))] 14533 "!TARGET_64BIT && TARGET_GNU_TLS" 14534{ 14535 output_asm_insn 14536 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); 14537 if (TARGET_SUN_TLS) 14538 { 14539 if (HAVE_AS_IX86_TLSLDMPLT) 14540 return "call\t%&@tlsldmplt"; 14541 else 14542 return "call\t%p2@plt"; 14543 } 14544 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14545 return "call\t%P2"; 14546 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}"; 14547} 14548 [(set_attr "type" "multi") 14549 (set_attr "length" "11")]) 14550 14551(define_expand "tls_local_dynamic_base_32" 14552 [(parallel 14553 [(set (match_operand:SI 0 "register_operand") 14554 (unspec:SI 14555 [(match_operand:SI 1 "register_operand") 14556 (match_operand 2 "constant_call_address_operand") 14557 (reg:SI SP_REG)] 14558 UNSPEC_TLS_LD_BASE)) 14559 (clobber (match_scratch:SI 3)) 14560 (clobber (match_scratch:SI 4)) 14561 (clobber (reg:CC FLAGS_REG))])] 14562 "" 14563 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14564 14565(define_insn "*tls_local_dynamic_base_64_<mode>" 14566 [(set (match_operand:P 0 "register_operand" "=a") 14567 (call:P 14568 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz")) 14569 (match_operand 2))) 14570 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)] 14571 "TARGET_64BIT" 14572{ 14573 output_asm_insn 14574 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 14575 if (TARGET_SUN_TLS) 14576 return "call\t%p1@plt"; 14577 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14578 return "call\t%P1"; 14579 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}"; 14580} 14581 [(set_attr "type" "multi") 14582 (set_attr "length" "12")]) 14583 14584(define_insn "*tls_local_dynamic_base_64_largepic" 14585 [(set (match_operand:DI 0 "register_operand" "=a") 14586 (call:DI 14587 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b") 14588 (match_operand:DI 2 "immediate_operand" "i"))) 14589 (match_operand 3))) 14590 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)] 14591 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 14592 && GET_CODE (operands[2]) == CONST 14593 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC 14594 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF" 14595{ 14596 output_asm_insn 14597 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 14598 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands); 14599 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands); 14600 return "call\t{*%%rax|rax}"; 14601} 14602 [(set_attr "type" "multi") 14603 (set_attr "length" "22")]) 14604 14605(define_expand "tls_local_dynamic_base_64_<mode>" 14606 [(parallel 14607 [(set (match_operand:P 0 "register_operand") 14608 (call:P 14609 (mem:QI (match_operand 1)) 14610 (const_int 0))) 14611 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])] 14612 "TARGET_64BIT" 14613 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14614 14615;; Local dynamic of a single variable is a lose. Show combine how 14616;; to convert that back to global dynamic. 14617 14618(define_insn_and_split "*tls_local_dynamic_32_once" 14619 [(set (match_operand:SI 0 "register_operand" "=a") 14620 (plus:SI 14621 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14622 (match_operand 2 "constant_call_address_operand" "Bz") 14623 (reg:SI SP_REG)] 14624 UNSPEC_TLS_LD_BASE) 14625 (const:SI (unspec:SI 14626 [(match_operand 3 "tls_symbolic_operand")] 14627 UNSPEC_DTPOFF)))) 14628 (clobber (match_scratch:SI 4 "=d")) 14629 (clobber (match_scratch:SI 5 "=c")) 14630 (clobber (reg:CC FLAGS_REG))] 14631 "" 14632 "#" 14633 "" 14634 [(parallel 14635 [(set (match_dup 0) 14636 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2) 14637 (reg:SI SP_REG)] 14638 UNSPEC_TLS_GD)) 14639 (clobber (match_dup 4)) 14640 (clobber (match_dup 5)) 14641 (clobber (reg:CC FLAGS_REG))])]) 14642 14643;; Load and add the thread base pointer from %<tp_seg>:0. 14644(define_insn_and_split "*load_tp_<mode>" 14645 [(set (match_operand:PTR 0 "register_operand" "=r") 14646 (unspec:PTR [(const_int 0)] UNSPEC_TP))] 14647 "" 14648 "#" 14649 "" 14650 [(set (match_dup 0) 14651 (match_dup 1))] 14652{ 14653 addr_space_t as = DEFAULT_TLS_SEG_REG; 14654 14655 operands[1] = gen_const_mem (<MODE>mode, const0_rtx); 14656 set_mem_addr_space (operands[1], as); 14657}) 14658 14659(define_insn_and_split "*load_tp_x32_zext" 14660 [(set (match_operand:DI 0 "register_operand" "=r") 14661 (zero_extend:DI 14662 (unspec:SI [(const_int 0)] UNSPEC_TP)))] 14663 "TARGET_X32" 14664 "#" 14665 "" 14666 [(set (match_dup 0) 14667 (zero_extend:DI (match_dup 1)))] 14668{ 14669 addr_space_t as = DEFAULT_TLS_SEG_REG; 14670 14671 operands[1] = gen_const_mem (SImode, const0_rtx); 14672 set_mem_addr_space (operands[1], as); 14673}) 14674 14675(define_insn_and_split "*add_tp_<mode>" 14676 [(set (match_operand:PTR 0 "register_operand" "=r") 14677 (plus:PTR 14678 (unspec:PTR [(const_int 0)] UNSPEC_TP) 14679 (match_operand:PTR 1 "register_operand" "0"))) 14680 (clobber (reg:CC FLAGS_REG))] 14681 "" 14682 "#" 14683 "" 14684 [(parallel 14685 [(set (match_dup 0) 14686 (plus:PTR (match_dup 1) (match_dup 2))) 14687 (clobber (reg:CC FLAGS_REG))])] 14688{ 14689 addr_space_t as = DEFAULT_TLS_SEG_REG; 14690 14691 operands[2] = gen_const_mem (<MODE>mode, const0_rtx); 14692 set_mem_addr_space (operands[2], as); 14693}) 14694 14695(define_insn_and_split "*add_tp_x32_zext" 14696 [(set (match_operand:DI 0 "register_operand" "=r") 14697 (zero_extend:DI 14698 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 14699 (match_operand:SI 1 "register_operand" "0")))) 14700 (clobber (reg:CC FLAGS_REG))] 14701 "TARGET_X32" 14702 "#" 14703 "" 14704 [(parallel 14705 [(set (match_dup 0) 14706 (zero_extend:DI 14707 (plus:SI (match_dup 1) (match_dup 2)))) 14708 (clobber (reg:CC FLAGS_REG))])] 14709{ 14710 addr_space_t as = DEFAULT_TLS_SEG_REG; 14711 14712 operands[2] = gen_const_mem (SImode, const0_rtx); 14713 set_mem_addr_space (operands[2], as); 14714}) 14715 14716;; The Sun linker took the AMD64 TLS spec literally and can only handle 14717;; %rax as destination of the initial executable code sequence. 14718(define_insn "tls_initial_exec_64_sun" 14719 [(set (match_operand:DI 0 "register_operand" "=a") 14720 (unspec:DI 14721 [(match_operand 1 "tls_symbolic_operand")] 14722 UNSPEC_TLS_IE_SUN)) 14723 (clobber (reg:CC FLAGS_REG))] 14724 "TARGET_64BIT && TARGET_SUN_TLS" 14725{ 14726 output_asm_insn 14727 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); 14728 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; 14729} 14730 [(set_attr "type" "multi")]) 14731 14732;; GNU2 TLS patterns can be split. 14733 14734(define_expand "tls_dynamic_gnu2_32" 14735 [(set (match_dup 3) 14736 (plus:SI (match_operand:SI 2 "register_operand") 14737 (const:SI 14738 (unspec:SI [(match_operand 1 "tls_symbolic_operand")] 14739 UNSPEC_TLSDESC)))) 14740 (parallel 14741 [(set (match_operand:SI 0 "register_operand") 14742 (unspec:SI [(match_dup 1) (match_dup 3) 14743 (match_dup 2) (reg:SI SP_REG)] 14744 UNSPEC_TLSDESC)) 14745 (clobber (reg:CC FLAGS_REG))])] 14746 "!TARGET_64BIT && TARGET_GNU2_TLS" 14747{ 14748 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14749 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14750}) 14751 14752(define_insn "*tls_dynamic_gnu2_lea_32" 14753 [(set (match_operand:SI 0 "register_operand" "=r") 14754 (plus:SI (match_operand:SI 1 "register_operand" "b") 14755 (const:SI 14756 (unspec:SI [(match_operand 2 "tls_symbolic_operand")] 14757 UNSPEC_TLSDESC))))] 14758 "!TARGET_64BIT && TARGET_GNU2_TLS" 14759 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" 14760 [(set_attr "type" "lea") 14761 (set_attr "mode" "SI") 14762 (set_attr "length" "6") 14763 (set_attr "length_address" "4")]) 14764 14765(define_insn "*tls_dynamic_gnu2_call_32" 14766 [(set (match_operand:SI 0 "register_operand" "=a") 14767 (unspec:SI [(match_operand 1 "tls_symbolic_operand") 14768 (match_operand:SI 2 "register_operand" "0") 14769 ;; we have to make sure %ebx still points to the GOT 14770 (match_operand:SI 3 "register_operand" "b") 14771 (reg:SI SP_REG)] 14772 UNSPEC_TLSDESC)) 14773 (clobber (reg:CC FLAGS_REG))] 14774 "!TARGET_64BIT && TARGET_GNU2_TLS" 14775 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 14776 [(set_attr "type" "call") 14777 (set_attr "length" "2") 14778 (set_attr "length_address" "0")]) 14779 14780(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 14781 [(set (match_operand:SI 0 "register_operand" "=&a") 14782 (plus:SI 14783 (unspec:SI [(match_operand 3 "tls_modbase_operand") 14784 (match_operand:SI 4) 14785 (match_operand:SI 2 "register_operand" "b") 14786 (reg:SI SP_REG)] 14787 UNSPEC_TLSDESC) 14788 (const:SI (unspec:SI 14789 [(match_operand 1 "tls_symbolic_operand")] 14790 UNSPEC_DTPOFF)))) 14791 (clobber (reg:CC FLAGS_REG))] 14792 "!TARGET_64BIT && TARGET_GNU2_TLS" 14793 "#" 14794 "" 14795 [(set (match_dup 0) (match_dup 5))] 14796{ 14797 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14798 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 14799}) 14800 14801(define_expand "tls_dynamic_gnu2_64" 14802 [(set (match_dup 2) 14803 (unspec:DI [(match_operand 1 "tls_symbolic_operand")] 14804 UNSPEC_TLSDESC)) 14805 (parallel 14806 [(set (match_operand:DI 0 "register_operand") 14807 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 14808 UNSPEC_TLSDESC)) 14809 (clobber (reg:CC FLAGS_REG))])] 14810 "TARGET_64BIT && TARGET_GNU2_TLS" 14811{ 14812 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14813 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14814}) 14815 14816(define_insn "*tls_dynamic_gnu2_lea_64" 14817 [(set (match_operand:DI 0 "register_operand" "=r") 14818 (unspec:DI [(match_operand 1 "tls_symbolic_operand")] 14819 UNSPEC_TLSDESC))] 14820 "TARGET_64BIT && TARGET_GNU2_TLS" 14821 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" 14822 [(set_attr "type" "lea") 14823 (set_attr "mode" "DI") 14824 (set_attr "length" "7") 14825 (set_attr "length_address" "4")]) 14826 14827(define_insn "*tls_dynamic_gnu2_call_64" 14828 [(set (match_operand:DI 0 "register_operand" "=a") 14829 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 14830 (match_operand:DI 2 "register_operand" "0") 14831 (reg:DI SP_REG)] 14832 UNSPEC_TLSDESC)) 14833 (clobber (reg:CC FLAGS_REG))] 14834 "TARGET_64BIT && TARGET_GNU2_TLS" 14835 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 14836 [(set_attr "type" "call") 14837 (set_attr "length" "2") 14838 (set_attr "length_address" "0")]) 14839 14840(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 14841 [(set (match_operand:DI 0 "register_operand" "=&a") 14842 (plus:DI 14843 (unspec:DI [(match_operand 2 "tls_modbase_operand") 14844 (match_operand:DI 3) 14845 (reg:DI SP_REG)] 14846 UNSPEC_TLSDESC) 14847 (const:DI (unspec:DI 14848 [(match_operand 1 "tls_symbolic_operand")] 14849 UNSPEC_DTPOFF)))) 14850 (clobber (reg:CC FLAGS_REG))] 14851 "TARGET_64BIT && TARGET_GNU2_TLS" 14852 "#" 14853 "" 14854 [(set (match_dup 0) (match_dup 4))] 14855{ 14856 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14857 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 14858}) 14859 14860(define_split 14861 [(match_operand 0 "tls_address_pattern")] 14862 "TARGET_TLS_DIRECT_SEG_REFS" 14863 [(match_dup 0)] 14864 "operands[0] = ix86_rewrite_tls_address (operands[0]);") 14865 14866 14867;; These patterns match the binary 387 instructions for addM3, subM3, 14868;; mulM3 and divM3. There are three patterns for each of DFmode and 14869;; SFmode. The first is the normal insn, the second the same insn but 14870;; with one operand a conversion, and the third the same insn but with 14871;; the other operand a conversion. The conversion may be SFmode or 14872;; SImode if the target mode DFmode, but only SImode if the target mode 14873;; is SFmode. 14874 14875;; Gcc is slightly more smart about handling normal two address instructions 14876;; so use special patterns for add and mull. 14877 14878(define_insn "*fop_<mode>_comm" 14879 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v") 14880 (match_operator:MODEF 3 "binary_fp_operator" 14881 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v") 14882 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))] 14883 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14884 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))) 14885 && COMMUTATIVE_ARITH_P (operands[3]) 14886 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 14887 "* return output_387_binary_op (insn, operands);" 14888 [(set (attr "type") 14889 (if_then_else (eq_attr "alternative" "1,2") 14890 (if_then_else (match_operand:MODEF 3 "mult_operator") 14891 (const_string "ssemul") 14892 (const_string "sseadd")) 14893 (if_then_else (match_operand:MODEF 3 "mult_operator") 14894 (const_string "fmul") 14895 (const_string "fop")))) 14896 (set_attr "isa" "*,noavx,avx") 14897 (set_attr "prefix" "orig,orig,vex") 14898 (set_attr "mode" "<MODE>") 14899 (set (attr "enabled") 14900 (if_then_else 14901 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 14902 (if_then_else 14903 (eq_attr "alternative" "0") 14904 (symbol_ref "TARGET_MIX_SSE_I387 14905 && X87_ENABLE_ARITH (<MODE>mode)") 14906 (const_string "*")) 14907 (if_then_else 14908 (eq_attr "alternative" "0") 14909 (symbol_ref "true") 14910 (symbol_ref "false"))))]) 14911 14912(define_insn "*rcpsf2_sse" 14913 [(set (match_operand:SF 0 "register_operand" "=x") 14914 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 14915 UNSPEC_RCP))] 14916 "TARGET_SSE && TARGET_SSE_MATH" 14917 "%vrcpss\t{%1, %d0|%d0, %1}" 14918 [(set_attr "type" "sse") 14919 (set_attr "atom_sse_attr" "rcp") 14920 (set_attr "btver2_sse_attr" "rcp") 14921 (set_attr "prefix" "maybe_vex") 14922 (set_attr "mode" "SF")]) 14923 14924(define_insn "*fop_<mode>_1" 14925 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v") 14926 (match_operator:MODEF 3 "binary_fp_operator" 14927 [(match_operand:MODEF 1 14928 "x87nonimm_ssenomem_operand" "0,fm,0,v") 14929 (match_operand:MODEF 2 14930 "nonimmediate_operand" "fm,0,xm,vm")]))] 14931 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14932 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))) 14933 && !COMMUTATIVE_ARITH_P (operands[3]) 14934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 14935 "* return output_387_binary_op (insn, operands);" 14936 [(set (attr "type") 14937 (if_then_else (eq_attr "alternative" "2,3") 14938 (if_then_else (match_operand:MODEF 3 "div_operator") 14939 (const_string "ssediv") 14940 (const_string "sseadd")) 14941 (if_then_else (match_operand:MODEF 3 "div_operator") 14942 (const_string "fdiv") 14943 (const_string "fop")))) 14944 (set_attr "isa" "*,*,noavx,avx") 14945 (set_attr "prefix" "orig,orig,orig,vex") 14946 (set_attr "mode" "<MODE>") 14947 (set (attr "enabled") 14948 (if_then_else 14949 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 14950 (if_then_else 14951 (eq_attr "alternative" "0,1") 14952 (symbol_ref "TARGET_MIX_SSE_I387 14953 && X87_ENABLE_ARITH (<MODE>mode)") 14954 (const_string "*")) 14955 (if_then_else 14956 (eq_attr "alternative" "0,1") 14957 (symbol_ref "true") 14958 (symbol_ref "false"))))]) 14959 14960;; ??? Add SSE splitters for these! 14961(define_insn "*fop_<MODEF:mode>_2_i387" 14962 [(set (match_operand:MODEF 0 "register_operand" "=f") 14963 (match_operator:MODEF 3 "binary_fp_operator" 14964 [(float:MODEF 14965 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 14966 (match_operand:MODEF 2 "register_operand" "0")]))] 14967 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 14968 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 14969 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 14970 || optimize_function_for_size_p (cfun))" 14971 "* return output_387_binary_op (insn, operands);" 14972 [(set (attr "type") 14973 (cond [(match_operand:MODEF 3 "mult_operator") 14974 (const_string "fmul") 14975 (match_operand:MODEF 3 "div_operator") 14976 (const_string "fdiv") 14977 ] 14978 (const_string "fop"))) 14979 (set_attr "fp_int_src" "true") 14980 (set_attr "mode" "<SWI24:MODE>")]) 14981 14982(define_insn "*fop_<MODEF:mode>_3_i387" 14983 [(set (match_operand:MODEF 0 "register_operand" "=f") 14984 (match_operator:MODEF 3 "binary_fp_operator" 14985 [(match_operand:MODEF 1 "register_operand" "0") 14986 (float:MODEF 14987 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 14988 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 14989 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 14990 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 14991 || optimize_function_for_size_p (cfun))" 14992 "* return output_387_binary_op (insn, operands);" 14993 [(set (attr "type") 14994 (cond [(match_operand:MODEF 3 "mult_operator") 14995 (const_string "fmul") 14996 (match_operand:MODEF 3 "div_operator") 14997 (const_string "fdiv") 14998 ] 14999 (const_string "fop"))) 15000 (set_attr "fp_int_src" "true") 15001 (set_attr "mode" "<MODE>")]) 15002 15003(define_insn "*fop_df_4_i387" 15004 [(set (match_operand:DF 0 "register_operand" "=f,f") 15005 (match_operator:DF 3 "binary_fp_operator" 15006 [(float_extend:DF 15007 (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 15008 (match_operand:DF 2 "register_operand" "0,f")]))] 15009 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15010 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15011 "* return output_387_binary_op (insn, operands);" 15012 [(set (attr "type") 15013 (cond [(match_operand:DF 3 "mult_operator") 15014 (const_string "fmul") 15015 (match_operand:DF 3 "div_operator") 15016 (const_string "fdiv") 15017 ] 15018 (const_string "fop"))) 15019 (set_attr "mode" "SF")]) 15020 15021(define_insn "*fop_df_5_i387" 15022 [(set (match_operand:DF 0 "register_operand" "=f,f") 15023 (match_operator:DF 3 "binary_fp_operator" 15024 [(match_operand:DF 1 "register_operand" "0,f") 15025 (float_extend:DF 15026 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15027 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15028 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15029 "* return output_387_binary_op (insn, operands);" 15030 [(set (attr "type") 15031 (cond [(match_operand:DF 3 "mult_operator") 15032 (const_string "fmul") 15033 (match_operand:DF 3 "div_operator") 15034 (const_string "fdiv") 15035 ] 15036 (const_string "fop"))) 15037 (set_attr "mode" "SF")]) 15038 15039(define_insn "*fop_df_6_i387" 15040 [(set (match_operand:DF 0 "register_operand" "=f,f") 15041 (match_operator:DF 3 "binary_fp_operator" 15042 [(float_extend:DF 15043 (match_operand:SF 1 "register_operand" "0,f")) 15044 (float_extend:DF 15045 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15046 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15047 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15048 "* return output_387_binary_op (insn, operands);" 15049 [(set (attr "type") 15050 (cond [(match_operand:DF 3 "mult_operator") 15051 (const_string "fmul") 15052 (match_operand:DF 3 "div_operator") 15053 (const_string "fdiv") 15054 ] 15055 (const_string "fop"))) 15056 (set_attr "mode" "SF")]) 15057 15058(define_insn "*fop_xf_comm_i387" 15059 [(set (match_operand:XF 0 "register_operand" "=f") 15060 (match_operator:XF 3 "binary_fp_operator" 15061 [(match_operand:XF 1 "register_operand" "%0") 15062 (match_operand:XF 2 "register_operand" "f")]))] 15063 "TARGET_80387 15064 && COMMUTATIVE_ARITH_P (operands[3])" 15065 "* return output_387_binary_op (insn, operands);" 15066 [(set (attr "type") 15067 (if_then_else (match_operand:XF 3 "mult_operator") 15068 (const_string "fmul") 15069 (const_string "fop"))) 15070 (set_attr "mode" "XF")]) 15071 15072(define_insn "*fop_xf_1_i387" 15073 [(set (match_operand:XF 0 "register_operand" "=f,f") 15074 (match_operator:XF 3 "binary_fp_operator" 15075 [(match_operand:XF 1 "register_operand" "0,f") 15076 (match_operand:XF 2 "register_operand" "f,0")]))] 15077 "TARGET_80387 15078 && !COMMUTATIVE_ARITH_P (operands[3])" 15079 "* return output_387_binary_op (insn, operands);" 15080 [(set (attr "type") 15081 (if_then_else (match_operand:XF 3 "div_operator") 15082 (const_string "fdiv") 15083 (const_string "fop"))) 15084 (set_attr "mode" "XF")]) 15085 15086(define_insn "*fop_xf_2_i387" 15087 [(set (match_operand:XF 0 "register_operand" "=f") 15088 (match_operator:XF 3 "binary_fp_operator" 15089 [(float:XF 15090 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 15091 (match_operand:XF 2 "register_operand" "0")]))] 15092 "TARGET_80387 15093 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 15094 "* return output_387_binary_op (insn, operands);" 15095 [(set (attr "type") 15096 (cond [(match_operand:XF 3 "mult_operator") 15097 (const_string "fmul") 15098 (match_operand:XF 3 "div_operator") 15099 (const_string "fdiv") 15100 ] 15101 (const_string "fop"))) 15102 (set_attr "fp_int_src" "true") 15103 (set_attr "mode" "<MODE>")]) 15104 15105(define_insn "*fop_xf_3_i387" 15106 [(set (match_operand:XF 0 "register_operand" "=f") 15107 (match_operator:XF 3 "binary_fp_operator" 15108 [(match_operand:XF 1 "register_operand" "0") 15109 (float:XF 15110 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 15111 "TARGET_80387 15112 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 15113 "* return output_387_binary_op (insn, operands);" 15114 [(set (attr "type") 15115 (cond [(match_operand:XF 3 "mult_operator") 15116 (const_string "fmul") 15117 (match_operand:XF 3 "div_operator") 15118 (const_string "fdiv") 15119 ] 15120 (const_string "fop"))) 15121 (set_attr "fp_int_src" "true") 15122 (set_attr "mode" "<MODE>")]) 15123 15124(define_insn "*fop_xf_4_i387" 15125 [(set (match_operand:XF 0 "register_operand" "=f,f") 15126 (match_operator:XF 3 "binary_fp_operator" 15127 [(float_extend:XF 15128 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) 15129 (match_operand:XF 2 "register_operand" "0,f")]))] 15130 "TARGET_80387" 15131 "* return output_387_binary_op (insn, operands);" 15132 [(set (attr "type") 15133 (cond [(match_operand:XF 3 "mult_operator") 15134 (const_string "fmul") 15135 (match_operand:XF 3 "div_operator") 15136 (const_string "fdiv") 15137 ] 15138 (const_string "fop"))) 15139 (set_attr "mode" "<MODE>")]) 15140 15141(define_insn "*fop_xf_5_i387" 15142 [(set (match_operand:XF 0 "register_operand" "=f,f") 15143 (match_operator:XF 3 "binary_fp_operator" 15144 [(match_operand:XF 1 "register_operand" "0,f") 15145 (float_extend:XF 15146 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 15147 "TARGET_80387" 15148 "* return output_387_binary_op (insn, operands);" 15149 [(set (attr "type") 15150 (cond [(match_operand:XF 3 "mult_operator") 15151 (const_string "fmul") 15152 (match_operand:XF 3 "div_operator") 15153 (const_string "fdiv") 15154 ] 15155 (const_string "fop"))) 15156 (set_attr "mode" "<MODE>")]) 15157 15158(define_insn "*fop_xf_6_i387" 15159 [(set (match_operand:XF 0 "register_operand" "=f,f") 15160 (match_operator:XF 3 "binary_fp_operator" 15161 [(float_extend:XF 15162 (match_operand:MODEF 1 "register_operand" "0,f")) 15163 (float_extend:XF 15164 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 15165 "TARGET_80387" 15166 "* return output_387_binary_op (insn, operands);" 15167 [(set (attr "type") 15168 (cond [(match_operand:XF 3 "mult_operator") 15169 (const_string "fmul") 15170 (match_operand:XF 3 "div_operator") 15171 (const_string "fdiv") 15172 ] 15173 (const_string "fop"))) 15174 (set_attr "mode" "<MODE>")]) 15175 15176;; FPU special functions. 15177 15178;; This pattern implements a no-op XFmode truncation for 15179;; all fancy i386 XFmode math functions. 15180 15181(define_insn "truncxf<mode>2_i387_noop_unspec" 15182 [(set (match_operand:MODEF 0 "register_operand" "=f") 15183 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] 15184 UNSPEC_TRUNC_NOOP))] 15185 "TARGET_USE_FANCY_MATH_387" 15186 "* return output_387_reg_move (insn, operands);" 15187 [(set_attr "type" "fmov") 15188 (set_attr "mode" "<MODE>")]) 15189 15190(define_insn "sqrtxf2" 15191 [(set (match_operand:XF 0 "register_operand" "=f") 15192 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15193 "TARGET_USE_FANCY_MATH_387" 15194 "fsqrt" 15195 [(set_attr "type" "fpspc") 15196 (set_attr "mode" "XF") 15197 (set_attr "athlon_decode" "direct") 15198 (set_attr "amdfam10_decode" "direct") 15199 (set_attr "bdver1_decode" "direct")]) 15200 15201(define_insn "sqrt_extend<mode>xf2_i387" 15202 [(set (match_operand:XF 0 "register_operand" "=f") 15203 (sqrt:XF 15204 (float_extend:XF 15205 (match_operand:MODEF 1 "register_operand" "0"))))] 15206 "TARGET_USE_FANCY_MATH_387" 15207 "fsqrt" 15208 [(set_attr "type" "fpspc") 15209 (set_attr "mode" "XF") 15210 (set_attr "athlon_decode" "direct") 15211 (set_attr "amdfam10_decode" "direct") 15212 (set_attr "bdver1_decode" "direct")]) 15213 15214(define_insn "*rsqrtsf2_sse" 15215 [(set (match_operand:SF 0 "register_operand" "=x") 15216 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 15217 UNSPEC_RSQRT))] 15218 "TARGET_SSE && TARGET_SSE_MATH" 15219 "%vrsqrtss\t{%1, %d0|%d0, %1}" 15220 [(set_attr "type" "sse") 15221 (set_attr "atom_sse_attr" "rcp") 15222 (set_attr "btver2_sse_attr" "rcp") 15223 (set_attr "prefix" "maybe_vex") 15224 (set_attr "mode" "SF")]) 15225 15226(define_expand "rsqrtsf2" 15227 [(set (match_operand:SF 0 "register_operand") 15228 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")] 15229 UNSPEC_RSQRT))] 15230 "TARGET_SSE && TARGET_SSE_MATH" 15231{ 15232 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); 15233 DONE; 15234}) 15235 15236(define_insn "*sqrt<mode>2_sse" 15237 [(set (match_operand:MODEF 0 "register_operand" "=v") 15238 (sqrt:MODEF 15239 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))] 15240 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 15241 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}" 15242 [(set_attr "type" "sse") 15243 (set_attr "atom_sse_attr" "sqrt") 15244 (set_attr "btver2_sse_attr" "sqrt") 15245 (set_attr "prefix" "maybe_vex") 15246 (set_attr "mode" "<MODE>") 15247 (set_attr "athlon_decode" "*") 15248 (set_attr "amdfam10_decode" "*") 15249 (set_attr "bdver1_decode" "*")]) 15250 15251(define_expand "sqrt<mode>2" 15252 [(set (match_operand:MODEF 0 "register_operand") 15253 (sqrt:MODEF 15254 (match_operand:MODEF 1 "nonimmediate_operand")))] 15255 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) 15256 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 15257{ 15258 if (<MODE>mode == SFmode 15259 && TARGET_SSE && TARGET_SSE_MATH 15260 && TARGET_RECIP_SQRT 15261 && !optimize_function_for_size_p (cfun) 15262 && flag_finite_math_only && !flag_trapping_math 15263 && flag_unsafe_math_optimizations) 15264 { 15265 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); 15266 DONE; 15267 } 15268 15269 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 15270 { 15271 rtx op0 = gen_reg_rtx (XFmode); 15272 rtx op1 = force_reg (<MODE>mode, operands[1]); 15273 15274 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1)); 15275 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 15276 DONE; 15277 } 15278}) 15279 15280(define_insn "fpremxf4_i387" 15281 [(set (match_operand:XF 0 "register_operand" "=f") 15282 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15283 (match_operand:XF 3 "register_operand" "1")] 15284 UNSPEC_FPREM_F)) 15285 (set (match_operand:XF 1 "register_operand" "=u") 15286 (unspec:XF [(match_dup 2) (match_dup 3)] 15287 UNSPEC_FPREM_U)) 15288 (set (reg:CCFP FPSR_REG) 15289 (unspec:CCFP [(match_dup 2) (match_dup 3)] 15290 UNSPEC_C2_FLAG))] 15291 "TARGET_USE_FANCY_MATH_387 15292 && flag_finite_math_only" 15293 "fprem" 15294 [(set_attr "type" "fpspc") 15295 (set_attr "znver1_decode" "vector") 15296 (set_attr "mode" "XF")]) 15297 15298(define_expand "fmodxf3" 15299 [(use (match_operand:XF 0 "register_operand")) 15300 (use (match_operand:XF 1 "general_operand")) 15301 (use (match_operand:XF 2 "general_operand"))] 15302 "TARGET_USE_FANCY_MATH_387 15303 && flag_finite_math_only" 15304{ 15305 rtx_code_label *label = gen_label_rtx (); 15306 15307 rtx op1 = gen_reg_rtx (XFmode); 15308 rtx op2 = gen_reg_rtx (XFmode); 15309 15310 emit_move_insn (op2, operands[2]); 15311 emit_move_insn (op1, operands[1]); 15312 15313 emit_label (label); 15314 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 15315 ix86_emit_fp_unordered_jump (label); 15316 LABEL_NUSES (label) = 1; 15317 15318 emit_move_insn (operands[0], op1); 15319 DONE; 15320}) 15321 15322(define_expand "fmod<mode>3" 15323 [(use (match_operand:MODEF 0 "register_operand")) 15324 (use (match_operand:MODEF 1 "general_operand")) 15325 (use (match_operand:MODEF 2 "general_operand"))] 15326 "TARGET_USE_FANCY_MATH_387 15327 && flag_finite_math_only" 15328{ 15329 rtx (*gen_truncxf) (rtx, rtx); 15330 15331 rtx_code_label *label = gen_label_rtx (); 15332 15333 rtx op1 = gen_reg_rtx (XFmode); 15334 rtx op2 = gen_reg_rtx (XFmode); 15335 15336 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15337 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15338 15339 emit_label (label); 15340 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 15341 ix86_emit_fp_unordered_jump (label); 15342 LABEL_NUSES (label) = 1; 15343 15344 /* Truncate the result properly for strict SSE math. */ 15345 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15346 && !TARGET_MIX_SSE_I387) 15347 gen_truncxf = gen_truncxf<mode>2; 15348 else 15349 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 15350 15351 emit_insn (gen_truncxf (operands[0], op1)); 15352 DONE; 15353}) 15354 15355(define_insn "fprem1xf4_i387" 15356 [(set (match_operand:XF 0 "register_operand" "=f") 15357 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15358 (match_operand:XF 3 "register_operand" "1")] 15359 UNSPEC_FPREM1_F)) 15360 (set (match_operand:XF 1 "register_operand" "=u") 15361 (unspec:XF [(match_dup 2) (match_dup 3)] 15362 UNSPEC_FPREM1_U)) 15363 (set (reg:CCFP FPSR_REG) 15364 (unspec:CCFP [(match_dup 2) (match_dup 3)] 15365 UNSPEC_C2_FLAG))] 15366 "TARGET_USE_FANCY_MATH_387 15367 && flag_finite_math_only" 15368 "fprem1" 15369 [(set_attr "type" "fpspc") 15370 (set_attr "znver1_decode" "vector") 15371 (set_attr "mode" "XF")]) 15372 15373(define_expand "remainderxf3" 15374 [(use (match_operand:XF 0 "register_operand")) 15375 (use (match_operand:XF 1 "general_operand")) 15376 (use (match_operand:XF 2 "general_operand"))] 15377 "TARGET_USE_FANCY_MATH_387 15378 && flag_finite_math_only" 15379{ 15380 rtx_code_label *label = gen_label_rtx (); 15381 15382 rtx op1 = gen_reg_rtx (XFmode); 15383 rtx op2 = gen_reg_rtx (XFmode); 15384 15385 emit_move_insn (op2, operands[2]); 15386 emit_move_insn (op1, operands[1]); 15387 15388 emit_label (label); 15389 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 15390 ix86_emit_fp_unordered_jump (label); 15391 LABEL_NUSES (label) = 1; 15392 15393 emit_move_insn (operands[0], op1); 15394 DONE; 15395}) 15396 15397(define_expand "remainder<mode>3" 15398 [(use (match_operand:MODEF 0 "register_operand")) 15399 (use (match_operand:MODEF 1 "general_operand")) 15400 (use (match_operand:MODEF 2 "general_operand"))] 15401 "TARGET_USE_FANCY_MATH_387 15402 && flag_finite_math_only" 15403{ 15404 rtx (*gen_truncxf) (rtx, rtx); 15405 15406 rtx_code_label *label = gen_label_rtx (); 15407 15408 rtx op1 = gen_reg_rtx (XFmode); 15409 rtx op2 = gen_reg_rtx (XFmode); 15410 15411 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15412 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15413 15414 emit_label (label); 15415 15416 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 15417 ix86_emit_fp_unordered_jump (label); 15418 LABEL_NUSES (label) = 1; 15419 15420 /* Truncate the result properly for strict SSE math. */ 15421 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15422 && !TARGET_MIX_SSE_I387) 15423 gen_truncxf = gen_truncxf<mode>2; 15424 else 15425 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 15426 15427 emit_insn (gen_truncxf (operands[0], op1)); 15428 DONE; 15429}) 15430 15431(define_int_iterator SINCOS 15432 [UNSPEC_SIN 15433 UNSPEC_COS]) 15434 15435(define_int_attr sincos 15436 [(UNSPEC_SIN "sin") 15437 (UNSPEC_COS "cos")]) 15438 15439(define_insn "*<sincos>xf2_i387" 15440 [(set (match_operand:XF 0 "register_operand" "=f") 15441 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15442 SINCOS))] 15443 "TARGET_USE_FANCY_MATH_387 15444 && flag_unsafe_math_optimizations" 15445 "f<sincos>" 15446 [(set_attr "type" "fpspc") 15447 (set_attr "znver1_decode" "vector") 15448 (set_attr "mode" "XF")]) 15449 15450(define_insn "*<sincos>_extend<mode>xf2_i387" 15451 [(set (match_operand:XF 0 "register_operand" "=f") 15452 (unspec:XF [(float_extend:XF 15453 (match_operand:MODEF 1 "register_operand" "0"))] 15454 SINCOS))] 15455 "TARGET_USE_FANCY_MATH_387 15456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15457 || TARGET_MIX_SSE_I387) 15458 && flag_unsafe_math_optimizations" 15459 "f<sincos>" 15460 [(set_attr "type" "fpspc") 15461 (set_attr "znver1_decode" "vector") 15462 (set_attr "mode" "XF")]) 15463 15464;; When sincos pattern is defined, sin and cos builtin functions will be 15465;; expanded to sincos pattern with one of its outputs left unused. 15466;; CSE pass will figure out if two sincos patterns can be combined, 15467;; otherwise sincos pattern will be split back to sin or cos pattern, 15468;; depending on the unused output. 15469 15470(define_insn "sincosxf3" 15471 [(set (match_operand:XF 0 "register_operand" "=f") 15472 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15473 UNSPEC_SINCOS_COS)) 15474 (set (match_operand:XF 1 "register_operand" "=u") 15475 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15476 "TARGET_USE_FANCY_MATH_387 15477 && flag_unsafe_math_optimizations" 15478 "fsincos" 15479 [(set_attr "type" "fpspc") 15480 (set_attr "znver1_decode" "vector") 15481 (set_attr "mode" "XF")]) 15482 15483(define_split 15484 [(set (match_operand:XF 0 "register_operand") 15485 (unspec:XF [(match_operand:XF 2 "register_operand")] 15486 UNSPEC_SINCOS_COS)) 15487 (set (match_operand:XF 1 "register_operand") 15488 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15489 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15490 && can_create_pseudo_p ()" 15491 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]) 15492 15493(define_split 15494 [(set (match_operand:XF 0 "register_operand") 15495 (unspec:XF [(match_operand:XF 2 "register_operand")] 15496 UNSPEC_SINCOS_COS)) 15497 (set (match_operand:XF 1 "register_operand") 15498 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15499 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15500 && can_create_pseudo_p ()" 15501 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]) 15502 15503(define_insn "sincos_extend<mode>xf3_i387" 15504 [(set (match_operand:XF 0 "register_operand" "=f") 15505 (unspec:XF [(float_extend:XF 15506 (match_operand:MODEF 2 "register_operand" "0"))] 15507 UNSPEC_SINCOS_COS)) 15508 (set (match_operand:XF 1 "register_operand" "=u") 15509 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15510 "TARGET_USE_FANCY_MATH_387 15511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15512 || TARGET_MIX_SSE_I387) 15513 && flag_unsafe_math_optimizations" 15514 "fsincos" 15515 [(set_attr "type" "fpspc") 15516 (set_attr "znver1_decode" "vector") 15517 (set_attr "mode" "XF")]) 15518 15519(define_split 15520 [(set (match_operand:XF 0 "register_operand") 15521 (unspec:XF [(float_extend:XF 15522 (match_operand:MODEF 2 "register_operand"))] 15523 UNSPEC_SINCOS_COS)) 15524 (set (match_operand:XF 1 "register_operand") 15525 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15526 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15527 && can_create_pseudo_p ()" 15528 [(set (match_dup 1) 15529 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]) 15530 15531(define_split 15532 [(set (match_operand:XF 0 "register_operand") 15533 (unspec:XF [(float_extend:XF 15534 (match_operand:MODEF 2 "register_operand"))] 15535 UNSPEC_SINCOS_COS)) 15536 (set (match_operand:XF 1 "register_operand") 15537 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15538 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15539 && can_create_pseudo_p ()" 15540 [(set (match_dup 0) 15541 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]) 15542 15543(define_expand "sincos<mode>3" 15544 [(use (match_operand:MODEF 0 "register_operand")) 15545 (use (match_operand:MODEF 1 "register_operand")) 15546 (use (match_operand:MODEF 2 "register_operand"))] 15547 "TARGET_USE_FANCY_MATH_387 15548 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15549 || TARGET_MIX_SSE_I387) 15550 && flag_unsafe_math_optimizations" 15551{ 15552 rtx op0 = gen_reg_rtx (XFmode); 15553 rtx op1 = gen_reg_rtx (XFmode); 15554 15555 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2])); 15556 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15557 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1)); 15558 DONE; 15559}) 15560 15561(define_insn "fptanxf4_i387" 15562 [(set (match_operand:XF 0 "register_operand" "=f") 15563 (match_operand:XF 3 "const_double_operand" "F")) 15564 (set (match_operand:XF 1 "register_operand" "=u") 15565 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15566 UNSPEC_TAN))] 15567 "TARGET_USE_FANCY_MATH_387 15568 && flag_unsafe_math_optimizations 15569 && standard_80387_constant_p (operands[3]) == 2" 15570 "fptan" 15571 [(set_attr "type" "fpspc") 15572 (set_attr "znver1_decode" "vector") 15573 (set_attr "mode" "XF")]) 15574 15575(define_insn "fptan_extend<mode>xf4_i387" 15576 [(set (match_operand:MODEF 0 "register_operand" "=f") 15577 (match_operand:MODEF 3 "const_double_operand" "F")) 15578 (set (match_operand:XF 1 "register_operand" "=u") 15579 (unspec:XF [(float_extend:XF 15580 (match_operand:MODEF 2 "register_operand" "0"))] 15581 UNSPEC_TAN))] 15582 "TARGET_USE_FANCY_MATH_387 15583 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15584 || TARGET_MIX_SSE_I387) 15585 && flag_unsafe_math_optimizations 15586 && standard_80387_constant_p (operands[3]) == 2" 15587 "fptan" 15588 [(set_attr "type" "fpspc") 15589 (set_attr "znver1_decode" "vector") 15590 (set_attr "mode" "XF")]) 15591 15592(define_expand "tanxf2" 15593 [(use (match_operand:XF 0 "register_operand")) 15594 (use (match_operand:XF 1 "register_operand"))] 15595 "TARGET_USE_FANCY_MATH_387 15596 && flag_unsafe_math_optimizations" 15597{ 15598 rtx one = gen_reg_rtx (XFmode); 15599 rtx op2 = CONST1_RTX (XFmode); /* fld1 */ 15600 15601 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2)); 15602 DONE; 15603}) 15604 15605(define_expand "tan<mode>2" 15606 [(use (match_operand:MODEF 0 "register_operand")) 15607 (use (match_operand:MODEF 1 "register_operand"))] 15608 "TARGET_USE_FANCY_MATH_387 15609 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15610 || TARGET_MIX_SSE_I387) 15611 && flag_unsafe_math_optimizations" 15612{ 15613 rtx op0 = gen_reg_rtx (XFmode); 15614 15615 rtx one = gen_reg_rtx (<MODE>mode); 15616 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */ 15617 15618 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0, 15619 operands[1], op2)); 15620 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15621 DONE; 15622}) 15623 15624(define_insn "*fpatanxf3_i387" 15625 [(set (match_operand:XF 0 "register_operand" "=f") 15626 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15627 (match_operand:XF 2 "register_operand" "u")] 15628 UNSPEC_FPATAN)) 15629 (clobber (match_scratch:XF 3 "=2"))] 15630 "TARGET_USE_FANCY_MATH_387 15631 && flag_unsafe_math_optimizations" 15632 "fpatan" 15633 [(set_attr "type" "fpspc") 15634 (set_attr "znver1_decode" "vector") 15635 (set_attr "mode" "XF")]) 15636 15637(define_insn "fpatan_extend<mode>xf3_i387" 15638 [(set (match_operand:XF 0 "register_operand" "=f") 15639 (unspec:XF [(float_extend:XF 15640 (match_operand:MODEF 1 "register_operand" "0")) 15641 (float_extend:XF 15642 (match_operand:MODEF 2 "register_operand" "u"))] 15643 UNSPEC_FPATAN)) 15644 (clobber (match_scratch:XF 3 "=2"))] 15645 "TARGET_USE_FANCY_MATH_387 15646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15647 || TARGET_MIX_SSE_I387) 15648 && flag_unsafe_math_optimizations" 15649 "fpatan" 15650 [(set_attr "type" "fpspc") 15651 (set_attr "znver1_decode" "vector") 15652 (set_attr "mode" "XF")]) 15653 15654(define_expand "atan2xf3" 15655 [(parallel [(set (match_operand:XF 0 "register_operand") 15656 (unspec:XF [(match_operand:XF 2 "register_operand") 15657 (match_operand:XF 1 "register_operand")] 15658 UNSPEC_FPATAN)) 15659 (clobber (match_scratch:XF 3))])] 15660 "TARGET_USE_FANCY_MATH_387 15661 && flag_unsafe_math_optimizations") 15662 15663(define_expand "atan2<mode>3" 15664 [(use (match_operand:MODEF 0 "register_operand")) 15665 (use (match_operand:MODEF 1 "register_operand")) 15666 (use (match_operand:MODEF 2 "register_operand"))] 15667 "TARGET_USE_FANCY_MATH_387 15668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15669 || TARGET_MIX_SSE_I387) 15670 && flag_unsafe_math_optimizations" 15671{ 15672 rtx op0 = gen_reg_rtx (XFmode); 15673 15674 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1])); 15675 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15676 DONE; 15677}) 15678 15679(define_expand "atanxf2" 15680 [(parallel [(set (match_operand:XF 0 "register_operand") 15681 (unspec:XF [(match_dup 2) 15682 (match_operand:XF 1 "register_operand")] 15683 UNSPEC_FPATAN)) 15684 (clobber (match_scratch:XF 3))])] 15685 "TARGET_USE_FANCY_MATH_387 15686 && flag_unsafe_math_optimizations" 15687{ 15688 operands[2] = gen_reg_rtx (XFmode); 15689 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 15690}) 15691 15692(define_expand "atan<mode>2" 15693 [(use (match_operand:MODEF 0 "register_operand")) 15694 (use (match_operand:MODEF 1 "register_operand"))] 15695 "TARGET_USE_FANCY_MATH_387 15696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15697 || TARGET_MIX_SSE_I387) 15698 && flag_unsafe_math_optimizations" 15699{ 15700 rtx op0 = gen_reg_rtx (XFmode); 15701 15702 rtx op2 = gen_reg_rtx (<MODE>mode); 15703 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */ 15704 15705 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1])); 15706 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15707 DONE; 15708}) 15709 15710(define_expand "asinxf2" 15711 [(set (match_dup 2) 15712 (mult:XF (match_operand:XF 1 "register_operand") 15713 (match_dup 1))) 15714 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 15715 (set (match_dup 5) (sqrt:XF (match_dup 4))) 15716 (parallel [(set (match_operand:XF 0 "register_operand") 15717 (unspec:XF [(match_dup 5) (match_dup 1)] 15718 UNSPEC_FPATAN)) 15719 (clobber (match_scratch:XF 6))])] 15720 "TARGET_USE_FANCY_MATH_387 15721 && flag_unsafe_math_optimizations" 15722{ 15723 int i; 15724 15725 for (i = 2; i < 6; i++) 15726 operands[i] = gen_reg_rtx (XFmode); 15727 15728 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 15729}) 15730 15731(define_expand "asin<mode>2" 15732 [(use (match_operand:MODEF 0 "register_operand")) 15733 (use (match_operand:MODEF 1 "general_operand"))] 15734 "TARGET_USE_FANCY_MATH_387 15735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15736 || TARGET_MIX_SSE_I387) 15737 && flag_unsafe_math_optimizations" 15738{ 15739 rtx op0 = gen_reg_rtx (XFmode); 15740 rtx op1 = gen_reg_rtx (XFmode); 15741 15742 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15743 emit_insn (gen_asinxf2 (op0, op1)); 15744 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15745 DONE; 15746}) 15747 15748(define_expand "acosxf2" 15749 [(set (match_dup 2) 15750 (mult:XF (match_operand:XF 1 "register_operand") 15751 (match_dup 1))) 15752 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 15753 (set (match_dup 5) (sqrt:XF (match_dup 4))) 15754 (parallel [(set (match_operand:XF 0 "register_operand") 15755 (unspec:XF [(match_dup 1) (match_dup 5)] 15756 UNSPEC_FPATAN)) 15757 (clobber (match_scratch:XF 6))])] 15758 "TARGET_USE_FANCY_MATH_387 15759 && flag_unsafe_math_optimizations" 15760{ 15761 int i; 15762 15763 for (i = 2; i < 6; i++) 15764 operands[i] = gen_reg_rtx (XFmode); 15765 15766 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 15767}) 15768 15769(define_expand "acos<mode>2" 15770 [(use (match_operand:MODEF 0 "register_operand")) 15771 (use (match_operand:MODEF 1 "general_operand"))] 15772 "TARGET_USE_FANCY_MATH_387 15773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15774 || TARGET_MIX_SSE_I387) 15775 && flag_unsafe_math_optimizations" 15776{ 15777 rtx op0 = gen_reg_rtx (XFmode); 15778 rtx op1 = gen_reg_rtx (XFmode); 15779 15780 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15781 emit_insn (gen_acosxf2 (op0, op1)); 15782 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15783 DONE; 15784}) 15785 15786(define_insn "fyl2xxf3_i387" 15787 [(set (match_operand:XF 0 "register_operand" "=f") 15788 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15789 (match_operand:XF 2 "register_operand" "u")] 15790 UNSPEC_FYL2X)) 15791 (clobber (match_scratch:XF 3 "=2"))] 15792 "TARGET_USE_FANCY_MATH_387 15793 && flag_unsafe_math_optimizations" 15794 "fyl2x" 15795 [(set_attr "type" "fpspc") 15796 (set_attr "znver1_decode" "vector") 15797 (set_attr "mode" "XF")]) 15798 15799(define_insn "fyl2x_extend<mode>xf3_i387" 15800 [(set (match_operand:XF 0 "register_operand" "=f") 15801 (unspec:XF [(float_extend:XF 15802 (match_operand:MODEF 1 "register_operand" "0")) 15803 (match_operand:XF 2 "register_operand" "u")] 15804 UNSPEC_FYL2X)) 15805 (clobber (match_scratch:XF 3 "=2"))] 15806 "TARGET_USE_FANCY_MATH_387 15807 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15808 || TARGET_MIX_SSE_I387) 15809 && flag_unsafe_math_optimizations" 15810 "fyl2x" 15811 [(set_attr "type" "fpspc") 15812 (set_attr "znver1_decode" "vector") 15813 (set_attr "mode" "XF")]) 15814 15815(define_expand "logxf2" 15816 [(parallel [(set (match_operand:XF 0 "register_operand") 15817 (unspec:XF [(match_operand:XF 1 "register_operand") 15818 (match_dup 2)] UNSPEC_FYL2X)) 15819 (clobber (match_scratch:XF 3))])] 15820 "TARGET_USE_FANCY_MATH_387 15821 && flag_unsafe_math_optimizations" 15822{ 15823 operands[2] = gen_reg_rtx (XFmode); 15824 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */ 15825}) 15826 15827(define_expand "log<mode>2" 15828 [(use (match_operand:MODEF 0 "register_operand")) 15829 (use (match_operand:MODEF 1 "register_operand"))] 15830 "TARGET_USE_FANCY_MATH_387 15831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15832 || TARGET_MIX_SSE_I387) 15833 && flag_unsafe_math_optimizations" 15834{ 15835 rtx op0 = gen_reg_rtx (XFmode); 15836 15837 rtx op2 = gen_reg_rtx (XFmode); 15838 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */ 15839 15840 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15841 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15842 DONE; 15843}) 15844 15845(define_expand "log10xf2" 15846 [(parallel [(set (match_operand:XF 0 "register_operand") 15847 (unspec:XF [(match_operand:XF 1 "register_operand") 15848 (match_dup 2)] UNSPEC_FYL2X)) 15849 (clobber (match_scratch:XF 3))])] 15850 "TARGET_USE_FANCY_MATH_387 15851 && flag_unsafe_math_optimizations" 15852{ 15853 operands[2] = gen_reg_rtx (XFmode); 15854 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */ 15855}) 15856 15857(define_expand "log10<mode>2" 15858 [(use (match_operand:MODEF 0 "register_operand")) 15859 (use (match_operand:MODEF 1 "register_operand"))] 15860 "TARGET_USE_FANCY_MATH_387 15861 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15862 || TARGET_MIX_SSE_I387) 15863 && flag_unsafe_math_optimizations" 15864{ 15865 rtx op0 = gen_reg_rtx (XFmode); 15866 15867 rtx op2 = gen_reg_rtx (XFmode); 15868 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */ 15869 15870 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15871 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15872 DONE; 15873}) 15874 15875(define_expand "log2xf2" 15876 [(parallel [(set (match_operand:XF 0 "register_operand") 15877 (unspec:XF [(match_operand:XF 1 "register_operand") 15878 (match_dup 2)] UNSPEC_FYL2X)) 15879 (clobber (match_scratch:XF 3))])] 15880 "TARGET_USE_FANCY_MATH_387 15881 && flag_unsafe_math_optimizations" 15882{ 15883 operands[2] = gen_reg_rtx (XFmode); 15884 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 15885}) 15886 15887(define_expand "log2<mode>2" 15888 [(use (match_operand:MODEF 0 "register_operand")) 15889 (use (match_operand:MODEF 1 "register_operand"))] 15890 "TARGET_USE_FANCY_MATH_387 15891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15892 || TARGET_MIX_SSE_I387) 15893 && flag_unsafe_math_optimizations" 15894{ 15895 rtx op0 = gen_reg_rtx (XFmode); 15896 15897 rtx op2 = gen_reg_rtx (XFmode); 15898 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 15899 15900 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15901 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15902 DONE; 15903}) 15904 15905(define_insn "fyl2xp1xf3_i387" 15906 [(set (match_operand:XF 0 "register_operand" "=f") 15907 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15908 (match_operand:XF 2 "register_operand" "u")] 15909 UNSPEC_FYL2XP1)) 15910 (clobber (match_scratch:XF 3 "=2"))] 15911 "TARGET_USE_FANCY_MATH_387 15912 && flag_unsafe_math_optimizations" 15913 "fyl2xp1" 15914 [(set_attr "type" "fpspc") 15915 (set_attr "znver1_decode" "vector") 15916 (set_attr "mode" "XF")]) 15917 15918(define_insn "fyl2xp1_extend<mode>xf3_i387" 15919 [(set (match_operand:XF 0 "register_operand" "=f") 15920 (unspec:XF [(float_extend:XF 15921 (match_operand:MODEF 1 "register_operand" "0")) 15922 (match_operand:XF 2 "register_operand" "u")] 15923 UNSPEC_FYL2XP1)) 15924 (clobber (match_scratch:XF 3 "=2"))] 15925 "TARGET_USE_FANCY_MATH_387 15926 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15927 || TARGET_MIX_SSE_I387) 15928 && flag_unsafe_math_optimizations" 15929 "fyl2xp1" 15930 [(set_attr "type" "fpspc") 15931 (set_attr "znver1_decode" "vector") 15932 (set_attr "mode" "XF")]) 15933 15934(define_expand "log1pxf2" 15935 [(use (match_operand:XF 0 "register_operand")) 15936 (use (match_operand:XF 1 "register_operand"))] 15937 "TARGET_USE_FANCY_MATH_387 15938 && flag_unsafe_math_optimizations" 15939{ 15940 ix86_emit_i387_log1p (operands[0], operands[1]); 15941 DONE; 15942}) 15943 15944(define_expand "log1p<mode>2" 15945 [(use (match_operand:MODEF 0 "register_operand")) 15946 (use (match_operand:MODEF 1 "register_operand"))] 15947 "TARGET_USE_FANCY_MATH_387 15948 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15949 || TARGET_MIX_SSE_I387) 15950 && flag_unsafe_math_optimizations" 15951{ 15952 rtx op0; 15953 15954 op0 = gen_reg_rtx (XFmode); 15955 15956 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]); 15957 15958 ix86_emit_i387_log1p (op0, operands[1]); 15959 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15960 DONE; 15961}) 15962 15963(define_insn "fxtractxf3_i387" 15964 [(set (match_operand:XF 0 "register_operand" "=f") 15965 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15966 UNSPEC_XTRACT_FRACT)) 15967 (set (match_operand:XF 1 "register_operand" "=u") 15968 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 15969 "TARGET_USE_FANCY_MATH_387 15970 && flag_unsafe_math_optimizations" 15971 "fxtract" 15972 [(set_attr "type" "fpspc") 15973 (set_attr "znver1_decode" "vector") 15974 (set_attr "mode" "XF")]) 15975 15976(define_insn "fxtract_extend<mode>xf3_i387" 15977 [(set (match_operand:XF 0 "register_operand" "=f") 15978 (unspec:XF [(float_extend:XF 15979 (match_operand:MODEF 2 "register_operand" "0"))] 15980 UNSPEC_XTRACT_FRACT)) 15981 (set (match_operand:XF 1 "register_operand" "=u") 15982 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))] 15983 "TARGET_USE_FANCY_MATH_387 15984 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15985 || TARGET_MIX_SSE_I387) 15986 && flag_unsafe_math_optimizations" 15987 "fxtract" 15988 [(set_attr "type" "fpspc") 15989 (set_attr "znver1_decode" "vector") 15990 (set_attr "mode" "XF")]) 15991 15992(define_expand "logbxf2" 15993 [(parallel [(set (match_dup 2) 15994 (unspec:XF [(match_operand:XF 1 "register_operand")] 15995 UNSPEC_XTRACT_FRACT)) 15996 (set (match_operand:XF 0 "register_operand") 15997 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 15998 "TARGET_USE_FANCY_MATH_387 15999 && flag_unsafe_math_optimizations" 16000 "operands[2] = gen_reg_rtx (XFmode);") 16001 16002(define_expand "logb<mode>2" 16003 [(use (match_operand:MODEF 0 "register_operand")) 16004 (use (match_operand:MODEF 1 "register_operand"))] 16005 "TARGET_USE_FANCY_MATH_387 16006 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16007 || TARGET_MIX_SSE_I387) 16008 && flag_unsafe_math_optimizations" 16009{ 16010 rtx op0 = gen_reg_rtx (XFmode); 16011 rtx op1 = gen_reg_rtx (XFmode); 16012 16013 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 16014 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1)); 16015 DONE; 16016}) 16017 16018(define_expand "ilogbxf2" 16019 [(use (match_operand:SI 0 "register_operand")) 16020 (use (match_operand:XF 1 "register_operand"))] 16021 "TARGET_USE_FANCY_MATH_387 16022 && flag_unsafe_math_optimizations" 16023{ 16024 rtx op0, op1; 16025 16026 if (optimize_insn_for_size_p ()) 16027 FAIL; 16028 16029 op0 = gen_reg_rtx (XFmode); 16030 op1 = gen_reg_rtx (XFmode); 16031 16032 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); 16033 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 16034 DONE; 16035}) 16036 16037(define_expand "ilogb<mode>2" 16038 [(use (match_operand:SI 0 "register_operand")) 16039 (use (match_operand:MODEF 1 "register_operand"))] 16040 "TARGET_USE_FANCY_MATH_387 16041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16042 || TARGET_MIX_SSE_I387) 16043 && flag_unsafe_math_optimizations" 16044{ 16045 rtx op0, op1; 16046 16047 if (optimize_insn_for_size_p ()) 16048 FAIL; 16049 16050 op0 = gen_reg_rtx (XFmode); 16051 op1 = gen_reg_rtx (XFmode); 16052 16053 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 16054 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 16055 DONE; 16056}) 16057 16058(define_insn "*f2xm1xf2_i387" 16059 [(set (match_operand:XF 0 "register_operand" "=f") 16060 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16061 UNSPEC_F2XM1))] 16062 "TARGET_USE_FANCY_MATH_387 16063 && flag_unsafe_math_optimizations" 16064 "f2xm1" 16065 [(set_attr "type" "fpspc") 16066 (set_attr "znver1_decode" "vector") 16067 (set_attr "mode" "XF")]) 16068 16069(define_insn "fscalexf4_i387" 16070 [(set (match_operand:XF 0 "register_operand" "=f") 16071 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16072 (match_operand:XF 3 "register_operand" "1")] 16073 UNSPEC_FSCALE_FRACT)) 16074 (set (match_operand:XF 1 "register_operand" "=u") 16075 (unspec:XF [(match_dup 2) (match_dup 3)] 16076 UNSPEC_FSCALE_EXP))] 16077 "TARGET_USE_FANCY_MATH_387 16078 && flag_unsafe_math_optimizations" 16079 "fscale" 16080 [(set_attr "type" "fpspc") 16081 (set_attr "znver1_decode" "vector") 16082 (set_attr "mode" "XF")]) 16083 16084(define_expand "expNcorexf3" 16085 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 16086 (match_operand:XF 2 "register_operand"))) 16087 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16088 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16089 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16090 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16091 (parallel [(set (match_operand:XF 0 "register_operand") 16092 (unspec:XF [(match_dup 8) (match_dup 4)] 16093 UNSPEC_FSCALE_FRACT)) 16094 (set (match_dup 9) 16095 (unspec:XF [(match_dup 8) (match_dup 4)] 16096 UNSPEC_FSCALE_EXP))])] 16097 "TARGET_USE_FANCY_MATH_387 16098 && flag_unsafe_math_optimizations" 16099{ 16100 int i; 16101 16102 for (i = 3; i < 10; i++) 16103 operands[i] = gen_reg_rtx (XFmode); 16104 16105 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16106}) 16107 16108(define_expand "expxf2" 16109 [(use (match_operand:XF 0 "register_operand")) 16110 (use (match_operand:XF 1 "register_operand"))] 16111 "TARGET_USE_FANCY_MATH_387 16112 && flag_unsafe_math_optimizations" 16113{ 16114 rtx op2; 16115 16116 op2 = gen_reg_rtx (XFmode); 16117 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */ 16118 16119 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16120 DONE; 16121}) 16122 16123(define_expand "exp<mode>2" 16124 [(use (match_operand:MODEF 0 "register_operand")) 16125 (use (match_operand:MODEF 1 "general_operand"))] 16126 "TARGET_USE_FANCY_MATH_387 16127 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16128 || TARGET_MIX_SSE_I387) 16129 && flag_unsafe_math_optimizations" 16130{ 16131 rtx op0, op1; 16132 16133 op0 = gen_reg_rtx (XFmode); 16134 op1 = gen_reg_rtx (XFmode); 16135 16136 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16137 emit_insn (gen_expxf2 (op0, op1)); 16138 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16139 DONE; 16140}) 16141 16142(define_expand "exp10xf2" 16143 [(use (match_operand:XF 0 "register_operand")) 16144 (use (match_operand:XF 1 "register_operand"))] 16145 "TARGET_USE_FANCY_MATH_387 16146 && flag_unsafe_math_optimizations" 16147{ 16148 rtx op2; 16149 16150 op2 = gen_reg_rtx (XFmode); 16151 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */ 16152 16153 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16154 DONE; 16155}) 16156 16157(define_expand "exp10<mode>2" 16158 [(use (match_operand:MODEF 0 "register_operand")) 16159 (use (match_operand:MODEF 1 "general_operand"))] 16160 "TARGET_USE_FANCY_MATH_387 16161 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16162 || TARGET_MIX_SSE_I387) 16163 && flag_unsafe_math_optimizations" 16164{ 16165 rtx op0, op1; 16166 16167 op0 = gen_reg_rtx (XFmode); 16168 op1 = gen_reg_rtx (XFmode); 16169 16170 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16171 emit_insn (gen_exp10xf2 (op0, op1)); 16172 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16173 DONE; 16174}) 16175 16176(define_expand "exp2xf2" 16177 [(use (match_operand:XF 0 "register_operand")) 16178 (use (match_operand:XF 1 "register_operand"))] 16179 "TARGET_USE_FANCY_MATH_387 16180 && flag_unsafe_math_optimizations" 16181{ 16182 rtx op2; 16183 16184 op2 = gen_reg_rtx (XFmode); 16185 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 16186 16187 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16188 DONE; 16189}) 16190 16191(define_expand "exp2<mode>2" 16192 [(use (match_operand:MODEF 0 "register_operand")) 16193 (use (match_operand:MODEF 1 "general_operand"))] 16194 "TARGET_USE_FANCY_MATH_387 16195 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16196 || TARGET_MIX_SSE_I387) 16197 && flag_unsafe_math_optimizations" 16198{ 16199 rtx op0, op1; 16200 16201 op0 = gen_reg_rtx (XFmode); 16202 op1 = gen_reg_rtx (XFmode); 16203 16204 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16205 emit_insn (gen_exp2xf2 (op0, op1)); 16206 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16207 DONE; 16208}) 16209 16210(define_expand "expm1xf2" 16211 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 16212 (match_dup 2))) 16213 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16214 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16215 (set (match_dup 9) (float_extend:XF (match_dup 13))) 16216 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16217 (parallel [(set (match_dup 7) 16218 (unspec:XF [(match_dup 6) (match_dup 4)] 16219 UNSPEC_FSCALE_FRACT)) 16220 (set (match_dup 8) 16221 (unspec:XF [(match_dup 6) (match_dup 4)] 16222 UNSPEC_FSCALE_EXP))]) 16223 (parallel [(set (match_dup 10) 16224 (unspec:XF [(match_dup 9) (match_dup 8)] 16225 UNSPEC_FSCALE_FRACT)) 16226 (set (match_dup 11) 16227 (unspec:XF [(match_dup 9) (match_dup 8)] 16228 UNSPEC_FSCALE_EXP))]) 16229 (set (match_dup 12) (minus:XF (match_dup 10) 16230 (float_extend:XF (match_dup 13)))) 16231 (set (match_operand:XF 0 "register_operand") 16232 (plus:XF (match_dup 12) (match_dup 7)))] 16233 "TARGET_USE_FANCY_MATH_387 16234 && flag_unsafe_math_optimizations" 16235{ 16236 int i; 16237 16238 for (i = 2; i < 13; i++) 16239 operands[i] = gen_reg_rtx (XFmode); 16240 16241 operands[13] 16242 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */ 16243 16244 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ 16245}) 16246 16247(define_expand "expm1<mode>2" 16248 [(use (match_operand:MODEF 0 "register_operand")) 16249 (use (match_operand:MODEF 1 "general_operand"))] 16250 "TARGET_USE_FANCY_MATH_387 16251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16252 || TARGET_MIX_SSE_I387) 16253 && flag_unsafe_math_optimizations" 16254{ 16255 rtx op0, op1; 16256 16257 op0 = gen_reg_rtx (XFmode); 16258 op1 = gen_reg_rtx (XFmode); 16259 16260 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16261 emit_insn (gen_expm1xf2 (op0, op1)); 16262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16263 DONE; 16264}) 16265 16266(define_expand "ldexpxf3" 16267 [(match_operand:XF 0 "register_operand") 16268 (match_operand:XF 1 "register_operand") 16269 (match_operand:SI 2 "register_operand")] 16270 "TARGET_USE_FANCY_MATH_387 16271 && flag_unsafe_math_optimizations" 16272{ 16273 rtx tmp1, tmp2; 16274 16275 tmp1 = gen_reg_rtx (XFmode); 16276 tmp2 = gen_reg_rtx (XFmode); 16277 16278 emit_insn (gen_floatsixf2 (tmp1, operands[2])); 16279 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2, 16280 operands[1], tmp1)); 16281 DONE; 16282}) 16283 16284(define_expand "ldexp<mode>3" 16285 [(use (match_operand:MODEF 0 "register_operand")) 16286 (use (match_operand:MODEF 1 "general_operand")) 16287 (use (match_operand:SI 2 "register_operand"))] 16288 "TARGET_USE_FANCY_MATH_387 16289 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16290 || TARGET_MIX_SSE_I387) 16291 && flag_unsafe_math_optimizations" 16292{ 16293 rtx op0, op1; 16294 16295 op0 = gen_reg_rtx (XFmode); 16296 op1 = gen_reg_rtx (XFmode); 16297 16298 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16299 emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); 16300 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16301 DONE; 16302}) 16303 16304(define_expand "scalbxf3" 16305 [(parallel [(set (match_operand:XF 0 " register_operand") 16306 (unspec:XF [(match_operand:XF 1 "register_operand") 16307 (match_operand:XF 2 "register_operand")] 16308 UNSPEC_FSCALE_FRACT)) 16309 (set (match_dup 3) 16310 (unspec:XF [(match_dup 1) (match_dup 2)] 16311 UNSPEC_FSCALE_EXP))])] 16312 "TARGET_USE_FANCY_MATH_387 16313 && flag_unsafe_math_optimizations" 16314{ 16315 operands[3] = gen_reg_rtx (XFmode); 16316}) 16317 16318(define_expand "scalb<mode>3" 16319 [(use (match_operand:MODEF 0 "register_operand")) 16320 (use (match_operand:MODEF 1 "general_operand")) 16321 (use (match_operand:MODEF 2 "general_operand"))] 16322 "TARGET_USE_FANCY_MATH_387 16323 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16324 || TARGET_MIX_SSE_I387) 16325 && flag_unsafe_math_optimizations" 16326{ 16327 rtx op0, op1, op2; 16328 16329 op0 = gen_reg_rtx (XFmode); 16330 op1 = gen_reg_rtx (XFmode); 16331 op2 = gen_reg_rtx (XFmode); 16332 16333 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16334 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 16335 emit_insn (gen_scalbxf3 (op0, op1, op2)); 16336 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16337 DONE; 16338}) 16339 16340(define_expand "significandxf2" 16341 [(parallel [(set (match_operand:XF 0 "register_operand") 16342 (unspec:XF [(match_operand:XF 1 "register_operand")] 16343 UNSPEC_XTRACT_FRACT)) 16344 (set (match_dup 2) 16345 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16346 "TARGET_USE_FANCY_MATH_387 16347 && flag_unsafe_math_optimizations" 16348 "operands[2] = gen_reg_rtx (XFmode);") 16349 16350(define_expand "significand<mode>2" 16351 [(use (match_operand:MODEF 0 "register_operand")) 16352 (use (match_operand:MODEF 1 "register_operand"))] 16353 "TARGET_USE_FANCY_MATH_387 16354 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16355 || TARGET_MIX_SSE_I387) 16356 && flag_unsafe_math_optimizations" 16357{ 16358 rtx op0 = gen_reg_rtx (XFmode); 16359 rtx op1 = gen_reg_rtx (XFmode); 16360 16361 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 16362 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16363 DONE; 16364}) 16365 16366 16367(define_insn "sse4_1_round<mode>2" 16368 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 16369 (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm") 16370 (match_operand:SI 2 "const_0_to_15_operand" "n,n")] 16371 UNSPEC_ROUND))] 16372 "TARGET_SSE4_1" 16373 "@ 16374 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2} 16375 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}" 16376 [(set_attr "type" "ssecvt") 16377 (set_attr "prefix_extra" "1,*") 16378 (set_attr "length_immediate" "*,1") 16379 (set_attr "prefix" "maybe_vex,evex") 16380 (set_attr "isa" "noavx512f,avx512f") 16381 (set_attr "mode" "<MODE>")]) 16382 16383(define_insn "rintxf2" 16384 [(set (match_operand:XF 0 "register_operand" "=f") 16385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16386 UNSPEC_FRNDINT))] 16387 "TARGET_USE_FANCY_MATH_387" 16388 "frndint" 16389 [(set_attr "type" "fpspc") 16390 (set_attr "znver1_decode" "vector") 16391 (set_attr "mode" "XF")]) 16392 16393(define_insn "rint<mode>2_frndint" 16394 [(set (match_operand:MODEF 0 "register_operand" "=f") 16395 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")] 16396 UNSPEC_FRNDINT))] 16397 "TARGET_USE_FANCY_MATH_387" 16398 "frndint" 16399 [(set_attr "type" "fpspc") 16400 (set_attr "znver1_decode" "vector") 16401 (set_attr "mode" "<MODE>")]) 16402 16403(define_expand "rint<mode>2" 16404 [(use (match_operand:MODEF 0 "register_operand")) 16405 (use (match_operand:MODEF 1 "register_operand"))] 16406 "(TARGET_USE_FANCY_MATH_387 16407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16408 || TARGET_MIX_SSE_I387)) 16409 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 16410{ 16411 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16412 { 16413 if (TARGET_SSE4_1) 16414 emit_insn (gen_sse4_1_round<mode>2 16415 (operands[0], operands[1], GEN_INT (ROUND_MXCSR))); 16416 else 16417 ix86_expand_rint (operands[0], operands[1]); 16418 } 16419 else 16420 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1])); 16421 DONE; 16422}) 16423 16424(define_expand "round<mode>2" 16425 [(match_operand:X87MODEF 0 "register_operand") 16426 (match_operand:X87MODEF 1 "nonimmediate_operand")] 16427 "(TARGET_USE_FANCY_MATH_387 16428 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16429 || TARGET_MIX_SSE_I387) 16430 && flag_unsafe_math_optimizations 16431 && (flag_fp_int_builtin_inexact || !flag_trapping_math)) 16432 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16433 && !flag_trapping_math && !flag_rounding_math)" 16434{ 16435 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16436 && !flag_trapping_math && !flag_rounding_math) 16437 { 16438 if (TARGET_SSE4_1) 16439 { 16440 operands[1] = force_reg (<MODE>mode, operands[1]); 16441 ix86_expand_round_sse4 (operands[0], operands[1]); 16442 } 16443 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 16444 ix86_expand_round (operands[0], operands[1]); 16445 else 16446 ix86_expand_rounddf_32 (operands[0], operands[1]); 16447 } 16448 else 16449 { 16450 operands[1] = force_reg (<MODE>mode, operands[1]); 16451 ix86_emit_i387_round (operands[0], operands[1]); 16452 } 16453 DONE; 16454}) 16455 16456(define_insn_and_split "*fistdi2_1" 16457 [(set (match_operand:DI 0 "nonimmediate_operand") 16458 (unspec:DI [(match_operand:XF 1 "register_operand")] 16459 UNSPEC_FIST))] 16460 "TARGET_USE_FANCY_MATH_387 16461 && can_create_pseudo_p ()" 16462 "#" 16463 "&& 1" 16464 [(const_int 0)] 16465{ 16466 if (memory_operand (operands[0], VOIDmode)) 16467 emit_insn (gen_fistdi2 (operands[0], operands[1])); 16468 else 16469 { 16470 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 16471 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 16472 operands[2])); 16473 } 16474 DONE; 16475} 16476 [(set_attr "type" "fpspc") 16477 (set_attr "mode" "DI")]) 16478 16479(define_insn "fistdi2" 16480 [(set (match_operand:DI 0 "memory_operand" "=m") 16481 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 16482 UNSPEC_FIST)) 16483 (clobber (match_scratch:XF 2 "=&1f"))] 16484 "TARGET_USE_FANCY_MATH_387" 16485 "* return output_fix_trunc (insn, operands, false);" 16486 [(set_attr "type" "fpspc") 16487 (set_attr "mode" "DI")]) 16488 16489(define_insn "fistdi2_with_temp" 16490 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 16491 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 16492 UNSPEC_FIST)) 16493 (clobber (match_operand:DI 2 "memory_operand" "=X,m")) 16494 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 16495 "TARGET_USE_FANCY_MATH_387" 16496 "#" 16497 [(set_attr "type" "fpspc") 16498 (set_attr "mode" "DI")]) 16499 16500(define_split 16501 [(set (match_operand:DI 0 "register_operand") 16502 (unspec:DI [(match_operand:XF 1 "register_operand")] 16503 UNSPEC_FIST)) 16504 (clobber (match_operand:DI 2 "memory_operand")) 16505 (clobber (match_scratch 3))] 16506 "reload_completed" 16507 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 16508 (clobber (match_dup 3))]) 16509 (set (match_dup 0) (match_dup 2))]) 16510 16511(define_split 16512 [(set (match_operand:DI 0 "memory_operand") 16513 (unspec:DI [(match_operand:XF 1 "register_operand")] 16514 UNSPEC_FIST)) 16515 (clobber (match_operand:DI 2 "memory_operand")) 16516 (clobber (match_scratch 3))] 16517 "reload_completed" 16518 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 16519 (clobber (match_dup 3))])]) 16520 16521(define_insn_and_split "*fist<mode>2_1" 16522 [(set (match_operand:SWI24 0 "register_operand") 16523 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16524 UNSPEC_FIST))] 16525 "TARGET_USE_FANCY_MATH_387 16526 && can_create_pseudo_p ()" 16527 "#" 16528 "&& 1" 16529 [(const_int 0)] 16530{ 16531 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 16532 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 16533 operands[2])); 16534 DONE; 16535} 16536 [(set_attr "type" "fpspc") 16537 (set_attr "mode" "<MODE>")]) 16538 16539(define_insn "fist<mode>2" 16540 [(set (match_operand:SWI24 0 "memory_operand" "=m") 16541 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16542 UNSPEC_FIST))] 16543 "TARGET_USE_FANCY_MATH_387" 16544 "* return output_fix_trunc (insn, operands, false);" 16545 [(set_attr "type" "fpspc") 16546 (set_attr "mode" "<MODE>")]) 16547 16548(define_insn "fist<mode>2_with_temp" 16549 [(set (match_operand:SWI24 0 "register_operand" "=r") 16550 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16551 UNSPEC_FIST)) 16552 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))] 16553 "TARGET_USE_FANCY_MATH_387" 16554 "#" 16555 [(set_attr "type" "fpspc") 16556 (set_attr "mode" "<MODE>")]) 16557 16558(define_split 16559 [(set (match_operand:SWI24 0 "register_operand") 16560 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16561 UNSPEC_FIST)) 16562 (clobber (match_operand:SWI24 2 "memory_operand"))] 16563 "reload_completed" 16564 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST)) 16565 (set (match_dup 0) (match_dup 2))]) 16566 16567(define_split 16568 [(set (match_operand:SWI24 0 "memory_operand") 16569 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16570 UNSPEC_FIST)) 16571 (clobber (match_operand:SWI24 2 "memory_operand"))] 16572 "reload_completed" 16573 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))]) 16574 16575(define_expand "lrintxf<mode>2" 16576 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16577 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16578 UNSPEC_FIST))] 16579 "TARGET_USE_FANCY_MATH_387") 16580 16581(define_expand "lrint<MODEF:mode><SWI48:mode>2" 16582 [(set (match_operand:SWI48 0 "nonimmediate_operand") 16583 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 16584 UNSPEC_FIX_NOTRUNC))] 16585 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH") 16586 16587(define_expand "lround<X87MODEF:mode><SWI248x:mode>2" 16588 [(match_operand:SWI248x 0 "nonimmediate_operand") 16589 (match_operand:X87MODEF 1 "register_operand")] 16590 "(TARGET_USE_FANCY_MATH_387 16591 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 16592 || TARGET_MIX_SSE_I387) 16593 && flag_unsafe_math_optimizations) 16594 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 16595 && <SWI248x:MODE>mode != HImode 16596 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 16597 && !flag_trapping_math && !flag_rounding_math)" 16598{ 16599 if (optimize_insn_for_size_p ()) 16600 FAIL; 16601 16602 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 16603 && <SWI248x:MODE>mode != HImode 16604 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 16605 && !flag_trapping_math && !flag_rounding_math) 16606 ix86_expand_lround (operands[0], operands[1]); 16607 else 16608 ix86_emit_i387_round (operands[0], operands[1]); 16609 DONE; 16610}) 16611 16612(define_int_iterator FRNDINT_ROUNDING 16613 [UNSPEC_FRNDINT_FLOOR 16614 UNSPEC_FRNDINT_CEIL 16615 UNSPEC_FRNDINT_TRUNC]) 16616 16617(define_int_iterator FIST_ROUNDING 16618 [UNSPEC_FIST_FLOOR 16619 UNSPEC_FIST_CEIL]) 16620 16621;; Base name for define_insn 16622(define_int_attr rounding_insn 16623 [(UNSPEC_FRNDINT_FLOOR "floor") 16624 (UNSPEC_FRNDINT_CEIL "ceil") 16625 (UNSPEC_FRNDINT_TRUNC "btrunc") 16626 (UNSPEC_FIST_FLOOR "floor") 16627 (UNSPEC_FIST_CEIL "ceil")]) 16628 16629(define_int_attr rounding 16630 [(UNSPEC_FRNDINT_FLOOR "floor") 16631 (UNSPEC_FRNDINT_CEIL "ceil") 16632 (UNSPEC_FRNDINT_TRUNC "trunc") 16633 (UNSPEC_FIST_FLOOR "floor") 16634 (UNSPEC_FIST_CEIL "ceil")]) 16635 16636(define_int_attr ROUNDING 16637 [(UNSPEC_FRNDINT_FLOOR "FLOOR") 16638 (UNSPEC_FRNDINT_CEIL "CEIL") 16639 (UNSPEC_FRNDINT_TRUNC "TRUNC") 16640 (UNSPEC_FIST_FLOOR "FLOOR") 16641 (UNSPEC_FIST_CEIL "CEIL")]) 16642 16643;; Rounding mode control word calculation could clobber FLAGS_REG. 16644(define_insn_and_split "frndint<mode>2_<rounding>" 16645 [(set (match_operand:X87MODEF 0 "register_operand") 16646 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")] 16647 FRNDINT_ROUNDING)) 16648 (clobber (reg:CC FLAGS_REG))] 16649 "TARGET_USE_FANCY_MATH_387 16650 && (flag_fp_int_builtin_inexact || !flag_trapping_math) 16651 && can_create_pseudo_p ()" 16652 "#" 16653 "&& 1" 16654 [(const_int 0)] 16655{ 16656 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 16657 16658 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16659 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 16660 16661 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1], 16662 operands[2], operands[3])); 16663 DONE; 16664} 16665 [(set_attr "type" "frndint") 16666 (set_attr "i387_cw" "<rounding>") 16667 (set_attr "mode" "<MODE>")]) 16668 16669(define_insn "frndint<mode>2_<rounding>_i387" 16670 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 16671 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")] 16672 FRNDINT_ROUNDING)) 16673 (use (match_operand:HI 2 "memory_operand" "m")) 16674 (use (match_operand:HI 3 "memory_operand" "m"))] 16675 "TARGET_USE_FANCY_MATH_387 16676 && (flag_fp_int_builtin_inexact || !flag_trapping_math)" 16677 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 16678 [(set_attr "type" "frndint") 16679 (set_attr "i387_cw" "<rounding>") 16680 (set_attr "mode" "<MODE>")]) 16681 16682(define_expand "<rounding_insn>xf2" 16683 [(parallel [(set (match_operand:XF 0 "register_operand") 16684 (unspec:XF [(match_operand:XF 1 "register_operand")] 16685 FRNDINT_ROUNDING)) 16686 (clobber (reg:CC FLAGS_REG))])] 16687 "TARGET_USE_FANCY_MATH_387 16688 && (flag_fp_int_builtin_inexact || !flag_trapping_math)") 16689 16690(define_expand "<rounding_insn><mode>2" 16691 [(parallel [(set (match_operand:MODEF 0 "register_operand") 16692 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")] 16693 FRNDINT_ROUNDING)) 16694 (clobber (reg:CC FLAGS_REG))])] 16695 "(TARGET_USE_FANCY_MATH_387 16696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16697 || TARGET_MIX_SSE_I387) 16698 && (flag_fp_int_builtin_inexact || !flag_trapping_math)) 16699 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16700 && (TARGET_SSE4_1 || !flag_trapping_math 16701 || flag_fp_int_builtin_inexact))" 16702{ 16703 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16704 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact)) 16705 { 16706 if (TARGET_SSE4_1) 16707 emit_insn (gen_sse4_1_round<mode>2 16708 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING> 16709 | ROUND_NO_EXC))); 16710 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 16711 { 16712 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16713 ix86_expand_floorceil (operands[0], operands[1], true); 16714 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16715 ix86_expand_floorceil (operands[0], operands[1], false); 16716 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 16717 ix86_expand_trunc (operands[0], operands[1]); 16718 else 16719 gcc_unreachable (); 16720 } 16721 else 16722 { 16723 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16724 ix86_expand_floorceildf_32 (operands[0], operands[1], true); 16725 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16726 ix86_expand_floorceildf_32 (operands[0], operands[1], false); 16727 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 16728 ix86_expand_truncdf_32 (operands[0], operands[1]); 16729 else 16730 gcc_unreachable (); 16731 } 16732 } 16733 else 16734 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1])); 16735 DONE; 16736}) 16737 16738;; Rounding mode control word calculation could clobber FLAGS_REG. 16739(define_insn_and_split "frndintxf2_mask_pm" 16740 [(set (match_operand:XF 0 "register_operand") 16741 (unspec:XF [(match_operand:XF 1 "register_operand")] 16742 UNSPEC_FRNDINT_MASK_PM)) 16743 (clobber (reg:CC FLAGS_REG))] 16744 "TARGET_USE_FANCY_MATH_387 16745 && flag_unsafe_math_optimizations 16746 && can_create_pseudo_p ()" 16747 "#" 16748 "&& 1" 16749 [(const_int 0)] 16750{ 16751 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 16752 16753 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16754 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 16755 16756 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 16757 operands[2], operands[3])); 16758 DONE; 16759} 16760 [(set_attr "type" "frndint") 16761 (set_attr "i387_cw" "mask_pm") 16762 (set_attr "mode" "XF")]) 16763 16764(define_insn "frndintxf2_mask_pm_i387" 16765 [(set (match_operand:XF 0 "register_operand" "=f") 16766 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16767 UNSPEC_FRNDINT_MASK_PM)) 16768 (use (match_operand:HI 2 "memory_operand" "m")) 16769 (use (match_operand:HI 3 "memory_operand" "m"))] 16770 "TARGET_USE_FANCY_MATH_387 16771 && flag_unsafe_math_optimizations" 16772 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 16773 [(set_attr "type" "frndint") 16774 (set_attr "i387_cw" "mask_pm") 16775 (set_attr "mode" "XF")]) 16776 16777(define_expand "nearbyintxf2" 16778 [(parallel [(set (match_operand:XF 0 "register_operand") 16779 (unspec:XF [(match_operand:XF 1 "register_operand")] 16780 UNSPEC_FRNDINT_MASK_PM)) 16781 (clobber (reg:CC FLAGS_REG))])] 16782 "TARGET_USE_FANCY_MATH_387 16783 && flag_unsafe_math_optimizations") 16784 16785(define_expand "nearbyint<mode>2" 16786 [(use (match_operand:MODEF 0 "register_operand")) 16787 (use (match_operand:MODEF 1 "register_operand"))] 16788 "TARGET_USE_FANCY_MATH_387 16789 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16790 || TARGET_MIX_SSE_I387) 16791 && flag_unsafe_math_optimizations" 16792{ 16793 rtx op0 = gen_reg_rtx (XFmode); 16794 rtx op1 = gen_reg_rtx (XFmode); 16795 16796 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16797 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 16798 16799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16800 DONE; 16801}) 16802 16803;; Rounding mode control word calculation could clobber FLAGS_REG. 16804(define_insn_and_split "*fist<mode>2_<rounding>_1" 16805 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16806 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16807 FIST_ROUNDING)) 16808 (clobber (reg:CC FLAGS_REG))] 16809 "TARGET_USE_FANCY_MATH_387 16810 && flag_unsafe_math_optimizations 16811 && can_create_pseudo_p ()" 16812 "#" 16813 "&& 1" 16814 [(const_int 0)] 16815{ 16816 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 16817 16818 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16819 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 16820 if (memory_operand (operands[0], VOIDmode)) 16821 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1], 16822 operands[2], operands[3])); 16823 else 16824 { 16825 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 16826 emit_insn (gen_fist<mode>2_<rounding>_with_temp 16827 (operands[0], operands[1], operands[2], 16828 operands[3], operands[4])); 16829 } 16830 DONE; 16831} 16832 [(set_attr "type" "fistp") 16833 (set_attr "i387_cw" "<rounding>") 16834 (set_attr "mode" "<MODE>")]) 16835 16836(define_insn "fistdi2_<rounding>" 16837 [(set (match_operand:DI 0 "memory_operand" "=m") 16838 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 16839 FIST_ROUNDING)) 16840 (use (match_operand:HI 2 "memory_operand" "m")) 16841 (use (match_operand:HI 3 "memory_operand" "m")) 16842 (clobber (match_scratch:XF 4 "=&1f"))] 16843 "TARGET_USE_FANCY_MATH_387 16844 && flag_unsafe_math_optimizations" 16845 "* return output_fix_trunc (insn, operands, false);" 16846 [(set_attr "type" "fistp") 16847 (set_attr "i387_cw" "<rounding>") 16848 (set_attr "mode" "DI")]) 16849 16850(define_insn "fistdi2_<rounding>_with_temp" 16851 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 16852 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 16853 FIST_ROUNDING)) 16854 (use (match_operand:HI 2 "memory_operand" "m,m")) 16855 (use (match_operand:HI 3 "memory_operand" "m,m")) 16856 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 16857 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 16858 "TARGET_USE_FANCY_MATH_387 16859 && flag_unsafe_math_optimizations" 16860 "#" 16861 [(set_attr "type" "fistp") 16862 (set_attr "i387_cw" "<rounding>") 16863 (set_attr "mode" "DI")]) 16864 16865(define_split 16866 [(set (match_operand:DI 0 "register_operand") 16867 (unspec:DI [(match_operand:XF 1 "register_operand")] 16868 FIST_ROUNDING)) 16869 (use (match_operand:HI 2 "memory_operand")) 16870 (use (match_operand:HI 3 "memory_operand")) 16871 (clobber (match_operand:DI 4 "memory_operand")) 16872 (clobber (match_scratch 5))] 16873 "reload_completed" 16874 [(parallel [(set (match_dup 4) 16875 (unspec:DI [(match_dup 1)] FIST_ROUNDING)) 16876 (use (match_dup 2)) 16877 (use (match_dup 3)) 16878 (clobber (match_dup 5))]) 16879 (set (match_dup 0) (match_dup 4))]) 16880 16881(define_split 16882 [(set (match_operand:DI 0 "memory_operand") 16883 (unspec:DI [(match_operand:XF 1 "register_operand")] 16884 FIST_ROUNDING)) 16885 (use (match_operand:HI 2 "memory_operand")) 16886 (use (match_operand:HI 3 "memory_operand")) 16887 (clobber (match_operand:DI 4 "memory_operand")) 16888 (clobber (match_scratch 5))] 16889 "reload_completed" 16890 [(parallel [(set (match_dup 0) 16891 (unspec:DI [(match_dup 1)] FIST_ROUNDING)) 16892 (use (match_dup 2)) 16893 (use (match_dup 3)) 16894 (clobber (match_dup 5))])]) 16895 16896(define_insn "fist<mode>2_<rounding>" 16897 [(set (match_operand:SWI24 0 "memory_operand" "=m") 16898 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16899 FIST_ROUNDING)) 16900 (use (match_operand:HI 2 "memory_operand" "m")) 16901 (use (match_operand:HI 3 "memory_operand" "m"))] 16902 "TARGET_USE_FANCY_MATH_387 16903 && flag_unsafe_math_optimizations" 16904 "* return output_fix_trunc (insn, operands, false);" 16905 [(set_attr "type" "fistp") 16906 (set_attr "i387_cw" "<rounding>") 16907 (set_attr "mode" "<MODE>")]) 16908 16909(define_insn "fist<mode>2_<rounding>_with_temp" 16910 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 16911 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 16912 FIST_ROUNDING)) 16913 (use (match_operand:HI 2 "memory_operand" "m,m")) 16914 (use (match_operand:HI 3 "memory_operand" "m,m")) 16915 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 16916 "TARGET_USE_FANCY_MATH_387 16917 && flag_unsafe_math_optimizations" 16918 "#" 16919 [(set_attr "type" "fistp") 16920 (set_attr "i387_cw" "<rounding>") 16921 (set_attr "mode" "<MODE>")]) 16922 16923(define_split 16924 [(set (match_operand:SWI24 0 "register_operand") 16925 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16926 FIST_ROUNDING)) 16927 (use (match_operand:HI 2 "memory_operand")) 16928 (use (match_operand:HI 3 "memory_operand")) 16929 (clobber (match_operand:SWI24 4 "memory_operand"))] 16930 "reload_completed" 16931 [(parallel [(set (match_dup 4) 16932 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) 16933 (use (match_dup 2)) 16934 (use (match_dup 3))]) 16935 (set (match_dup 0) (match_dup 4))]) 16936 16937(define_split 16938 [(set (match_operand:SWI24 0 "memory_operand") 16939 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16940 FIST_ROUNDING)) 16941 (use (match_operand:HI 2 "memory_operand")) 16942 (use (match_operand:HI 3 "memory_operand")) 16943 (clobber (match_operand:SWI24 4 "memory_operand"))] 16944 "reload_completed" 16945 [(parallel [(set (match_dup 0) 16946 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) 16947 (use (match_dup 2)) 16948 (use (match_dup 3))])]) 16949 16950(define_expand "l<rounding_insn>xf<mode>2" 16951 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16952 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16953 FIST_ROUNDING)) 16954 (clobber (reg:CC FLAGS_REG))])] 16955 "TARGET_USE_FANCY_MATH_387 16956 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16957 && flag_unsafe_math_optimizations") 16958 16959(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2" 16960 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand") 16961 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 16962 FIST_ROUNDING)) 16963 (clobber (reg:CC FLAGS_REG))])] 16964 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 16965 && (TARGET_SSE4_1 || !flag_trapping_math)" 16966{ 16967 if (TARGET_SSE4_1) 16968 { 16969 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode); 16970 16971 emit_insn (gen_sse4_1_round<mode>2 16972 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING> 16973 | ROUND_NO_EXC))); 16974 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2 16975 (operands[0], tmp)); 16976 } 16977 else if (ROUND_<ROUNDING> == ROUND_FLOOR) 16978 ix86_expand_lfloorceil (operands[0], operands[1], true); 16979 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16980 ix86_expand_lfloorceil (operands[0], operands[1], false); 16981 else 16982 gcc_unreachable (); 16983 16984 DONE; 16985}) 16986 16987(define_insn "fxam<mode>2_i387" 16988 [(set (match_operand:HI 0 "register_operand" "=a") 16989 (unspec:HI 16990 [(match_operand:X87MODEF 1 "register_operand" "f")] 16991 UNSPEC_FXAM))] 16992 "TARGET_USE_FANCY_MATH_387" 16993 "fxam\n\tfnstsw\t%0" 16994 [(set_attr "type" "multi") 16995 (set_attr "length" "4") 16996 (set_attr "unit" "i387") 16997 (set_attr "mode" "<MODE>")]) 16998 16999(define_insn_and_split "fxam<mode>2_i387_with_temp" 17000 [(set (match_operand:HI 0 "register_operand") 17001 (unspec:HI 17002 [(match_operand:MODEF 1 "memory_operand")] 17003 UNSPEC_FXAM_MEM))] 17004 "TARGET_USE_FANCY_MATH_387 17005 && can_create_pseudo_p ()" 17006 "#" 17007 "&& 1" 17008 [(set (match_dup 2)(match_dup 1)) 17009 (set (match_dup 0) 17010 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))] 17011{ 17012 operands[2] = gen_reg_rtx (<MODE>mode); 17013 17014 MEM_VOLATILE_P (operands[1]) = 1; 17015} 17016 [(set_attr "type" "multi") 17017 (set_attr "unit" "i387") 17018 (set_attr "mode" "<MODE>")]) 17019 17020(define_expand "isinfxf2" 17021 [(use (match_operand:SI 0 "register_operand")) 17022 (use (match_operand:XF 1 "register_operand"))] 17023 "TARGET_USE_FANCY_MATH_387 17024 && ix86_libc_has_function (function_c99_misc)" 17025{ 17026 rtx mask = GEN_INT (0x45); 17027 rtx val = GEN_INT (0x05); 17028 17029 rtx scratch = gen_reg_rtx (HImode); 17030 rtx res = gen_reg_rtx (QImode); 17031 17032 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 17033 17034 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask)); 17035 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 17036 ix86_expand_setcc (res, EQ, 17037 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 17038 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 17039 DONE; 17040}) 17041 17042(define_expand "isinf<mode>2" 17043 [(use (match_operand:SI 0 "register_operand")) 17044 (use (match_operand:MODEF 1 "nonimmediate_operand"))] 17045 "TARGET_USE_FANCY_MATH_387 17046 && ix86_libc_has_function (function_c99_misc) 17047 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 17048{ 17049 rtx mask = GEN_INT (0x45); 17050 rtx val = GEN_INT (0x05); 17051 17052 rtx scratch = gen_reg_rtx (HImode); 17053 rtx res = gen_reg_rtx (QImode); 17054 17055 /* Remove excess precision by forcing value through memory. */ 17056 if (memory_operand (operands[1], VOIDmode)) 17057 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1])); 17058 else 17059 { 17060 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17061 17062 emit_move_insn (temp, operands[1]); 17063 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp)); 17064 } 17065 17066 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask)); 17067 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 17068 ix86_expand_setcc (res, EQ, 17069 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 17070 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 17071 DONE; 17072}) 17073 17074(define_expand "signbittf2" 17075 [(use (match_operand:SI 0 "register_operand")) 17076 (use (match_operand:TF 1 "register_operand"))] 17077 "TARGET_SSE" 17078{ 17079 if (TARGET_SSE4_1) 17080 { 17081 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0); 17082 rtx scratch = gen_reg_rtx (QImode); 17083 17084 emit_insn (gen_ptesttf2 (operands[1], mask)); 17085 ix86_expand_setcc (scratch, NE, 17086 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 17087 17088 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 17089 } 17090 else 17091 { 17092 emit_insn (gen_sse_movmskps (operands[0], 17093 gen_lowpart (V4SFmode, operands[1]))); 17094 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8))); 17095 } 17096 DONE; 17097}) 17098 17099(define_expand "signbitxf2" 17100 [(use (match_operand:SI 0 "register_operand")) 17101 (use (match_operand:XF 1 "register_operand"))] 17102 "TARGET_USE_FANCY_MATH_387" 17103{ 17104 rtx scratch = gen_reg_rtx (HImode); 17105 17106 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 17107 emit_insn (gen_andsi3 (operands[0], 17108 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17109 DONE; 17110}) 17111 17112(define_insn "movmsk_df" 17113 [(set (match_operand:SI 0 "register_operand" "=r") 17114 (unspec:SI 17115 [(match_operand:DF 1 "register_operand" "x")] 17116 UNSPEC_MOVMSK))] 17117 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH" 17118 "%vmovmskpd\t{%1, %0|%0, %1}" 17119 [(set_attr "type" "ssemov") 17120 (set_attr "prefix" "maybe_vex") 17121 (set_attr "mode" "DF")]) 17122 17123;; Use movmskpd in SSE mode to avoid store forwarding stall 17124;; for 32bit targets and movq+shrq sequence for 64bit targets. 17125(define_expand "signbitdf2" 17126 [(use (match_operand:SI 0 "register_operand")) 17127 (use (match_operand:DF 1 "register_operand"))] 17128 "TARGET_USE_FANCY_MATH_387 17129 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 17130{ 17131 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH) 17132 { 17133 emit_insn (gen_movmsk_df (operands[0], operands[1])); 17134 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx)); 17135 } 17136 else 17137 { 17138 rtx scratch = gen_reg_rtx (HImode); 17139 17140 emit_insn (gen_fxamdf2_i387 (scratch, operands[1])); 17141 emit_insn (gen_andsi3 (operands[0], 17142 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17143 } 17144 DONE; 17145}) 17146 17147(define_expand "signbitsf2" 17148 [(use (match_operand:SI 0 "register_operand")) 17149 (use (match_operand:SF 1 "register_operand"))] 17150 "TARGET_USE_FANCY_MATH_387 17151 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)" 17152{ 17153 rtx scratch = gen_reg_rtx (HImode); 17154 17155 emit_insn (gen_fxamsf2_i387 (scratch, operands[1])); 17156 emit_insn (gen_andsi3 (operands[0], 17157 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17158 DONE; 17159}) 17160 17161;; Block operation instructions 17162 17163(define_insn "cld" 17164 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] 17165 "" 17166 "cld" 17167 [(set_attr "length" "1") 17168 (set_attr "length_immediate" "0") 17169 (set_attr "modrm" "0")]) 17170 17171(define_expand "movmem<mode>" 17172 [(use (match_operand:BLK 0 "memory_operand")) 17173 (use (match_operand:BLK 1 "memory_operand")) 17174 (use (match_operand:SWI48 2 "nonmemory_operand")) 17175 (use (match_operand:SWI48 3 "const_int_operand")) 17176 (use (match_operand:SI 4 "const_int_operand")) 17177 (use (match_operand:SI 5 "const_int_operand")) 17178 (use (match_operand:SI 6 "")) 17179 (use (match_operand:SI 7 "")) 17180 (use (match_operand:SI 8 ""))] 17181 "" 17182{ 17183 if (ix86_expand_set_or_movmem (operands[0], operands[1], 17184 operands[2], NULL, operands[3], 17185 operands[4], operands[5], 17186 operands[6], operands[7], 17187 operands[8], false)) 17188 DONE; 17189 else 17190 FAIL; 17191}) 17192 17193;; Most CPUs don't like single string operations 17194;; Handle this case here to simplify previous expander. 17195 17196(define_expand "strmov" 17197 [(set (match_dup 4) (match_operand 3 "memory_operand")) 17198 (set (match_operand 1 "memory_operand") (match_dup 4)) 17199 (parallel [(set (match_operand 0 "register_operand") (match_dup 5)) 17200 (clobber (reg:CC FLAGS_REG))]) 17201 (parallel [(set (match_operand 2 "register_operand") (match_dup 6)) 17202 (clobber (reg:CC FLAGS_REG))])] 17203 "" 17204{ 17205 /* Can't use this for non-default address spaces. */ 17206 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3]))) 17207 FAIL; 17208 17209 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 17210 17211 /* If .md ever supports :P for Pmode, these can be directly 17212 in the pattern above. */ 17213 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 17214 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 17215 17216 /* Can't use this if the user has appropriated esi or edi. */ 17217 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 17218 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])) 17219 { 17220 emit_insn (gen_strmov_singleop (operands[0], operands[1], 17221 operands[2], operands[3], 17222 operands[5], operands[6])); 17223 DONE; 17224 } 17225 17226 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 17227}) 17228 17229(define_expand "strmov_singleop" 17230 [(parallel [(set (match_operand 1 "memory_operand") 17231 (match_operand 3 "memory_operand")) 17232 (set (match_operand 0 "register_operand") 17233 (match_operand 4)) 17234 (set (match_operand 2 "register_operand") 17235 (match_operand 5))])] 17236 "" 17237{ 17238 if (TARGET_CLD) 17239 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17240}) 17241 17242(define_insn "*strmovdi_rex_1" 17243 [(set (mem:DI (match_operand:P 2 "register_operand" "0")) 17244 (mem:DI (match_operand:P 3 "register_operand" "1"))) 17245 (set (match_operand:P 0 "register_operand" "=D") 17246 (plus:P (match_dup 2) 17247 (const_int 8))) 17248 (set (match_operand:P 1 "register_operand" "=S") 17249 (plus:P (match_dup 3) 17250 (const_int 8)))] 17251 "TARGET_64BIT 17252 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17253 && ix86_check_no_addr_space (insn)" 17254 "%^movsq" 17255 [(set_attr "type" "str") 17256 (set_attr "memory" "both") 17257 (set_attr "mode" "DI")]) 17258 17259(define_insn "*strmovsi_1" 17260 [(set (mem:SI (match_operand:P 2 "register_operand" "0")) 17261 (mem:SI (match_operand:P 3 "register_operand" "1"))) 17262 (set (match_operand:P 0 "register_operand" "=D") 17263 (plus:P (match_dup 2) 17264 (const_int 4))) 17265 (set (match_operand:P 1 "register_operand" "=S") 17266 (plus:P (match_dup 3) 17267 (const_int 4)))] 17268 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17269 && ix86_check_no_addr_space (insn)" 17270 "%^movs{l|d}" 17271 [(set_attr "type" "str") 17272 (set_attr "memory" "both") 17273 (set_attr "mode" "SI")]) 17274 17275(define_insn "*strmovhi_1" 17276 [(set (mem:HI (match_operand:P 2 "register_operand" "0")) 17277 (mem:HI (match_operand:P 3 "register_operand" "1"))) 17278 (set (match_operand:P 0 "register_operand" "=D") 17279 (plus:P (match_dup 2) 17280 (const_int 2))) 17281 (set (match_operand:P 1 "register_operand" "=S") 17282 (plus:P (match_dup 3) 17283 (const_int 2)))] 17284 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17285 && ix86_check_no_addr_space (insn)" 17286 "%^movsw" 17287 [(set_attr "type" "str") 17288 (set_attr "memory" "both") 17289 (set_attr "mode" "HI")]) 17290 17291(define_insn "*strmovqi_1" 17292 [(set (mem:QI (match_operand:P 2 "register_operand" "0")) 17293 (mem:QI (match_operand:P 3 "register_operand" "1"))) 17294 (set (match_operand:P 0 "register_operand" "=D") 17295 (plus:P (match_dup 2) 17296 (const_int 1))) 17297 (set (match_operand:P 1 "register_operand" "=S") 17298 (plus:P (match_dup 3) 17299 (const_int 1)))] 17300 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17301 && ix86_check_no_addr_space (insn)" 17302 "%^movsb" 17303 [(set_attr "type" "str") 17304 (set_attr "memory" "both") 17305 (set (attr "prefix_rex") 17306 (if_then_else 17307 (match_test "<P:MODE>mode == DImode") 17308 (const_string "0") 17309 (const_string "*"))) 17310 (set_attr "mode" "QI")]) 17311 17312(define_expand "rep_mov" 17313 [(parallel [(set (match_operand 4 "register_operand") (const_int 0)) 17314 (set (match_operand 0 "register_operand") 17315 (match_operand 5)) 17316 (set (match_operand 2 "register_operand") 17317 (match_operand 6)) 17318 (set (match_operand 1 "memory_operand") 17319 (match_operand 3 "memory_operand")) 17320 (use (match_dup 4))])] 17321 "" 17322{ 17323 if (TARGET_CLD) 17324 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17325}) 17326 17327(define_insn "*rep_movdi_rex64" 17328 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17329 (set (match_operand:P 0 "register_operand" "=D") 17330 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 17331 (const_int 3)) 17332 (match_operand:P 3 "register_operand" "0"))) 17333 (set (match_operand:P 1 "register_operand" "=S") 17334 (plus:P (ashift:P (match_dup 5) (const_int 3)) 17335 (match_operand:P 4 "register_operand" "1"))) 17336 (set (mem:BLK (match_dup 3)) 17337 (mem:BLK (match_dup 4))) 17338 (use (match_dup 5))] 17339 "TARGET_64BIT 17340 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17341 && ix86_check_no_addr_space (insn)" 17342 "%^rep{%;} movsq" 17343 [(set_attr "type" "str") 17344 (set_attr "prefix_rep" "1") 17345 (set_attr "memory" "both") 17346 (set_attr "mode" "DI")]) 17347 17348(define_insn "*rep_movsi" 17349 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17350 (set (match_operand:P 0 "register_operand" "=D") 17351 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 17352 (const_int 2)) 17353 (match_operand:P 3 "register_operand" "0"))) 17354 (set (match_operand:P 1 "register_operand" "=S") 17355 (plus:P (ashift:P (match_dup 5) (const_int 2)) 17356 (match_operand:P 4 "register_operand" "1"))) 17357 (set (mem:BLK (match_dup 3)) 17358 (mem:BLK (match_dup 4))) 17359 (use (match_dup 5))] 17360 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17361 && ix86_check_no_addr_space (insn)" 17362 "%^rep{%;} movs{l|d}" 17363 [(set_attr "type" "str") 17364 (set_attr "prefix_rep" "1") 17365 (set_attr "memory" "both") 17366 (set_attr "mode" "SI")]) 17367 17368(define_insn "*rep_movqi" 17369 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17370 (set (match_operand:P 0 "register_operand" "=D") 17371 (plus:P (match_operand:P 3 "register_operand" "0") 17372 (match_operand:P 5 "register_operand" "2"))) 17373 (set (match_operand:P 1 "register_operand" "=S") 17374 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5))) 17375 (set (mem:BLK (match_dup 3)) 17376 (mem:BLK (match_dup 4))) 17377 (use (match_dup 5))] 17378 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17379 && ix86_check_no_addr_space (insn)" 17380 "%^rep{%;} movsb" 17381 [(set_attr "type" "str") 17382 (set_attr "prefix_rep" "1") 17383 (set_attr "memory" "both") 17384 (set_attr "mode" "QI")]) 17385 17386(define_expand "setmem<mode>" 17387 [(use (match_operand:BLK 0 "memory_operand")) 17388 (use (match_operand:SWI48 1 "nonmemory_operand")) 17389 (use (match_operand:QI 2 "nonmemory_operand")) 17390 (use (match_operand 3 "const_int_operand")) 17391 (use (match_operand:SI 4 "const_int_operand")) 17392 (use (match_operand:SI 5 "const_int_operand")) 17393 (use (match_operand:SI 6 "")) 17394 (use (match_operand:SI 7 "")) 17395 (use (match_operand:SI 8 ""))] 17396 "" 17397{ 17398 if (ix86_expand_set_or_movmem (operands[0], NULL, 17399 operands[1], operands[2], 17400 operands[3], operands[4], 17401 operands[5], operands[6], 17402 operands[7], operands[8], true)) 17403 DONE; 17404 else 17405 FAIL; 17406}) 17407 17408;; Most CPUs don't like single string operations 17409;; Handle this case here to simplify previous expander. 17410 17411(define_expand "strset" 17412 [(set (match_operand 1 "memory_operand") 17413 (match_operand 2 "register_operand")) 17414 (parallel [(set (match_operand 0 "register_operand") 17415 (match_dup 3)) 17416 (clobber (reg:CC FLAGS_REG))])] 17417 "" 17418{ 17419 /* Can't use this for non-default address spaces. */ 17420 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1]))) 17421 FAIL; 17422 17423 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 17424 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 17425 17426 /* If .md ever supports :P for Pmode, this can be directly 17427 in the pattern above. */ 17428 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 17429 GEN_INT (GET_MODE_SIZE (GET_MODE 17430 (operands[2])))); 17431 /* Can't use this if the user has appropriated eax or edi. */ 17432 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 17433 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])) 17434 { 17435 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 17436 operands[3])); 17437 DONE; 17438 } 17439}) 17440 17441(define_expand "strset_singleop" 17442 [(parallel [(set (match_operand 1 "memory_operand") 17443 (match_operand 2 "register_operand")) 17444 (set (match_operand 0 "register_operand") 17445 (match_operand 3)) 17446 (unspec [(const_int 0)] UNSPEC_STOS)])] 17447 "" 17448{ 17449 if (TARGET_CLD) 17450 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17451}) 17452 17453(define_insn "*strsetdi_rex_1" 17454 [(set (mem:DI (match_operand:P 1 "register_operand" "0")) 17455 (match_operand:DI 2 "register_operand" "a")) 17456 (set (match_operand:P 0 "register_operand" "=D") 17457 (plus:P (match_dup 1) 17458 (const_int 8))) 17459 (unspec [(const_int 0)] UNSPEC_STOS)] 17460 "TARGET_64BIT 17461 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17462 && ix86_check_no_addr_space (insn)" 17463 "%^stosq" 17464 [(set_attr "type" "str") 17465 (set_attr "memory" "store") 17466 (set_attr "mode" "DI")]) 17467 17468(define_insn "*strsetsi_1" 17469 [(set (mem:SI (match_operand:P 1 "register_operand" "0")) 17470 (match_operand:SI 2 "register_operand" "a")) 17471 (set (match_operand:P 0 "register_operand" "=D") 17472 (plus:P (match_dup 1) 17473 (const_int 4))) 17474 (unspec [(const_int 0)] UNSPEC_STOS)] 17475 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17476 && ix86_check_no_addr_space (insn)" 17477 "%^stos{l|d}" 17478 [(set_attr "type" "str") 17479 (set_attr "memory" "store") 17480 (set_attr "mode" "SI")]) 17481 17482(define_insn "*strsethi_1" 17483 [(set (mem:HI (match_operand:P 1 "register_operand" "0")) 17484 (match_operand:HI 2 "register_operand" "a")) 17485 (set (match_operand:P 0 "register_operand" "=D") 17486 (plus:P (match_dup 1) 17487 (const_int 2))) 17488 (unspec [(const_int 0)] UNSPEC_STOS)] 17489 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17490 && ix86_check_no_addr_space (insn)" 17491 "%^stosw" 17492 [(set_attr "type" "str") 17493 (set_attr "memory" "store") 17494 (set_attr "mode" "HI")]) 17495 17496(define_insn "*strsetqi_1" 17497 [(set (mem:QI (match_operand:P 1 "register_operand" "0")) 17498 (match_operand:QI 2 "register_operand" "a")) 17499 (set (match_operand:P 0 "register_operand" "=D") 17500 (plus:P (match_dup 1) 17501 (const_int 1))) 17502 (unspec [(const_int 0)] UNSPEC_STOS)] 17503 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17504 && ix86_check_no_addr_space (insn)" 17505 "%^stosb" 17506 [(set_attr "type" "str") 17507 (set_attr "memory" "store") 17508 (set (attr "prefix_rex") 17509 (if_then_else 17510 (match_test "<P:MODE>mode == DImode") 17511 (const_string "0") 17512 (const_string "*"))) 17513 (set_attr "mode" "QI")]) 17514 17515(define_expand "rep_stos" 17516 [(parallel [(set (match_operand 1 "register_operand") (const_int 0)) 17517 (set (match_operand 0 "register_operand") 17518 (match_operand 4)) 17519 (set (match_operand 2 "memory_operand") (const_int 0)) 17520 (use (match_operand 3 "register_operand")) 17521 (use (match_dup 1))])] 17522 "" 17523{ 17524 if (TARGET_CLD) 17525 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17526}) 17527 17528(define_insn "*rep_stosdi_rex64" 17529 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17530 (set (match_operand:P 0 "register_operand" "=D") 17531 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 17532 (const_int 3)) 17533 (match_operand:P 3 "register_operand" "0"))) 17534 (set (mem:BLK (match_dup 3)) 17535 (const_int 0)) 17536 (use (match_operand:DI 2 "register_operand" "a")) 17537 (use (match_dup 4))] 17538 "TARGET_64BIT 17539 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17540 && ix86_check_no_addr_space (insn)" 17541 "%^rep{%;} stosq" 17542 [(set_attr "type" "str") 17543 (set_attr "prefix_rep" "1") 17544 (set_attr "memory" "store") 17545 (set_attr "mode" "DI")]) 17546 17547(define_insn "*rep_stossi" 17548 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17549 (set (match_operand:P 0 "register_operand" "=D") 17550 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 17551 (const_int 2)) 17552 (match_operand:P 3 "register_operand" "0"))) 17553 (set (mem:BLK (match_dup 3)) 17554 (const_int 0)) 17555 (use (match_operand:SI 2 "register_operand" "a")) 17556 (use (match_dup 4))] 17557 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17558 && ix86_check_no_addr_space (insn)" 17559 "%^rep{%;} stos{l|d}" 17560 [(set_attr "type" "str") 17561 (set_attr "prefix_rep" "1") 17562 (set_attr "memory" "store") 17563 (set_attr "mode" "SI")]) 17564 17565(define_insn "*rep_stosqi" 17566 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17567 (set (match_operand:P 0 "register_operand" "=D") 17568 (plus:P (match_operand:P 3 "register_operand" "0") 17569 (match_operand:P 4 "register_operand" "1"))) 17570 (set (mem:BLK (match_dup 3)) 17571 (const_int 0)) 17572 (use (match_operand:QI 2 "register_operand" "a")) 17573 (use (match_dup 4))] 17574 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17575 && ix86_check_no_addr_space (insn)" 17576 "%^rep{%;} stosb" 17577 [(set_attr "type" "str") 17578 (set_attr "prefix_rep" "1") 17579 (set_attr "memory" "store") 17580 (set (attr "prefix_rex") 17581 (if_then_else 17582 (match_test "<P:MODE>mode == DImode") 17583 (const_string "0") 17584 (const_string "*"))) 17585 (set_attr "mode" "QI")]) 17586 17587(define_expand "cmpstrnsi" 17588 [(set (match_operand:SI 0 "register_operand") 17589 (compare:SI (match_operand:BLK 1 "general_operand") 17590 (match_operand:BLK 2 "general_operand"))) 17591 (use (match_operand 3 "general_operand")) 17592 (use (match_operand 4 "immediate_operand"))] 17593 "" 17594{ 17595 rtx addr1, addr2, out, outlow, count, countreg, align; 17596 17597 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) 17598 FAIL; 17599 17600 /* Can't use this if the user has appropriated ecx, esi or edi. */ 17601 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17602 FAIL; 17603 17604 /* One of the strings must be a constant. If so, expand_builtin_strncmp() 17605 will have rewritten the length arg to be the minimum of the const string 17606 length and the actual length arg. If both strings are the same and 17607 shorter than the length arg, repz cmpsb will not stop at the 0 byte and 17608 will incorrectly base the results on chars past the 0 byte. */ 17609 tree t1 = MEM_EXPR (operands[1]); 17610 tree t2 = MEM_EXPR (operands[2]); 17611 if (!((t1 && TREE_CODE (t1) == MEM_REF 17612 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR 17613 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST) 17614 || (t2 && TREE_CODE (t2) == MEM_REF 17615 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR 17616 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST))) 17617 FAIL; 17618 17619 out = operands[0]; 17620 if (!REG_P (out)) 17621 out = gen_reg_rtx (SImode); 17622 17623 addr1 = copy_addr_to_reg (XEXP (operands[1], 0)); 17624 addr2 = copy_addr_to_reg (XEXP (operands[2], 0)); 17625 if (addr1 != XEXP (operands[1], 0)) 17626 operands[1] = replace_equiv_address_nv (operands[1], addr1); 17627 if (addr2 != XEXP (operands[2], 0)) 17628 operands[2] = replace_equiv_address_nv (operands[2], addr2); 17629 17630 count = operands[3]; 17631 countreg = ix86_zero_extend_to_Pmode (count); 17632 17633 /* %%% Iff we are testing strict equality, we can use known alignment 17634 to good advantage. This may be possible with combine, particularly 17635 once cc0 is dead. */ 17636 align = operands[4]; 17637 17638 if (CONST_INT_P (count)) 17639 { 17640 if (INTVAL (count) == 0) 17641 { 17642 emit_move_insn (operands[0], const0_rtx); 17643 DONE; 17644 } 17645 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 17646 operands[1], operands[2])); 17647 } 17648 else 17649 { 17650 rtx (*gen_cmp) (rtx, rtx); 17651 17652 gen_cmp = (TARGET_64BIT 17653 ? gen_cmpdi_1 : gen_cmpsi_1); 17654 17655 emit_insn (gen_cmp (countreg, countreg)); 17656 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 17657 operands[1], operands[2])); 17658 } 17659 17660 outlow = gen_lowpart (QImode, out); 17661 emit_insn (gen_cmpintqi (outlow)); 17662 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 17663 17664 if (operands[0] != out) 17665 emit_move_insn (operands[0], out); 17666 17667 DONE; 17668}) 17669 17670;; Produce a tri-state integer (-1, 0, 1) from condition codes. 17671 17672(define_expand "cmpintqi" 17673 [(set (match_dup 1) 17674 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17675 (set (match_dup 2) 17676 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17677 (parallel [(set (match_operand:QI 0 "register_operand") 17678 (minus:QI (match_dup 1) 17679 (match_dup 2))) 17680 (clobber (reg:CC FLAGS_REG))])] 17681 "" 17682{ 17683 operands[1] = gen_reg_rtx (QImode); 17684 operands[2] = gen_reg_rtx (QImode); 17685}) 17686 17687;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 17688;; zero. Emit extra code to make sure that a zero-length compare is EQ. 17689 17690(define_expand "cmpstrnqi_nz_1" 17691 [(parallel [(set (reg:CC FLAGS_REG) 17692 (compare:CC (match_operand 4 "memory_operand") 17693 (match_operand 5 "memory_operand"))) 17694 (use (match_operand 2 "register_operand")) 17695 (use (match_operand:SI 3 "immediate_operand")) 17696 (clobber (match_operand 0 "register_operand")) 17697 (clobber (match_operand 1 "register_operand")) 17698 (clobber (match_dup 2))])] 17699 "" 17700{ 17701 if (TARGET_CLD) 17702 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17703}) 17704 17705(define_insn "*cmpstrnqi_nz_1" 17706 [(set (reg:CC FLAGS_REG) 17707 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 17708 (mem:BLK (match_operand:P 5 "register_operand" "1")))) 17709 (use (match_operand:P 6 "register_operand" "2")) 17710 (use (match_operand:SI 3 "immediate_operand" "i")) 17711 (clobber (match_operand:P 0 "register_operand" "=S")) 17712 (clobber (match_operand:P 1 "register_operand" "=D")) 17713 (clobber (match_operand:P 2 "register_operand" "=c"))] 17714 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17715 && ix86_check_no_addr_space (insn)" 17716 "%^repz{%;} cmpsb" 17717 [(set_attr "type" "str") 17718 (set_attr "mode" "QI") 17719 (set (attr "prefix_rex") 17720 (if_then_else 17721 (match_test "<P:MODE>mode == DImode") 17722 (const_string "0") 17723 (const_string "*"))) 17724 (set_attr "prefix_rep" "1")]) 17725 17726;; The same, but the count is not known to not be zero. 17727 17728(define_expand "cmpstrnqi_1" 17729 [(parallel [(set (reg:CC FLAGS_REG) 17730 (if_then_else:CC (ne (match_operand 2 "register_operand") 17731 (const_int 0)) 17732 (compare:CC (match_operand 4 "memory_operand") 17733 (match_operand 5 "memory_operand")) 17734 (const_int 0))) 17735 (use (match_operand:SI 3 "immediate_operand")) 17736 (use (reg:CC FLAGS_REG)) 17737 (clobber (match_operand 0 "register_operand")) 17738 (clobber (match_operand 1 "register_operand")) 17739 (clobber (match_dup 2))])] 17740 "" 17741{ 17742 if (TARGET_CLD) 17743 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17744}) 17745 17746(define_insn "*cmpstrnqi_1" 17747 [(set (reg:CC FLAGS_REG) 17748 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2") 17749 (const_int 0)) 17750 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 17751 (mem:BLK (match_operand:P 5 "register_operand" "1"))) 17752 (const_int 0))) 17753 (use (match_operand:SI 3 "immediate_operand" "i")) 17754 (use (reg:CC FLAGS_REG)) 17755 (clobber (match_operand:P 0 "register_operand" "=S")) 17756 (clobber (match_operand:P 1 "register_operand" "=D")) 17757 (clobber (match_operand:P 2 "register_operand" "=c"))] 17758 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17759 && ix86_check_no_addr_space (insn)" 17760 "%^repz{%;} cmpsb" 17761 [(set_attr "type" "str") 17762 (set_attr "mode" "QI") 17763 (set (attr "prefix_rex") 17764 (if_then_else 17765 (match_test "<P:MODE>mode == DImode") 17766 (const_string "0") 17767 (const_string "*"))) 17768 (set_attr "prefix_rep" "1")]) 17769 17770(define_expand "strlen<mode>" 17771 [(set (match_operand:P 0 "register_operand") 17772 (unspec:P [(match_operand:BLK 1 "general_operand") 17773 (match_operand:QI 2 "immediate_operand") 17774 (match_operand 3 "immediate_operand")] 17775 UNSPEC_SCAS))] 17776 "" 17777{ 17778 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 17779 DONE; 17780 else 17781 FAIL; 17782}) 17783 17784(define_expand "strlenqi_1" 17785 [(parallel [(set (match_operand 0 "register_operand") 17786 (match_operand 2)) 17787 (clobber (match_operand 1 "register_operand")) 17788 (clobber (reg:CC FLAGS_REG))])] 17789 "" 17790{ 17791 if (TARGET_CLD) 17792 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17793}) 17794 17795(define_insn "*strlenqi_1" 17796 [(set (match_operand:P 0 "register_operand" "=&c") 17797 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1")) 17798 (match_operand:QI 2 "register_operand" "a") 17799 (match_operand:P 3 "immediate_operand" "i") 17800 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS)) 17801 (clobber (match_operand:P 1 "register_operand" "=D")) 17802 (clobber (reg:CC FLAGS_REG))] 17803 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17804 && ix86_check_no_addr_space (insn)" 17805 "%^repnz{%;} scasb" 17806 [(set_attr "type" "str") 17807 (set_attr "mode" "QI") 17808 (set (attr "prefix_rex") 17809 (if_then_else 17810 (match_test "<P:MODE>mode == DImode") 17811 (const_string "0") 17812 (const_string "*"))) 17813 (set_attr "prefix_rep" "1")]) 17814 17815;; Peephole optimizations to clean up after cmpstrn*. This should be 17816;; handled in combine, but it is not currently up to the task. 17817;; When used for their truth value, the cmpstrn* expanders generate 17818;; code like this: 17819;; 17820;; repz cmpsb 17821;; seta %al 17822;; setb %dl 17823;; cmpb %al, %dl 17824;; jcc label 17825;; 17826;; The intermediate three instructions are unnecessary. 17827 17828;; This one handles cmpstrn*_nz_1... 17829(define_peephole2 17830 [(parallel[ 17831 (set (reg:CC FLAGS_REG) 17832 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 17833 (mem:BLK (match_operand 5 "register_operand")))) 17834 (use (match_operand 6 "register_operand")) 17835 (use (match_operand:SI 3 "immediate_operand")) 17836 (clobber (match_operand 0 "register_operand")) 17837 (clobber (match_operand 1 "register_operand")) 17838 (clobber (match_operand 2 "register_operand"))]) 17839 (set (match_operand:QI 7 "register_operand") 17840 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17841 (set (match_operand:QI 8 "register_operand") 17842 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17843 (set (reg FLAGS_REG) 17844 (compare (match_dup 7) (match_dup 8))) 17845 ] 17846 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 17847 [(parallel[ 17848 (set (reg:CC FLAGS_REG) 17849 (compare:CC (mem:BLK (match_dup 4)) 17850 (mem:BLK (match_dup 5)))) 17851 (use (match_dup 6)) 17852 (use (match_dup 3)) 17853 (clobber (match_dup 0)) 17854 (clobber (match_dup 1)) 17855 (clobber (match_dup 2))])]) 17856 17857;; ...and this one handles cmpstrn*_1. 17858(define_peephole2 17859 [(parallel[ 17860 (set (reg:CC FLAGS_REG) 17861 (if_then_else:CC (ne (match_operand 6 "register_operand") 17862 (const_int 0)) 17863 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 17864 (mem:BLK (match_operand 5 "register_operand"))) 17865 (const_int 0))) 17866 (use (match_operand:SI 3 "immediate_operand")) 17867 (use (reg:CC FLAGS_REG)) 17868 (clobber (match_operand 0 "register_operand")) 17869 (clobber (match_operand 1 "register_operand")) 17870 (clobber (match_operand 2 "register_operand"))]) 17871 (set (match_operand:QI 7 "register_operand") 17872 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17873 (set (match_operand:QI 8 "register_operand") 17874 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17875 (set (reg FLAGS_REG) 17876 (compare (match_dup 7) (match_dup 8))) 17877 ] 17878 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 17879 [(parallel[ 17880 (set (reg:CC FLAGS_REG) 17881 (if_then_else:CC (ne (match_dup 6) 17882 (const_int 0)) 17883 (compare:CC (mem:BLK (match_dup 4)) 17884 (mem:BLK (match_dup 5))) 17885 (const_int 0))) 17886 (use (match_dup 3)) 17887 (use (reg:CC FLAGS_REG)) 17888 (clobber (match_dup 0)) 17889 (clobber (match_dup 1)) 17890 (clobber (match_dup 2))])]) 17891 17892;; Conditional move instructions. 17893 17894(define_expand "mov<mode>cc" 17895 [(set (match_operand:SWIM 0 "register_operand") 17896 (if_then_else:SWIM (match_operand 1 "comparison_operator") 17897 (match_operand:SWIM 2 "<general_operand>") 17898 (match_operand:SWIM 3 "<general_operand>")))] 17899 "" 17900 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") 17901 17902;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 17903;; the register first winds up with `sbbl $0,reg', which is also weird. 17904;; So just document what we're doing explicitly. 17905 17906(define_expand "x86_mov<mode>cc_0_m1" 17907 [(parallel 17908 [(set (match_operand:SWI48 0 "register_operand") 17909 (if_then_else:SWI48 17910 (match_operator:SWI48 2 "ix86_carry_flag_operator" 17911 [(match_operand 1 "flags_reg_operand") 17912 (const_int 0)]) 17913 (const_int -1) 17914 (const_int 0))) 17915 (clobber (reg:CC FLAGS_REG))])]) 17916 17917(define_insn "*x86_mov<mode>cc_0_m1" 17918 [(set (match_operand:SWI48 0 "register_operand" "=r") 17919 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17920 [(reg FLAGS_REG) (const_int 0)]) 17921 (const_int -1) 17922 (const_int 0))) 17923 (clobber (reg:CC FLAGS_REG))] 17924 "" 17925 "sbb{<imodesuffix>}\t%0, %0" 17926 ; Since we don't have the proper number of operands for an alu insn, 17927 ; fill in all the blanks. 17928 [(set_attr "type" "alu") 17929 (set_attr "modrm_class" "op0") 17930 (set_attr "use_carry" "1") 17931 (set_attr "pent_pair" "pu") 17932 (set_attr "memory" "none") 17933 (set_attr "imm_disp" "false") 17934 (set_attr "mode" "<MODE>") 17935 (set_attr "length_immediate" "0")]) 17936 17937(define_insn "*x86_mov<mode>cc_0_m1_se" 17938 [(set (match_operand:SWI48 0 "register_operand" "=r") 17939 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17940 [(reg FLAGS_REG) (const_int 0)]) 17941 (const_int 1) 17942 (const_int 0))) 17943 (clobber (reg:CC FLAGS_REG))] 17944 "" 17945 "sbb{<imodesuffix>}\t%0, %0" 17946 [(set_attr "type" "alu") 17947 (set_attr "modrm_class" "op0") 17948 (set_attr "use_carry" "1") 17949 (set_attr "pent_pair" "pu") 17950 (set_attr "memory" "none") 17951 (set_attr "imm_disp" "false") 17952 (set_attr "mode" "<MODE>") 17953 (set_attr "length_immediate" "0")]) 17954 17955(define_insn "*x86_mov<mode>cc_0_m1_neg" 17956 [(set (match_operand:SWI48 0 "register_operand" "=r") 17957 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17958 [(reg FLAGS_REG) (const_int 0)]))) 17959 (clobber (reg:CC FLAGS_REG))] 17960 "" 17961 "sbb{<imodesuffix>}\t%0, %0" 17962 [(set_attr "type" "alu") 17963 (set_attr "modrm_class" "op0") 17964 (set_attr "use_carry" "1") 17965 (set_attr "pent_pair" "pu") 17966 (set_attr "memory" "none") 17967 (set_attr "imm_disp" "false") 17968 (set_attr "mode" "<MODE>") 17969 (set_attr "length_immediate" "0")]) 17970 17971(define_insn "*mov<mode>cc_noc" 17972 [(set (match_operand:SWI248 0 "register_operand" "=r,r") 17973 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 17974 [(reg FLAGS_REG) (const_int 0)]) 17975 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0") 17976 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))] 17977 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 17978 "@ 17979 cmov%O2%C1\t{%2, %0|%0, %2} 17980 cmov%O2%c1\t{%3, %0|%0, %3}" 17981 [(set_attr "type" "icmov") 17982 (set_attr "mode" "<MODE>")]) 17983 17984(define_insn "*movsicc_noc_zext" 17985 [(set (match_operand:DI 0 "register_operand" "=r,r") 17986 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 17987 [(reg FLAGS_REG) (const_int 0)]) 17988 (zero_extend:DI 17989 (match_operand:SI 2 "nonimmediate_operand" "rm,0")) 17990 (zero_extend:DI 17991 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))] 17992 "TARGET_64BIT 17993 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 17994 "@ 17995 cmov%O2%C1\t{%2, %k0|%k0, %2} 17996 cmov%O2%c1\t{%3, %k0|%k0, %3}" 17997 [(set_attr "type" "icmov") 17998 (set_attr "mode" "SI")]) 17999 18000;; Don't do conditional moves with memory inputs. This splitter helps 18001;; register starved x86_32 by forcing inputs into registers before reload. 18002(define_split 18003 [(set (match_operand:SWI248 0 "register_operand") 18004 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 18005 [(reg FLAGS_REG) (const_int 0)]) 18006 (match_operand:SWI248 2 "nonimmediate_operand") 18007 (match_operand:SWI248 3 "nonimmediate_operand")))] 18008 "!TARGET_64BIT && TARGET_CMOVE 18009 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18010 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18011 && can_create_pseudo_p () 18012 && optimize_insn_for_speed_p ()" 18013 [(set (match_dup 0) 18014 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 18015{ 18016 if (MEM_P (operands[2])) 18017 operands[2] = force_reg (<MODE>mode, operands[2]); 18018 if (MEM_P (operands[3])) 18019 operands[3] = force_reg (<MODE>mode, operands[3]); 18020}) 18021 18022(define_insn "*movqicc_noc" 18023 [(set (match_operand:QI 0 "register_operand" "=r,r") 18024 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 18025 [(reg FLAGS_REG) (const_int 0)]) 18026 (match_operand:QI 2 "register_operand" "r,0") 18027 (match_operand:QI 3 "register_operand" "0,r")))] 18028 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 18029 "#" 18030 [(set_attr "type" "icmov") 18031 (set_attr "mode" "QI")]) 18032 18033(define_split 18034 [(set (match_operand:SWI12 0 "register_operand") 18035 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator" 18036 [(reg FLAGS_REG) (const_int 0)]) 18037 (match_operand:SWI12 2 "register_operand") 18038 (match_operand:SWI12 3 "register_operand")))] 18039 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL 18040 && reload_completed" 18041 [(set (match_dup 0) 18042 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 18043{ 18044 operands[0] = gen_lowpart (SImode, operands[0]); 18045 operands[2] = gen_lowpart (SImode, operands[2]); 18046 operands[3] = gen_lowpart (SImode, operands[3]); 18047}) 18048 18049;; Don't do conditional moves with memory inputs 18050(define_peephole2 18051 [(match_scratch:SWI248 4 "r") 18052 (set (match_operand:SWI248 0 "register_operand") 18053 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 18054 [(reg FLAGS_REG) (const_int 0)]) 18055 (match_operand:SWI248 2 "nonimmediate_operand") 18056 (match_operand:SWI248 3 "nonimmediate_operand")))] 18057 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18058 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18059 && optimize_insn_for_speed_p ()" 18060 [(set (match_dup 4) (match_dup 5)) 18061 (set (match_dup 0) 18062 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 18063{ 18064 if (MEM_P (operands[2])) 18065 { 18066 operands[5] = operands[2]; 18067 operands[2] = operands[4]; 18068 } 18069 else if (MEM_P (operands[3])) 18070 { 18071 operands[5] = operands[3]; 18072 operands[3] = operands[4]; 18073 } 18074 else 18075 gcc_unreachable (); 18076}) 18077 18078(define_peephole2 18079 [(match_scratch:SI 4 "r") 18080 (set (match_operand:DI 0 "register_operand") 18081 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 18082 [(reg FLAGS_REG) (const_int 0)]) 18083 (zero_extend:DI 18084 (match_operand:SI 2 "nonimmediate_operand")) 18085 (zero_extend:DI 18086 (match_operand:SI 3 "nonimmediate_operand"))))] 18087 "TARGET_64BIT 18088 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18089 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18090 && optimize_insn_for_speed_p ()" 18091 [(set (match_dup 4) (match_dup 5)) 18092 (set (match_dup 0) 18093 (if_then_else:DI (match_dup 1) 18094 (zero_extend:DI (match_dup 2)) 18095 (zero_extend:DI (match_dup 3))))] 18096{ 18097 if (MEM_P (operands[2])) 18098 { 18099 operands[5] = operands[2]; 18100 operands[2] = operands[4]; 18101 } 18102 else if (MEM_P (operands[3])) 18103 { 18104 operands[5] = operands[3]; 18105 operands[3] = operands[4]; 18106 } 18107 else 18108 gcc_unreachable (); 18109}) 18110 18111(define_expand "mov<mode>cc" 18112 [(set (match_operand:X87MODEF 0 "register_operand") 18113 (if_then_else:X87MODEF 18114 (match_operand 1 "comparison_operator") 18115 (match_operand:X87MODEF 2 "register_operand") 18116 (match_operand:X87MODEF 3 "register_operand")))] 18117 "(TARGET_80387 && TARGET_CMOVE) 18118 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 18119 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;") 18120 18121(define_insn "*movxfcc_1" 18122 [(set (match_operand:XF 0 "register_operand" "=f,f") 18123 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 18124 [(reg FLAGS_REG) (const_int 0)]) 18125 (match_operand:XF 2 "register_operand" "f,0") 18126 (match_operand:XF 3 "register_operand" "0,f")))] 18127 "TARGET_80387 && TARGET_CMOVE" 18128 "@ 18129 fcmov%F1\t{%2, %0|%0, %2} 18130 fcmov%f1\t{%3, %0|%0, %3}" 18131 [(set_attr "type" "fcmov") 18132 (set_attr "mode" "XF")]) 18133 18134(define_insn "*movdfcc_1" 18135 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r") 18136 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18137 [(reg FLAGS_REG) (const_int 0)]) 18138 (match_operand:DF 2 "nonimmediate_operand" 18139 "f ,0,rm,0 ,rm,0") 18140 (match_operand:DF 3 "nonimmediate_operand" 18141 "0 ,f,0 ,rm,0, rm")))] 18142 "TARGET_80387 && TARGET_CMOVE 18143 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18144 "@ 18145 fcmov%F1\t{%2, %0|%0, %2} 18146 fcmov%f1\t{%3, %0|%0, %3} 18147 # 18148 # 18149 cmov%O2%C1\t{%2, %0|%0, %2} 18150 cmov%O2%c1\t{%3, %0|%0, %3}" 18151 [(set_attr "isa" "*,*,nox64,nox64,x64,x64") 18152 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov") 18153 (set_attr "mode" "DF,DF,DI,DI,DI,DI")]) 18154 18155(define_split 18156 [(set (match_operand:DF 0 "general_reg_operand") 18157 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18158 [(reg FLAGS_REG) (const_int 0)]) 18159 (match_operand:DF 2 "nonimmediate_operand") 18160 (match_operand:DF 3 "nonimmediate_operand")))] 18161 "!TARGET_64BIT && reload_completed" 18162 [(set (match_dup 2) 18163 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5))) 18164 (set (match_dup 3) 18165 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))] 18166{ 18167 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]); 18168 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]); 18169}) 18170 18171(define_insn "*movsfcc_1_387" 18172 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 18173 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 18174 [(reg FLAGS_REG) (const_int 0)]) 18175 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 18176 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 18177 "TARGET_80387 && TARGET_CMOVE 18178 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18179 "@ 18180 fcmov%F1\t{%2, %0|%0, %2} 18181 fcmov%f1\t{%3, %0|%0, %3} 18182 cmov%O2%C1\t{%2, %0|%0, %2} 18183 cmov%O2%c1\t{%3, %0|%0, %3}" 18184 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 18185 (set_attr "mode" "SF,SF,SI,SI")]) 18186 18187;; Don't do conditional moves with memory inputs. This splitter helps 18188;; register starved x86_32 by forcing inputs into registers before reload. 18189(define_split 18190 [(set (match_operand:MODEF 0 "register_operand") 18191 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator" 18192 [(reg FLAGS_REG) (const_int 0)]) 18193 (match_operand:MODEF 2 "nonimmediate_operand") 18194 (match_operand:MODEF 3 "nonimmediate_operand")))] 18195 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 18196 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18197 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18198 && can_create_pseudo_p () 18199 && optimize_insn_for_speed_p ()" 18200 [(set (match_dup 0) 18201 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 18202{ 18203 if (MEM_P (operands[2])) 18204 operands[2] = force_reg (<MODE>mode, operands[2]); 18205 if (MEM_P (operands[3])) 18206 operands[3] = force_reg (<MODE>mode, operands[3]); 18207}) 18208 18209;; Don't do conditional moves with memory inputs 18210(define_peephole2 18211 [(match_scratch:MODEF 4 "r") 18212 (set (match_operand:MODEF 0 "general_reg_operand") 18213 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator" 18214 [(reg FLAGS_REG) (const_int 0)]) 18215 (match_operand:MODEF 2 "nonimmediate_operand") 18216 (match_operand:MODEF 3 "nonimmediate_operand")))] 18217 "(<MODE>mode != DFmode || TARGET_64BIT) 18218 && TARGET_80387 && TARGET_CMOVE 18219 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18220 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18221 && optimize_insn_for_speed_p ()" 18222 [(set (match_dup 4) (match_dup 5)) 18223 (set (match_dup 0) 18224 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 18225{ 18226 if (MEM_P (operands[2])) 18227 { 18228 operands[5] = operands[2]; 18229 operands[2] = operands[4]; 18230 } 18231 else if (MEM_P (operands[3])) 18232 { 18233 operands[5] = operands[3]; 18234 operands[3] = operands[4]; 18235 } 18236 else 18237 gcc_unreachable (); 18238}) 18239 18240;; All moves in XOP pcmov instructions are 128 bits and hence we restrict 18241;; the scalar versions to have only XMM registers as operands. 18242 18243;; XOP conditional move 18244(define_insn "*xop_pcmov_<mode>" 18245 [(set (match_operand:MODEF 0 "register_operand" "=x") 18246 (if_then_else:MODEF 18247 (match_operand:MODEF 1 "register_operand" "x") 18248 (match_operand:MODEF 2 "register_operand" "x") 18249 (match_operand:MODEF 3 "register_operand" "x")))] 18250 "TARGET_XOP" 18251 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}" 18252 [(set_attr "type" "sse4arg")]) 18253 18254;; These versions of the min/max patterns are intentionally ignorant of 18255;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 18256;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 18257;; are undefined in this condition, we're certain this is correct. 18258 18259(define_insn "<code><mode>3" 18260 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 18261 (smaxmin:MODEF 18262 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v") 18263 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))] 18264 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 18265 "@ 18266 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2} 18267 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 18268 [(set_attr "isa" "noavx,avx") 18269 (set_attr "prefix" "orig,vex") 18270 (set_attr "type" "sseadd") 18271 (set_attr "mode" "<MODE>")]) 18272 18273;; These versions of the min/max patterns implement exactly the operations 18274;; min = (op1 < op2 ? op1 : op2) 18275;; max = (!(op1 < op2) ? op1 : op2) 18276;; Their operands are not commutative, and thus they may be used in the 18277;; presence of -0.0 and NaN. 18278 18279(define_insn "*ieee_s<ieee_maxmin><mode>3" 18280 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 18281 (unspec:MODEF 18282 [(match_operand:MODEF 1 "register_operand" "0,v") 18283 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")] 18284 IEEE_MAXMIN))] 18285 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 18286 "@ 18287 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2} 18288 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 18289 [(set_attr "isa" "noavx,avx") 18290 (set_attr "prefix" "orig,maybe_evex") 18291 (set_attr "type" "sseadd") 18292 (set_attr "mode" "<MODE>")]) 18293 18294;; Make two stack loads independent: 18295;; fld aa fld aa 18296;; fld %st(0) -> fld bb 18297;; fmul bb fmul %st(1), %st 18298;; 18299;; Actually we only match the last two instructions for simplicity. 18300 18301(define_peephole2 18302 [(set (match_operand 0 "fp_register_operand") 18303 (match_operand 1 "fp_register_operand")) 18304 (set (match_dup 0) 18305 (match_operator 2 "binary_fp_operator" 18306 [(match_dup 0) 18307 (match_operand 3 "memory_operand")]))] 18308 "REGNO (operands[0]) != REGNO (operands[1])" 18309 [(set (match_dup 0) (match_dup 3)) 18310 (set (match_dup 0) 18311 (match_op_dup 2 18312 [(match_dup 5) (match_dup 4)]))] 18313{ 18314 operands[4] = operands[0]; 18315 operands[5] = operands[1]; 18316 18317 /* The % modifier is not operational anymore in peephole2's, so we have to 18318 swap the operands manually in the case of addition and multiplication. */ 18319 if (COMMUTATIVE_ARITH_P (operands[2])) 18320 std::swap (operands[4], operands[5]); 18321}) 18322 18323(define_peephole2 18324 [(set (match_operand 0 "fp_register_operand") 18325 (match_operand 1 "fp_register_operand")) 18326 (set (match_dup 0) 18327 (match_operator 2 "binary_fp_operator" 18328 [(match_operand 3 "memory_operand") 18329 (match_dup 0)]))] 18330 "REGNO (operands[0]) != REGNO (operands[1])" 18331 [(set (match_dup 0) (match_dup 3)) 18332 (set (match_dup 0) 18333 (match_op_dup 2 18334 [(match_dup 4) (match_dup 5)]))] 18335{ 18336 operands[4] = operands[0]; 18337 operands[5] = operands[1]; 18338 18339 /* The % modifier is not operational anymore in peephole2's, so we have to 18340 swap the operands manually in the case of addition and multiplication. */ 18341 if (COMMUTATIVE_ARITH_P (operands[2])) 18342 std::swap (operands[4], operands[5]); 18343}) 18344 18345;; Conditional addition patterns 18346(define_expand "add<mode>cc" 18347 [(match_operand:SWI 0 "register_operand") 18348 (match_operand 1 "ordered_comparison_operator") 18349 (match_operand:SWI 2 "register_operand") 18350 (match_operand:SWI 3 "const_int_operand")] 18351 "" 18352 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;") 18353 18354;; Misc patterns (?) 18355 18356;; This pattern exists to put a dependency on all ebp-based memory accesses. 18357;; Otherwise there will be nothing to keep 18358;; 18359;; [(set (reg ebp) (reg esp))] 18360;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 18361;; (clobber (eflags)] 18362;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 18363;; 18364;; in proper program order. 18365 18366(define_insn "pro_epilogue_adjust_stack_<mode>_add" 18367 [(set (match_operand:P 0 "register_operand" "=r,r") 18368 (plus:P (match_operand:P 1 "register_operand" "0,r") 18369 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>"))) 18370 (clobber (reg:CC FLAGS_REG)) 18371 (clobber (mem:BLK (scratch)))] 18372 "" 18373{ 18374 switch (get_attr_type (insn)) 18375 { 18376 case TYPE_IMOV: 18377 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 18378 18379 case TYPE_ALU: 18380 gcc_assert (rtx_equal_p (operands[0], operands[1])); 18381 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 18382 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 18383 18384 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 18385 18386 default: 18387 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 18388 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}"; 18389 } 18390} 18391 [(set (attr "type") 18392 (cond [(and (eq_attr "alternative" "0") 18393 (not (match_test "TARGET_OPT_AGU"))) 18394 (const_string "alu") 18395 (match_operand:<MODE> 2 "const0_operand") 18396 (const_string "imov") 18397 ] 18398 (const_string "lea"))) 18399 (set (attr "length_immediate") 18400 (cond [(eq_attr "type" "imov") 18401 (const_string "0") 18402 (and (eq_attr "type" "alu") 18403 (match_operand 2 "const128_operand")) 18404 (const_string "1") 18405 ] 18406 (const_string "*"))) 18407 (set_attr "mode" "<MODE>")]) 18408 18409(define_insn "pro_epilogue_adjust_stack_<mode>_sub" 18410 [(set (match_operand:P 0 "register_operand" "=r") 18411 (minus:P (match_operand:P 1 "register_operand" "0") 18412 (match_operand:P 2 "register_operand" "r"))) 18413 (clobber (reg:CC FLAGS_REG)) 18414 (clobber (mem:BLK (scratch)))] 18415 "" 18416 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 18417 [(set_attr "type" "alu") 18418 (set_attr "mode" "<MODE>")]) 18419 18420(define_insn "allocate_stack_worker_probe_<mode>" 18421 [(set (match_operand:P 0 "register_operand" "=a") 18422 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 18423 UNSPECV_STACK_PROBE)) 18424 (clobber (reg:CC FLAGS_REG))] 18425 "ix86_target_stack_probe ()" 18426 "call\t___chkstk_ms" 18427 [(set_attr "type" "multi") 18428 (set_attr "length" "5")]) 18429 18430(define_expand "allocate_stack" 18431 [(match_operand 0 "register_operand") 18432 (match_operand 1 "general_operand")] 18433 "ix86_target_stack_probe ()" 18434{ 18435 rtx x; 18436 18437#ifndef CHECK_STACK_LIMIT 18438#define CHECK_STACK_LIMIT 0 18439#endif 18440 18441 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1]) 18442 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 18443 x = operands[1]; 18444 else 18445 { 18446 rtx (*insn) (rtx, rtx); 18447 18448 x = copy_to_mode_reg (Pmode, operands[1]); 18449 18450 insn = (TARGET_64BIT 18451 ? gen_allocate_stack_worker_probe_di 18452 : gen_allocate_stack_worker_probe_si); 18453 18454 emit_insn (insn (x, x)); 18455 } 18456 18457 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x, 18458 stack_pointer_rtx, 0, OPTAB_DIRECT); 18459 18460 if (x != stack_pointer_rtx) 18461 emit_move_insn (stack_pointer_rtx, x); 18462 18463 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 18464 DONE; 18465}) 18466 18467(define_expand "probe_stack" 18468 [(match_operand 0 "memory_operand")] 18469 "" 18470{ 18471 rtx (*insn) (rtx, rtx) 18472 = (GET_MODE (operands[0]) == DImode 18473 ? gen_probe_stack_di : gen_probe_stack_si); 18474 18475 emit_insn (insn (operands[0], const0_rtx)); 18476 DONE; 18477}) 18478 18479;; Use OR for stack probes, this is shorter. 18480(define_insn "probe_stack_<mode>" 18481 [(set (match_operand:W 0 "memory_operand" "=m") 18482 (unspec:W [(match_operand:W 1 "const0_operand")] 18483 UNSPEC_PROBE_STACK)) 18484 (clobber (reg:CC FLAGS_REG))] 18485 "" 18486 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 18487 [(set_attr "type" "alu1") 18488 (set_attr "mode" "<MODE>") 18489 (set_attr "length_immediate" "1")]) 18490 18491(define_insn "adjust_stack_and_probe<mode>" 18492 [(set (match_operand:P 0 "register_operand" "=r") 18493 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 18494 UNSPECV_PROBE_STACK_RANGE)) 18495 (set (reg:P SP_REG) 18496 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n"))) 18497 (clobber (reg:CC FLAGS_REG)) 18498 (clobber (mem:BLK (scratch)))] 18499 "" 18500 "* return output_adjust_stack_and_probe (operands[0]);" 18501 [(set_attr "type" "multi")]) 18502 18503(define_insn "probe_stack_range<mode>" 18504 [(set (match_operand:P 0 "register_operand" "=r") 18505 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 18506 (match_operand:P 2 "const_int_operand" "n")] 18507 UNSPECV_PROBE_STACK_RANGE)) 18508 (clobber (reg:CC FLAGS_REG))] 18509 "" 18510 "* return output_probe_stack_range (operands[0], operands[2]);" 18511 [(set_attr "type" "multi")]) 18512 18513(define_expand "builtin_setjmp_receiver" 18514 [(label_ref (match_operand 0))] 18515 "!TARGET_64BIT && flag_pic" 18516{ 18517#if TARGET_MACHO 18518 if (TARGET_MACHO) 18519 { 18520 rtx xops[3]; 18521 rtx_code_label *label_rtx = gen_label_rtx (); 18522 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 18523 xops[0] = xops[1] = pic_offset_table_rtx; 18524 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx)); 18525 ix86_expand_binary_operator (MINUS, SImode, xops); 18526 } 18527 else 18528#endif 18529 emit_insn (gen_set_got (pic_offset_table_rtx)); 18530 DONE; 18531}) 18532 18533(define_expand "save_stack_nonlocal" 18534 [(set (match_operand 0 "memory_operand") 18535 (match_operand 1 "register_operand"))] 18536 "" 18537{ 18538 rtx stack_slot; 18539 if ((flag_cf_protection & CF_RETURN)) 18540 { 18541 /* Copy shadow stack pointer to the first slot and stack ppointer 18542 to the second slot. */ 18543 rtx ssp_slot = adjust_address (operands[0], word_mode, 0); 18544 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD); 18545 rtx ssp = gen_reg_rtx (word_mode); 18546 emit_insn ((word_mode == SImode) 18547 ? gen_rdsspsi (ssp) 18548 : gen_rdsspdi (ssp)); 18549 emit_move_insn (ssp_slot, ssp); 18550 } 18551 else 18552 stack_slot = adjust_address (operands[0], Pmode, 0); 18553 emit_move_insn (stack_slot, operands[1]); 18554 DONE; 18555}) 18556 18557(define_expand "restore_stack_nonlocal" 18558 [(set (match_operand 0 "register_operand" "") 18559 (match_operand 1 "memory_operand" ""))] 18560 "" 18561{ 18562 rtx stack_slot; 18563 if ((flag_cf_protection & CF_RETURN)) 18564 { 18565 /* Restore shadow stack pointer from the first slot and stack 18566 pointer from the second slot. */ 18567 rtx ssp_slot = adjust_address (operands[1], word_mode, 0); 18568 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD); 18569 18570 rtx flags, jump, noadj_label, inc_label, loop_label; 18571 rtx reg_adj, reg_ssp, tmp, clob; 18572 18573 /* Get the current shadow stack pointer. The code below will check if 18574 SHSTK feature is enabled. If it is not enabled the RDSSP instruction 18575 is a NOP. */ 18576 reg_ssp = gen_reg_rtx (word_mode); 18577 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx)); 18578 emit_insn ((word_mode == SImode) 18579 ? gen_rdsspsi (reg_ssp) 18580 : gen_rdsspdi (reg_ssp)); 18581 18582 /* Compare through substraction the saved and the current ssp to decide 18583 if ssp has to be adjusted. */ 18584 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp, 18585 ssp_slot)); 18586 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18587 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18588 emit_insn (tmp); 18589 18590 /* Compare and jump over adjustment code. */ 18591 noadj_label = gen_label_rtx (); 18592 flags = gen_rtx_REG (CCZmode, FLAGS_REG); 18593 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx); 18594 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18595 gen_rtx_LABEL_REF (VOIDmode, noadj_label), 18596 pc_rtx); 18597 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18598 JUMP_LABEL (jump) = noadj_label; 18599 18600 /* Compute the numebr of frames to adjust. */ 18601 reg_adj = gen_lowpart (ptr_mode, reg_ssp); 18602 tmp = gen_rtx_SET (reg_adj, 18603 gen_rtx_LSHIFTRT (ptr_mode, 18604 negate_rtx (ptr_mode, reg_adj), 18605 GEN_INT ((word_mode == SImode) 18606 ? 2 18607 : 3))); 18608 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18609 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18610 emit_insn (tmp); 18611 18612 /* Check if number of frames <= 255 so no loop is needed. */ 18613 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255)); 18614 flags = gen_rtx_REG (CCmode, FLAGS_REG); 18615 emit_insn (gen_rtx_SET (flags, tmp)); 18616 18617 inc_label = gen_label_rtx (); 18618 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx); 18619 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18620 gen_rtx_LABEL_REF (VOIDmode, inc_label), 18621 pc_rtx); 18622 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18623 JUMP_LABEL (jump) = inc_label; 18624 18625 rtx reg_255 = gen_reg_rtx (word_mode); 18626 emit_move_insn (reg_255, GEN_INT (255)); 18627 18628 /* Adjust the ssp in a loop. */ 18629 loop_label = gen_label_rtx (); 18630 emit_label (loop_label); 18631 LABEL_NUSES (loop_label) = 1; 18632 18633 emit_insn ((word_mode == SImode) 18634 ? gen_incsspsi (reg_255) 18635 : gen_incsspdi (reg_255)); 18636 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode, 18637 reg_adj, 18638 GEN_INT (255))); 18639 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18640 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18641 emit_insn (tmp); 18642 18643 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255)); 18644 flags = gen_rtx_REG (CCmode, FLAGS_REG); 18645 emit_insn (gen_rtx_SET (flags, tmp)); 18646 18647 /* Jump to the loop label. */ 18648 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx); 18649 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18650 gen_rtx_LABEL_REF (VOIDmode, loop_label), 18651 pc_rtx); 18652 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18653 JUMP_LABEL (jump) = loop_label; 18654 18655 emit_label (inc_label); 18656 LABEL_NUSES (inc_label) = 1; 18657 emit_insn ((word_mode == SImode) 18658 ? gen_incsspsi (reg_ssp) 18659 : gen_incsspdi (reg_ssp)); 18660 18661 emit_label (noadj_label); 18662 LABEL_NUSES (noadj_label) = 1; 18663 } 18664 else 18665 stack_slot = adjust_address (operands[1], Pmode, 0); 18666 emit_move_insn (operands[0], stack_slot); 18667 DONE; 18668}) 18669 18670 18671;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 18672;; Do not split instructions with mask registers. 18673(define_split 18674 [(set (match_operand 0 "general_reg_operand") 18675 (match_operator 3 "promotable_binary_operator" 18676 [(match_operand 1 "general_reg_operand") 18677 (match_operand 2 "aligned_operand")])) 18678 (clobber (reg:CC FLAGS_REG))] 18679 "! TARGET_PARTIAL_REG_STALL && reload_completed 18680 && ((GET_MODE (operands[0]) == HImode 18681 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX) 18682 /* ??? next two lines just !satisfies_constraint_K (...) */ 18683 || !CONST_INT_P (operands[2]) 18684 || satisfies_constraint_K (operands[2]))) 18685 || (GET_MODE (operands[0]) == QImode 18686 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))" 18687 [(parallel [(set (match_dup 0) 18688 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 18689 (clobber (reg:CC FLAGS_REG))])] 18690{ 18691 operands[0] = gen_lowpart (SImode, operands[0]); 18692 operands[1] = gen_lowpart (SImode, operands[1]); 18693 if (GET_CODE (operands[3]) != ASHIFT) 18694 operands[2] = gen_lowpart (SImode, operands[2]); 18695 operands[3] = shallow_copy_rtx (operands[3]); 18696 PUT_MODE (operands[3], SImode); 18697}) 18698 18699; Promote the QImode tests, as i386 has encoding of the AND 18700; instruction with 32-bit sign-extended immediate and thus the 18701; instruction size is unchanged, except in the %eax case for 18702; which it is increased by one byte, hence the ! optimize_size. 18703(define_split 18704 [(set (match_operand 0 "flags_reg_operand") 18705 (match_operator 2 "compare_operator" 18706 [(and (match_operand 3 "aligned_operand") 18707 (match_operand 4 "const_int_operand")) 18708 (const_int 0)])) 18709 (set (match_operand 1 "register_operand") 18710 (and (match_dup 3) (match_dup 4)))] 18711 "! TARGET_PARTIAL_REG_STALL && reload_completed 18712 && optimize_insn_for_speed_p () 18713 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 18714 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode)) 18715 /* Ensure that the operand will remain sign-extended immediate. */ 18716 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)" 18717 [(parallel [(set (match_dup 0) 18718 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 18719 (const_int 0)])) 18720 (set (match_dup 1) 18721 (and:SI (match_dup 3) (match_dup 4)))])] 18722{ 18723 operands[4] 18724 = gen_int_mode (INTVAL (operands[4]) 18725 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 18726 operands[1] = gen_lowpart (SImode, operands[1]); 18727 operands[3] = gen_lowpart (SImode, operands[3]); 18728}) 18729 18730; Don't promote the QImode tests, as i386 doesn't have encoding of 18731; the TEST instruction with 32-bit sign-extended immediate and thus 18732; the instruction size would at least double, which is not what we 18733; want even with ! optimize_size. 18734(define_split 18735 [(set (match_operand 0 "flags_reg_operand") 18736 (match_operator 1 "compare_operator" 18737 [(and (match_operand:HI 2 "aligned_operand") 18738 (match_operand:HI 3 "const_int_operand")) 18739 (const_int 0)]))] 18740 "! TARGET_PARTIAL_REG_STALL && reload_completed 18741 && ! TARGET_FAST_PREFIX 18742 && optimize_insn_for_speed_p () 18743 /* Ensure that the operand will remain sign-extended immediate. */ 18744 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)" 18745 [(set (match_dup 0) 18746 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 18747 (const_int 0)]))] 18748{ 18749 operands[3] 18750 = gen_int_mode (INTVAL (operands[3]) 18751 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 18752 operands[2] = gen_lowpart (SImode, operands[2]); 18753}) 18754 18755(define_split 18756 [(set (match_operand 0 "register_operand") 18757 (neg (match_operand 1 "register_operand"))) 18758 (clobber (reg:CC FLAGS_REG))] 18759 "! TARGET_PARTIAL_REG_STALL && reload_completed 18760 && (GET_MODE (operands[0]) == HImode 18761 || (GET_MODE (operands[0]) == QImode 18762 && (TARGET_PROMOTE_QImode 18763 || optimize_insn_for_size_p ())))" 18764 [(parallel [(set (match_dup 0) 18765 (neg:SI (match_dup 1))) 18766 (clobber (reg:CC FLAGS_REG))])] 18767{ 18768 operands[0] = gen_lowpart (SImode, operands[0]); 18769 operands[1] = gen_lowpart (SImode, operands[1]); 18770}) 18771 18772;; Do not split instructions with mask regs. 18773(define_split 18774 [(set (match_operand 0 "general_reg_operand") 18775 (not (match_operand 1 "general_reg_operand")))] 18776 "! TARGET_PARTIAL_REG_STALL && reload_completed 18777 && (GET_MODE (operands[0]) == HImode 18778 || (GET_MODE (operands[0]) == QImode 18779 && (TARGET_PROMOTE_QImode 18780 || optimize_insn_for_size_p ())))" 18781 [(set (match_dup 0) 18782 (not:SI (match_dup 1)))] 18783{ 18784 operands[0] = gen_lowpart (SImode, operands[0]); 18785 operands[1] = gen_lowpart (SImode, operands[1]); 18786}) 18787 18788;; RTL Peephole optimizations, run before sched2. These primarily look to 18789;; transform a complex memory operation into two memory to register operations. 18790 18791;; Don't push memory operands 18792(define_peephole2 18793 [(set (match_operand:SWI 0 "push_operand") 18794 (match_operand:SWI 1 "memory_operand")) 18795 (match_scratch:SWI 2 "<r>")] 18796 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 18797 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 18798 [(set (match_dup 2) (match_dup 1)) 18799 (set (match_dup 0) (match_dup 2))]) 18800 18801;; We need to handle SFmode only, because DFmode and XFmode are split to 18802;; SImode pushes. 18803(define_peephole2 18804 [(set (match_operand:SF 0 "push_operand") 18805 (match_operand:SF 1 "memory_operand")) 18806 (match_scratch:SF 2 "r")] 18807 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 18808 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 18809 [(set (match_dup 2) (match_dup 1)) 18810 (set (match_dup 0) (match_dup 2))]) 18811 18812;; Don't move an immediate directly to memory when the instruction 18813;; gets too big, or if LCP stalls are a problem for 16-bit moves. 18814(define_peephole2 18815 [(match_scratch:SWI124 1 "<r>") 18816 (set (match_operand:SWI124 0 "memory_operand") 18817 (const_int 0))] 18818 "optimize_insn_for_speed_p () 18819 && ((<MODE>mode == HImode 18820 && TARGET_LCP_STALL) 18821 || (!TARGET_USE_MOV0 18822 && TARGET_SPLIT_LONG_MOVES 18823 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn)) 18824 && peep2_regno_dead_p (0, FLAGS_REG)" 18825 [(parallel [(set (match_dup 2) (const_int 0)) 18826 (clobber (reg:CC FLAGS_REG))]) 18827 (set (match_dup 0) (match_dup 1))] 18828 "operands[2] = gen_lowpart (SImode, operands[1]);") 18829 18830(define_peephole2 18831 [(match_scratch:SWI124 2 "<r>") 18832 (set (match_operand:SWI124 0 "memory_operand") 18833 (match_operand:SWI124 1 "immediate_operand"))] 18834 "optimize_insn_for_speed_p () 18835 && ((<MODE>mode == HImode 18836 && TARGET_LCP_STALL) 18837 || (TARGET_SPLIT_LONG_MOVES 18838 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))" 18839 [(set (match_dup 2) (match_dup 1)) 18840 (set (match_dup 0) (match_dup 2))]) 18841 18842;; Don't compare memory with zero, load and use a test instead. 18843(define_peephole2 18844 [(set (match_operand 0 "flags_reg_operand") 18845 (match_operator 1 "compare_operator" 18846 [(match_operand:SI 2 "memory_operand") 18847 (const_int 0)])) 18848 (match_scratch:SI 3 "r")] 18849 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)" 18850 [(set (match_dup 3) (match_dup 2)) 18851 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]) 18852 18853;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 18854;; Don't split NOTs with a displacement operand, because resulting XOR 18855;; will not be pairable anyway. 18856;; 18857;; On AMD K6, NOT is vector decoded with memory operand that cannot be 18858;; represented using a modRM byte. The XOR replacement is long decoded, 18859;; so this split helps here as well. 18860;; 18861;; Note: Can't do this as a regular split because we can't get proper 18862;; lifetime information then. 18863 18864(define_peephole2 18865 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand") 18866 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))] 18867 "optimize_insn_for_speed_p () 18868 && ((TARGET_NOT_UNPAIRABLE 18869 && (!MEM_P (operands[0]) 18870 || !memory_displacement_operand (operands[0], <MODE>mode))) 18871 || (TARGET_NOT_VECTORMODE 18872 && long_memory_operand (operands[0], <MODE>mode))) 18873 && peep2_regno_dead_p (0, FLAGS_REG)" 18874 [(parallel [(set (match_dup 0) 18875 (xor:SWI124 (match_dup 1) (const_int -1))) 18876 (clobber (reg:CC FLAGS_REG))])]) 18877 18878;; Non pairable "test imm, reg" instructions can be translated to 18879;; "and imm, reg" if reg dies. The "and" form is also shorter (one 18880;; byte opcode instead of two, have a short form for byte operands), 18881;; so do it for other CPUs as well. Given that the value was dead, 18882;; this should not create any new dependencies. Pass on the sub-word 18883;; versions if we're concerned about partial register stalls. 18884 18885(define_peephole2 18886 [(set (match_operand 0 "flags_reg_operand") 18887 (match_operator 1 "compare_operator" 18888 [(and:SI (match_operand:SI 2 "register_operand") 18889 (match_operand:SI 3 "immediate_operand")) 18890 (const_int 0)]))] 18891 "ix86_match_ccmode (insn, CCNOmode) 18892 && (REGNO (operands[2]) != AX_REG 18893 || satisfies_constraint_K (operands[3])) 18894 && peep2_reg_dead_p (1, operands[2])" 18895 [(parallel 18896 [(set (match_dup 0) 18897 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 18898 (const_int 0)])) 18899 (set (match_dup 2) 18900 (and:SI (match_dup 2) (match_dup 3)))])]) 18901 18902;; We don't need to handle HImode case, because it will be promoted to SImode 18903;; on ! TARGET_PARTIAL_REG_STALL 18904 18905(define_peephole2 18906 [(set (match_operand 0 "flags_reg_operand") 18907 (match_operator 1 "compare_operator" 18908 [(and:QI (match_operand:QI 2 "register_operand") 18909 (match_operand:QI 3 "immediate_operand")) 18910 (const_int 0)]))] 18911 "! TARGET_PARTIAL_REG_STALL 18912 && ix86_match_ccmode (insn, CCNOmode) 18913 && REGNO (operands[2]) != AX_REG 18914 && peep2_reg_dead_p (1, operands[2])" 18915 [(parallel 18916 [(set (match_dup 0) 18917 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 18918 (const_int 0)])) 18919 (set (match_dup 2) 18920 (and:QI (match_dup 2) (match_dup 3)))])]) 18921 18922(define_peephole2 18923 [(set (match_operand 0 "flags_reg_operand") 18924 (match_operator 1 "compare_operator" 18925 [(and:QI 18926 (subreg:QI 18927 (zero_extract:SI (match_operand 2 "QIreg_operand") 18928 (const_int 8) 18929 (const_int 8)) 0) 18930 (match_operand 3 "const_int_operand")) 18931 (const_int 0)]))] 18932 "! TARGET_PARTIAL_REG_STALL 18933 && ix86_match_ccmode (insn, CCNOmode) 18934 && REGNO (operands[2]) != AX_REG 18935 && peep2_reg_dead_p (1, operands[2])" 18936 [(parallel 18937 [(set (match_dup 0) 18938 (match_op_dup 1 18939 [(and:QI 18940 (subreg:QI 18941 (zero_extract:SI (match_dup 2) 18942 (const_int 8) 18943 (const_int 8)) 0) 18944 (match_dup 3)) 18945 (const_int 0)])) 18946 (set (zero_extract:SI (match_dup 2) 18947 (const_int 8) 18948 (const_int 8)) 18949 (subreg:SI 18950 (and:QI 18951 (subreg:QI 18952 (zero_extract:SI (match_dup 2) 18953 (const_int 8) 18954 (const_int 8)) 0) 18955 (match_dup 3)) 0))])]) 18956 18957;; Don't do logical operations with memory inputs. 18958(define_peephole2 18959 [(match_scratch:SWI 2 "<r>") 18960 (parallel [(set (match_operand:SWI 0 "register_operand") 18961 (match_operator:SWI 3 "arith_or_logical_operator" 18962 [(match_dup 0) 18963 (match_operand:SWI 1 "memory_operand")])) 18964 (clobber (reg:CC FLAGS_REG))])] 18965 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 18966 [(set (match_dup 2) (match_dup 1)) 18967 (parallel [(set (match_dup 0) 18968 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 18969 (clobber (reg:CC FLAGS_REG))])]) 18970 18971(define_peephole2 18972 [(match_scratch:SWI 2 "<r>") 18973 (parallel [(set (match_operand:SWI 0 "register_operand") 18974 (match_operator:SWI 3 "arith_or_logical_operator" 18975 [(match_operand:SWI 1 "memory_operand") 18976 (match_dup 0)])) 18977 (clobber (reg:CC FLAGS_REG))])] 18978 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 18979 [(set (match_dup 2) (match_dup 1)) 18980 (parallel [(set (match_dup 0) 18981 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 18982 (clobber (reg:CC FLAGS_REG))])]) 18983 18984;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when 18985;; the memory address refers to the destination of the load! 18986 18987(define_peephole2 18988 [(set (match_operand:SWI 0 "general_reg_operand") 18989 (match_operand:SWI 1 "general_reg_operand")) 18990 (parallel [(set (match_dup 0) 18991 (match_operator:SWI 3 "commutative_operator" 18992 [(match_dup 0) 18993 (match_operand:SWI 2 "memory_operand")])) 18994 (clobber (reg:CC FLAGS_REG))])] 18995 "REGNO (operands[0]) != REGNO (operands[1]) 18996 && (<MODE>mode != QImode 18997 || any_QIreg_operand (operands[1], QImode))" 18998 [(set (match_dup 0) (match_dup 4)) 18999 (parallel [(set (match_dup 0) 19000 (match_op_dup 3 [(match_dup 0) (match_dup 1)])) 19001 (clobber (reg:CC FLAGS_REG))])] 19002 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);") 19003 19004(define_peephole2 19005 [(set (match_operand 0 "mmx_reg_operand") 19006 (match_operand 1 "mmx_reg_operand")) 19007 (set (match_dup 0) 19008 (match_operator 3 "commutative_operator" 19009 [(match_dup 0) 19010 (match_operand 2 "memory_operand")]))] 19011 "REGNO (operands[0]) != REGNO (operands[1])" 19012 [(set (match_dup 0) (match_dup 2)) 19013 (set (match_dup 0) 19014 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 19015 19016(define_peephole2 19017 [(set (match_operand 0 "sse_reg_operand") 19018 (match_operand 1 "sse_reg_operand")) 19019 (set (match_dup 0) 19020 (match_operator 3 "commutative_operator" 19021 [(match_dup 0) 19022 (match_operand 2 "memory_operand")]))] 19023 "REGNO (operands[0]) != REGNO (operands[1])" 19024 [(set (match_dup 0) (match_dup 2)) 19025 (set (match_dup 0) 19026 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 19027 19028; Don't do logical operations with memory outputs 19029; 19030; These two don't make sense for PPro/PII -- we're expanding a 4-uop 19031; instruction into two 1-uop insns plus a 2-uop insn. That last has 19032; the same decoder scheduling characteristics as the original. 19033 19034(define_peephole2 19035 [(match_scratch:SWI 2 "<r>") 19036 (parallel [(set (match_operand:SWI 0 "memory_operand") 19037 (match_operator:SWI 3 "arith_or_logical_operator" 19038 [(match_dup 0) 19039 (match_operand:SWI 1 "<nonmemory_operand>")])) 19040 (clobber (reg:CC FLAGS_REG))])] 19041 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())" 19042 [(set (match_dup 2) (match_dup 0)) 19043 (parallel [(set (match_dup 2) 19044 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 19045 (clobber (reg:CC FLAGS_REG))]) 19046 (set (match_dup 0) (match_dup 2))]) 19047 19048(define_peephole2 19049 [(match_scratch:SWI 2 "<r>") 19050 (parallel [(set (match_operand:SWI 0 "memory_operand") 19051 (match_operator:SWI 3 "arith_or_logical_operator" 19052 [(match_operand:SWI 1 "<nonmemory_operand>") 19053 (match_dup 0)])) 19054 (clobber (reg:CC FLAGS_REG))])] 19055 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())" 19056 [(set (match_dup 2) (match_dup 0)) 19057 (parallel [(set (match_dup 2) 19058 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19059 (clobber (reg:CC FLAGS_REG))]) 19060 (set (match_dup 0) (match_dup 2))]) 19061 19062;; Attempt to use arith or logical operations with memory outputs with 19063;; setting of flags. 19064(define_peephole2 19065 [(set (match_operand:SWI 0 "register_operand") 19066 (match_operand:SWI 1 "memory_operand")) 19067 (parallel [(set (match_dup 0) 19068 (match_operator:SWI 3 "plusminuslogic_operator" 19069 [(match_dup 0) 19070 (match_operand:SWI 2 "<nonmemory_operand>")])) 19071 (clobber (reg:CC FLAGS_REG))]) 19072 (set (match_dup 1) (match_dup 0)) 19073 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19074 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19075 && peep2_reg_dead_p (4, operands[0]) 19076 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19077 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19078 && (<MODE>mode != QImode 19079 || immediate_operand (operands[2], QImode) 19080 || any_QIreg_operand (operands[2], QImode)) 19081 && ix86_match_ccmode (peep2_next_insn (3), 19082 (GET_CODE (operands[3]) == PLUS 19083 || GET_CODE (operands[3]) == MINUS) 19084 ? CCGOCmode : CCNOmode)" 19085 [(parallel [(set (match_dup 4) (match_dup 6)) 19086 (set (match_dup 1) (match_dup 5))])] 19087{ 19088 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19089 operands[5] 19090 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19091 copy_rtx (operands[1]), 19092 operands[2]); 19093 operands[6] 19094 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19095 copy_rtx (operands[5]), 19096 const0_rtx); 19097}) 19098 19099;; Likewise for cmpelim optimized pattern. 19100(define_peephole2 19101 [(set (match_operand:SWI 0 "register_operand") 19102 (match_operand:SWI 1 "memory_operand")) 19103 (parallel [(set (reg FLAGS_REG) 19104 (compare (match_operator:SWI 3 "plusminuslogic_operator" 19105 [(match_dup 0) 19106 (match_operand:SWI 2 "<nonmemory_operand>")]) 19107 (const_int 0))) 19108 (set (match_dup 0) (match_dup 3))]) 19109 (set (match_dup 1) (match_dup 0))] 19110 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19111 && peep2_reg_dead_p (3, operands[0]) 19112 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19113 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19114 && ix86_match_ccmode (peep2_next_insn (1), 19115 (GET_CODE (operands[3]) == PLUS 19116 || GET_CODE (operands[3]) == MINUS) 19117 ? CCGOCmode : CCNOmode)" 19118 [(parallel [(set (match_dup 4) (match_dup 6)) 19119 (set (match_dup 1) (match_dup 5))])] 19120{ 19121 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0)); 19122 operands[5] 19123 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19124 copy_rtx (operands[1]), operands[2]); 19125 operands[6] 19126 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]), 19127 const0_rtx); 19128}) 19129 19130;; Likewise for instances where we have a lea pattern. 19131(define_peephole2 19132 [(set (match_operand:SWI 0 "register_operand") 19133 (match_operand:SWI 1 "memory_operand")) 19134 (set (match_operand:SWI 3 "register_operand") 19135 (plus:SWI (match_dup 0) 19136 (match_operand:SWI 2 "<nonmemory_operand>"))) 19137 (set (match_dup 1) (match_dup 3)) 19138 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))] 19139 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19140 && peep2_reg_dead_p (4, operands[3]) 19141 && (rtx_equal_p (operands[0], operands[3]) 19142 || peep2_reg_dead_p (2, operands[0])) 19143 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19144 && !reg_overlap_mentioned_p (operands[3], operands[1]) 19145 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19146 && (<MODE>mode != QImode 19147 || immediate_operand (operands[2], QImode) 19148 || any_QIreg_operand (operands[2], QImode)) 19149 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)" 19150 [(parallel [(set (match_dup 4) (match_dup 6)) 19151 (set (match_dup 1) (match_dup 5))])] 19152{ 19153 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19154 operands[5] 19155 = gen_rtx_PLUS (<MODE>mode, 19156 copy_rtx (operands[1]), 19157 operands[2]); 19158 operands[6] 19159 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19160 copy_rtx (operands[5]), 19161 const0_rtx); 19162}) 19163 19164(define_peephole2 19165 [(parallel [(set (match_operand:SWI 0 "register_operand") 19166 (match_operator:SWI 2 "plusminuslogic_operator" 19167 [(match_dup 0) 19168 (match_operand:SWI 1 "memory_operand")])) 19169 (clobber (reg:CC FLAGS_REG))]) 19170 (set (match_dup 1) (match_dup 0)) 19171 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19172 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19173 && COMMUTATIVE_ARITH_P (operands[2]) 19174 && peep2_reg_dead_p (3, operands[0]) 19175 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19176 && ix86_match_ccmode (peep2_next_insn (2), 19177 GET_CODE (operands[2]) == PLUS 19178 ? CCGOCmode : CCNOmode)" 19179 [(parallel [(set (match_dup 3) (match_dup 5)) 19180 (set (match_dup 1) (match_dup 4))])] 19181{ 19182 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); 19183 operands[4] 19184 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19185 copy_rtx (operands[1]), 19186 operands[0]); 19187 operands[5] 19188 = gen_rtx_COMPARE (GET_MODE (operands[3]), 19189 copy_rtx (operands[4]), 19190 const0_rtx); 19191}) 19192 19193;; Likewise for cmpelim optimized pattern. 19194(define_peephole2 19195 [(parallel [(set (reg FLAGS_REG) 19196 (compare (match_operator:SWI 2 "plusminuslogic_operator" 19197 [(match_operand:SWI 0 "register_operand") 19198 (match_operand:SWI 1 "memory_operand")]) 19199 (const_int 0))) 19200 (set (match_dup 0) (match_dup 2))]) 19201 (set (match_dup 1) (match_dup 0))] 19202 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19203 && COMMUTATIVE_ARITH_P (operands[2]) 19204 && peep2_reg_dead_p (2, operands[0]) 19205 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19206 && ix86_match_ccmode (peep2_next_insn (0), 19207 GET_CODE (operands[2]) == PLUS 19208 ? CCGOCmode : CCNOmode)" 19209 [(parallel [(set (match_dup 3) (match_dup 5)) 19210 (set (match_dup 1) (match_dup 4))])] 19211{ 19212 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0)); 19213 operands[4] 19214 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19215 copy_rtx (operands[1]), operands[0]); 19216 operands[5] 19217 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]), 19218 const0_rtx); 19219}) 19220 19221(define_peephole2 19222 [(set (match_operand:SWI12 0 "register_operand") 19223 (match_operand:SWI12 1 "memory_operand")) 19224 (parallel [(set (match_operand:SI 4 "register_operand") 19225 (match_operator:SI 3 "plusminuslogic_operator" 19226 [(match_dup 4) 19227 (match_operand:SI 2 "nonmemory_operand")])) 19228 (clobber (reg:CC FLAGS_REG))]) 19229 (set (match_dup 1) (match_dup 0)) 19230 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19231 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19232 && REGNO (operands[0]) == REGNO (operands[4]) 19233 && peep2_reg_dead_p (4, operands[0]) 19234 && (<MODE>mode != QImode 19235 || immediate_operand (operands[2], SImode) 19236 || any_QIreg_operand (operands[2], SImode)) 19237 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19238 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19239 && ix86_match_ccmode (peep2_next_insn (3), 19240 (GET_CODE (operands[3]) == PLUS 19241 || GET_CODE (operands[3]) == MINUS) 19242 ? CCGOCmode : CCNOmode)" 19243 [(parallel [(set (match_dup 4) (match_dup 6)) 19244 (set (match_dup 1) (match_dup 5))])] 19245{ 19246 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19247 operands[5] 19248 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 19249 copy_rtx (operands[1]), 19250 gen_lowpart (<MODE>mode, operands[2])); 19251 operands[6] 19252 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19253 copy_rtx (operands[5]), 19254 const0_rtx); 19255}) 19256 19257;; Attempt to always use XOR for zeroing registers (including FP modes). 19258(define_peephole2 19259 [(set (match_operand 0 "general_reg_operand") 19260 (match_operand 1 "const0_operand"))] 19261 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 19262 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 19263 && peep2_regno_dead_p (0, FLAGS_REG)" 19264 [(parallel [(set (match_dup 0) (const_int 0)) 19265 (clobber (reg:CC FLAGS_REG))])] 19266 "operands[0] = gen_lowpart (word_mode, operands[0]);") 19267 19268(define_peephole2 19269 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand")) 19270 (const_int 0))] 19271 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 19272 && peep2_regno_dead_p (0, FLAGS_REG)" 19273 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 19274 (clobber (reg:CC FLAGS_REG))])]) 19275 19276;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg. 19277(define_peephole2 19278 [(set (match_operand:SWI248 0 "general_reg_operand") 19279 (const_int -1))] 19280 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ()) 19281 && peep2_regno_dead_p (0, FLAGS_REG)" 19282 [(parallel [(set (match_dup 0) (const_int -1)) 19283 (clobber (reg:CC FLAGS_REG))])] 19284{ 19285 if (<MODE_SIZE> < GET_MODE_SIZE (SImode)) 19286 operands[0] = gen_lowpart (SImode, operands[0]); 19287}) 19288 19289;; Attempt to convert simple lea to add/shift. 19290;; These can be created by move expanders. 19291;; Disable PLUS peepholes on TARGET_OPT_AGU, since all 19292;; relevant lea instructions were already split. 19293 19294(define_peephole2 19295 [(set (match_operand:SWI48 0 "register_operand") 19296 (plus:SWI48 (match_dup 0) 19297 (match_operand:SWI48 1 "<nonmemory_operand>")))] 19298 "!TARGET_OPT_AGU 19299 && peep2_regno_dead_p (0, FLAGS_REG)" 19300 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 19301 (clobber (reg:CC FLAGS_REG))])]) 19302 19303(define_peephole2 19304 [(set (match_operand:SWI48 0 "register_operand") 19305 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>") 19306 (match_dup 0)))] 19307 "!TARGET_OPT_AGU 19308 && peep2_regno_dead_p (0, FLAGS_REG)" 19309 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 19310 (clobber (reg:CC FLAGS_REG))])]) 19311 19312(define_peephole2 19313 [(set (match_operand:DI 0 "register_operand") 19314 (zero_extend:DI 19315 (plus:SI (match_operand:SI 1 "register_operand") 19316 (match_operand:SI 2 "nonmemory_operand"))))] 19317 "TARGET_64BIT && !TARGET_OPT_AGU 19318 && REGNO (operands[0]) == REGNO (operands[1]) 19319 && peep2_regno_dead_p (0, FLAGS_REG)" 19320 [(parallel [(set (match_dup 0) 19321 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))) 19322 (clobber (reg:CC FLAGS_REG))])]) 19323 19324(define_peephole2 19325 [(set (match_operand:DI 0 "register_operand") 19326 (zero_extend:DI 19327 (plus:SI (match_operand:SI 1 "nonmemory_operand") 19328 (match_operand:SI 2 "register_operand"))))] 19329 "TARGET_64BIT && !TARGET_OPT_AGU 19330 && REGNO (operands[0]) == REGNO (operands[2]) 19331 && peep2_regno_dead_p (0, FLAGS_REG)" 19332 [(parallel [(set (match_dup 0) 19333 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1)))) 19334 (clobber (reg:CC FLAGS_REG))])]) 19335 19336(define_peephole2 19337 [(set (match_operand:SWI48 0 "register_operand") 19338 (mult:SWI48 (match_dup 0) 19339 (match_operand:SWI48 1 "const_int_operand")))] 19340 "pow2p_hwi (INTVAL (operands[1])) 19341 && peep2_regno_dead_p (0, FLAGS_REG)" 19342 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1))) 19343 (clobber (reg:CC FLAGS_REG))])] 19344 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 19345 19346(define_peephole2 19347 [(set (match_operand:DI 0 "register_operand") 19348 (zero_extend:DI 19349 (mult:SI (match_operand:SI 1 "register_operand") 19350 (match_operand:SI 2 "const_int_operand"))))] 19351 "TARGET_64BIT 19352 && pow2p_hwi (INTVAL (operands[2])) 19353 && REGNO (operands[0]) == REGNO (operands[1]) 19354 && peep2_regno_dead_p (0, FLAGS_REG)" 19355 [(parallel [(set (match_dup 0) 19356 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2)))) 19357 (clobber (reg:CC FLAGS_REG))])] 19358 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 19359 19360;; The ESP adjustments can be done by the push and pop instructions. Resulting 19361;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes. 19362;; On many CPUs it is also faster, since special hardware to avoid esp 19363;; dependencies is present. 19364 19365;; While some of these conversions may be done using splitters, we use 19366;; peepholes in order to allow combine_stack_adjustments pass to see 19367;; nonobfuscated RTL. 19368 19369;; Convert prologue esp subtractions to push. 19370;; We need register to push. In order to keep verify_flow_info happy we have 19371;; two choices 19372;; - use scratch and clobber it in order to avoid dependencies 19373;; - use already live register 19374;; We can't use the second way right now, since there is no reliable way how to 19375;; verify that given register is live. First choice will also most likely in 19376;; fewer dependencies. On the place of esp adjustments it is very likely that 19377;; call clobbered registers are dead. We may want to use base pointer as an 19378;; alternative when no register is available later. 19379 19380(define_peephole2 19381 [(match_scratch:W 1 "r") 19382 (parallel [(set (reg:P SP_REG) 19383 (plus:P (reg:P SP_REG) 19384 (match_operand:P 0 "const_int_operand"))) 19385 (clobber (reg:CC FLAGS_REG)) 19386 (clobber (mem:BLK (scratch)))])] 19387 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 19388 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) 19389 && ix86_red_zone_size == 0" 19390 [(clobber (match_dup 1)) 19391 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19392 (clobber (mem:BLK (scratch)))])]) 19393 19394(define_peephole2 19395 [(match_scratch:W 1 "r") 19396 (parallel [(set (reg:P SP_REG) 19397 (plus:P (reg:P SP_REG) 19398 (match_operand:P 0 "const_int_operand"))) 19399 (clobber (reg:CC FLAGS_REG)) 19400 (clobber (mem:BLK (scratch)))])] 19401 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 19402 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) 19403 && ix86_red_zone_size == 0" 19404 [(clobber (match_dup 1)) 19405 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19406 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19407 (clobber (mem:BLK (scratch)))])]) 19408 19409;; Convert esp subtractions to push. 19410(define_peephole2 19411 [(match_scratch:W 1 "r") 19412 (parallel [(set (reg:P SP_REG) 19413 (plus:P (reg:P SP_REG) 19414 (match_operand:P 0 "const_int_operand"))) 19415 (clobber (reg:CC FLAGS_REG))])] 19416 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 19417 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) 19418 && ix86_red_zone_size == 0" 19419 [(clobber (match_dup 1)) 19420 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 19421 19422(define_peephole2 19423 [(match_scratch:W 1 "r") 19424 (parallel [(set (reg:P SP_REG) 19425 (plus:P (reg:P SP_REG) 19426 (match_operand:P 0 "const_int_operand"))) 19427 (clobber (reg:CC FLAGS_REG))])] 19428 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 19429 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) 19430 && ix86_red_zone_size == 0" 19431 [(clobber (match_dup 1)) 19432 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19433 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 19434 19435;; Convert epilogue deallocator to pop. 19436(define_peephole2 19437 [(match_scratch:W 1 "r") 19438 (parallel [(set (reg:P SP_REG) 19439 (plus:P (reg:P SP_REG) 19440 (match_operand:P 0 "const_int_operand"))) 19441 (clobber (reg:CC FLAGS_REG)) 19442 (clobber (mem:BLK (scratch)))])] 19443 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ()) 19444 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 19445 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19446 (clobber (mem:BLK (scratch)))])]) 19447 19448;; Two pops case is tricky, since pop causes dependency 19449;; on destination register. We use two registers if available. 19450(define_peephole2 19451 [(match_scratch:W 1 "r") 19452 (match_scratch:W 2 "r") 19453 (parallel [(set (reg:P SP_REG) 19454 (plus:P (reg:P SP_REG) 19455 (match_operand:P 0 "const_int_operand"))) 19456 (clobber (reg:CC FLAGS_REG)) 19457 (clobber (mem:BLK (scratch)))])] 19458 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ()) 19459 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19460 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19461 (clobber (mem:BLK (scratch)))]) 19462 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 19463 19464(define_peephole2 19465 [(match_scratch:W 1 "r") 19466 (parallel [(set (reg:P SP_REG) 19467 (plus:P (reg:P SP_REG) 19468 (match_operand:P 0 "const_int_operand"))) 19469 (clobber (reg:CC FLAGS_REG)) 19470 (clobber (mem:BLK (scratch)))])] 19471 "optimize_insn_for_size_p () 19472 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19473 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19474 (clobber (mem:BLK (scratch)))]) 19475 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19476 19477;; Convert esp additions to pop. 19478(define_peephole2 19479 [(match_scratch:W 1 "r") 19480 (parallel [(set (reg:P SP_REG) 19481 (plus:P (reg:P SP_REG) 19482 (match_operand:P 0 "const_int_operand"))) 19483 (clobber (reg:CC FLAGS_REG))])] 19484 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 19485 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19486 19487;; Two pops case is tricky, since pop causes dependency 19488;; on destination register. We use two registers if available. 19489(define_peephole2 19490 [(match_scratch:W 1 "r") 19491 (match_scratch:W 2 "r") 19492 (parallel [(set (reg:P SP_REG) 19493 (plus:P (reg:P SP_REG) 19494 (match_operand:P 0 "const_int_operand"))) 19495 (clobber (reg:CC FLAGS_REG))])] 19496 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19497 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19498 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 19499 19500(define_peephole2 19501 [(match_scratch:W 1 "r") 19502 (parallel [(set (reg:P SP_REG) 19503 (plus:P (reg:P SP_REG) 19504 (match_operand:P 0 "const_int_operand"))) 19505 (clobber (reg:CC FLAGS_REG))])] 19506 "optimize_insn_for_size_p () 19507 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19508 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19509 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19510 19511;; Convert compares with 1 to shorter inc/dec operations when CF is not 19512;; required and register dies. Similarly for 128 to -128. 19513(define_peephole2 19514 [(set (match_operand 0 "flags_reg_operand") 19515 (match_operator 1 "compare_operator" 19516 [(match_operand 2 "register_operand") 19517 (match_operand 3 "const_int_operand")]))] 19518 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ()) 19519 && incdec_operand (operands[3], GET_MODE (operands[3]))) 19520 || (!TARGET_FUSE_CMP_AND_BRANCH 19521 && INTVAL (operands[3]) == 128)) 19522 && ix86_match_ccmode (insn, CCGCmode) 19523 && peep2_reg_dead_p (1, operands[2])" 19524 [(parallel [(set (match_dup 0) 19525 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 19526 (clobber (match_dup 2))])]) 19527 19528;; Convert imul by three, five and nine into lea 19529(define_peephole2 19530 [(parallel 19531 [(set (match_operand:SWI48 0 "register_operand") 19532 (mult:SWI48 (match_operand:SWI48 1 "register_operand") 19533 (match_operand:SWI48 2 "const359_operand"))) 19534 (clobber (reg:CC FLAGS_REG))])] 19535 "!TARGET_PARTIAL_REG_STALL 19536 || <MODE>mode == SImode 19537 || optimize_function_for_size_p (cfun)" 19538 [(set (match_dup 0) 19539 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2)) 19540 (match_dup 1)))] 19541 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 19542 19543(define_peephole2 19544 [(parallel 19545 [(set (match_operand:SWI48 0 "register_operand") 19546 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 19547 (match_operand:SWI48 2 "const359_operand"))) 19548 (clobber (reg:CC FLAGS_REG))])] 19549 "optimize_insn_for_speed_p () 19550 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)" 19551 [(set (match_dup 0) (match_dup 1)) 19552 (set (match_dup 0) 19553 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2)) 19554 (match_dup 0)))] 19555 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 19556 19557;; imul $32bit_imm, mem, reg is vector decoded, while 19558;; imul $32bit_imm, reg, reg is direct decoded. 19559(define_peephole2 19560 [(match_scratch:SWI48 3 "r") 19561 (parallel [(set (match_operand:SWI48 0 "register_operand") 19562 (mult:SWI48 (match_operand:SWI48 1 "memory_operand") 19563 (match_operand:SWI48 2 "immediate_operand"))) 19564 (clobber (reg:CC FLAGS_REG))])] 19565 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 19566 && !satisfies_constraint_K (operands[2])" 19567 [(set (match_dup 3) (match_dup 1)) 19568 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2))) 19569 (clobber (reg:CC FLAGS_REG))])]) 19570 19571(define_peephole2 19572 [(match_scratch:SI 3 "r") 19573 (parallel [(set (match_operand:DI 0 "register_operand") 19574 (zero_extend:DI 19575 (mult:SI (match_operand:SI 1 "memory_operand") 19576 (match_operand:SI 2 "immediate_operand")))) 19577 (clobber (reg:CC FLAGS_REG))])] 19578 "TARGET_64BIT 19579 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 19580 && !satisfies_constraint_K (operands[2])" 19581 [(set (match_dup 3) (match_dup 1)) 19582 (parallel [(set (match_dup 0) 19583 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 19584 (clobber (reg:CC FLAGS_REG))])]) 19585 19586;; imul $8/16bit_imm, regmem, reg is vector decoded. 19587;; Convert it into imul reg, reg 19588;; It would be better to force assembler to encode instruction using long 19589;; immediate, but there is apparently no way to do so. 19590(define_peephole2 19591 [(parallel [(set (match_operand:SWI248 0 "register_operand") 19592 (mult:SWI248 19593 (match_operand:SWI248 1 "nonimmediate_operand") 19594 (match_operand:SWI248 2 "const_int_operand"))) 19595 (clobber (reg:CC FLAGS_REG))]) 19596 (match_scratch:SWI248 3 "r")] 19597 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () 19598 && satisfies_constraint_K (operands[2])" 19599 [(set (match_dup 3) (match_dup 2)) 19600 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3))) 19601 (clobber (reg:CC FLAGS_REG))])] 19602{ 19603 if (!rtx_equal_p (operands[0], operands[1])) 19604 emit_move_insn (operands[0], operands[1]); 19605}) 19606 19607;; After splitting up read-modify operations, array accesses with memory 19608;; operands might end up in form: 19609;; sall $2, %eax 19610;; movl 4(%esp), %edx 19611;; addl %edx, %eax 19612;; instead of pre-splitting: 19613;; sall $2, %eax 19614;; addl 4(%esp), %eax 19615;; Turn it into: 19616;; movl 4(%esp), %edx 19617;; leal (%edx,%eax,4), %eax 19618 19619(define_peephole2 19620 [(match_scratch:W 5 "r") 19621 (parallel [(set (match_operand 0 "register_operand") 19622 (ashift (match_operand 1 "register_operand") 19623 (match_operand 2 "const_int_operand"))) 19624 (clobber (reg:CC FLAGS_REG))]) 19625 (parallel [(set (match_operand 3 "register_operand") 19626 (plus (match_dup 0) 19627 (match_operand 4 "x86_64_general_operand"))) 19628 (clobber (reg:CC FLAGS_REG))])] 19629 "IN_RANGE (INTVAL (operands[2]), 1, 3) 19630 /* Validate MODE for lea. */ 19631 && ((!TARGET_PARTIAL_REG_STALL 19632 && (GET_MODE (operands[0]) == QImode 19633 || GET_MODE (operands[0]) == HImode)) 19634 || GET_MODE (operands[0]) == SImode 19635 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 19636 && (rtx_equal_p (operands[0], operands[3]) 19637 || peep2_reg_dead_p (2, operands[0])) 19638 /* We reorder load and the shift. */ 19639 && !reg_overlap_mentioned_p (operands[0], operands[4])" 19640 [(set (match_dup 5) (match_dup 4)) 19641 (set (match_dup 0) (match_dup 1))] 19642{ 19643 machine_mode op1mode = GET_MODE (operands[1]); 19644 machine_mode mode = op1mode == DImode ? DImode : SImode; 19645 int scale = 1 << INTVAL (operands[2]); 19646 rtx index = gen_lowpart (word_mode, operands[1]); 19647 rtx base = gen_lowpart (word_mode, operands[5]); 19648 rtx dest = gen_lowpart (mode, operands[3]); 19649 19650 operands[1] = gen_rtx_PLUS (word_mode, base, 19651 gen_rtx_MULT (word_mode, index, GEN_INT (scale))); 19652 if (mode != word_mode) 19653 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 19654 19655 operands[5] = base; 19656 if (op1mode != word_mode) 19657 operands[5] = gen_lowpart (op1mode, operands[5]); 19658 19659 operands[0] = dest; 19660}) 19661 19662;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 19663;; That, however, is usually mapped by the OS to SIGSEGV, which is often 19664;; caught for use by garbage collectors and the like. Using an insn that 19665;; maps to SIGILL makes it more likely the program will rightfully die. 19666;; Keeping with tradition, "6" is in honor of #UD. 19667(define_insn "trap" 19668 [(trap_if (const_int 1) (const_int 6))] 19669 "" 19670{ 19671#ifdef HAVE_AS_IX86_UD2 19672 return "ud2"; 19673#else 19674 return ASM_SHORT "0x0b0f"; 19675#endif 19676} 19677 [(set_attr "length" "2")]) 19678 19679(define_insn "ud2" 19680 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)] 19681 "" 19682{ 19683#ifdef HAVE_AS_IX86_UD2 19684 return "ud2"; 19685#else 19686 return ASM_SHORT "0x0b0f"; 19687#endif 19688} 19689 [(set_attr "length" "2")]) 19690 19691(define_expand "prefetch" 19692 [(prefetch (match_operand 0 "address_operand") 19693 (match_operand:SI 1 "const_int_operand") 19694 (match_operand:SI 2 "const_int_operand"))] 19695 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1" 19696{ 19697 bool write = INTVAL (operands[1]) != 0; 19698 int locality = INTVAL (operands[2]); 19699 19700 gcc_assert (IN_RANGE (locality, 0, 3)); 19701 19702 /* Use 3dNOW prefetch in case we are asking for write prefetch not 19703 supported by SSE counterpart (non-SSE2 athlon machines) or the 19704 SSE prefetch is not available (K6 machines). Otherwise use SSE 19705 prefetch as it allows specifying of locality. */ 19706 19707 if (write) 19708 { 19709 if (TARGET_PREFETCHWT1) 19710 operands[2] = GEN_INT (MAX (locality, 2)); 19711 else if (TARGET_PRFCHW) 19712 operands[2] = GEN_INT (3); 19713 else if (TARGET_3DNOW && !TARGET_SSE2) 19714 operands[2] = GEN_INT (3); 19715 else if (TARGET_PREFETCH_SSE) 19716 operands[1] = const0_rtx; 19717 else 19718 { 19719 gcc_assert (TARGET_3DNOW); 19720 operands[2] = GEN_INT (3); 19721 } 19722 } 19723 else 19724 { 19725 if (TARGET_PREFETCH_SSE) 19726 ; 19727 else 19728 { 19729 gcc_assert (TARGET_3DNOW); 19730 operands[2] = GEN_INT (3); 19731 } 19732 } 19733}) 19734 19735(define_insn "*prefetch_sse" 19736 [(prefetch (match_operand 0 "address_operand" "p") 19737 (const_int 0) 19738 (match_operand:SI 1 "const_int_operand"))] 19739 "TARGET_PREFETCH_SSE" 19740{ 19741 static const char * const patterns[4] = { 19742 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 19743 }; 19744 19745 int locality = INTVAL (operands[1]); 19746 gcc_assert (IN_RANGE (locality, 0, 3)); 19747 19748 return patterns[locality]; 19749} 19750 [(set_attr "type" "sse") 19751 (set_attr "atom_sse_attr" "prefetch") 19752 (set (attr "length_address") 19753 (symbol_ref "memory_address_length (operands[0], false)")) 19754 (set_attr "memory" "none")]) 19755 19756(define_insn "*prefetch_3dnow" 19757 [(prefetch (match_operand 0 "address_operand" "p") 19758 (match_operand:SI 1 "const_int_operand" "n") 19759 (const_int 3))] 19760 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1" 19761{ 19762 if (INTVAL (operands[1]) == 0) 19763 return "prefetch\t%a0"; 19764 else 19765 return "prefetchw\t%a0"; 19766} 19767 [(set_attr "type" "mmx") 19768 (set (attr "length_address") 19769 (symbol_ref "memory_address_length (operands[0], false)")) 19770 (set_attr "memory" "none")]) 19771 19772(define_insn "*prefetch_prefetchwt1" 19773 [(prefetch (match_operand 0 "address_operand" "p") 19774 (const_int 1) 19775 (const_int 2))] 19776 "TARGET_PREFETCHWT1" 19777 "prefetchwt1\t%a0"; 19778 [(set_attr "type" "sse") 19779 (set (attr "length_address") 19780 (symbol_ref "memory_address_length (operands[0], false)")) 19781 (set_attr "memory" "none")]) 19782 19783(define_expand "stack_protect_set" 19784 [(match_operand 0 "memory_operand") 19785 (match_operand 1 "memory_operand")] 19786 "" 19787{ 19788 rtx (*insn)(rtx, rtx); 19789 19790 insn = (TARGET_LP64 19791 ? gen_stack_protect_set_di 19792 : gen_stack_protect_set_si); 19793 19794 emit_insn (insn (operands[0], operands[1])); 19795 DONE; 19796}) 19797 19798(define_insn "stack_protect_set_<mode>" 19799 [(set (match_operand:PTR 0 "memory_operand" "=m") 19800 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] 19801 UNSPEC_SP_SET)) 19802 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 19803 (clobber (reg:CC FLAGS_REG))] 19804 "" 19805 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 19806 [(set_attr "type" "multi")]) 19807 19808(define_expand "stack_protect_test" 19809 [(match_operand 0 "memory_operand") 19810 (match_operand 1 "memory_operand") 19811 (match_operand 2)] 19812 "" 19813{ 19814 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 19815 19816 rtx (*insn)(rtx, rtx, rtx); 19817 19818 insn = (TARGET_LP64 19819 ? gen_stack_protect_test_di 19820 : gen_stack_protect_test_si); 19821 19822 emit_insn (insn (flags, operands[0], operands[1])); 19823 19824 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx), 19825 flags, const0_rtx, operands[2])); 19826 DONE; 19827}) 19828 19829(define_insn "stack_protect_test_<mode>" 19830 [(set (match_operand:CCZ 0 "flags_reg_operand") 19831 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 19832 (match_operand:PTR 2 "memory_operand" "m")] 19833 UNSPEC_SP_TEST)) 19834 (clobber (match_scratch:PTR 3 "=&r"))] 19835 "" 19836 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}" 19837 [(set_attr "type" "multi")]) 19838 19839(define_insn "sse4_2_crc32<mode>" 19840 [(set (match_operand:SI 0 "register_operand" "=r") 19841 (unspec:SI 19842 [(match_operand:SI 1 "register_operand" "0") 19843 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")] 19844 UNSPEC_CRC32))] 19845 "TARGET_SSE4_2 || TARGET_CRC32" 19846 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}" 19847 [(set_attr "type" "sselog1") 19848 (set_attr "prefix_rep" "1") 19849 (set_attr "prefix_extra" "1") 19850 (set (attr "prefix_data16") 19851 (if_then_else (match_operand:HI 2) 19852 (const_string "1") 19853 (const_string "*"))) 19854 (set (attr "prefix_rex") 19855 (if_then_else (match_operand:QI 2 "ext_QIreg_operand") 19856 (const_string "1") 19857 (const_string "*"))) 19858 (set_attr "mode" "SI")]) 19859 19860(define_insn "sse4_2_crc32di" 19861 [(set (match_operand:DI 0 "register_operand" "=r") 19862 (unspec:DI 19863 [(match_operand:DI 1 "register_operand" "0") 19864 (match_operand:DI 2 "nonimmediate_operand" "rm")] 19865 UNSPEC_CRC32))] 19866 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)" 19867 "crc32{q}\t{%2, %0|%0, %2}" 19868 [(set_attr "type" "sselog1") 19869 (set_attr "prefix_rep" "1") 19870 (set_attr "prefix_extra" "1") 19871 (set_attr "mode" "DI")]) 19872 19873(define_insn "rdpmc" 19874 [(set (match_operand:DI 0 "register_operand" "=A") 19875 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 19876 UNSPECV_RDPMC))] 19877 "!TARGET_64BIT" 19878 "rdpmc" 19879 [(set_attr "type" "other") 19880 (set_attr "length" "2")]) 19881 19882(define_insn "rdpmc_rex64" 19883 [(set (match_operand:DI 0 "register_operand" "=a") 19884 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 19885 UNSPECV_RDPMC)) 19886 (set (match_operand:DI 1 "register_operand" "=d") 19887 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))] 19888 "TARGET_64BIT" 19889 "rdpmc" 19890 [(set_attr "type" "other") 19891 (set_attr "length" "2")]) 19892 19893(define_insn "rdtsc" 19894 [(set (match_operand:DI 0 "register_operand" "=A") 19895 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 19896 "!TARGET_64BIT" 19897 "rdtsc" 19898 [(set_attr "type" "other") 19899 (set_attr "length" "2")]) 19900 19901(define_insn "rdtsc_rex64" 19902 [(set (match_operand:DI 0 "register_operand" "=a") 19903 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC)) 19904 (set (match_operand:DI 1 "register_operand" "=d") 19905 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 19906 "TARGET_64BIT" 19907 "rdtsc" 19908 [(set_attr "type" "other") 19909 (set_attr "length" "2")]) 19910 19911(define_insn "rdtscp" 19912 [(set (match_operand:DI 0 "register_operand" "=A") 19913 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19914 (set (match_operand:SI 1 "register_operand" "=c") 19915 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 19916 "!TARGET_64BIT" 19917 "rdtscp" 19918 [(set_attr "type" "other") 19919 (set_attr "length" "3")]) 19920 19921(define_insn "rdtscp_rex64" 19922 [(set (match_operand:DI 0 "register_operand" "=a") 19923 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19924 (set (match_operand:DI 1 "register_operand" "=d") 19925 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19926 (set (match_operand:SI 2 "register_operand" "=c") 19927 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 19928 "TARGET_64BIT" 19929 "rdtscp" 19930 [(set_attr "type" "other") 19931 (set_attr "length" "3")]) 19932 19933;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19934;; 19935;; FXSR, XSAVE and XSAVEOPT instructions 19936;; 19937;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19938 19939(define_insn "fxsave" 19940 [(set (match_operand:BLK 0 "memory_operand" "=m") 19941 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))] 19942 "TARGET_FXSR" 19943 "fxsave\t%0" 19944 [(set_attr "type" "other") 19945 (set_attr "memory" "store") 19946 (set (attr "length") 19947 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19948 19949(define_insn "fxsave64" 19950 [(set (match_operand:BLK 0 "memory_operand" "=m") 19951 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))] 19952 "TARGET_64BIT && TARGET_FXSR" 19953 "fxsave64\t%0" 19954 [(set_attr "type" "other") 19955 (set_attr "memory" "store") 19956 (set (attr "length") 19957 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 19958 19959(define_insn "fxrstor" 19960 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 19961 UNSPECV_FXRSTOR)] 19962 "TARGET_FXSR" 19963 "fxrstor\t%0" 19964 [(set_attr "type" "other") 19965 (set_attr "memory" "load") 19966 (set (attr "length") 19967 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19968 19969(define_insn "fxrstor64" 19970 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 19971 UNSPECV_FXRSTOR64)] 19972 "TARGET_64BIT && TARGET_FXSR" 19973 "fxrstor64\t%0" 19974 [(set_attr "type" "other") 19975 (set_attr "memory" "load") 19976 (set (attr "length") 19977 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 19978 19979(define_int_iterator ANY_XSAVE 19980 [UNSPECV_XSAVE 19981 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT") 19982 (UNSPECV_XSAVEC "TARGET_XSAVEC") 19983 (UNSPECV_XSAVES "TARGET_XSAVES")]) 19984 19985(define_int_iterator ANY_XSAVE64 19986 [UNSPECV_XSAVE64 19987 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT") 19988 (UNSPECV_XSAVEC64 "TARGET_XSAVEC") 19989 (UNSPECV_XSAVES64 "TARGET_XSAVES")]) 19990 19991(define_int_attr xsave 19992 [(UNSPECV_XSAVE "xsave") 19993 (UNSPECV_XSAVE64 "xsave64") 19994 (UNSPECV_XSAVEOPT "xsaveopt") 19995 (UNSPECV_XSAVEOPT64 "xsaveopt64") 19996 (UNSPECV_XSAVEC "xsavec") 19997 (UNSPECV_XSAVEC64 "xsavec64") 19998 (UNSPECV_XSAVES "xsaves") 19999 (UNSPECV_XSAVES64 "xsaves64")]) 20000 20001(define_int_iterator ANY_XRSTOR 20002 [UNSPECV_XRSTOR 20003 (UNSPECV_XRSTORS "TARGET_XSAVES")]) 20004 20005(define_int_iterator ANY_XRSTOR64 20006 [UNSPECV_XRSTOR64 20007 (UNSPECV_XRSTORS64 "TARGET_XSAVES")]) 20008 20009(define_int_attr xrstor 20010 [(UNSPECV_XRSTOR "xrstor") 20011 (UNSPECV_XRSTOR64 "xrstor") 20012 (UNSPECV_XRSTORS "xrstors") 20013 (UNSPECV_XRSTORS64 "xrstors")]) 20014 20015(define_insn "<xsave>" 20016 [(set (match_operand:BLK 0 "memory_operand" "=m") 20017 (unspec_volatile:BLK 20018 [(match_operand:DI 1 "register_operand" "A")] 20019 ANY_XSAVE))] 20020 "!TARGET_64BIT && TARGET_XSAVE" 20021 "<xsave>\t%0" 20022 [(set_attr "type" "other") 20023 (set_attr "memory" "store") 20024 (set (attr "length") 20025 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20026 20027(define_insn "<xsave>_rex64" 20028 [(set (match_operand:BLK 0 "memory_operand" "=m") 20029 (unspec_volatile:BLK 20030 [(match_operand:SI 1 "register_operand" "a") 20031 (match_operand:SI 2 "register_operand" "d")] 20032 ANY_XSAVE))] 20033 "TARGET_64BIT && TARGET_XSAVE" 20034 "<xsave>\t%0" 20035 [(set_attr "type" "other") 20036 (set_attr "memory" "store") 20037 (set (attr "length") 20038 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20039 20040(define_insn "<xsave>" 20041 [(set (match_operand:BLK 0 "memory_operand" "=m") 20042 (unspec_volatile:BLK 20043 [(match_operand:SI 1 "register_operand" "a") 20044 (match_operand:SI 2 "register_operand" "d")] 20045 ANY_XSAVE64))] 20046 "TARGET_64BIT && TARGET_XSAVE" 20047 "<xsave>\t%0" 20048 [(set_attr "type" "other") 20049 (set_attr "memory" "store") 20050 (set (attr "length") 20051 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20052 20053(define_insn "<xrstor>" 20054 [(unspec_volatile:BLK 20055 [(match_operand:BLK 0 "memory_operand" "m") 20056 (match_operand:DI 1 "register_operand" "A")] 20057 ANY_XRSTOR)] 20058 "!TARGET_64BIT && TARGET_XSAVE" 20059 "<xrstor>\t%0" 20060 [(set_attr "type" "other") 20061 (set_attr "memory" "load") 20062 (set (attr "length") 20063 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20064 20065(define_insn "<xrstor>_rex64" 20066 [(unspec_volatile:BLK 20067 [(match_operand:BLK 0 "memory_operand" "m") 20068 (match_operand:SI 1 "register_operand" "a") 20069 (match_operand:SI 2 "register_operand" "d")] 20070 ANY_XRSTOR)] 20071 "TARGET_64BIT && TARGET_XSAVE" 20072 "<xrstor>\t%0" 20073 [(set_attr "type" "other") 20074 (set_attr "memory" "load") 20075 (set (attr "length") 20076 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20077 20078(define_insn "<xrstor>64" 20079 [(unspec_volatile:BLK 20080 [(match_operand:BLK 0 "memory_operand" "m") 20081 (match_operand:SI 1 "register_operand" "a") 20082 (match_operand:SI 2 "register_operand" "d")] 20083 ANY_XRSTOR64)] 20084 "TARGET_64BIT && TARGET_XSAVE" 20085 "<xrstor>64\t%0" 20086 [(set_attr "type" "other") 20087 (set_attr "memory" "load") 20088 (set (attr "length") 20089 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20090 20091(define_insn "xsetbv" 20092 [(unspec_volatile:SI 20093 [(match_operand:SI 0 "register_operand" "c") 20094 (match_operand:DI 1 "register_operand" "A")] 20095 UNSPECV_XSETBV)] 20096 "!TARGET_64BIT && TARGET_XSAVE" 20097 "xsetbv" 20098 [(set_attr "type" "other")]) 20099 20100(define_insn "xsetbv_rex64" 20101 [(unspec_volatile:SI 20102 [(match_operand:SI 0 "register_operand" "c") 20103 (match_operand:SI 1 "register_operand" "a") 20104 (match_operand:SI 2 "register_operand" "d")] 20105 UNSPECV_XSETBV)] 20106 "TARGET_64BIT && TARGET_XSAVE" 20107 "xsetbv" 20108 [(set_attr "type" "other")]) 20109 20110(define_insn "xgetbv" 20111 [(set (match_operand:DI 0 "register_operand" "=A") 20112 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 20113 UNSPECV_XGETBV))] 20114 "!TARGET_64BIT && TARGET_XSAVE" 20115 "xgetbv" 20116 [(set_attr "type" "other")]) 20117 20118(define_insn "xgetbv_rex64" 20119 [(set (match_operand:DI 0 "register_operand" "=a") 20120 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 20121 UNSPECV_XGETBV)) 20122 (set (match_operand:DI 1 "register_operand" "=d") 20123 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))] 20124 "TARGET_64BIT && TARGET_XSAVE" 20125 "xgetbv" 20126 [(set_attr "type" "other")]) 20127 20128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20129;; 20130;; Floating-point instructions for atomic compound assignments 20131;; 20132;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20133 20134; Clobber all floating-point registers on environment save and restore 20135; to ensure that the TOS value saved at fnstenv is valid after fldenv. 20136(define_insn "fnstenv" 20137 [(set (match_operand:BLK 0 "memory_operand" "=m") 20138 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV)) 20139 (clobber (reg:HI FPCR_REG)) 20140 (clobber (reg:XF ST0_REG)) 20141 (clobber (reg:XF ST1_REG)) 20142 (clobber (reg:XF ST2_REG)) 20143 (clobber (reg:XF ST3_REG)) 20144 (clobber (reg:XF ST4_REG)) 20145 (clobber (reg:XF ST5_REG)) 20146 (clobber (reg:XF ST6_REG)) 20147 (clobber (reg:XF ST7_REG))] 20148 "TARGET_80387" 20149 "fnstenv\t%0" 20150 [(set_attr "type" "other") 20151 (set_attr "memory" "store") 20152 (set (attr "length") 20153 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20154 20155(define_insn "fldenv" 20156 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 20157 UNSPECV_FLDENV) 20158 (clobber (reg:CCFP FPSR_REG)) 20159 (clobber (reg:HI FPCR_REG)) 20160 (clobber (reg:XF ST0_REG)) 20161 (clobber (reg:XF ST1_REG)) 20162 (clobber (reg:XF ST2_REG)) 20163 (clobber (reg:XF ST3_REG)) 20164 (clobber (reg:XF ST4_REG)) 20165 (clobber (reg:XF ST5_REG)) 20166 (clobber (reg:XF ST6_REG)) 20167 (clobber (reg:XF ST7_REG))] 20168 "TARGET_80387" 20169 "fldenv\t%0" 20170 [(set_attr "type" "other") 20171 (set_attr "memory" "load") 20172 (set (attr "length") 20173 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20174 20175(define_insn "fnstsw" 20176 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m") 20177 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))] 20178 "TARGET_80387" 20179 "fnstsw\t%0" 20180 [(set_attr "type" "other,other") 20181 (set_attr "memory" "none,store") 20182 (set (attr "length") 20183 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20184 20185(define_insn "fnclex" 20186 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)] 20187 "TARGET_80387" 20188 "fnclex" 20189 [(set_attr "type" "other") 20190 (set_attr "memory" "none") 20191 (set_attr "length" "2")]) 20192 20193;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20194;; 20195;; LWP instructions 20196;; 20197;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20198 20199(define_expand "lwp_llwpcb" 20200 [(unspec_volatile [(match_operand 0 "register_operand")] 20201 UNSPECV_LLWP_INTRINSIC)] 20202 "TARGET_LWP") 20203 20204(define_insn "*lwp_llwpcb<mode>1" 20205 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 20206 UNSPECV_LLWP_INTRINSIC)] 20207 "TARGET_LWP" 20208 "llwpcb\t%0" 20209 [(set_attr "type" "lwp") 20210 (set_attr "mode" "<MODE>") 20211 (set_attr "length" "5")]) 20212 20213(define_expand "lwp_slwpcb" 20214 [(set (match_operand 0 "register_operand") 20215 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 20216 "TARGET_LWP" 20217{ 20218 rtx (*insn)(rtx); 20219 20220 insn = (Pmode == DImode 20221 ? gen_lwp_slwpcbdi 20222 : gen_lwp_slwpcbsi); 20223 20224 emit_insn (insn (operands[0])); 20225 DONE; 20226}) 20227 20228(define_insn "lwp_slwpcb<mode>" 20229 [(set (match_operand:P 0 "register_operand" "=r") 20230 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 20231 "TARGET_LWP" 20232 "slwpcb\t%0" 20233 [(set_attr "type" "lwp") 20234 (set_attr "mode" "<MODE>") 20235 (set_attr "length" "5")]) 20236 20237(define_expand "lwp_lwpval<mode>3" 20238 [(unspec_volatile [(match_operand:SWI48 1 "register_operand") 20239 (match_operand:SI 2 "nonimmediate_operand") 20240 (match_operand:SI 3 "const_int_operand")] 20241 UNSPECV_LWPVAL_INTRINSIC)] 20242 "TARGET_LWP" 20243 ;; Avoid unused variable warning. 20244 "(void) operands[0];") 20245 20246(define_insn "*lwp_lwpval<mode>3_1" 20247 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") 20248 (match_operand:SI 1 "nonimmediate_operand" "rm") 20249 (match_operand:SI 2 "const_int_operand" "i")] 20250 UNSPECV_LWPVAL_INTRINSIC)] 20251 "TARGET_LWP" 20252 "lwpval\t{%2, %1, %0|%0, %1, %2}" 20253 [(set_attr "type" "lwp") 20254 (set_attr "mode" "<MODE>") 20255 (set (attr "length") 20256 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 20257 20258(define_expand "lwp_lwpins<mode>3" 20259 [(set (reg:CCC FLAGS_REG) 20260 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand") 20261 (match_operand:SI 2 "nonimmediate_operand") 20262 (match_operand:SI 3 "const_int_operand")] 20263 UNSPECV_LWPINS_INTRINSIC)) 20264 (set (match_operand:QI 0 "nonimmediate_operand") 20265 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] 20266 "TARGET_LWP") 20267 20268(define_insn "*lwp_lwpins<mode>3_1" 20269 [(set (reg:CCC FLAGS_REG) 20270 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r") 20271 (match_operand:SI 1 "nonimmediate_operand" "rm") 20272 (match_operand:SI 2 "const_int_operand" "i")] 20273 UNSPECV_LWPINS_INTRINSIC))] 20274 "TARGET_LWP" 20275 "lwpins\t{%2, %1, %0|%0, %1, %2}" 20276 [(set_attr "type" "lwp") 20277 (set_attr "mode" "<MODE>") 20278 (set (attr "length") 20279 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 20280 20281(define_int_iterator RDFSGSBASE 20282 [UNSPECV_RDFSBASE 20283 UNSPECV_RDGSBASE]) 20284 20285(define_int_iterator WRFSGSBASE 20286 [UNSPECV_WRFSBASE 20287 UNSPECV_WRGSBASE]) 20288 20289(define_int_attr fsgs 20290 [(UNSPECV_RDFSBASE "fs") 20291 (UNSPECV_RDGSBASE "gs") 20292 (UNSPECV_WRFSBASE "fs") 20293 (UNSPECV_WRGSBASE "gs")]) 20294 20295(define_insn "rd<fsgs>base<mode>" 20296 [(set (match_operand:SWI48 0 "register_operand" "=r") 20297 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))] 20298 "TARGET_64BIT && TARGET_FSGSBASE" 20299 "rd<fsgs>base\t%0" 20300 [(set_attr "type" "other") 20301 (set_attr "prefix_extra" "2")]) 20302 20303(define_insn "wr<fsgs>base<mode>" 20304 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 20305 WRFSGSBASE)] 20306 "TARGET_64BIT && TARGET_FSGSBASE" 20307 "wr<fsgs>base\t%0" 20308 [(set_attr "type" "other") 20309 (set_attr "prefix_extra" "2")]) 20310 20311(define_insn "rdrand<mode>_1" 20312 [(set (match_operand:SWI248 0 "register_operand" "=r") 20313 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND)) 20314 (set (reg:CCC FLAGS_REG) 20315 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))] 20316 "TARGET_RDRND" 20317 "rdrand\t%0" 20318 [(set_attr "type" "other") 20319 (set_attr "prefix_extra" "1")]) 20320 20321(define_insn "rdseed<mode>_1" 20322 [(set (match_operand:SWI248 0 "register_operand" "=r") 20323 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED)) 20324 (set (reg:CCC FLAGS_REG) 20325 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))] 20326 "TARGET_RDSEED" 20327 "rdseed\t%0" 20328 [(set_attr "type" "other") 20329 (set_attr "prefix_extra" "1")]) 20330 20331(define_expand "pause" 20332 [(set (match_dup 0) 20333 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 20334 "" 20335{ 20336 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 20337 MEM_VOLATILE_P (operands[0]) = 1; 20338}) 20339 20340;; Use "rep; nop", instead of "pause", to support older assemblers. 20341;; They have the same encoding. 20342(define_insn "*pause" 20343 [(set (match_operand:BLK 0) 20344 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 20345 "" 20346 "rep%; nop" 20347 [(set_attr "length" "2") 20348 (set_attr "memory" "unknown")]) 20349 20350;; CET instructions 20351(define_insn "rdssp<mode>" 20352 [(set (match_operand:SWI48x 0 "register_operand" "=r") 20353 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))] 20354 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" 20355 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0" 20356 [(set_attr "length" "6") 20357 (set_attr "type" "other")]) 20358 20359(define_insn "incssp<mode>" 20360 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")] 20361 UNSPECV_INCSSP)] 20362 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" 20363 "incssp<mskmodesuffix>\t%0" 20364 [(set_attr "length" "4") 20365 (set_attr "type" "other")]) 20366 20367(define_insn "saveprevssp" 20368 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)] 20369 "TARGET_SHSTK" 20370 "saveprevssp" 20371 [(set_attr "length" "5") 20372 (set_attr "type" "other")]) 20373 20374(define_insn "rstorssp" 20375 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 20376 UNSPECV_RSTORSSP)] 20377 "TARGET_SHSTK" 20378 "rstorssp\t%0" 20379 [(set_attr "length" "5") 20380 (set_attr "type" "other")]) 20381 20382(define_insn "wrss<mode>" 20383 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") 20384 (match_operand:SWI48x 1 "memory_operand" "m")] 20385 UNSPECV_WRSS)] 20386 "TARGET_SHSTK" 20387 "wrss<mskmodesuffix>\t%0, %1" 20388 [(set_attr "length" "3") 20389 (set_attr "type" "other")]) 20390 20391(define_insn "wruss<mode>" 20392 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") 20393 (match_operand:SWI48x 1 "memory_operand" "m")] 20394 UNSPECV_WRUSS)] 20395 "TARGET_SHSTK" 20396 "wruss<mskmodesuffix>\t%0, %1" 20397 [(set_attr "length" "4") 20398 (set_attr "type" "other")]) 20399 20400(define_insn "setssbsy" 20401 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)] 20402 "TARGET_SHSTK" 20403 "setssbsy" 20404 [(set_attr "length" "4") 20405 (set_attr "type" "other")]) 20406 20407(define_insn "clrssbsy" 20408 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 20409 UNSPECV_CLRSSBSY)] 20410 "TARGET_SHSTK" 20411 "clrssbsy\t%0" 20412 [(set_attr "length" "4") 20413 (set_attr "type" "other")]) 20414 20415(define_insn "nop_endbr" 20416 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)] 20417 "(flag_cf_protection & CF_BRANCH)" 20418 "* 20419{ return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }" 20420 [(set_attr "length" "4") 20421 (set_attr "length_immediate" "0") 20422 (set_attr "modrm" "0")]) 20423 20424;; For RTM support 20425(define_expand "xbegin" 20426 [(set (match_operand:SI 0 "register_operand") 20427 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))] 20428 "TARGET_RTM" 20429{ 20430 rtx_code_label *label = gen_label_rtx (); 20431 20432 /* xbegin is emitted as jump_insn, so reload won't be able 20433 to reload its operand. Force the value into AX hard register. */ 20434 rtx ax_reg = gen_rtx_REG (SImode, AX_REG); 20435 emit_move_insn (ax_reg, constm1_rtx); 20436 20437 emit_jump_insn (gen_xbegin_1 (ax_reg, label)); 20438 20439 emit_label (label); 20440 LABEL_NUSES (label) = 1; 20441 20442 emit_move_insn (operands[0], ax_reg); 20443 20444 DONE; 20445}) 20446 20447(define_insn "xbegin_1" 20448 [(set (pc) 20449 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT) 20450 (const_int 0)) 20451 (label_ref (match_operand 1)) 20452 (pc))) 20453 (set (match_operand:SI 0 "register_operand" "+a") 20454 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))] 20455 "TARGET_RTM" 20456 "xbegin\t%l1" 20457 [(set_attr "type" "other") 20458 (set_attr "length" "6")]) 20459 20460(define_insn "xend" 20461 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)] 20462 "TARGET_RTM" 20463 "xend" 20464 [(set_attr "type" "other") 20465 (set_attr "length" "3")]) 20466 20467(define_insn "xabort" 20468 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")] 20469 UNSPECV_XABORT)] 20470 "TARGET_RTM" 20471 "xabort\t%0" 20472 [(set_attr "type" "other") 20473 (set_attr "length" "3")]) 20474 20475(define_expand "xtest" 20476 [(set (match_operand:QI 0 "register_operand") 20477 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))] 20478 "TARGET_RTM" 20479{ 20480 emit_insn (gen_xtest_1 ()); 20481 20482 ix86_expand_setcc (operands[0], NE, 20483 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 20484 DONE; 20485}) 20486 20487(define_insn "xtest_1" 20488 [(set (reg:CCZ FLAGS_REG) 20489 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))] 20490 "TARGET_RTM" 20491 "xtest" 20492 [(set_attr "type" "other") 20493 (set_attr "length" "3")]) 20494 20495(define_insn "clwb" 20496 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 20497 UNSPECV_CLWB)] 20498 "TARGET_CLWB" 20499 "clwb\t%a0" 20500 [(set_attr "type" "sse") 20501 (set_attr "atom_sse_attr" "fence") 20502 (set_attr "memory" "unknown")]) 20503 20504(define_insn "clflushopt" 20505 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 20506 UNSPECV_CLFLUSHOPT)] 20507 "TARGET_CLFLUSHOPT" 20508 "clflushopt\t%a0" 20509 [(set_attr "type" "sse") 20510 (set_attr "atom_sse_attr" "fence") 20511 (set_attr "memory" "unknown")]) 20512 20513;; MONITORX and MWAITX 20514(define_insn "mwaitx" 20515 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c") 20516 (match_operand:SI 1 "register_operand" "a") 20517 (match_operand:SI 2 "register_operand" "b")] 20518 UNSPECV_MWAITX)] 20519 "TARGET_MWAITX" 20520;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used. 20521;; Since 32bit register operands are implicitly zero extended to 64bit, 20522;; we only need to set up 32bit registers. 20523 "mwaitx" 20524 [(set_attr "length" "3")]) 20525 20526(define_insn "monitorx_<mode>" 20527 [(unspec_volatile [(match_operand:P 0 "register_operand" "a") 20528 (match_operand:SI 1 "register_operand" "c") 20529 (match_operand:SI 2 "register_operand" "d")] 20530 UNSPECV_MONITORX)] 20531 "TARGET_MWAITX" 20532;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in 20533;; RCX and RDX are used. Since 32bit register operands are implicitly 20534;; zero extended to 64bit, we only need to set up 32bit registers. 20535 "%^monitorx" 20536 [(set (attr "length") 20537 (symbol_ref ("(Pmode != word_mode) + 3")))]) 20538 20539;; CLZERO 20540(define_insn "clzero_<mode>" 20541 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")] 20542 UNSPECV_CLZERO)] 20543 "TARGET_CLZERO" 20544 "clzero" 20545 [(set_attr "length" "3") 20546 (set_attr "memory" "unknown")]) 20547 20548;; MPX instructions 20549 20550(define_expand "<mode>_mk" 20551 [(set (match_operand:BND 0 "register_operand") 20552 (unspec:BND 20553 [(mem:<bnd_ptr> 20554 (match_par_dup 3 20555 [(match_operand:<bnd_ptr> 1 "register_operand") 20556 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))] 20557 UNSPEC_BNDMK))] 20558 "TARGET_MPX" 20559{ 20560 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], 20561 operands[2]), 20562 UNSPEC_BNDMK_ADDR); 20563}) 20564 20565(define_insn "*<mode>_mk" 20566 [(set (match_operand:BND 0 "register_operand" "=w") 20567 (unspec:BND 20568 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20569 [(unspec:<bnd_ptr> 20570 [(match_operand:<bnd_ptr> 1 "register_operand" "r") 20571 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")] 20572 UNSPEC_BNDMK_ADDR)])] 20573 UNSPEC_BNDMK))] 20574 "TARGET_MPX" 20575 "bndmk\t{%3, %0|%0, %3}" 20576 [(set_attr "type" "mpxmk")]) 20577 20578(define_expand "mov<mode>" 20579 [(set (match_operand:BND 0 "general_operand") 20580 (match_operand:BND 1 "general_operand"))] 20581 "TARGET_MPX" 20582 "ix86_expand_move (<MODE>mode, operands); DONE;") 20583 20584(define_insn "*mov<mode>_internal_mpx" 20585 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m") 20586 (match_operand:BND 1 "general_operand" "wm,w"))] 20587 "TARGET_MPX" 20588 "bndmov\t{%1, %0|%0, %1}" 20589 [(set_attr "type" "mpxmov")]) 20590 20591(define_expand "<mode>_<bndcheck>" 20592 [(parallel 20593 [(unspec 20594 [(match_operand:BND 0 "register_operand") 20595 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK) 20596 (set (match_dup 2) 20597 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])] 20598 "TARGET_MPX" 20599{ 20600 operands[2] = gen_rtx_MEM (BLKmode, operands[1]); 20601 MEM_VOLATILE_P (operands[2]) = 1; 20602}) 20603 20604(define_insn "*<mode>_<bndcheck>" 20605 [(unspec 20606 [(match_operand:BND 0 "register_operand" "w") 20607 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK) 20608 (set (match_operand:BLK 2 "bnd_mem_operator") 20609 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))] 20610 "TARGET_MPX" 20611 "bnd<bndcheck>\t{%a1, %0|%0, %a1}" 20612 [(set_attr "type" "mpxchk")]) 20613 20614(define_expand "<mode>_ldx" 20615 [(parallel 20616 [(set (match_operand:BND 0 "register_operand") 20617 (unspec:BND 20618 [(mem:<bnd_ptr> 20619 (match_par_dup 3 20620 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand") 20621 (match_operand:<bnd_ptr> 2 "register_operand")]))] 20622 UNSPEC_BNDLDX)) 20623 (use (mem:BLK (match_dup 1)))])] 20624 "TARGET_MPX" 20625{ 20626 /* Avoid registers which cannot be used as index. */ 20627 if (!index_register_operand (operands[2], Pmode)) 20628 operands[2] = copy_addr_to_reg (operands[2]); 20629 20630 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], 20631 operands[2]), 20632 UNSPEC_BNDLDX_ADDR); 20633}) 20634 20635(define_insn "*<mode>_ldx" 20636 [(set (match_operand:BND 0 "register_operand" "=w") 20637 (unspec:BND 20638 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20639 [(unspec:<bnd_ptr> 20640 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti") 20641 (match_operand:<bnd_ptr> 2 "register_operand" "l")] 20642 UNSPEC_BNDLDX_ADDR)])] 20643 UNSPEC_BNDLDX)) 20644 (use (mem:BLK (match_dup 1)))] 20645 "TARGET_MPX" 20646 "bndldx\t{%3, %0|%0, %3}" 20647 [(set_attr "type" "mpxld")]) 20648 20649(define_expand "<mode>_stx" 20650 [(parallel 20651 [(unspec 20652 [(mem:<bnd_ptr> 20653 (match_par_dup 3 20654 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand") 20655 (match_operand:<bnd_ptr> 1 "register_operand")])) 20656 (match_operand:BND 2 "register_operand")] 20657 UNSPEC_BNDSTX) 20658 (set (match_dup 4) 20659 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])] 20660 "TARGET_MPX" 20661{ 20662 /* Avoid registers which cannot be used as index. */ 20663 if (!index_register_operand (operands[1], Pmode)) 20664 operands[1] = copy_addr_to_reg (operands[1]); 20665 20666 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0], 20667 operands[1]), 20668 UNSPEC_BNDLDX_ADDR); 20669 operands[4] = gen_rtx_MEM (BLKmode, operands[0]); 20670 MEM_VOLATILE_P (operands[4]) = 1; 20671}) 20672 20673(define_insn "*<mode>_stx" 20674 [(unspec 20675 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20676 [(unspec:<bnd_ptr> 20677 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti") 20678 (match_operand:<bnd_ptr> 1 "register_operand" "l")] 20679 UNSPEC_BNDLDX_ADDR)]) 20680 (match_operand:BND 2 "register_operand" "w")] 20681 UNSPEC_BNDSTX) 20682 (set (match_operand:BLK 4 "bnd_mem_operator") 20683 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))] 20684 "TARGET_MPX" 20685 "bndstx\t{%2, %3|%3, %2}" 20686 [(set_attr "type" "mpxst")]) 20687 20688(define_insn "move_size_reloc_<mode>" 20689 [(set (match_operand:SWI48 0 "register_operand" "=r") 20690 (unspec:SWI48 20691 [(match_operand:SWI48 1 "symbol_operand")] 20692 UNSPEC_SIZEOF))] 20693 "TARGET_MPX" 20694{ 20695 if (x86_64_immediate_size_operand (operands[1], VOIDmode)) 20696 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}"; 20697 else 20698 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}"; 20699} 20700 [(set_attr "type" "imov") 20701 (set_attr "mode" "<MODE>")]) 20702 20703;; RDPKRU and WRPKRU 20704 20705(define_expand "rdpkru" 20706 [(parallel 20707 [(set (match_operand:SI 0 "register_operand") 20708 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU)) 20709 (set (match_dup 2) (const_int 0))])] 20710 "TARGET_PKU" 20711{ 20712 operands[1] = force_reg (SImode, const0_rtx); 20713 operands[2] = gen_reg_rtx (SImode); 20714}) 20715 20716(define_insn "*rdpkru" 20717 [(set (match_operand:SI 0 "register_operand" "=a") 20718 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")] 20719 UNSPECV_PKU)) 20720 (set (match_operand:SI 1 "register_operand" "=d") 20721 (const_int 0))] 20722 "TARGET_PKU" 20723 "rdpkru" 20724 [(set_attr "type" "other")]) 20725 20726(define_expand "wrpkru" 20727 [(unspec_volatile:SI 20728 [(match_operand:SI 0 "register_operand") 20729 (match_dup 1) (match_dup 2)] UNSPECV_PKU)] 20730 "TARGET_PKU" 20731{ 20732 operands[1] = force_reg (SImode, const0_rtx); 20733 operands[2] = force_reg (SImode, const0_rtx); 20734}) 20735 20736(define_insn "*wrpkru" 20737 [(unspec_volatile:SI 20738 [(match_operand:SI 0 "register_operand" "a") 20739 (match_operand:SI 1 "register_operand" "d") 20740 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)] 20741 "TARGET_PKU" 20742 "wrpkru" 20743 [(set_attr "type" "other")]) 20744 20745(define_insn "rdpid" 20746 [(set (match_operand:SI 0 "register_operand" "=r") 20747 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))] 20748 "!TARGET_64BIT && TARGET_RDPID" 20749 "rdpid\t%0" 20750 [(set_attr "type" "other")]) 20751 20752(define_insn "rdpid_rex64" 20753 [(set (match_operand:DI 0 "register_operand" "=r") 20754 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))] 20755 "TARGET_64BIT && TARGET_RDPID" 20756 "rdpid\t%0" 20757 [(set_attr "type" "other")]) 20758 20759;; Intirinsics for > i486 20760 20761(define_insn "wbinvd" 20762 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)] 20763 "" 20764 "wbinvd" 20765 [(set_attr "type" "other")]) 20766 20767(define_insn "wbnoinvd" 20768 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)] 20769 "TARGET_WBNOINVD" 20770 "wbnoinvd" 20771 [(set_attr "type" "other")]) 20772 20773(define_insn "movdiri<mode>" 20774 [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m") 20775 (match_operand:SWI48 1 "register_operand" "r")] 20776 UNSPECV_MOVDIRI)] 20777 "TARGET_MOVDIRI" 20778 "movdiri\t{%1, %0|%0, %1}" 20779 [(set_attr "type" "other")]) 20780 20781(define_insn "movdir64b_<mode>" 20782 [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r") 20783 (match_operand:XI 1 "memory_operand")] 20784 UNSPECV_MOVDIR64B)] 20785 "TARGET_MOVDIR64B" 20786 "movdir64b\t{%1, %0|%0, %1}" 20787 [(set_attr "type" "other")]) 20788 20789(include "mmx.md") 20790(include "sse.md") 20791(include "sync.md") 20792