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 if (GET_CODE (operands[2]) == CONST) 8953 { 8954 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */ 8955 operands[2] = copy_rtx (operands[2]); 8956 PUT_MODE (operands[2], SImode); 8957 PUT_MODE (XEXP (operands[2], 0), SImode); 8958 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode); 8959 } 8960 else 8961 operands[2] = gen_lowpart (SImode, operands[2]); 8962}) 8963 8964;; See comment for addsi_1_zext why we do use nonimmediate_operand 8965(define_insn "*andsi_1_zext" 8966 [(set (match_operand:DI 0 "register_operand" "=r") 8967 (zero_extend:DI 8968 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8969 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 8970 (clobber (reg:CC FLAGS_REG))] 8971 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 8972 "and{l}\t{%2, %k0|%k0, %2}" 8973 [(set_attr "type" "alu") 8974 (set_attr "mode" "SI")]) 8975 8976(define_insn "*and<mode>_1" 8977 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya") 8978 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm") 8979 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L"))) 8980 (clobber (reg:CC FLAGS_REG))] 8981 "ix86_binary_operator_ok (AND, <MODE>mode, operands)" 8982 "@ 8983 and{<imodesuffix>}\t{%2, %0|%0, %2} 8984 and{<imodesuffix>}\t{%2, %0|%0, %2} 8985 #" 8986 [(set_attr "type" "alu,alu,imovx") 8987 (set_attr "length_immediate" "*,*,0") 8988 (set (attr "prefix_rex") 8989 (if_then_else 8990 (and (eq_attr "type" "imovx") 8991 (and (match_test "INTVAL (operands[2]) == 0xff") 8992 (match_operand 1 "ext_QIreg_operand"))) 8993 (const_string "1") 8994 (const_string "*"))) 8995 (set_attr "mode" "<MODE>,<MODE>,SI")]) 8996 8997(define_insn "*andqi_1" 8998 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 8999 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9000 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 9001 (clobber (reg:CC FLAGS_REG))] 9002 "ix86_binary_operator_ok (AND, QImode, operands)" 9003 "@ 9004 and{b}\t{%2, %0|%0, %2} 9005 and{b}\t{%2, %0|%0, %2} 9006 and{l}\t{%k2, %k0|%k0, %k2}" 9007 [(set_attr "type" "alu") 9008 (set_attr "mode" "QI,QI,SI") 9009 ;; Potential partial reg stall on alternative 2. 9010 (set (attr "preferred_for_speed") 9011 (cond [(eq_attr "alternative" "2") 9012 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 9013 (symbol_ref "true")))]) 9014 9015(define_insn "*andqi_1_slp" 9016 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 9017 (and:QI (match_dup 0) 9018 (match_operand:QI 1 "general_operand" "qn,qmn"))) 9019 (clobber (reg:CC FLAGS_REG))] 9020 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9021 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9022 "and{b}\t{%1, %0|%0, %1}" 9023 [(set_attr "type" "alu1") 9024 (set_attr "mode" "QI")]) 9025 9026(define_split 9027 [(set (match_operand:SWI248 0 "register_operand") 9028 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand") 9029 (match_operand:SWI248 2 "const_int_operand"))) 9030 (clobber (reg:CC FLAGS_REG))] 9031 "reload_completed 9032 && (!REG_P (operands[1]) 9033 || REGNO (operands[0]) != REGNO (operands[1]))" 9034 [(const_int 0)] 9035{ 9036 HOST_WIDE_INT ival = INTVAL (operands[2]); 9037 machine_mode mode; 9038 rtx (*insn) (rtx, rtx); 9039 9040 if (ival == (HOST_WIDE_INT) 0xffffffff) 9041 mode = SImode; 9042 else if (ival == 0xffff) 9043 mode = HImode; 9044 else 9045 { 9046 gcc_assert (ival == 0xff); 9047 mode = QImode; 9048 } 9049 9050 if (<MODE>mode == DImode) 9051 insn = (mode == SImode) 9052 ? gen_zero_extendsidi2 9053 : (mode == HImode) 9054 ? gen_zero_extendhidi2 9055 : gen_zero_extendqidi2; 9056 else 9057 { 9058 if (<MODE>mode != SImode) 9059 /* Zero extend to SImode to avoid partial register stalls. */ 9060 operands[0] = gen_lowpart (SImode, operands[0]); 9061 9062 insn = (mode == HImode) 9063 ? gen_zero_extendhisi2 9064 : gen_zero_extendqisi2; 9065 } 9066 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1]))); 9067 DONE; 9068}) 9069 9070(define_split 9071 [(set (match_operand:SWI48 0 "register_operand") 9072 (and:SWI48 (match_dup 0) 9073 (const_int -65536))) 9074 (clobber (reg:CC FLAGS_REG))] 9075 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL) 9076 || optimize_function_for_size_p (cfun)" 9077 [(set (strict_low_part (match_dup 1)) (const_int 0))] 9078 "operands[1] = gen_lowpart (HImode, operands[0]);") 9079 9080(define_split 9081 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9082 (and:SWI248 (match_dup 0) 9083 (const_int -256))) 9084 (clobber (reg:CC FLAGS_REG))] 9085 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9086 && reload_completed" 9087 [(set (strict_low_part (match_dup 1)) (const_int 0))] 9088 "operands[1] = gen_lowpart (QImode, operands[0]);") 9089 9090(define_split 9091 [(set (match_operand:SWI248 0 "QIreg_operand") 9092 (and:SWI248 (match_dup 0) 9093 (const_int -65281))) 9094 (clobber (reg:CC FLAGS_REG))] 9095 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9096 && reload_completed" 9097 [(parallel 9098 [(set (zero_extract:SI (match_dup 0) 9099 (const_int 8) 9100 (const_int 8)) 9101 (subreg:SI 9102 (xor:QI 9103 (subreg:QI 9104 (zero_extract:SI (match_dup 0) 9105 (const_int 8) 9106 (const_int 8)) 0) 9107 (subreg:QI 9108 (zero_extract:SI (match_dup 0) 9109 (const_int 8) 9110 (const_int 8)) 0)) 0)) 9111 (clobber (reg:CC FLAGS_REG))])] 9112 "operands[0] = gen_lowpart (SImode, operands[0]);") 9113 9114(define_insn "*anddi_2" 9115 [(set (reg FLAGS_REG) 9116 (compare 9117 (and:DI 9118 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 9119 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 9120 (const_int 0))) 9121 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 9122 (and:DI (match_dup 1) (match_dup 2)))] 9123 "TARGET_64BIT 9124 && ix86_match_ccmode 9125 (insn, 9126 /* If we are going to emit andl instead of andq, and the operands[2] 9127 constant might have the SImode sign bit set, make sure the sign 9128 flag isn't tested, because the instruction will set the sign flag 9129 based on bit 31 rather than bit 63. If it isn't CONST_INT, 9130 conservatively assume it might have bit 31 set. */ 9131 (satisfies_constraint_Z (operands[2]) 9132 && (!CONST_INT_P (operands[2]) 9133 || val_signbit_known_set_p (SImode, INTVAL (operands[2])))) 9134 ? CCZmode : CCNOmode) 9135 && ix86_binary_operator_ok (AND, DImode, operands)" 9136 "@ 9137 and{l}\t{%k2, %k0|%k0, %k2} 9138 and{q}\t{%2, %0|%0, %2} 9139 and{q}\t{%2, %0|%0, %2}" 9140 [(set_attr "type" "alu") 9141 (set_attr "mode" "SI,DI,DI")]) 9142 9143;; See comment for addsi_1_zext why we do use nonimmediate_operand 9144(define_insn "*andsi_2_zext" 9145 [(set (reg FLAGS_REG) 9146 (compare (and:SI 9147 (match_operand:SI 1 "nonimmediate_operand" "%0") 9148 (match_operand:SI 2 "x86_64_general_operand" "rme")) 9149 (const_int 0))) 9150 (set (match_operand:DI 0 "register_operand" "=r") 9151 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 9152 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9153 && ix86_binary_operator_ok (AND, SImode, operands)" 9154 "and{l}\t{%2, %k0|%k0, %2}" 9155 [(set_attr "type" "alu") 9156 (set_attr "mode" "SI")]) 9157 9158(define_insn "*andqi_2_maybe_si" 9159 [(set (reg FLAGS_REG) 9160 (compare (and:QI 9161 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9162 (match_operand:QI 2 "general_operand" "qmn,qn,n")) 9163 (const_int 0))) 9164 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 9165 (and:QI (match_dup 1) (match_dup 2)))] 9166 "ix86_binary_operator_ok (AND, QImode, operands) 9167 && ix86_match_ccmode (insn, 9168 CONST_INT_P (operands[2]) 9169 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 9170{ 9171 if (which_alternative == 2) 9172 { 9173 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 9174 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 9175 return "and{l}\t{%2, %k0|%k0, %2}"; 9176 } 9177 return "and{b}\t{%2, %0|%0, %2}"; 9178} 9179 [(set_attr "type" "alu") 9180 (set_attr "mode" "QI,QI,SI")]) 9181 9182(define_insn "*and<mode>_2" 9183 [(set (reg FLAGS_REG) 9184 (compare (and:SWI124 9185 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") 9186 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>")) 9187 (const_int 0))) 9188 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m") 9189 (and:SWI124 (match_dup 1) (match_dup 2)))] 9190 "ix86_match_ccmode (insn, CCNOmode) 9191 && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 9192 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 9193 [(set_attr "type" "alu") 9194 (set_attr "mode" "<MODE>")]) 9195 9196(define_insn "*andqi_2_slp" 9197 [(set (reg FLAGS_REG) 9198 (compare (and:QI 9199 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9200 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) 9201 (const_int 0))) 9202 (set (strict_low_part (match_dup 0)) 9203 (and:QI (match_dup 0) (match_dup 1)))] 9204 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9205 && ix86_match_ccmode (insn, CCNOmode) 9206 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9207 "and{b}\t{%1, %0|%0, %1}" 9208 [(set_attr "type" "alu1") 9209 (set_attr "mode" "QI")]) 9210 9211(define_insn "andqi_ext_1" 9212 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9213 (const_int 8) 9214 (const_int 8)) 9215 (subreg:SI 9216 (and:QI 9217 (subreg:QI 9218 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9219 (const_int 8) 9220 (const_int 8)) 0) 9221 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 9222 (clobber (reg:CC FLAGS_REG))] 9223 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9224 rtx_equal_p (operands[0], operands[1])" 9225 "and{b}\t{%2, %h0|%h0, %2}" 9226 [(set_attr "isa" "*,nox64") 9227 (set_attr "type" "alu") 9228 (set_attr "mode" "QI")]) 9229 9230;; Generated by peephole translating test to and. This shows up 9231;; often in fp comparisons. 9232(define_insn "*andqi_ext_1_cc" 9233 [(set (reg FLAGS_REG) 9234 (compare 9235 (and:QI 9236 (subreg:QI 9237 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9238 (const_int 8) 9239 (const_int 8)) 0) 9240 (match_operand:QI 2 "general_operand" "QnBc,m")) 9241 (const_int 0))) 9242 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9243 (const_int 8) 9244 (const_int 8)) 9245 (subreg:SI 9246 (and:QI 9247 (subreg:QI 9248 (zero_extract:SI (match_dup 1) 9249 (const_int 8) 9250 (const_int 8)) 0) 9251 (match_dup 2)) 0))] 9252 "ix86_match_ccmode (insn, CCNOmode) 9253 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9254 && rtx_equal_p (operands[0], operands[1])" 9255 "and{b}\t{%2, %h0|%h0, %2}" 9256 [(set_attr "isa" "*,nox64") 9257 (set_attr "type" "alu") 9258 (set_attr "mode" "QI")]) 9259 9260(define_insn "*andqi_ext_2" 9261 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 9262 (const_int 8) 9263 (const_int 8)) 9264 (subreg:SI 9265 (and:QI 9266 (subreg:QI 9267 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 9268 (const_int 8) 9269 (const_int 8)) 0) 9270 (subreg:QI 9271 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9272 (const_int 8) 9273 (const_int 8)) 0)) 0)) 9274 (clobber (reg:CC FLAGS_REG))] 9275 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9276 rtx_equal_p (operands[0], operands[1]) 9277 || rtx_equal_p (operands[0], operands[2])" 9278 "and{b}\t{%h2, %h0|%h0, %h2}" 9279 [(set_attr "type" "alu") 9280 (set_attr "mode" "QI")]) 9281 9282;; Convert wide AND instructions with immediate operand to shorter QImode 9283;; equivalents when possible. 9284;; Don't do the splitting with memory operands, since it introduces risk 9285;; of memory mismatch stalls. We may want to do the splitting for optimizing 9286;; for size, but that can (should?) be handled by generic code instead. 9287(define_split 9288 [(set (match_operand:SWI248 0 "QIreg_operand") 9289 (and:SWI248 (match_operand:SWI248 1 "register_operand") 9290 (match_operand:SWI248 2 "const_int_operand"))) 9291 (clobber (reg:CC FLAGS_REG))] 9292 "reload_completed 9293 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9294 && !(~INTVAL (operands[2]) & ~(255 << 8))" 9295 [(parallel 9296 [(set (zero_extract:SI (match_dup 0) 9297 (const_int 8) 9298 (const_int 8)) 9299 (subreg:SI 9300 (and:QI 9301 (subreg:QI 9302 (zero_extract:SI (match_dup 1) 9303 (const_int 8) 9304 (const_int 8)) 0) 9305 (match_dup 2)) 0)) 9306 (clobber (reg:CC FLAGS_REG))])] 9307{ 9308 operands[0] = gen_lowpart (SImode, operands[0]); 9309 operands[1] = gen_lowpart (SImode, operands[1]); 9310 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode); 9311}) 9312 9313;; Since AND can be encoded with sign extended immediate, this is only 9314;; profitable when 7th bit is not set. 9315(define_split 9316 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9317 (and:SWI248 (match_operand:SWI248 1 "general_operand") 9318 (match_operand:SWI248 2 "const_int_operand"))) 9319 (clobber (reg:CC FLAGS_REG))] 9320 "reload_completed 9321 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9322 && !(~INTVAL (operands[2]) & ~255) 9323 && !(INTVAL (operands[2]) & 128)" 9324 [(parallel [(set (strict_low_part (match_dup 0)) 9325 (and:QI (match_dup 1) 9326 (match_dup 2))) 9327 (clobber (reg:CC FLAGS_REG))])] 9328{ 9329 operands[0] = gen_lowpart (QImode, operands[0]); 9330 operands[1] = gen_lowpart (QImode, operands[1]); 9331 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 9332}) 9333 9334(define_insn "*andndi3_doubleword" 9335 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r") 9336 (and:DI 9337 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0")) 9338 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm"))) 9339 (clobber (reg:CC FLAGS_REG))] 9340 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" 9341 "#" 9342 [(set_attr "isa" "bmi,bmi,bmi,*")]) 9343 9344(define_split 9345 [(set (match_operand:DI 0 "register_operand") 9346 (and:DI 9347 (not:DI (match_operand:DI 1 "register_operand")) 9348 (match_operand:DI 2 "nonimmediate_operand"))) 9349 (clobber (reg:CC FLAGS_REG))] 9350 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2 9351 && reload_completed" 9352 [(parallel [(set (match_dup 0) 9353 (and:SI (not:SI (match_dup 1)) (match_dup 2))) 9354 (clobber (reg:CC FLAGS_REG))]) 9355 (parallel [(set (match_dup 3) 9356 (and:SI (not:SI (match_dup 4)) (match_dup 5))) 9357 (clobber (reg:CC FLAGS_REG))])] 9358 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);") 9359 9360(define_split 9361 [(set (match_operand:DI 0 "register_operand") 9362 (and:DI 9363 (not:DI (match_dup 0)) 9364 (match_operand:DI 1 "nonimmediate_operand"))) 9365 (clobber (reg:CC FLAGS_REG))] 9366 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2 9367 && reload_completed" 9368 [(set (match_dup 0) (not:SI (match_dup 0))) 9369 (parallel [(set (match_dup 0) 9370 (and:SI (match_dup 0) (match_dup 1))) 9371 (clobber (reg:CC FLAGS_REG))]) 9372 (set (match_dup 2) (not:SI (match_dup 2))) 9373 (parallel [(set (match_dup 2) 9374 (and:SI (match_dup 2) (match_dup 3))) 9375 (clobber (reg:CC FLAGS_REG))])] 9376 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);") 9377 9378(define_insn "*andn<mode>_1" 9379 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 9380 (and:SWI48 9381 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r")) 9382 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))) 9383 (clobber (reg:CC FLAGS_REG))] 9384 "TARGET_BMI" 9385 "andn\t{%2, %1, %0|%0, %1, %2}" 9386 [(set_attr "type" "bitmanip") 9387 (set_attr "btver2_decode" "direct, double") 9388 (set_attr "mode" "<MODE>")]) 9389 9390(define_insn "*andn<mode>_1" 9391 [(set (match_operand:SWI12 0 "register_operand" "=r") 9392 (and:SWI12 9393 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r")) 9394 (match_operand:SWI12 2 "register_operand" "r"))) 9395 (clobber (reg:CC FLAGS_REG))] 9396 "TARGET_BMI" 9397 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}" 9398 [(set_attr "type" "bitmanip") 9399 (set_attr "btver2_decode" "direct") 9400 (set_attr "mode" "SI")]) 9401 9402(define_insn "*andn_<mode>_ccno" 9403 [(set (reg FLAGS_REG) 9404 (compare 9405 (and:SWI48 9406 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r")) 9407 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")) 9408 (const_int 0))) 9409 (clobber (match_scratch:SWI48 0 "=r,r"))] 9410 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)" 9411 "andn\t{%2, %1, %0|%0, %1, %2}" 9412 [(set_attr "type" "bitmanip") 9413 (set_attr "btver2_decode" "direct, double") 9414 (set_attr "mode" "<MODE>")]) 9415 9416;; Logical inclusive and exclusive OR instructions 9417 9418;; %%% This used to optimize known byte-wide and operations to memory. 9419;; If this is considered useful, it should be done with splitters. 9420 9421(define_expand "<code><mode>3" 9422 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand") 9423 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand") 9424 (match_operand:SWIM1248x 2 "<general_operand>")))] 9425 "" 9426 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 9427 9428(define_insn_and_split "*<code>di3_doubleword" 9429 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 9430 (any_or:DI 9431 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 9432 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm"))) 9433 (clobber (reg:CC FLAGS_REG))] 9434 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 9435 && ix86_binary_operator_ok (<CODE>, DImode, operands)" 9436 "#" 9437 "&& reload_completed" 9438 [(const_int 0)] 9439{ 9440 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); 9441 if (operands[2] == constm1_rtx) 9442 { 9443 if (<CODE> == IOR) 9444 { 9445 operands[1] = constm1_rtx; 9446 ix86_expand_move (SImode, &operands[0]); 9447 } 9448 else 9449 ix86_expand_unary_operator (NOT, SImode, &operands[0]); 9450 } 9451 else if (operands[2] != const0_rtx) 9452 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]); 9453 else if (operands[5] == const0_rtx) 9454 emit_note (NOTE_INSN_DELETED); 9455 if (operands[5] == constm1_rtx) 9456 { 9457 if (<CODE> == IOR) 9458 { 9459 operands[4] = constm1_rtx; 9460 ix86_expand_move (SImode, &operands[3]); 9461 } 9462 else 9463 ix86_expand_unary_operator (NOT, SImode, &operands[3]); 9464 } 9465 else if (operands[5] != const0_rtx) 9466 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]); 9467 DONE; 9468}) 9469 9470(define_insn "*<code><mode>_1" 9471 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm") 9472 (any_or:SWI248 9473 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0") 9474 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>"))) 9475 (clobber (reg:CC FLAGS_REG))] 9476 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9477 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9478 [(set_attr "type" "alu") 9479 (set_attr "mode" "<MODE>")]) 9480 9481(define_insn_and_split "*iordi_1_bts" 9482 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9483 (ior:DI 9484 (match_operand:DI 1 "nonimmediate_operand" "%0") 9485 (match_operand:DI 2 "const_int_operand" "n"))) 9486 (clobber (reg:CC FLAGS_REG))] 9487 "TARGET_64BIT && TARGET_USE_BT 9488 && ix86_binary_operator_ok (IOR, DImode, operands) 9489 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)" 9490 "#" 9491 "&& reload_completed" 9492 [(parallel [(set (zero_extract:DI (match_dup 0) 9493 (const_int 1) 9494 (match_dup 3)) 9495 (const_int 1)) 9496 (clobber (reg:CC FLAGS_REG))])] 9497 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));" 9498 [(set_attr "type" "alu1") 9499 (set_attr "prefix_0f" "1") 9500 (set_attr "znver1_decode" "double") 9501 (set_attr "mode" "DI")]) 9502 9503(define_insn_and_split "*xordi_1_btc" 9504 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9505 (xor:DI 9506 (match_operand:DI 1 "nonimmediate_operand" "%0") 9507 (match_operand:DI 2 "const_int_operand" "n"))) 9508 (clobber (reg:CC FLAGS_REG))] 9509 "TARGET_64BIT && TARGET_USE_BT 9510 && ix86_binary_operator_ok (XOR, DImode, operands) 9511 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)" 9512 "#" 9513 "&& reload_completed" 9514 [(parallel [(set (zero_extract:DI (match_dup 0) 9515 (const_int 1) 9516 (match_dup 3)) 9517 (not:DI (zero_extract:DI (match_dup 0) 9518 (const_int 1) 9519 (match_dup 3)))) 9520 (clobber (reg:CC FLAGS_REG))])] 9521 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));" 9522 [(set_attr "type" "alu1") 9523 (set_attr "prefix_0f" "1") 9524 (set_attr "znver1_decode" "double") 9525 (set_attr "mode" "DI")]) 9526 9527;; See comment for addsi_1_zext why we do use nonimmediate_operand 9528(define_insn "*<code>si_1_zext" 9529 [(set (match_operand:DI 0 "register_operand" "=r") 9530 (zero_extend:DI 9531 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9532 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 9533 (clobber (reg:CC FLAGS_REG))] 9534 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9535 "<logic>{l}\t{%2, %k0|%k0, %2}" 9536 [(set_attr "type" "alu") 9537 (set_attr "mode" "SI")]) 9538 9539(define_insn "*<code>si_1_zext_imm" 9540 [(set (match_operand:DI 0 "register_operand" "=r") 9541 (any_or:DI 9542 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 9543 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 9544 (clobber (reg:CC FLAGS_REG))] 9545 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9546 "<logic>{l}\t{%2, %k0|%k0, %2}" 9547 [(set_attr "type" "alu") 9548 (set_attr "mode" "SI")]) 9549 9550(define_insn "*<code>qi_1" 9551 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 9552 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9553 (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) 9554 (clobber (reg:CC FLAGS_REG))] 9555 "ix86_binary_operator_ok (<CODE>, QImode, operands)" 9556 "@ 9557 <logic>{b}\t{%2, %0|%0, %2} 9558 <logic>{b}\t{%2, %0|%0, %2} 9559 <logic>{l}\t{%k2, %k0|%k0, %k2}" 9560 [(set_attr "type" "alu") 9561 (set_attr "mode" "QI,QI,SI") 9562 ;; Potential partial reg stall on alternative 2. 9563 (set (attr "preferred_for_speed") 9564 (cond [(eq_attr "alternative" "2") 9565 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 9566 (symbol_ref "true")))]) 9567 9568(define_insn "*<code>qi_1_slp" 9569 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 9570 (any_or:QI (match_dup 0) 9571 (match_operand:QI 1 "general_operand" "qmn,qn"))) 9572 (clobber (reg:CC FLAGS_REG))] 9573 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9574 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9575 "<logic>{b}\t{%1, %0|%0, %1}" 9576 [(set_attr "type" "alu1") 9577 (set_attr "mode" "QI")]) 9578 9579(define_insn "*<code><mode>_2" 9580 [(set (reg FLAGS_REG) 9581 (compare (any_or:SWI 9582 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 9583 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")) 9584 (const_int 0))) 9585 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 9586 (any_or:SWI (match_dup 1) (match_dup 2)))] 9587 "ix86_match_ccmode (insn, CCNOmode) 9588 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9589 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9590 [(set_attr "type" "alu") 9591 (set_attr "mode" "<MODE>")]) 9592 9593;; See comment for addsi_1_zext why we do use nonimmediate_operand 9594;; ??? Special case for immediate operand is missing - it is tricky. 9595(define_insn "*<code>si_2_zext" 9596 [(set (reg FLAGS_REG) 9597 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9598 (match_operand:SI 2 "x86_64_general_operand" "rme")) 9599 (const_int 0))) 9600 (set (match_operand:DI 0 "register_operand" "=r") 9601 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] 9602 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9603 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9604 "<logic>{l}\t{%2, %k0|%k0, %2}" 9605 [(set_attr "type" "alu") 9606 (set_attr "mode" "SI")]) 9607 9608(define_insn "*<code>si_2_zext_imm" 9609 [(set (reg FLAGS_REG) 9610 (compare (any_or:SI 9611 (match_operand:SI 1 "nonimmediate_operand" "%0") 9612 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z")) 9613 (const_int 0))) 9614 (set (match_operand:DI 0 "register_operand" "=r") 9615 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 9616 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9617 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9618 "<logic>{l}\t{%2, %k0|%k0, %2}" 9619 [(set_attr "type" "alu") 9620 (set_attr "mode" "SI")]) 9621 9622(define_insn "*<code>qi_2_slp" 9623 [(set (reg FLAGS_REG) 9624 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9625 (match_operand:QI 1 "general_operand" "qmn,qn")) 9626 (const_int 0))) 9627 (set (strict_low_part (match_dup 0)) 9628 (any_or:QI (match_dup 0) (match_dup 1)))] 9629 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9630 && ix86_match_ccmode (insn, CCNOmode) 9631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9632 "<logic>{b}\t{%1, %0|%0, %1}" 9633 [(set_attr "type" "alu1") 9634 (set_attr "mode" "QI")]) 9635 9636(define_insn "*<code><mode>_3" 9637 [(set (reg FLAGS_REG) 9638 (compare (any_or:SWI 9639 (match_operand:SWI 1 "nonimmediate_operand" "%0") 9640 (match_operand:SWI 2 "<general_operand>" "<g>")) 9641 (const_int 0))) 9642 (clobber (match_scratch:SWI 0 "=<r>"))] 9643 "ix86_match_ccmode (insn, CCNOmode) 9644 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 9645 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9646 [(set_attr "type" "alu") 9647 (set_attr "mode" "<MODE>")]) 9648 9649(define_insn "*<code>qi_ext_1" 9650 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9651 (const_int 8) 9652 (const_int 8)) 9653 (subreg:SI 9654 (any_or:QI 9655 (subreg:QI 9656 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9657 (const_int 8) 9658 (const_int 8)) 0) 9659 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 9660 (clobber (reg:CC FLAGS_REG))] 9661 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9662 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9663 && rtx_equal_p (operands[0], operands[1])" 9664 "<logic>{b}\t{%2, %h0|%h0, %2}" 9665 [(set_attr "isa" "*,nox64") 9666 (set_attr "type" "alu") 9667 (set_attr "mode" "QI")]) 9668 9669(define_insn "*<code>qi_ext_2" 9670 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 9671 (const_int 8) 9672 (const_int 8)) 9673 (subreg:SI 9674 (any_or:QI 9675 (subreg:QI 9676 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 9677 (const_int 8) 9678 (const_int 8)) 0) 9679 (subreg:QI 9680 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9681 (const_int 8) 9682 (const_int 8)) 0)) 0)) 9683 (clobber (reg:CC FLAGS_REG))] 9684 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9685 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9686 && (rtx_equal_p (operands[0], operands[1]) 9687 || rtx_equal_p (operands[0], operands[2]))" 9688 "<logic>{b}\t{%h2, %h0|%h0, %h2}" 9689 [(set_attr "type" "alu") 9690 (set_attr "mode" "QI")]) 9691 9692;; Convert wide OR instructions with immediate operand to shorter QImode 9693;; equivalents when possible. 9694;; Don't do the splitting with memory operands, since it introduces risk 9695;; of memory mismatch stalls. We may want to do the splitting for optimizing 9696;; for size, but that can (should?) be handled by generic code instead. 9697(define_split 9698 [(set (match_operand:SWI248 0 "QIreg_operand") 9699 (any_or:SWI248 (match_operand:SWI248 1 "register_operand") 9700 (match_operand:SWI248 2 "const_int_operand"))) 9701 (clobber (reg:CC FLAGS_REG))] 9702 "reload_completed 9703 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9704 && !(INTVAL (operands[2]) & ~(255 << 8))" 9705 [(parallel 9706 [(set (zero_extract:SI (match_dup 0) 9707 (const_int 8) 9708 (const_int 8)) 9709 (subreg:SI 9710 (any_or:QI 9711 (subreg:QI 9712 (zero_extract:SI (match_dup 1) 9713 (const_int 8) 9714 (const_int 8)) 0) 9715 (match_dup 2)) 0)) 9716 (clobber (reg:CC FLAGS_REG))])] 9717{ 9718 operands[0] = gen_lowpart (SImode, operands[0]); 9719 operands[1] = gen_lowpart (SImode, operands[1]); 9720 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode); 9721}) 9722 9723;; Since OR can be encoded with sign extended immediate, this is only 9724;; profitable when 7th bit is set. 9725(define_split 9726 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9727 (any_or:SWI248 (match_operand:SWI248 1 "general_operand") 9728 (match_operand:SWI248 2 "const_int_operand"))) 9729 (clobber (reg:CC FLAGS_REG))] 9730 "reload_completed 9731 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9732 && !(INTVAL (operands[2]) & ~255) 9733 && (INTVAL (operands[2]) & 128)" 9734 [(parallel [(set (strict_low_part (match_dup 0)) 9735 (any_or:QI (match_dup 1) 9736 (match_dup 2))) 9737 (clobber (reg:CC FLAGS_REG))])] 9738{ 9739 operands[0] = gen_lowpart (QImode, operands[0]); 9740 operands[1] = gen_lowpart (QImode, operands[1]); 9741 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 9742}) 9743 9744(define_expand "xorqi_ext_1_cc" 9745 [(parallel [ 9746 (set (reg:CCNO FLAGS_REG) 9747 (compare:CCNO 9748 (xor:QI 9749 (subreg:QI 9750 (zero_extract:SI (match_operand 1 "ext_register_operand") 9751 (const_int 8) 9752 (const_int 8)) 0) 9753 (match_operand 2 "const_int_operand")) 9754 (const_int 0))) 9755 (set (zero_extract:SI (match_operand 0 "ext_register_operand") 9756 (const_int 8) 9757 (const_int 8)) 9758 (subreg:SI 9759 (xor:QI 9760 (subreg:QI 9761 (zero_extract:SI (match_dup 1) 9762 (const_int 8) 9763 (const_int 8)) 0) 9764 (match_dup 2)) 0))])]) 9765 9766(define_insn "*xorqi_ext_1_cc" 9767 [(set (reg FLAGS_REG) 9768 (compare 9769 (xor:QI 9770 (subreg:QI 9771 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9772 (const_int 8) 9773 (const_int 8)) 0) 9774 (match_operand:QI 2 "general_operand" "QnBc,m")) 9775 (const_int 0))) 9776 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9777 (const_int 8) 9778 (const_int 8)) 9779 (subreg:SI 9780 (xor:QI 9781 (subreg:QI 9782 (zero_extract:SI (match_dup 1) 9783 (const_int 8) 9784 (const_int 8)) 0) 9785 (match_dup 2)) 0))] 9786 "ix86_match_ccmode (insn, CCNOmode) 9787 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9788 && rtx_equal_p (operands[0], operands[1])" 9789 "xor{b}\t{%2, %h0|%h0, %2}" 9790 [(set_attr "isa" "*,nox64") 9791 (set_attr "type" "alu") 9792 (set_attr "mode" "QI")]) 9793 9794;; Negation instructions 9795 9796(define_expand "neg<mode>2" 9797 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 9798 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))] 9799 "" 9800 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;") 9801 9802(define_insn_and_split "*neg<dwi>2_doubleword" 9803 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 9804 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0"))) 9805 (clobber (reg:CC FLAGS_REG))] 9806 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)" 9807 "#" 9808 "reload_completed" 9809 [(parallel 9810 [(set (reg:CCZ FLAGS_REG) 9811 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0))) 9812 (set (match_dup 0) (neg:DWIH (match_dup 1)))]) 9813 (parallel 9814 [(set (match_dup 2) 9815 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 9816 (match_dup 3)) 9817 (const_int 0))) 9818 (clobber (reg:CC FLAGS_REG))]) 9819 (parallel 9820 [(set (match_dup 2) 9821 (neg:DWIH (match_dup 2))) 9822 (clobber (reg:CC FLAGS_REG))])] 9823 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);") 9824 9825(define_insn "*neg<mode>2_1" 9826 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9827 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) 9828 (clobber (reg:CC FLAGS_REG))] 9829 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 9830 "neg{<imodesuffix>}\t%0" 9831 [(set_attr "type" "negnot") 9832 (set_attr "mode" "<MODE>")]) 9833 9834;; Combine is quite creative about this pattern. 9835(define_insn "*negsi2_1_zext" 9836 [(set (match_operand:DI 0 "register_operand" "=r") 9837 (lshiftrt:DI 9838 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 9839 (const_int 32))) 9840 (const_int 32))) 9841 (clobber (reg:CC FLAGS_REG))] 9842 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9843 "neg{l}\t%k0" 9844 [(set_attr "type" "negnot") 9845 (set_attr "mode" "SI")]) 9846 9847;; The problem with neg is that it does not perform (compare x 0), 9848;; it really performs (compare 0 x), which leaves us with the zero 9849;; flag being the only useful item. 9850 9851(define_insn "*neg<mode>2_cmpz" 9852 [(set (reg:CCZ FLAGS_REG) 9853 (compare:CCZ 9854 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 9855 (const_int 0))) 9856 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9857 (neg:SWI (match_dup 1)))] 9858 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 9859 "neg{<imodesuffix>}\t%0" 9860 [(set_attr "type" "negnot") 9861 (set_attr "mode" "<MODE>")]) 9862 9863(define_insn "*negsi2_cmpz_zext" 9864 [(set (reg:CCZ FLAGS_REG) 9865 (compare:CCZ 9866 (lshiftrt:DI 9867 (neg:DI (ashift:DI 9868 (match_operand:DI 1 "register_operand" "0") 9869 (const_int 32))) 9870 (const_int 32)) 9871 (const_int 0))) 9872 (set (match_operand:DI 0 "register_operand" "=r") 9873 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 9874 (const_int 32))) 9875 (const_int 32)))] 9876 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9877 "neg{l}\t%k0" 9878 [(set_attr "type" "negnot") 9879 (set_attr "mode" "SI")]) 9880 9881;; Negate with jump on overflow. 9882(define_expand "negv<mode>3" 9883 [(parallel [(set (reg:CCO FLAGS_REG) 9884 (ne:CCO (match_operand:SWI 1 "register_operand") 9885 (match_dup 3))) 9886 (set (match_operand:SWI 0 "register_operand") 9887 (neg:SWI (match_dup 1)))]) 9888 (set (pc) (if_then_else 9889 (eq (reg:CCO FLAGS_REG) (const_int 0)) 9890 (label_ref (match_operand 2)) 9891 (pc)))] 9892 "" 9893{ 9894 operands[3] 9895 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1), 9896 <MODE>mode); 9897}) 9898 9899(define_insn "*negv<mode>3" 9900 [(set (reg:CCO FLAGS_REG) 9901 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") 9902 (match_operand:SWI 2 "const_int_operand"))) 9903 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9904 (neg:SWI (match_dup 1)))] 9905 "ix86_unary_operator_ok (NEG, <MODE>mode, operands) 9906 && mode_signbit_p (<MODE>mode, operands[2])" 9907 "neg{<imodesuffix>}\t%0" 9908 [(set_attr "type" "negnot") 9909 (set_attr "mode" "<MODE>")]) 9910 9911;; Changing of sign for FP values is doable using integer unit too. 9912 9913(define_expand "<code><mode>2" 9914 [(set (match_operand:X87MODEF 0 "register_operand") 9915 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))] 9916 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 9917 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 9918 9919(define_insn "*absneg<mode>2" 9920 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r") 9921 (match_operator:MODEF 3 "absneg_operator" 9922 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")])) 9923 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X")) 9924 (clobber (reg:CC FLAGS_REG))] 9925 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 9926 "#" 9927 [(set (attr "enabled") 9928 (if_then_else 9929 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 9930 (if_then_else 9931 (eq_attr "alternative" "2") 9932 (symbol_ref "TARGET_MIX_SSE_I387") 9933 (symbol_ref "true")) 9934 (if_then_else 9935 (eq_attr "alternative" "2,3") 9936 (symbol_ref "true") 9937 (symbol_ref "false"))))]) 9938 9939(define_insn "*absnegxf2_i387" 9940 [(set (match_operand:XF 0 "register_operand" "=f,!r") 9941 (match_operator:XF 3 "absneg_operator" 9942 [(match_operand:XF 1 "register_operand" "0,0")])) 9943 (use (match_operand 2)) 9944 (clobber (reg:CC FLAGS_REG))] 9945 "TARGET_80387" 9946 "#") 9947 9948(define_expand "<code>tf2" 9949 [(set (match_operand:TF 0 "register_operand") 9950 (absneg:TF (match_operand:TF 1 "register_operand")))] 9951 "TARGET_SSE" 9952 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") 9953 9954(define_insn "*absnegtf2_sse" 9955 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv") 9956 (match_operator:TF 3 "absneg_operator" 9957 [(match_operand:TF 1 "register_operand" "0,Yv")])) 9958 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0")) 9959 (clobber (reg:CC FLAGS_REG))] 9960 "TARGET_SSE" 9961 "#") 9962 9963;; Splitters for fp abs and neg. 9964 9965(define_split 9966 [(set (match_operand 0 "fp_register_operand") 9967 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9968 (use (match_operand 2)) 9969 (clobber (reg:CC FLAGS_REG))] 9970 "reload_completed" 9971 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 9972 9973(define_split 9974 [(set (match_operand 0 "sse_reg_operand") 9975 (match_operator 3 "absneg_operator" 9976 [(match_operand 1 "register_operand")])) 9977 (use (match_operand 2 "nonimmediate_operand")) 9978 (clobber (reg:CC FLAGS_REG))] 9979 "reload_completed" 9980 [(set (match_dup 0) (match_dup 3))] 9981{ 9982 machine_mode mode = GET_MODE (operands[0]); 9983 machine_mode vmode = GET_MODE (operands[2]); 9984 rtx tmp; 9985 9986 operands[0] = lowpart_subreg (vmode, operands[0], mode); 9987 operands[1] = lowpart_subreg (vmode, operands[1], mode); 9988 if (operands_match_p (operands[0], operands[2])) 9989 std::swap (operands[1], operands[2]); 9990 if (GET_CODE (operands[3]) == ABS) 9991 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 9992 else 9993 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 9994 operands[3] = tmp; 9995}) 9996 9997(define_split 9998 [(set (match_operand:SF 0 "general_reg_operand") 9999 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 10000 (use (match_operand:V4SF 2)) 10001 (clobber (reg:CC FLAGS_REG))] 10002 "reload_completed" 10003 [(parallel [(set (match_dup 0) (match_dup 1)) 10004 (clobber (reg:CC FLAGS_REG))])] 10005{ 10006 rtx tmp; 10007 operands[0] = gen_lowpart (SImode, operands[0]); 10008 if (GET_CODE (operands[1]) == ABS) 10009 { 10010 tmp = gen_int_mode (0x7fffffff, SImode); 10011 tmp = gen_rtx_AND (SImode, operands[0], tmp); 10012 } 10013 else 10014 { 10015 tmp = gen_int_mode (0x80000000, SImode); 10016 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10017 } 10018 operands[1] = tmp; 10019}) 10020 10021(define_split 10022 [(set (match_operand:DF 0 "general_reg_operand") 10023 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 10024 (use (match_operand 2)) 10025 (clobber (reg:CC FLAGS_REG))] 10026 "reload_completed" 10027 [(parallel [(set (match_dup 0) (match_dup 1)) 10028 (clobber (reg:CC FLAGS_REG))])] 10029{ 10030 rtx tmp; 10031 if (TARGET_64BIT) 10032 { 10033 tmp = gen_lowpart (DImode, operands[0]); 10034 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 10035 operands[0] = tmp; 10036 10037 if (GET_CODE (operands[1]) == ABS) 10038 tmp = const0_rtx; 10039 else 10040 tmp = gen_rtx_NOT (DImode, tmp); 10041 } 10042 else 10043 { 10044 operands[0] = gen_highpart (SImode, operands[0]); 10045 if (GET_CODE (operands[1]) == ABS) 10046 { 10047 tmp = gen_int_mode (0x7fffffff, SImode); 10048 tmp = gen_rtx_AND (SImode, operands[0], tmp); 10049 } 10050 else 10051 { 10052 tmp = gen_int_mode (0x80000000, SImode); 10053 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10054 } 10055 } 10056 operands[1] = tmp; 10057}) 10058 10059(define_split 10060 [(set (match_operand:XF 0 "general_reg_operand") 10061 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 10062 (use (match_operand 2)) 10063 (clobber (reg:CC FLAGS_REG))] 10064 "reload_completed" 10065 [(parallel [(set (match_dup 0) (match_dup 1)) 10066 (clobber (reg:CC FLAGS_REG))])] 10067{ 10068 rtx tmp; 10069 operands[0] = gen_rtx_REG (SImode, 10070 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2)); 10071 if (GET_CODE (operands[1]) == ABS) 10072 { 10073 tmp = GEN_INT (0x7fff); 10074 tmp = gen_rtx_AND (SImode, operands[0], tmp); 10075 } 10076 else 10077 { 10078 tmp = GEN_INT (0x8000); 10079 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10080 } 10081 operands[1] = tmp; 10082}) 10083 10084;; Conditionalize these after reload. If they match before reload, we 10085;; lose the clobber and ability to use integer instructions. 10086 10087(define_insn "*<code><mode>2_1" 10088 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 10089 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] 10090 "TARGET_80387 10091 && (reload_completed 10092 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 10093 "f<absneg_mnemonic>" 10094 [(set_attr "type" "fsgn") 10095 (set_attr "mode" "<MODE>")]) 10096 10097(define_insn "*<code>extendsfdf2" 10098 [(set (match_operand:DF 0 "register_operand" "=f") 10099 (absneg:DF (float_extend:DF 10100 (match_operand:SF 1 "register_operand" "0"))))] 10101 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 10102 "f<absneg_mnemonic>" 10103 [(set_attr "type" "fsgn") 10104 (set_attr "mode" "DF")]) 10105 10106(define_insn "*<code>extendsfxf2" 10107 [(set (match_operand:XF 0 "register_operand" "=f") 10108 (absneg:XF (float_extend:XF 10109 (match_operand:SF 1 "register_operand" "0"))))] 10110 "TARGET_80387" 10111 "f<absneg_mnemonic>" 10112 [(set_attr "type" "fsgn") 10113 (set_attr "mode" "XF")]) 10114 10115(define_insn "*<code>extenddfxf2" 10116 [(set (match_operand:XF 0 "register_operand" "=f") 10117 (absneg:XF (float_extend:XF 10118 (match_operand:DF 1 "register_operand" "0"))))] 10119 "TARGET_80387" 10120 "f<absneg_mnemonic>" 10121 [(set_attr "type" "fsgn") 10122 (set_attr "mode" "XF")]) 10123 10124;; Copysign instructions 10125 10126(define_mode_iterator CSGNMODE [SF DF TF]) 10127(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) 10128 10129(define_expand "copysign<mode>3" 10130 [(match_operand:CSGNMODE 0 "register_operand") 10131 (match_operand:CSGNMODE 1 "nonmemory_operand") 10132 (match_operand:CSGNMODE 2 "register_operand")] 10133 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10134 || (TARGET_SSE && (<MODE>mode == TFmode))" 10135 "ix86_expand_copysign (operands); DONE;") 10136 10137(define_insn_and_split "copysign<mode>3_const" 10138 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv") 10139 (unspec:CSGNMODE 10140 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC") 10141 (match_operand:CSGNMODE 2 "register_operand" "0") 10142 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")] 10143 UNSPEC_COPYSIGN))] 10144 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10145 || (TARGET_SSE && (<MODE>mode == TFmode))" 10146 "#" 10147 "&& reload_completed" 10148 [(const_int 0)] 10149 "ix86_split_copysign_const (operands); DONE;") 10150 10151(define_insn "copysign<mode>3_var" 10152 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv") 10153 (unspec:CSGNMODE 10154 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv") 10155 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv") 10156 (match_operand:<CSGNVMODE> 4 10157 "nonimmediate_operand" "X,Yvm,Yvm,0,0") 10158 (match_operand:<CSGNVMODE> 5 10159 "nonimmediate_operand" "0,Yvm,1,Yvm,1")] 10160 UNSPEC_COPYSIGN)) 10161 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))] 10162 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10163 || (TARGET_SSE && (<MODE>mode == TFmode))" 10164 "#") 10165 10166(define_split 10167 [(set (match_operand:CSGNMODE 0 "register_operand") 10168 (unspec:CSGNMODE 10169 [(match_operand:CSGNMODE 2 "register_operand") 10170 (match_operand:CSGNMODE 3 "register_operand") 10171 (match_operand:<CSGNVMODE> 4) 10172 (match_operand:<CSGNVMODE> 5)] 10173 UNSPEC_COPYSIGN)) 10174 (clobber (match_scratch:<CSGNVMODE> 1))] 10175 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10176 || (TARGET_SSE && (<MODE>mode == TFmode))) 10177 && reload_completed" 10178 [(const_int 0)] 10179 "ix86_split_copysign_var (operands); DONE;") 10180 10181;; One complement instructions 10182 10183(define_expand "one_cmpl<mode>2" 10184 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand") 10185 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))] 10186 "" 10187 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") 10188 10189(define_insn_and_split "*one_cmpldi2_doubleword" 10190 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10191 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] 10192 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 10193 && ix86_unary_operator_ok (NOT, DImode, operands)" 10194 "#" 10195 "&& reload_completed" 10196 [(set (match_dup 0) 10197 (not:SI (match_dup 1))) 10198 (set (match_dup 2) 10199 (not:SI (match_dup 3)))] 10200 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);") 10201 10202(define_insn "*one_cmpl<mode>2_1" 10203 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") 10204 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))] 10205 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 10206 "not{<imodesuffix>}\t%0" 10207 [(set_attr "type" "negnot") 10208 (set_attr "mode" "<MODE>")]) 10209 10210;; ??? Currently never generated - xor is used instead. 10211(define_insn "*one_cmplsi2_1_zext" 10212 [(set (match_operand:DI 0 "register_operand" "=r") 10213 (zero_extend:DI 10214 (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10215 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10216 "not{l}\t%k0" 10217 [(set_attr "type" "negnot") 10218 (set_attr "mode" "SI")]) 10219 10220(define_insn "*one_cmplqi2_1" 10221 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10222 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10223 "ix86_unary_operator_ok (NOT, QImode, operands)" 10224 "@ 10225 not{b}\t%0 10226 not{l}\t%k0" 10227 [(set_attr "type" "negnot") 10228 (set_attr "mode" "QI,SI") 10229 ;; Potential partial reg stall on alternative 1. 10230 (set (attr "preferred_for_speed") 10231 (cond [(eq_attr "alternative" "1") 10232 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 10233 (symbol_ref "true")))]) 10234 10235(define_insn "*one_cmpl<mode>2_2" 10236 [(set (reg FLAGS_REG) 10237 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 10238 (const_int 0))) 10239 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10240 (not:SWI (match_dup 1)))] 10241 "ix86_match_ccmode (insn, CCNOmode) 10242 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 10243 "#" 10244 [(set_attr "type" "alu1") 10245 (set_attr "mode" "<MODE>")]) 10246 10247(define_split 10248 [(set (match_operand 0 "flags_reg_operand") 10249 (match_operator 2 "compare_operator" 10250 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand")) 10251 (const_int 0)])) 10252 (set (match_operand:SWI 1 "nonimmediate_operand") 10253 (not:SWI (match_dup 3)))] 10254 "ix86_match_ccmode (insn, CCNOmode)" 10255 [(parallel [(set (match_dup 0) 10256 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1)) 10257 (const_int 0)])) 10258 (set (match_dup 1) 10259 (xor:SWI (match_dup 3) (const_int -1)))])]) 10260 10261;; ??? Currently never generated - xor is used instead. 10262(define_insn "*one_cmplsi2_2_zext" 10263 [(set (reg FLAGS_REG) 10264 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10265 (const_int 0))) 10266 (set (match_operand:DI 0 "register_operand" "=r") 10267 (zero_extend:DI (not:SI (match_dup 1))))] 10268 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10269 && ix86_unary_operator_ok (NOT, SImode, operands)" 10270 "#" 10271 [(set_attr "type" "alu1") 10272 (set_attr "mode" "SI")]) 10273 10274(define_split 10275 [(set (match_operand 0 "flags_reg_operand") 10276 (match_operator 2 "compare_operator" 10277 [(not:SI (match_operand:SI 3 "register_operand")) 10278 (const_int 0)])) 10279 (set (match_operand:DI 1 "register_operand") 10280 (zero_extend:DI (not:SI (match_dup 3))))] 10281 "ix86_match_ccmode (insn, CCNOmode)" 10282 [(parallel [(set (match_dup 0) 10283 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10284 (const_int 0)])) 10285 (set (match_dup 1) 10286 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]) 10287 10288;; Shift instructions 10289 10290;; DImode shifts are implemented using the i386 "shift double" opcode, 10291;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10292;; is variable, then the count is in %cl and the "imm" operand is dropped 10293;; from the assembler input. 10294;; 10295;; This instruction shifts the target reg/mem as usual, but instead of 10296;; shifting in zeros, bits are shifted in from reg operand. If the insn 10297;; is a left shift double, bits are taken from the high order bits of 10298;; reg, else if the insn is a shift right double, bits are taken from the 10299;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10300;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10301;; 10302;; Since sh[lr]d does not change the `reg' operand, that is done 10303;; separately, making all shifts emit pairs of shift double and normal 10304;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10305;; support a 63 bit shift, each shift where the count is in a reg expands 10306;; to a pair of shifts, a branch, a shift by 32 and a label. 10307;; 10308;; If the shift count is a constant, we need never emit more than one 10309;; shift pair, instead using moves and sign extension for counts greater 10310;; than 31. 10311 10312(define_expand "ashl<mode>3" 10313 [(set (match_operand:SDWIM 0 "<shift_operand>") 10314 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>") 10315 (match_operand:QI 2 "nonmemory_operand")))] 10316 "" 10317 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") 10318 10319(define_insn "*ashl<mode>3_doubleword" 10320 [(set (match_operand:DWI 0 "register_operand" "=&r") 10321 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n") 10322 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 10323 (clobber (reg:CC FLAGS_REG))] 10324 "" 10325 "#" 10326 [(set_attr "type" "multi")]) 10327 10328(define_split 10329 [(set (match_operand:DWI 0 "register_operand") 10330 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand") 10331 (match_operand:QI 2 "nonmemory_operand"))) 10332 (clobber (reg:CC FLAGS_REG))] 10333 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 10334 [(const_int 0)] 10335 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;") 10336 10337;; By default we don't ask for a scratch register, because when DWImode 10338;; values are manipulated, registers are already at a premium. But if 10339;; we have one handy, we won't turn it away. 10340 10341(define_peephole2 10342 [(match_scratch:DWIH 3 "r") 10343 (parallel [(set (match_operand:<DWI> 0 "register_operand") 10344 (ashift:<DWI> 10345 (match_operand:<DWI> 1 "nonmemory_operand") 10346 (match_operand:QI 2 "nonmemory_operand"))) 10347 (clobber (reg:CC FLAGS_REG))]) 10348 (match_dup 3)] 10349 "TARGET_CMOVE" 10350 [(const_int 0)] 10351 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;") 10352 10353(define_insn "x86_64_shld" 10354 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 10355 (ior:DI (ashift:DI (match_dup 0) 10356 (match_operand:QI 2 "nonmemory_operand" "Jc")) 10357 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 10358 (minus:QI (const_int 64) (match_dup 2))))) 10359 (clobber (reg:CC FLAGS_REG))] 10360 "TARGET_64BIT" 10361 "shld{q}\t{%s2%1, %0|%0, %1, %2}" 10362 [(set_attr "type" "ishift") 10363 (set_attr "prefix_0f" "1") 10364 (set_attr "mode" "DI") 10365 (set_attr "athlon_decode" "vector") 10366 (set_attr "amdfam10_decode" "vector") 10367 (set_attr "bdver1_decode" "vector")]) 10368 10369(define_insn "x86_shld" 10370 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 10371 (ior:SI (ashift:SI (match_dup 0) 10372 (match_operand:QI 2 "nonmemory_operand" "Ic")) 10373 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 10374 (minus:QI (const_int 32) (match_dup 2))))) 10375 (clobber (reg:CC FLAGS_REG))] 10376 "" 10377 "shld{l}\t{%s2%1, %0|%0, %1, %2}" 10378 [(set_attr "type" "ishift") 10379 (set_attr "prefix_0f" "1") 10380 (set_attr "mode" "SI") 10381 (set_attr "pent_pair" "np") 10382 (set_attr "athlon_decode" "vector") 10383 (set_attr "amdfam10_decode" "vector") 10384 (set_attr "bdver1_decode" "vector")]) 10385 10386(define_expand "x86_shift<mode>_adj_1" 10387 [(set (reg:CCZ FLAGS_REG) 10388 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand") 10389 (match_dup 4)) 10390 (const_int 0))) 10391 (set (match_operand:SWI48 0 "register_operand") 10392 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10393 (match_operand:SWI48 1 "register_operand") 10394 (match_dup 0))) 10395 (set (match_dup 1) 10396 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10397 (match_operand:SWI48 3 "register_operand") 10398 (match_dup 1)))] 10399 "TARGET_CMOVE" 10400 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 10401 10402(define_expand "x86_shift<mode>_adj_2" 10403 [(use (match_operand:SWI48 0 "register_operand")) 10404 (use (match_operand:SWI48 1 "register_operand")) 10405 (use (match_operand:QI 2 "register_operand"))] 10406 "" 10407{ 10408 rtx_code_label *label = gen_label_rtx (); 10409 rtx tmp; 10410 10411 emit_insn (gen_testqi_ccz_1 (operands[2], 10412 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 10413 10414 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10415 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10416 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10417 gen_rtx_LABEL_REF (VOIDmode, label), 10418 pc_rtx); 10419 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 10420 JUMP_LABEL (tmp) = label; 10421 10422 emit_move_insn (operands[0], operands[1]); 10423 ix86_expand_clear (operands[1]); 10424 10425 emit_label (label); 10426 LABEL_NUSES (label) = 1; 10427 10428 DONE; 10429}) 10430 10431;; Avoid useless masking of count operand. 10432(define_insn_and_split "*ashl<mode>3_mask" 10433 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10434 (ashift:SWI48 10435 (match_operand:SWI48 1 "nonimmediate_operand") 10436 (subreg:QI 10437 (and:SI 10438 (match_operand:SI 2 "register_operand" "c,r") 10439 (match_operand:SI 3 "const_int_operand")) 0))) 10440 (clobber (reg:CC FLAGS_REG))] 10441 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 10442 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10443 == GET_MODE_BITSIZE (<MODE>mode)-1 10444 && can_create_pseudo_p ()" 10445 "#" 10446 "&& 1" 10447 [(parallel 10448 [(set (match_dup 0) 10449 (ashift:SWI48 (match_dup 1) 10450 (match_dup 2))) 10451 (clobber (reg:CC FLAGS_REG))])] 10452 "operands[2] = gen_lowpart (QImode, operands[2]);" 10453 [(set_attr "isa" "*,bmi2")]) 10454 10455(define_insn_and_split "*ashl<mode>3_mask_1" 10456 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10457 (ashift:SWI48 10458 (match_operand:SWI48 1 "nonimmediate_operand") 10459 (and:QI 10460 (match_operand:QI 2 "register_operand" "c,r") 10461 (match_operand:QI 3 "const_int_operand")))) 10462 (clobber (reg:CC FLAGS_REG))] 10463 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 10464 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10465 == GET_MODE_BITSIZE (<MODE>mode)-1 10466 && can_create_pseudo_p ()" 10467 "#" 10468 "&& 1" 10469 [(parallel 10470 [(set (match_dup 0) 10471 (ashift:SWI48 (match_dup 1) 10472 (match_dup 2))) 10473 (clobber (reg:CC FLAGS_REG))])] 10474 "" 10475 [(set_attr "isa" "*,bmi2")]) 10476 10477(define_insn "*bmi2_ashl<mode>3_1" 10478 [(set (match_operand:SWI48 0 "register_operand" "=r") 10479 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10480 (match_operand:SWI48 2 "register_operand" "r")))] 10481 "TARGET_BMI2" 10482 "shlx\t{%2, %1, %0|%0, %1, %2}" 10483 [(set_attr "type" "ishiftx") 10484 (set_attr "mode" "<MODE>")]) 10485 10486(define_insn "*ashl<mode>3_1" 10487 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") 10488 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm") 10489 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r"))) 10490 (clobber (reg:CC FLAGS_REG))] 10491 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 10492{ 10493 switch (get_attr_type (insn)) 10494 { 10495 case TYPE_LEA: 10496 case TYPE_ISHIFTX: 10497 return "#"; 10498 10499 case TYPE_ALU: 10500 gcc_assert (operands[2] == const1_rtx); 10501 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10502 return "add{<imodesuffix>}\t%0, %0"; 10503 10504 default: 10505 if (operands[2] == const1_rtx 10506 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10507 return "sal{<imodesuffix>}\t%0"; 10508 else 10509 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10510 } 10511} 10512 [(set_attr "isa" "*,*,bmi2") 10513 (set (attr "type") 10514 (cond [(eq_attr "alternative" "1") 10515 (const_string "lea") 10516 (eq_attr "alternative" "2") 10517 (const_string "ishiftx") 10518 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10519 (match_operand 0 "register_operand")) 10520 (match_operand 2 "const1_operand")) 10521 (const_string "alu") 10522 ] 10523 (const_string "ishift"))) 10524 (set (attr "length_immediate") 10525 (if_then_else 10526 (ior (eq_attr "type" "alu") 10527 (and (eq_attr "type" "ishift") 10528 (and (match_operand 2 "const1_operand") 10529 (ior (match_test "TARGET_SHIFT1") 10530 (match_test "optimize_function_for_size_p (cfun)"))))) 10531 (const_string "0") 10532 (const_string "*"))) 10533 (set_attr "mode" "<MODE>")]) 10534 10535;; Convert shift to the shiftx pattern to avoid flags dependency. 10536(define_split 10537 [(set (match_operand:SWI48 0 "register_operand") 10538 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 10539 (match_operand:QI 2 "register_operand"))) 10540 (clobber (reg:CC FLAGS_REG))] 10541 "TARGET_BMI2 && reload_completed" 10542 [(set (match_dup 0) 10543 (ashift:SWI48 (match_dup 1) (match_dup 2)))] 10544 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 10545 10546(define_insn "*bmi2_ashlsi3_1_zext" 10547 [(set (match_operand:DI 0 "register_operand" "=r") 10548 (zero_extend:DI 10549 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10550 (match_operand:SI 2 "register_operand" "r"))))] 10551 "TARGET_64BIT && TARGET_BMI2" 10552 "shlx\t{%2, %1, %k0|%k0, %1, %2}" 10553 [(set_attr "type" "ishiftx") 10554 (set_attr "mode" "SI")]) 10555 10556(define_insn "*ashlsi3_1_zext" 10557 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 10558 (zero_extend:DI 10559 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm") 10560 (match_operand:QI 2 "nonmemory_operand" "cI,M,r")))) 10561 (clobber (reg:CC FLAGS_REG))] 10562 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10563{ 10564 switch (get_attr_type (insn)) 10565 { 10566 case TYPE_LEA: 10567 case TYPE_ISHIFTX: 10568 return "#"; 10569 10570 case TYPE_ALU: 10571 gcc_assert (operands[2] == const1_rtx); 10572 return "add{l}\t%k0, %k0"; 10573 10574 default: 10575 if (operands[2] == const1_rtx 10576 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10577 return "sal{l}\t%k0"; 10578 else 10579 return "sal{l}\t{%2, %k0|%k0, %2}"; 10580 } 10581} 10582 [(set_attr "isa" "*,*,bmi2") 10583 (set (attr "type") 10584 (cond [(eq_attr "alternative" "1") 10585 (const_string "lea") 10586 (eq_attr "alternative" "2") 10587 (const_string "ishiftx") 10588 (and (match_test "TARGET_DOUBLE_WITH_ADD") 10589 (match_operand 2 "const1_operand")) 10590 (const_string "alu") 10591 ] 10592 (const_string "ishift"))) 10593 (set (attr "length_immediate") 10594 (if_then_else 10595 (ior (eq_attr "type" "alu") 10596 (and (eq_attr "type" "ishift") 10597 (and (match_operand 2 "const1_operand") 10598 (ior (match_test "TARGET_SHIFT1") 10599 (match_test "optimize_function_for_size_p (cfun)"))))) 10600 (const_string "0") 10601 (const_string "*"))) 10602 (set_attr "mode" "SI")]) 10603 10604;; Convert shift to the shiftx pattern to avoid flags dependency. 10605(define_split 10606 [(set (match_operand:DI 0 "register_operand") 10607 (zero_extend:DI 10608 (ashift:SI (match_operand:SI 1 "nonimmediate_operand") 10609 (match_operand:QI 2 "register_operand")))) 10610 (clobber (reg:CC FLAGS_REG))] 10611 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10612 [(set (match_dup 0) 10613 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10614 "operands[2] = gen_lowpart (SImode, operands[2]);") 10615 10616(define_insn "*ashlhi3_1" 10617 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") 10618 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10619 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10620 (clobber (reg:CC FLAGS_REG))] 10621 "ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10622{ 10623 switch (get_attr_type (insn)) 10624 { 10625 case TYPE_LEA: 10626 return "#"; 10627 10628 case TYPE_ALU: 10629 gcc_assert (operands[2] == const1_rtx); 10630 return "add{w}\t%0, %0"; 10631 10632 default: 10633 if (operands[2] == const1_rtx 10634 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10635 return "sal{w}\t%0"; 10636 else 10637 return "sal{w}\t{%2, %0|%0, %2}"; 10638 } 10639} 10640 [(set (attr "type") 10641 (cond [(eq_attr "alternative" "1") 10642 (const_string "lea") 10643 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10644 (match_operand 0 "register_operand")) 10645 (match_operand 2 "const1_operand")) 10646 (const_string "alu") 10647 ] 10648 (const_string "ishift"))) 10649 (set (attr "length_immediate") 10650 (if_then_else 10651 (ior (eq_attr "type" "alu") 10652 (and (eq_attr "type" "ishift") 10653 (and (match_operand 2 "const1_operand") 10654 (ior (match_test "TARGET_SHIFT1") 10655 (match_test "optimize_function_for_size_p (cfun)"))))) 10656 (const_string "0") 10657 (const_string "*"))) 10658 (set_attr "mode" "HI,SI")]) 10659 10660(define_insn "*ashlqi3_1" 10661 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") 10662 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 10663 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 10664 (clobber (reg:CC FLAGS_REG))] 10665 "ix86_binary_operator_ok (ASHIFT, QImode, operands)" 10666{ 10667 switch (get_attr_type (insn)) 10668 { 10669 case TYPE_LEA: 10670 return "#"; 10671 10672 case TYPE_ALU: 10673 gcc_assert (operands[2] == const1_rtx); 10674 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1]))) 10675 return "add{l}\t%k0, %k0"; 10676 else 10677 return "add{b}\t%0, %0"; 10678 10679 default: 10680 if (operands[2] == const1_rtx 10681 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10682 { 10683 if (get_attr_mode (insn) == MODE_SI) 10684 return "sal{l}\t%k0"; 10685 else 10686 return "sal{b}\t%0"; 10687 } 10688 else 10689 { 10690 if (get_attr_mode (insn) == MODE_SI) 10691 return "sal{l}\t{%2, %k0|%k0, %2}"; 10692 else 10693 return "sal{b}\t{%2, %0|%0, %2}"; 10694 } 10695 } 10696} 10697 [(set (attr "type") 10698 (cond [(eq_attr "alternative" "2") 10699 (const_string "lea") 10700 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10701 (match_operand 0 "register_operand")) 10702 (match_operand 2 "const1_operand")) 10703 (const_string "alu") 10704 ] 10705 (const_string "ishift"))) 10706 (set (attr "length_immediate") 10707 (if_then_else 10708 (ior (eq_attr "type" "alu") 10709 (and (eq_attr "type" "ishift") 10710 (and (match_operand 2 "const1_operand") 10711 (ior (match_test "TARGET_SHIFT1") 10712 (match_test "optimize_function_for_size_p (cfun)"))))) 10713 (const_string "0") 10714 (const_string "*"))) 10715 (set_attr "mode" "QI,SI,SI") 10716 ;; Potential partial reg stall on alternative 1. 10717 (set (attr "preferred_for_speed") 10718 (cond [(eq_attr "alternative" "1") 10719 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 10720 (symbol_ref "true")))]) 10721 10722(define_insn "*ashlqi3_1_slp" 10723 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10724 (ashift:QI (match_dup 0) 10725 (match_operand:QI 1 "nonmemory_operand" "cI"))) 10726 (clobber (reg:CC FLAGS_REG))] 10727 "(optimize_function_for_size_p (cfun) 10728 || !TARGET_PARTIAL_FLAG_REG_STALL 10729 || (operands[1] == const1_rtx 10730 && (TARGET_SHIFT1 10731 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10732{ 10733 switch (get_attr_type (insn)) 10734 { 10735 case TYPE_ALU1: 10736 gcc_assert (operands[1] == const1_rtx); 10737 return "add{b}\t%0, %0"; 10738 10739 default: 10740 if (operands[1] == const1_rtx 10741 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10742 return "sal{b}\t%0"; 10743 else 10744 return "sal{b}\t{%1, %0|%0, %1}"; 10745 } 10746} 10747 [(set (attr "type") 10748 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10749 (match_operand 0 "register_operand")) 10750 (match_operand 1 "const1_operand")) 10751 (const_string "alu1") 10752 ] 10753 (const_string "ishift1"))) 10754 (set (attr "length_immediate") 10755 (if_then_else 10756 (ior (eq_attr "type" "alu1") 10757 (and (eq_attr "type" "ishift1") 10758 (and (match_operand 1 "const1_operand") 10759 (ior (match_test "TARGET_SHIFT1") 10760 (match_test "optimize_function_for_size_p (cfun)"))))) 10761 (const_string "0") 10762 (const_string "*"))) 10763 (set_attr "mode" "QI")]) 10764 10765;; Convert ashift to the lea pattern to avoid flags dependency. 10766(define_split 10767 [(set (match_operand:SWI 0 "register_operand") 10768 (ashift:SWI (match_operand:SWI 1 "index_register_operand") 10769 (match_operand 2 "const_0_to_3_operand"))) 10770 (clobber (reg:CC FLAGS_REG))] 10771 "reload_completed 10772 && REGNO (operands[0]) != REGNO (operands[1])" 10773 [(set (match_dup 0) 10774 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))] 10775{ 10776 if (<MODE>mode != <LEAMODE>mode) 10777 { 10778 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]); 10779 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]); 10780 } 10781 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10782}) 10783 10784;; Convert ashift to the lea pattern to avoid flags dependency. 10785(define_split 10786 [(set (match_operand:DI 0 "register_operand") 10787 (zero_extend:DI 10788 (ashift:SI (match_operand:SI 1 "index_register_operand") 10789 (match_operand 2 "const_0_to_3_operand")))) 10790 (clobber (reg:CC FLAGS_REG))] 10791 "TARGET_64BIT && reload_completed 10792 && REGNO (operands[0]) != REGNO (operands[1])" 10793 [(set (match_dup 0) 10794 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))] 10795{ 10796 operands[1] = gen_lowpart (SImode, operands[1]); 10797 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10798}) 10799 10800;; This pattern can't accept a variable shift count, since shifts by 10801;; zero don't affect the flags. We assume that shifts by constant 10802;; zero are optimized away. 10803(define_insn "*ashl<mode>3_cmp" 10804 [(set (reg FLAGS_REG) 10805 (compare 10806 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") 10807 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10808 (const_int 0))) 10809 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10810 (ashift:SWI (match_dup 1) (match_dup 2)))] 10811 "(optimize_function_for_size_p (cfun) 10812 || !TARGET_PARTIAL_FLAG_REG_STALL 10813 || (operands[2] == const1_rtx 10814 && (TARGET_SHIFT1 10815 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) 10816 && ix86_match_ccmode (insn, CCGOCmode) 10817 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 10818{ 10819 switch (get_attr_type (insn)) 10820 { 10821 case TYPE_ALU: 10822 gcc_assert (operands[2] == const1_rtx); 10823 return "add{<imodesuffix>}\t%0, %0"; 10824 10825 default: 10826 if (operands[2] == const1_rtx 10827 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10828 return "sal{<imodesuffix>}\t%0"; 10829 else 10830 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10831 } 10832} 10833 [(set (attr "type") 10834 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10835 (match_operand 0 "register_operand")) 10836 (match_operand 2 "const1_operand")) 10837 (const_string "alu") 10838 ] 10839 (const_string "ishift"))) 10840 (set (attr "length_immediate") 10841 (if_then_else 10842 (ior (eq_attr "type" "alu") 10843 (and (eq_attr "type" "ishift") 10844 (and (match_operand 2 "const1_operand") 10845 (ior (match_test "TARGET_SHIFT1") 10846 (match_test "optimize_function_for_size_p (cfun)"))))) 10847 (const_string "0") 10848 (const_string "*"))) 10849 (set_attr "mode" "<MODE>")]) 10850 10851(define_insn "*ashlsi3_cmp_zext" 10852 [(set (reg FLAGS_REG) 10853 (compare 10854 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10855 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10856 (const_int 0))) 10857 (set (match_operand:DI 0 "register_operand" "=r") 10858 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10859 "TARGET_64BIT 10860 && (optimize_function_for_size_p (cfun) 10861 || !TARGET_PARTIAL_FLAG_REG_STALL 10862 || (operands[2] == const1_rtx 10863 && (TARGET_SHIFT1 10864 || TARGET_DOUBLE_WITH_ADD))) 10865 && ix86_match_ccmode (insn, CCGOCmode) 10866 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10867{ 10868 switch (get_attr_type (insn)) 10869 { 10870 case TYPE_ALU: 10871 gcc_assert (operands[2] == const1_rtx); 10872 return "add{l}\t%k0, %k0"; 10873 10874 default: 10875 if (operands[2] == const1_rtx 10876 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10877 return "sal{l}\t%k0"; 10878 else 10879 return "sal{l}\t{%2, %k0|%k0, %2}"; 10880 } 10881} 10882 [(set (attr "type") 10883 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 10884 (match_operand 2 "const1_operand")) 10885 (const_string "alu") 10886 ] 10887 (const_string "ishift"))) 10888 (set (attr "length_immediate") 10889 (if_then_else 10890 (ior (eq_attr "type" "alu") 10891 (and (eq_attr "type" "ishift") 10892 (and (match_operand 2 "const1_operand") 10893 (ior (match_test "TARGET_SHIFT1") 10894 (match_test "optimize_function_for_size_p (cfun)"))))) 10895 (const_string "0") 10896 (const_string "*"))) 10897 (set_attr "mode" "SI")]) 10898 10899(define_insn "*ashl<mode>3_cconly" 10900 [(set (reg FLAGS_REG) 10901 (compare 10902 (ashift:SWI (match_operand:SWI 1 "register_operand" "0") 10903 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10904 (const_int 0))) 10905 (clobber (match_scratch:SWI 0 "=<r>"))] 10906 "(optimize_function_for_size_p (cfun) 10907 || !TARGET_PARTIAL_FLAG_REG_STALL 10908 || (operands[2] == const1_rtx 10909 && (TARGET_SHIFT1 10910 || TARGET_DOUBLE_WITH_ADD))) 10911 && ix86_match_ccmode (insn, CCGOCmode)" 10912{ 10913 switch (get_attr_type (insn)) 10914 { 10915 case TYPE_ALU: 10916 gcc_assert (operands[2] == const1_rtx); 10917 return "add{<imodesuffix>}\t%0, %0"; 10918 10919 default: 10920 if (operands[2] == const1_rtx 10921 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10922 return "sal{<imodesuffix>}\t%0"; 10923 else 10924 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10925 } 10926} 10927 [(set (attr "type") 10928 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10929 (match_operand 0 "register_operand")) 10930 (match_operand 2 "const1_operand")) 10931 (const_string "alu") 10932 ] 10933 (const_string "ishift"))) 10934 (set (attr "length_immediate") 10935 (if_then_else 10936 (ior (eq_attr "type" "alu") 10937 (and (eq_attr "type" "ishift") 10938 (and (match_operand 2 "const1_operand") 10939 (ior (match_test "TARGET_SHIFT1") 10940 (match_test "optimize_function_for_size_p (cfun)"))))) 10941 (const_string "0") 10942 (const_string "*"))) 10943 (set_attr "mode" "<MODE>")]) 10944 10945;; See comment above `ashl<mode>3' about how this works. 10946 10947(define_expand "<shift_insn><mode>3" 10948 [(set (match_operand:SDWIM 0 "<shift_operand>") 10949 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>") 10950 (match_operand:QI 2 "nonmemory_operand")))] 10951 "" 10952 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 10953 10954;; Avoid useless masking of count operand. 10955(define_insn_and_split "*<shift_insn><mode>3_mask" 10956 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10957 (any_shiftrt:SWI48 10958 (match_operand:SWI48 1 "nonimmediate_operand") 10959 (subreg:QI 10960 (and:SI 10961 (match_operand:SI 2 "register_operand" "c,r") 10962 (match_operand:SI 3 "const_int_operand")) 0))) 10963 (clobber (reg:CC FLAGS_REG))] 10964 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10965 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10966 == GET_MODE_BITSIZE (<MODE>mode)-1 10967 && can_create_pseudo_p ()" 10968 "#" 10969 "&& 1" 10970 [(parallel 10971 [(set (match_dup 0) 10972 (any_shiftrt:SWI48 (match_dup 1) 10973 (match_dup 2))) 10974 (clobber (reg:CC FLAGS_REG))])] 10975 "operands[2] = gen_lowpart (QImode, operands[2]);" 10976 [(set_attr "isa" "*,bmi2")]) 10977 10978(define_insn_and_split "*<shift_insn><mode>3_mask_1" 10979 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10980 (any_shiftrt:SWI48 10981 (match_operand:SWI48 1 "nonimmediate_operand") 10982 (and:QI 10983 (match_operand:QI 2 "register_operand" "c,r") 10984 (match_operand:QI 3 "const_int_operand")))) 10985 (clobber (reg:CC FLAGS_REG))] 10986 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10987 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10988 == GET_MODE_BITSIZE (<MODE>mode)-1 10989 && can_create_pseudo_p ()" 10990 "#" 10991 "&& 1" 10992 [(parallel 10993 [(set (match_dup 0) 10994 (any_shiftrt:SWI48 (match_dup 1) 10995 (match_dup 2))) 10996 (clobber (reg:CC FLAGS_REG))])] 10997 "" 10998 [(set_attr "isa" "*,bmi2")]) 10999 11000(define_insn_and_split "*<shift_insn><mode>3_doubleword" 11001 [(set (match_operand:DWI 0 "register_operand" "=&r") 11002 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") 11003 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 11004 (clobber (reg:CC FLAGS_REG))] 11005 "" 11006 "#" 11007 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 11008 [(const_int 0)] 11009 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;" 11010 [(set_attr "type" "multi")]) 11011 11012;; By default we don't ask for a scratch register, because when DWImode 11013;; values are manipulated, registers are already at a premium. But if 11014;; we have one handy, we won't turn it away. 11015 11016(define_peephole2 11017 [(match_scratch:DWIH 3 "r") 11018 (parallel [(set (match_operand:<DWI> 0 "register_operand") 11019 (any_shiftrt:<DWI> 11020 (match_operand:<DWI> 1 "register_operand") 11021 (match_operand:QI 2 "nonmemory_operand"))) 11022 (clobber (reg:CC FLAGS_REG))]) 11023 (match_dup 3)] 11024 "TARGET_CMOVE" 11025 [(const_int 0)] 11026 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;") 11027 11028(define_insn "x86_64_shrd" 11029 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 11030 (ior:DI (lshiftrt:DI (match_dup 0) 11031 (match_operand:QI 2 "nonmemory_operand" "Jc")) 11032 (ashift:DI (match_operand:DI 1 "register_operand" "r") 11033 (minus:QI (const_int 64) (match_dup 2))))) 11034 (clobber (reg:CC FLAGS_REG))] 11035 "TARGET_64BIT" 11036 "shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11037 [(set_attr "type" "ishift") 11038 (set_attr "prefix_0f" "1") 11039 (set_attr "mode" "DI") 11040 (set_attr "athlon_decode" "vector") 11041 (set_attr "amdfam10_decode" "vector") 11042 (set_attr "bdver1_decode" "vector")]) 11043 11044(define_insn "x86_shrd" 11045 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 11046 (ior:SI (lshiftrt:SI (match_dup 0) 11047 (match_operand:QI 2 "nonmemory_operand" "Ic")) 11048 (ashift:SI (match_operand:SI 1 "register_operand" "r") 11049 (minus:QI (const_int 32) (match_dup 2))))) 11050 (clobber (reg:CC FLAGS_REG))] 11051 "" 11052 "shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11053 [(set_attr "type" "ishift") 11054 (set_attr "prefix_0f" "1") 11055 (set_attr "mode" "SI") 11056 (set_attr "pent_pair" "np") 11057 (set_attr "athlon_decode" "vector") 11058 (set_attr "amdfam10_decode" "vector") 11059 (set_attr "bdver1_decode" "vector")]) 11060 11061(define_insn "ashrdi3_cvt" 11062 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 11063 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 11064 (match_operand:QI 2 "const_int_operand"))) 11065 (clobber (reg:CC FLAGS_REG))] 11066 "TARGET_64BIT && INTVAL (operands[2]) == 63 11067 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11068 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11069 "@ 11070 {cqto|cqo} 11071 sar{q}\t{%2, %0|%0, %2}" 11072 [(set_attr "type" "imovx,ishift") 11073 (set_attr "prefix_0f" "0,*") 11074 (set_attr "length_immediate" "0,*") 11075 (set_attr "modrm" "0,1") 11076 (set_attr "mode" "DI")]) 11077 11078(define_insn "*ashrsi3_cvt_zext" 11079 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11080 (zero_extend:DI 11081 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11082 (match_operand:QI 2 "const_int_operand")))) 11083 (clobber (reg:CC FLAGS_REG))] 11084 "TARGET_64BIT && INTVAL (operands[2]) == 31 11085 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11086 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11087 "@ 11088 {cltd|cdq} 11089 sar{l}\t{%2, %k0|%k0, %2}" 11090 [(set_attr "type" "imovx,ishift") 11091 (set_attr "prefix_0f" "0,*") 11092 (set_attr "length_immediate" "0,*") 11093 (set_attr "modrm" "0,1") 11094 (set_attr "mode" "SI")]) 11095 11096(define_insn "ashrsi3_cvt" 11097 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 11098 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 11099 (match_operand:QI 2 "const_int_operand"))) 11100 (clobber (reg:CC FLAGS_REG))] 11101 "INTVAL (operands[2]) == 31 11102 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11103 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11104 "@ 11105 {cltd|cdq} 11106 sar{l}\t{%2, %0|%0, %2}" 11107 [(set_attr "type" "imovx,ishift") 11108 (set_attr "prefix_0f" "0,*") 11109 (set_attr "length_immediate" "0,*") 11110 (set_attr "modrm" "0,1") 11111 (set_attr "mode" "SI")]) 11112 11113(define_expand "x86_shift<mode>_adj_3" 11114 [(use (match_operand:SWI48 0 "register_operand")) 11115 (use (match_operand:SWI48 1 "register_operand")) 11116 (use (match_operand:QI 2 "register_operand"))] 11117 "" 11118{ 11119 rtx_code_label *label = gen_label_rtx (); 11120 rtx tmp; 11121 11122 emit_insn (gen_testqi_ccz_1 (operands[2], 11123 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 11124 11125 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11126 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11127 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11128 gen_rtx_LABEL_REF (VOIDmode, label), 11129 pc_rtx); 11130 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 11131 JUMP_LABEL (tmp) = label; 11132 11133 emit_move_insn (operands[0], operands[1]); 11134 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1], 11135 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1))); 11136 emit_label (label); 11137 LABEL_NUSES (label) = 1; 11138 11139 DONE; 11140}) 11141 11142(define_insn "*bmi2_<shift_insn><mode>3_1" 11143 [(set (match_operand:SWI48 0 "register_operand" "=r") 11144 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 11145 (match_operand:SWI48 2 "register_operand" "r")))] 11146 "TARGET_BMI2" 11147 "<shift>x\t{%2, %1, %0|%0, %1, %2}" 11148 [(set_attr "type" "ishiftx") 11149 (set_attr "mode" "<MODE>")]) 11150 11151(define_insn "*<shift_insn><mode>3_1" 11152 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 11153 (any_shiftrt:SWI48 11154 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 11155 (match_operand:QI 2 "nonmemory_operand" "c<S>,r"))) 11156 (clobber (reg:CC FLAGS_REG))] 11157 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11158{ 11159 switch (get_attr_type (insn)) 11160 { 11161 case TYPE_ISHIFTX: 11162 return "#"; 11163 11164 default: 11165 if (operands[2] == const1_rtx 11166 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11167 return "<shift>{<imodesuffix>}\t%0"; 11168 else 11169 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11170 } 11171} 11172 [(set_attr "isa" "*,bmi2") 11173 (set_attr "type" "ishift,ishiftx") 11174 (set (attr "length_immediate") 11175 (if_then_else 11176 (and (match_operand 2 "const1_operand") 11177 (ior (match_test "TARGET_SHIFT1") 11178 (match_test "optimize_function_for_size_p (cfun)"))) 11179 (const_string "0") 11180 (const_string "*"))) 11181 (set_attr "mode" "<MODE>")]) 11182 11183;; Convert shift to the shiftx pattern to avoid flags dependency. 11184(define_split 11185 [(set (match_operand:SWI48 0 "register_operand") 11186 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11187 (match_operand:QI 2 "register_operand"))) 11188 (clobber (reg:CC FLAGS_REG))] 11189 "TARGET_BMI2 && reload_completed" 11190 [(set (match_dup 0) 11191 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))] 11192 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 11193 11194(define_insn "*bmi2_<shift_insn>si3_1_zext" 11195 [(set (match_operand:DI 0 "register_operand" "=r") 11196 (zero_extend:DI 11197 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 11198 (match_operand:SI 2 "register_operand" "r"))))] 11199 "TARGET_64BIT && TARGET_BMI2" 11200 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}" 11201 [(set_attr "type" "ishiftx") 11202 (set_attr "mode" "SI")]) 11203 11204(define_insn "*<shift_insn>si3_1_zext" 11205 [(set (match_operand:DI 0 "register_operand" "=r,r") 11206 (zero_extend:DI 11207 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 11208 (match_operand:QI 2 "nonmemory_operand" "cI,r")))) 11209 (clobber (reg:CC FLAGS_REG))] 11210 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11211{ 11212 switch (get_attr_type (insn)) 11213 { 11214 case TYPE_ISHIFTX: 11215 return "#"; 11216 11217 default: 11218 if (operands[2] == const1_rtx 11219 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11220 return "<shift>{l}\t%k0"; 11221 else 11222 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 11223 } 11224} 11225 [(set_attr "isa" "*,bmi2") 11226 (set_attr "type" "ishift,ishiftx") 11227 (set (attr "length_immediate") 11228 (if_then_else 11229 (and (match_operand 2 "const1_operand") 11230 (ior (match_test "TARGET_SHIFT1") 11231 (match_test "optimize_function_for_size_p (cfun)"))) 11232 (const_string "0") 11233 (const_string "*"))) 11234 (set_attr "mode" "SI")]) 11235 11236;; Convert shift to the shiftx pattern to avoid flags dependency. 11237(define_split 11238 [(set (match_operand:DI 0 "register_operand") 11239 (zero_extend:DI 11240 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand") 11241 (match_operand:QI 2 "register_operand")))) 11242 (clobber (reg:CC FLAGS_REG))] 11243 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11244 [(set (match_dup 0) 11245 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 11246 "operands[2] = gen_lowpart (SImode, operands[2]);") 11247 11248(define_insn "*<shift_insn><mode>3_1" 11249 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 11250 (any_shiftrt:SWI12 11251 (match_operand:SWI12 1 "nonimmediate_operand" "0") 11252 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 11253 (clobber (reg:CC FLAGS_REG))] 11254 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11255{ 11256 if (operands[2] == const1_rtx 11257 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11258 return "<shift>{<imodesuffix>}\t%0"; 11259 else 11260 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11261} 11262 [(set_attr "type" "ishift") 11263 (set (attr "length_immediate") 11264 (if_then_else 11265 (and (match_operand 2 "const1_operand") 11266 (ior (match_test "TARGET_SHIFT1") 11267 (match_test "optimize_function_for_size_p (cfun)"))) 11268 (const_string "0") 11269 (const_string "*"))) 11270 (set_attr "mode" "<MODE>")]) 11271 11272(define_insn "*<shift_insn>qi3_1_slp" 11273 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11274 (any_shiftrt:QI (match_dup 0) 11275 (match_operand:QI 1 "nonmemory_operand" "cI"))) 11276 (clobber (reg:CC FLAGS_REG))] 11277 "(optimize_function_for_size_p (cfun) 11278 || !TARGET_PARTIAL_REG_STALL 11279 || (operands[1] == const1_rtx 11280 && TARGET_SHIFT1))" 11281{ 11282 if (operands[1] == const1_rtx 11283 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11284 return "<shift>{b}\t%0"; 11285 else 11286 return "<shift>{b}\t{%1, %0|%0, %1}"; 11287} 11288 [(set_attr "type" "ishift1") 11289 (set (attr "length_immediate") 11290 (if_then_else 11291 (and (match_operand 1 "const1_operand") 11292 (ior (match_test "TARGET_SHIFT1") 11293 (match_test "optimize_function_for_size_p (cfun)"))) 11294 (const_string "0") 11295 (const_string "*"))) 11296 (set_attr "mode" "QI")]) 11297 11298;; This pattern can't accept a variable shift count, since shifts by 11299;; zero don't affect the flags. We assume that shifts by constant 11300;; zero are optimized away. 11301(define_insn "*<shift_insn><mode>3_cmp" 11302 [(set (reg FLAGS_REG) 11303 (compare 11304 (any_shiftrt:SWI 11305 (match_operand:SWI 1 "nonimmediate_operand" "0") 11306 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11307 (const_int 0))) 11308 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 11309 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] 11310 "(optimize_function_for_size_p (cfun) 11311 || !TARGET_PARTIAL_FLAG_REG_STALL 11312 || (operands[2] == const1_rtx 11313 && TARGET_SHIFT1)) 11314 && ix86_match_ccmode (insn, CCGOCmode) 11315 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11316{ 11317 if (operands[2] == const1_rtx 11318 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11319 return "<shift>{<imodesuffix>}\t%0"; 11320 else 11321 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11322} 11323 [(set_attr "type" "ishift") 11324 (set (attr "length_immediate") 11325 (if_then_else 11326 (and (match_operand 2 "const1_operand") 11327 (ior (match_test "TARGET_SHIFT1") 11328 (match_test "optimize_function_for_size_p (cfun)"))) 11329 (const_string "0") 11330 (const_string "*"))) 11331 (set_attr "mode" "<MODE>")]) 11332 11333(define_insn "*<shift_insn>si3_cmp_zext" 11334 [(set (reg FLAGS_REG) 11335 (compare 11336 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") 11337 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11338 (const_int 0))) 11339 (set (match_operand:DI 0 "register_operand" "=r") 11340 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 11341 "TARGET_64BIT 11342 && (optimize_function_for_size_p (cfun) 11343 || !TARGET_PARTIAL_FLAG_REG_STALL 11344 || (operands[2] == const1_rtx 11345 && TARGET_SHIFT1)) 11346 && ix86_match_ccmode (insn, CCGOCmode) 11347 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11348{ 11349 if (operands[2] == const1_rtx 11350 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11351 return "<shift>{l}\t%k0"; 11352 else 11353 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 11354} 11355 [(set_attr "type" "ishift") 11356 (set (attr "length_immediate") 11357 (if_then_else 11358 (and (match_operand 2 "const1_operand") 11359 (ior (match_test "TARGET_SHIFT1") 11360 (match_test "optimize_function_for_size_p (cfun)"))) 11361 (const_string "0") 11362 (const_string "*"))) 11363 (set_attr "mode" "SI")]) 11364 11365(define_insn "*<shift_insn><mode>3_cconly" 11366 [(set (reg FLAGS_REG) 11367 (compare 11368 (any_shiftrt:SWI 11369 (match_operand:SWI 1 "register_operand" "0") 11370 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11371 (const_int 0))) 11372 (clobber (match_scratch:SWI 0 "=<r>"))] 11373 "(optimize_function_for_size_p (cfun) 11374 || !TARGET_PARTIAL_FLAG_REG_STALL 11375 || (operands[2] == const1_rtx 11376 && TARGET_SHIFT1)) 11377 && ix86_match_ccmode (insn, CCGOCmode)" 11378{ 11379 if (operands[2] == const1_rtx 11380 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11381 return "<shift>{<imodesuffix>}\t%0"; 11382 else 11383 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11384} 11385 [(set_attr "type" "ishift") 11386 (set (attr "length_immediate") 11387 (if_then_else 11388 (and (match_operand 2 "const1_operand") 11389 (ior (match_test "TARGET_SHIFT1") 11390 (match_test "optimize_function_for_size_p (cfun)"))) 11391 (const_string "0") 11392 (const_string "*"))) 11393 (set_attr "mode" "<MODE>")]) 11394 11395;; Rotate instructions 11396 11397(define_expand "<rotate_insn>ti3" 11398 [(set (match_operand:TI 0 "register_operand") 11399 (any_rotate:TI (match_operand:TI 1 "register_operand") 11400 (match_operand:QI 2 "nonmemory_operand")))] 11401 "TARGET_64BIT" 11402{ 11403 if (const_1_to_63_operand (operands[2], VOIDmode)) 11404 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword 11405 (operands[0], operands[1], operands[2])); 11406 else 11407 FAIL; 11408 11409 DONE; 11410}) 11411 11412(define_expand "<rotate_insn>di3" 11413 [(set (match_operand:DI 0 "shiftdi_operand") 11414 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand") 11415 (match_operand:QI 2 "nonmemory_operand")))] 11416 "" 11417{ 11418 if (TARGET_64BIT) 11419 ix86_expand_binary_operator (<CODE>, DImode, operands); 11420 else if (const_1_to_31_operand (operands[2], VOIDmode)) 11421 emit_insn (gen_ix86_<rotate_insn>di3_doubleword 11422 (operands[0], operands[1], operands[2])); 11423 else 11424 FAIL; 11425 11426 DONE; 11427}) 11428 11429(define_expand "<rotate_insn><mode>3" 11430 [(set (match_operand:SWIM124 0 "nonimmediate_operand") 11431 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand") 11432 (match_operand:QI 2 "nonmemory_operand")))] 11433 "" 11434 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 11435 11436;; Avoid useless masking of count operand. 11437(define_insn_and_split "*<rotate_insn><mode>3_mask" 11438 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11439 (any_rotate:SWI48 11440 (match_operand:SWI48 1 "nonimmediate_operand") 11441 (subreg:QI 11442 (and:SI 11443 (match_operand:SI 2 "register_operand" "c") 11444 (match_operand:SI 3 "const_int_operand")) 0))) 11445 (clobber (reg:CC FLAGS_REG))] 11446 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11447 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11448 == GET_MODE_BITSIZE (<MODE>mode)-1 11449 && can_create_pseudo_p ()" 11450 "#" 11451 "&& 1" 11452 [(parallel 11453 [(set (match_dup 0) 11454 (any_rotate:SWI48 (match_dup 1) 11455 (match_dup 2))) 11456 (clobber (reg:CC FLAGS_REG))])] 11457 "operands[2] = gen_lowpart (QImode, operands[2]);") 11458 11459(define_insn_and_split "*<rotate_insn><mode>3_mask_1" 11460 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11461 (any_rotate:SWI48 11462 (match_operand:SWI48 1 "nonimmediate_operand") 11463 (and:QI 11464 (match_operand:QI 2 "register_operand" "c") 11465 (match_operand:QI 3 "const_int_operand")))) 11466 (clobber (reg:CC FLAGS_REG))] 11467 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11468 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11469 == GET_MODE_BITSIZE (<MODE>mode)-1 11470 && can_create_pseudo_p ()" 11471 "#" 11472 "&& 1" 11473 [(parallel 11474 [(set (match_dup 0) 11475 (any_rotate:SWI48 (match_dup 1) 11476 (match_dup 2))) 11477 (clobber (reg:CC FLAGS_REG))])]) 11478 11479;; Implement rotation using two double-precision 11480;; shift instructions and a scratch register. 11481 11482(define_insn_and_split "ix86_rotl<dwi>3_doubleword" 11483 [(set (match_operand:<DWI> 0 "register_operand" "=r") 11484 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 11485 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 11486 (clobber (reg:CC FLAGS_REG)) 11487 (clobber (match_scratch:DWIH 3 "=&r"))] 11488 "" 11489 "#" 11490 "reload_completed" 11491 [(set (match_dup 3) (match_dup 4)) 11492 (parallel 11493 [(set (match_dup 4) 11494 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) 11495 (lshiftrt:DWIH (match_dup 5) 11496 (minus:QI (match_dup 6) (match_dup 2))))) 11497 (clobber (reg:CC FLAGS_REG))]) 11498 (parallel 11499 [(set (match_dup 5) 11500 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) 11501 (lshiftrt:DWIH (match_dup 3) 11502 (minus:QI (match_dup 6) (match_dup 2))))) 11503 (clobber (reg:CC FLAGS_REG))])] 11504{ 11505 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 11506 11507 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 11508}) 11509 11510(define_insn_and_split "ix86_rotr<dwi>3_doubleword" 11511 [(set (match_operand:<DWI> 0 "register_operand" "=r") 11512 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 11513 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 11514 (clobber (reg:CC FLAGS_REG)) 11515 (clobber (match_scratch:DWIH 3 "=&r"))] 11516 "" 11517 "#" 11518 "reload_completed" 11519 [(set (match_dup 3) (match_dup 4)) 11520 (parallel 11521 [(set (match_dup 4) 11522 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) 11523 (ashift:DWIH (match_dup 5) 11524 (minus:QI (match_dup 6) (match_dup 2))))) 11525 (clobber (reg:CC FLAGS_REG))]) 11526 (parallel 11527 [(set (match_dup 5) 11528 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2)) 11529 (ashift:DWIH (match_dup 3) 11530 (minus:QI (match_dup 6) (match_dup 2))))) 11531 (clobber (reg:CC FLAGS_REG))])] 11532{ 11533 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 11534 11535 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 11536}) 11537 11538(define_mode_attr rorx_immediate_operand 11539 [(SI "const_0_to_31_operand") 11540 (DI "const_0_to_63_operand")]) 11541 11542(define_insn "*bmi2_rorx<mode>3_1" 11543 [(set (match_operand:SWI48 0 "register_operand" "=r") 11544 (rotatert:SWI48 11545 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 11546 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))] 11547 "TARGET_BMI2" 11548 "rorx\t{%2, %1, %0|%0, %1, %2}" 11549 [(set_attr "type" "rotatex") 11550 (set_attr "mode" "<MODE>")]) 11551 11552(define_insn "*<rotate_insn><mode>3_1" 11553 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 11554 (any_rotate:SWI48 11555 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 11556 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>"))) 11557 (clobber (reg:CC FLAGS_REG))] 11558 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11559{ 11560 switch (get_attr_type (insn)) 11561 { 11562 case TYPE_ROTATEX: 11563 return "#"; 11564 11565 default: 11566 if (operands[2] == const1_rtx 11567 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11568 return "<rotate>{<imodesuffix>}\t%0"; 11569 else 11570 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11571 } 11572} 11573 [(set_attr "isa" "*,bmi2") 11574 (set_attr "type" "rotate,rotatex") 11575 (set (attr "length_immediate") 11576 (if_then_else 11577 (and (eq_attr "type" "rotate") 11578 (and (match_operand 2 "const1_operand") 11579 (ior (match_test "TARGET_SHIFT1") 11580 (match_test "optimize_function_for_size_p (cfun)")))) 11581 (const_string "0") 11582 (const_string "*"))) 11583 (set_attr "mode" "<MODE>")]) 11584 11585;; Convert rotate to the rotatex pattern to avoid flags dependency. 11586(define_split 11587 [(set (match_operand:SWI48 0 "register_operand") 11588 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11589 (match_operand:QI 2 "const_int_operand"))) 11590 (clobber (reg:CC FLAGS_REG))] 11591 "TARGET_BMI2 && reload_completed" 11592 [(set (match_dup 0) 11593 (rotatert:SWI48 (match_dup 1) (match_dup 2)))] 11594{ 11595 int bitsize = GET_MODE_BITSIZE (<MODE>mode); 11596 11597 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize); 11598}) 11599 11600(define_split 11601 [(set (match_operand:SWI48 0 "register_operand") 11602 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11603 (match_operand:QI 2 "const_int_operand"))) 11604 (clobber (reg:CC FLAGS_REG))] 11605 "TARGET_BMI2 && reload_completed" 11606 [(set (match_dup 0) 11607 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]) 11608 11609(define_insn "*bmi2_rorxsi3_1_zext" 11610 [(set (match_operand:DI 0 "register_operand" "=r") 11611 (zero_extend:DI 11612 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 11613 (match_operand:QI 2 "const_0_to_31_operand" "I"))))] 11614 "TARGET_64BIT && TARGET_BMI2" 11615 "rorx\t{%2, %1, %k0|%k0, %1, %2}" 11616 [(set_attr "type" "rotatex") 11617 (set_attr "mode" "SI")]) 11618 11619(define_insn "*<rotate_insn>si3_1_zext" 11620 [(set (match_operand:DI 0 "register_operand" "=r,r") 11621 (zero_extend:DI 11622 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 11623 (match_operand:QI 2 "nonmemory_operand" "cI,I")))) 11624 (clobber (reg:CC FLAGS_REG))] 11625 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11626{ 11627 switch (get_attr_type (insn)) 11628 { 11629 case TYPE_ROTATEX: 11630 return "#"; 11631 11632 default: 11633 if (operands[2] == const1_rtx 11634 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11635 return "<rotate>{l}\t%k0"; 11636 else 11637 return "<rotate>{l}\t{%2, %k0|%k0, %2}"; 11638 } 11639} 11640 [(set_attr "isa" "*,bmi2") 11641 (set_attr "type" "rotate,rotatex") 11642 (set (attr "length_immediate") 11643 (if_then_else 11644 (and (eq_attr "type" "rotate") 11645 (and (match_operand 2 "const1_operand") 11646 (ior (match_test "TARGET_SHIFT1") 11647 (match_test "optimize_function_for_size_p (cfun)")))) 11648 (const_string "0") 11649 (const_string "*"))) 11650 (set_attr "mode" "SI")]) 11651 11652;; Convert rotate to the rotatex pattern to avoid flags dependency. 11653(define_split 11654 [(set (match_operand:DI 0 "register_operand") 11655 (zero_extend:DI 11656 (rotate:SI (match_operand:SI 1 "nonimmediate_operand") 11657 (match_operand:QI 2 "const_int_operand")))) 11658 (clobber (reg:CC FLAGS_REG))] 11659 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11660 [(set (match_dup 0) 11661 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))] 11662{ 11663 int bitsize = GET_MODE_BITSIZE (SImode); 11664 11665 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize); 11666}) 11667 11668(define_split 11669 [(set (match_operand:DI 0 "register_operand") 11670 (zero_extend:DI 11671 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand") 11672 (match_operand:QI 2 "const_int_operand")))) 11673 (clobber (reg:CC FLAGS_REG))] 11674 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11675 [(set (match_dup 0) 11676 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) 11677 11678(define_insn "*<rotate_insn><mode>3_1" 11679 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 11680 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0") 11681 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 11682 (clobber (reg:CC FLAGS_REG))] 11683 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11684{ 11685 if (operands[2] == const1_rtx 11686 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11687 return "<rotate>{<imodesuffix>}\t%0"; 11688 else 11689 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11690} 11691 [(set_attr "type" "rotate") 11692 (set (attr "length_immediate") 11693 (if_then_else 11694 (and (match_operand 2 "const1_operand") 11695 (ior (match_test "TARGET_SHIFT1") 11696 (match_test "optimize_function_for_size_p (cfun)"))) 11697 (const_string "0") 11698 (const_string "*"))) 11699 (set_attr "mode" "<MODE>")]) 11700 11701(define_insn "*<rotate_insn>qi3_1_slp" 11702 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11703 (any_rotate:QI (match_dup 0) 11704 (match_operand:QI 1 "nonmemory_operand" "cI"))) 11705 (clobber (reg:CC FLAGS_REG))] 11706 "(optimize_function_for_size_p (cfun) 11707 || !TARGET_PARTIAL_REG_STALL 11708 || (operands[1] == const1_rtx 11709 && TARGET_SHIFT1))" 11710{ 11711 if (operands[1] == const1_rtx 11712 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11713 return "<rotate>{b}\t%0"; 11714 else 11715 return "<rotate>{b}\t{%1, %0|%0, %1}"; 11716} 11717 [(set_attr "type" "rotate1") 11718 (set (attr "length_immediate") 11719 (if_then_else 11720 (and (match_operand 1 "const1_operand") 11721 (ior (match_test "TARGET_SHIFT1") 11722 (match_test "optimize_function_for_size_p (cfun)"))) 11723 (const_string "0") 11724 (const_string "*"))) 11725 (set_attr "mode" "QI")]) 11726 11727(define_split 11728 [(set (match_operand:HI 0 "QIreg_operand") 11729 (any_rotate:HI (match_dup 0) (const_int 8))) 11730 (clobber (reg:CC FLAGS_REG))] 11731 "reload_completed 11732 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" 11733 [(parallel [(set (strict_low_part (match_dup 0)) 11734 (bswap:HI (match_dup 0))) 11735 (clobber (reg:CC FLAGS_REG))])]) 11736 11737;; Bit set / bit test instructions 11738 11739;; %%% bts, btr, btc 11740 11741;; These instructions are *slow* when applied to memory. 11742 11743(define_code_attr btsc [(ior "bts") (xor "btc")]) 11744 11745(define_insn "*<btsc><mode>" 11746 [(set (match_operand:SWI48 0 "register_operand" "=r") 11747 (any_or:SWI48 11748 (ashift:SWI48 (const_int 1) 11749 (match_operand:QI 2 "register_operand" "r")) 11750 (match_operand:SWI48 1 "register_operand" "0"))) 11751 (clobber (reg:CC FLAGS_REG))] 11752 "TARGET_USE_BT" 11753 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}" 11754 [(set_attr "type" "alu1") 11755 (set_attr "prefix_0f" "1") 11756 (set_attr "znver1_decode" "double") 11757 (set_attr "mode" "<MODE>")]) 11758 11759;; Avoid useless masking of count operand. 11760(define_insn_and_split "*<btsc><mode>_mask" 11761 [(set (match_operand:SWI48 0 "register_operand") 11762 (any_or:SWI48 11763 (ashift:SWI48 11764 (const_int 1) 11765 (subreg:QI 11766 (and:SI 11767 (match_operand:SI 1 "register_operand") 11768 (match_operand:SI 2 "const_int_operand")) 0)) 11769 (match_operand:SWI48 3 "register_operand"))) 11770 (clobber (reg:CC FLAGS_REG))] 11771 "TARGET_USE_BT 11772 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11773 == GET_MODE_BITSIZE (<MODE>mode)-1 11774 && can_create_pseudo_p ()" 11775 "#" 11776 "&& 1" 11777 [(parallel 11778 [(set (match_dup 0) 11779 (any_or:SWI48 11780 (ashift:SWI48 (const_int 1) 11781 (match_dup 1)) 11782 (match_dup 3))) 11783 (clobber (reg:CC FLAGS_REG))])] 11784 "operands[1] = gen_lowpart (QImode, operands[1]);") 11785 11786(define_insn_and_split "*<btsc><mode>_mask_1" 11787 [(set (match_operand:SWI48 0 "register_operand") 11788 (any_or:SWI48 11789 (ashift:SWI48 11790 (const_int 1) 11791 (and:QI 11792 (match_operand:QI 1 "register_operand") 11793 (match_operand:QI 2 "const_int_operand"))) 11794 (match_operand:SWI48 3 "register_operand"))) 11795 (clobber (reg:CC FLAGS_REG))] 11796 "TARGET_USE_BT 11797 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11798 == GET_MODE_BITSIZE (<MODE>mode)-1 11799 && can_create_pseudo_p ()" 11800 "#" 11801 "&& 1" 11802 [(parallel 11803 [(set (match_dup 0) 11804 (any_or:SWI48 11805 (ashift:SWI48 (const_int 1) 11806 (match_dup 1)) 11807 (match_dup 3))) 11808 (clobber (reg:CC FLAGS_REG))])]) 11809 11810(define_insn "*btr<mode>" 11811 [(set (match_operand:SWI48 0 "register_operand" "=r") 11812 (and:SWI48 11813 (rotate:SWI48 (const_int -2) 11814 (match_operand:QI 2 "register_operand" "r")) 11815 (match_operand:SWI48 1 "register_operand" "0"))) 11816 (clobber (reg:CC FLAGS_REG))] 11817 "TARGET_USE_BT" 11818 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}" 11819 [(set_attr "type" "alu1") 11820 (set_attr "prefix_0f" "1") 11821 (set_attr "znver1_decode" "double") 11822 (set_attr "mode" "<MODE>")]) 11823 11824;; Avoid useless masking of count operand. 11825(define_insn_and_split "*btr<mode>_mask" 11826 [(set (match_operand:SWI48 0 "register_operand") 11827 (and:SWI48 11828 (rotate:SWI48 11829 (const_int -2) 11830 (subreg:QI 11831 (and:SI 11832 (match_operand:SI 1 "register_operand") 11833 (match_operand:SI 2 "const_int_operand")) 0)) 11834 (match_operand:SWI48 3 "register_operand"))) 11835 (clobber (reg:CC FLAGS_REG))] 11836 "TARGET_USE_BT 11837 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11838 == GET_MODE_BITSIZE (<MODE>mode)-1 11839 && can_create_pseudo_p ()" 11840 "#" 11841 "&& 1" 11842 [(parallel 11843 [(set (match_dup 0) 11844 (and:SWI48 11845 (rotate:SWI48 (const_int -2) 11846 (match_dup 1)) 11847 (match_dup 3))) 11848 (clobber (reg:CC FLAGS_REG))])] 11849 "operands[1] = gen_lowpart (QImode, operands[1]);") 11850 11851(define_insn_and_split "*btr<mode>_mask_1" 11852 [(set (match_operand:SWI48 0 "register_operand") 11853 (and:SWI48 11854 (rotate:SWI48 11855 (const_int -2) 11856 (and:QI 11857 (match_operand:QI 1 "register_operand") 11858 (match_operand:QI 2 "const_int_operand"))) 11859 (match_operand:SWI48 3 "register_operand"))) 11860 (clobber (reg:CC FLAGS_REG))] 11861 "TARGET_USE_BT 11862 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11863 == GET_MODE_BITSIZE (<MODE>mode)-1 11864 && can_create_pseudo_p ()" 11865 "#" 11866 "&& 1" 11867 [(parallel 11868 [(set (match_dup 0) 11869 (and:SWI48 11870 (rotate:SWI48 (const_int -2) 11871 (match_dup 1)) 11872 (match_dup 3))) 11873 (clobber (reg:CC FLAGS_REG))])]) 11874 11875;; These instructions are never faster than the corresponding 11876;; and/ior/xor operations when using immediate operand, so with 11877;; 32-bit there's no point. But in 64-bit, we can't hold the 11878;; relevant immediates within the instruction itself, so operating 11879;; on bits in the high 32-bits of a register becomes easier. 11880;; 11881;; These are slow on Nocona, but fast on Athlon64. We do require the use 11882;; of btrq and btcq for corner cases of post-reload expansion of absdf and 11883;; negdf respectively, so they can never be disabled entirely. 11884 11885(define_insn "*btsq_imm" 11886 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11887 (const_int 1) 11888 (match_operand 1 "const_0_to_63_operand" "J")) 11889 (const_int 1)) 11890 (clobber (reg:CC FLAGS_REG))] 11891 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11892 "bts{q}\t{%1, %0|%0, %1}" 11893 [(set_attr "type" "alu1") 11894 (set_attr "prefix_0f" "1") 11895 (set_attr "znver1_decode" "double") 11896 (set_attr "mode" "DI")]) 11897 11898(define_insn "*btrq_imm" 11899 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11900 (const_int 1) 11901 (match_operand 1 "const_0_to_63_operand" "J")) 11902 (const_int 0)) 11903 (clobber (reg:CC FLAGS_REG))] 11904 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11905 "btr{q}\t{%1, %0|%0, %1}" 11906 [(set_attr "type" "alu1") 11907 (set_attr "prefix_0f" "1") 11908 (set_attr "znver1_decode" "double") 11909 (set_attr "mode" "DI")]) 11910 11911(define_insn "*btcq_imm" 11912 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11913 (const_int 1) 11914 (match_operand 1 "const_0_to_63_operand" "J")) 11915 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 11916 (clobber (reg:CC FLAGS_REG))] 11917 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11918 "btc{q}\t{%1, %0|%0, %1}" 11919 [(set_attr "type" "alu1") 11920 (set_attr "prefix_0f" "1") 11921 (set_attr "znver1_decode" "double") 11922 (set_attr "mode" "DI")]) 11923 11924;; Allow Nocona to avoid these instructions if a register is available. 11925 11926(define_peephole2 11927 [(match_scratch:DI 2 "r") 11928 (parallel [(set (zero_extract:DI 11929 (match_operand:DI 0 "nonimmediate_operand") 11930 (const_int 1) 11931 (match_operand 1 "const_0_to_63_operand")) 11932 (const_int 1)) 11933 (clobber (reg:CC FLAGS_REG))])] 11934 "TARGET_64BIT && !TARGET_USE_BT" 11935 [(parallel [(set (match_dup 0) 11936 (ior:DI (match_dup 0) (match_dup 3))) 11937 (clobber (reg:CC FLAGS_REG))])] 11938{ 11939 int i = INTVAL (operands[1]); 11940 11941 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); 11942 11943 if (!x86_64_immediate_operand (operands[3], DImode)) 11944 { 11945 emit_move_insn (operands[2], operands[3]); 11946 operands[3] = operands[2]; 11947 } 11948}) 11949 11950(define_peephole2 11951 [(match_scratch:DI 2 "r") 11952 (parallel [(set (zero_extract:DI 11953 (match_operand:DI 0 "nonimmediate_operand") 11954 (const_int 1) 11955 (match_operand 1 "const_0_to_63_operand")) 11956 (const_int 0)) 11957 (clobber (reg:CC FLAGS_REG))])] 11958 "TARGET_64BIT && !TARGET_USE_BT" 11959 [(parallel [(set (match_dup 0) 11960 (and:DI (match_dup 0) (match_dup 3))) 11961 (clobber (reg:CC FLAGS_REG))])] 11962{ 11963 int i = INTVAL (operands[1]); 11964 11965 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode); 11966 11967 if (!x86_64_immediate_operand (operands[3], DImode)) 11968 { 11969 emit_move_insn (operands[2], operands[3]); 11970 operands[3] = operands[2]; 11971 } 11972}) 11973 11974(define_peephole2 11975 [(match_scratch:DI 2 "r") 11976 (parallel [(set (zero_extract:DI 11977 (match_operand:DI 0 "nonimmediate_operand") 11978 (const_int 1) 11979 (match_operand 1 "const_0_to_63_operand")) 11980 (not:DI (zero_extract:DI 11981 (match_dup 0) (const_int 1) (match_dup 1)))) 11982 (clobber (reg:CC FLAGS_REG))])] 11983 "TARGET_64BIT && !TARGET_USE_BT" 11984 [(parallel [(set (match_dup 0) 11985 (xor:DI (match_dup 0) (match_dup 3))) 11986 (clobber (reg:CC FLAGS_REG))])] 11987{ 11988 int i = INTVAL (operands[1]); 11989 11990 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); 11991 11992 if (!x86_64_immediate_operand (operands[3], DImode)) 11993 { 11994 emit_move_insn (operands[2], operands[3]); 11995 operands[3] = operands[2]; 11996 } 11997}) 11998 11999;; %%% bt 12000 12001(define_insn "*bt<mode>" 12002 [(set (reg:CCC FLAGS_REG) 12003 (compare:CCC 12004 (zero_extract:SWI48 12005 (match_operand:SWI48 0 "nonimmediate_operand" "r,m") 12006 (const_int 1) 12007 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>")) 12008 (const_int 0)))] 12009 "" 12010{ 12011 switch (get_attr_mode (insn)) 12012 { 12013 case MODE_SI: 12014 return "bt{l}\t{%1, %k0|%k0, %1}"; 12015 12016 case MODE_DI: 12017 return "bt{q}\t{%q1, %0|%0, %q1}"; 12018 12019 default: 12020 gcc_unreachable (); 12021 } 12022} 12023 [(set_attr "type" "alu1") 12024 (set_attr "prefix_0f" "1") 12025 (set (attr "mode") 12026 (if_then_else 12027 (and (match_test "CONST_INT_P (operands[1])") 12028 (match_test "INTVAL (operands[1]) < 32")) 12029 (const_string "SI") 12030 (const_string "<MODE>")))]) 12031 12032(define_insn_and_split "*jcc_bt<mode>" 12033 [(set (pc) 12034 (if_then_else (match_operator 0 "bt_comparison_operator" 12035 [(zero_extract:SWI48 12036 (match_operand:SWI48 1 "nonimmediate_operand") 12037 (const_int 1) 12038 (match_operand:SI 2 "nonmemory_operand")) 12039 (const_int 0)]) 12040 (label_ref (match_operand 3)) 12041 (pc))) 12042 (clobber (reg:CC FLAGS_REG))] 12043 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12044 && (CONST_INT_P (operands[2]) 12045 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode) 12046 && INTVAL (operands[2]) 12047 >= (optimize_function_for_size_p (cfun) ? 8 : 32)) 12048 : !memory_operand (operands[1], <MODE>mode)) 12049 && can_create_pseudo_p ()" 12050 "#" 12051 "&& 1" 12052 [(set (reg:CCC FLAGS_REG) 12053 (compare:CCC 12054 (zero_extract:SWI48 12055 (match_dup 1) 12056 (const_int 1) 12057 (match_dup 2)) 12058 (const_int 0))) 12059 (set (pc) 12060 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12061 (label_ref (match_dup 3)) 12062 (pc)))] 12063{ 12064 operands[0] = shallow_copy_rtx (operands[0]); 12065 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12066}) 12067 12068(define_insn_and_split "*jcc_bt<mode>_1" 12069 [(set (pc) 12070 (if_then_else (match_operator 0 "bt_comparison_operator" 12071 [(zero_extract:SWI48 12072 (match_operand:SWI48 1 "register_operand") 12073 (const_int 1) 12074 (zero_extend:SI 12075 (match_operand:QI 2 "register_operand"))) 12076 (const_int 0)]) 12077 (label_ref (match_operand 3)) 12078 (pc))) 12079 (clobber (reg:CC FLAGS_REG))] 12080 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12081 && can_create_pseudo_p ()" 12082 "#" 12083 "&& 1" 12084 [(set (reg:CCC FLAGS_REG) 12085 (compare:CCC 12086 (zero_extract:SWI48 12087 (match_dup 1) 12088 (const_int 1) 12089 (match_dup 2)) 12090 (const_int 0))) 12091 (set (pc) 12092 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12093 (label_ref (match_dup 3)) 12094 (pc)))] 12095{ 12096 operands[2] = lowpart_subreg (SImode, operands[2], QImode); 12097 operands[0] = shallow_copy_rtx (operands[0]); 12098 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12099}) 12100 12101;; Avoid useless masking of bit offset operand. 12102(define_insn_and_split "*jcc_bt<mode>_mask" 12103 [(set (pc) 12104 (if_then_else (match_operator 0 "bt_comparison_operator" 12105 [(zero_extract:SWI48 12106 (match_operand:SWI48 1 "register_operand") 12107 (const_int 1) 12108 (and:SI 12109 (match_operand:SI 2 "register_operand") 12110 (match_operand 3 "const_int_operand")))]) 12111 (label_ref (match_operand 4)) 12112 (pc))) 12113 (clobber (reg:CC FLAGS_REG))] 12114 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12115 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 12116 == GET_MODE_BITSIZE (<MODE>mode)-1 12117 && can_create_pseudo_p ()" 12118 "#" 12119 "&& 1" 12120 [(set (reg:CCC FLAGS_REG) 12121 (compare:CCC 12122 (zero_extract:SWI48 12123 (match_dup 1) 12124 (const_int 1) 12125 (match_dup 2)) 12126 (const_int 0))) 12127 (set (pc) 12128 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12129 (label_ref (match_dup 4)) 12130 (pc)))] 12131{ 12132 operands[0] = shallow_copy_rtx (operands[0]); 12133 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12134}) 12135 12136;; Store-flag instructions. 12137 12138;; For all sCOND expanders, also expand the compare or test insn that 12139;; generates cc0. Generate an equality comparison if `seq' or `sne'. 12140 12141(define_insn_and_split "*setcc_di_1" 12142 [(set (match_operand:DI 0 "register_operand" "=q") 12143 (match_operator:DI 1 "ix86_comparison_operator" 12144 [(reg FLAGS_REG) (const_int 0)]))] 12145 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL" 12146 "#" 12147 "&& reload_completed" 12148 [(set (match_dup 2) (match_dup 1)) 12149 (set (match_dup 0) (zero_extend:DI (match_dup 2)))] 12150{ 12151 operands[1] = shallow_copy_rtx (operands[1]); 12152 PUT_MODE (operands[1], QImode); 12153 operands[2] = gen_lowpart (QImode, operands[0]); 12154}) 12155 12156(define_insn_and_split "*setcc_si_1_and" 12157 [(set (match_operand:SI 0 "register_operand" "=q") 12158 (match_operator:SI 1 "ix86_comparison_operator" 12159 [(reg FLAGS_REG) (const_int 0)])) 12160 (clobber (reg:CC FLAGS_REG))] 12161 "!TARGET_PARTIAL_REG_STALL 12162 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 12163 "#" 12164 "&& reload_completed" 12165 [(set (match_dup 2) (match_dup 1)) 12166 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) 12167 (clobber (reg:CC FLAGS_REG))])] 12168{ 12169 operands[1] = shallow_copy_rtx (operands[1]); 12170 PUT_MODE (operands[1], QImode); 12171 operands[2] = gen_lowpart (QImode, operands[0]); 12172}) 12173 12174(define_insn_and_split "*setcc_si_1_movzbl" 12175 [(set (match_operand:SI 0 "register_operand" "=q") 12176 (match_operator:SI 1 "ix86_comparison_operator" 12177 [(reg FLAGS_REG) (const_int 0)]))] 12178 "!TARGET_PARTIAL_REG_STALL 12179 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 12180 "#" 12181 "&& reload_completed" 12182 [(set (match_dup 2) (match_dup 1)) 12183 (set (match_dup 0) (zero_extend:SI (match_dup 2)))] 12184{ 12185 operands[1] = shallow_copy_rtx (operands[1]); 12186 PUT_MODE (operands[1], QImode); 12187 operands[2] = gen_lowpart (QImode, operands[0]); 12188}) 12189 12190(define_insn "*setcc_qi" 12191 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12192 (match_operator:QI 1 "ix86_comparison_operator" 12193 [(reg FLAGS_REG) (const_int 0)]))] 12194 "" 12195 "set%C1\t%0" 12196 [(set_attr "type" "setcc") 12197 (set_attr "mode" "QI")]) 12198 12199(define_insn "*setcc_qi_slp" 12200 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12201 (match_operator:QI 1 "ix86_comparison_operator" 12202 [(reg FLAGS_REG) (const_int 0)]))] 12203 "" 12204 "set%C1\t%0" 12205 [(set_attr "type" "setcc") 12206 (set_attr "mode" "QI")]) 12207 12208;; In general it is not safe to assume too much about CCmode registers, 12209;; so simplify-rtx stops when it sees a second one. Under certain 12210;; conditions this is safe on x86, so help combine not create 12211;; 12212;; seta %al 12213;; testb %al, %al 12214;; sete %al 12215 12216(define_split 12217 [(set (match_operand:QI 0 "nonimmediate_operand") 12218 (ne:QI (match_operator 1 "ix86_comparison_operator" 12219 [(reg FLAGS_REG) (const_int 0)]) 12220 (const_int 0)))] 12221 "" 12222 [(set (match_dup 0) (match_dup 1))] 12223{ 12224 operands[1] = shallow_copy_rtx (operands[1]); 12225 PUT_MODE (operands[1], QImode); 12226}) 12227 12228(define_split 12229 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) 12230 (ne:QI (match_operator 1 "ix86_comparison_operator" 12231 [(reg FLAGS_REG) (const_int 0)]) 12232 (const_int 0)))] 12233 "" 12234 [(set (match_dup 0) (match_dup 1))] 12235{ 12236 operands[1] = shallow_copy_rtx (operands[1]); 12237 PUT_MODE (operands[1], QImode); 12238}) 12239 12240(define_split 12241 [(set (match_operand:QI 0 "nonimmediate_operand") 12242 (eq:QI (match_operator 1 "ix86_comparison_operator" 12243 [(reg FLAGS_REG) (const_int 0)]) 12244 (const_int 0)))] 12245 "" 12246 [(set (match_dup 0) (match_dup 1))] 12247{ 12248 operands[1] = shallow_copy_rtx (operands[1]); 12249 PUT_MODE (operands[1], QImode); 12250 PUT_CODE (operands[1], 12251 ix86_reverse_condition (GET_CODE (operands[1]), 12252 GET_MODE (XEXP (operands[1], 0)))); 12253 12254 /* Make sure that (a) the CCmode we have for the flags is strong 12255 enough for the reversed compare or (b) we have a valid FP compare. */ 12256 if (! ix86_comparison_operator (operands[1], VOIDmode)) 12257 FAIL; 12258}) 12259 12260(define_split 12261 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) 12262 (eq:QI (match_operator 1 "ix86_comparison_operator" 12263 [(reg FLAGS_REG) (const_int 0)]) 12264 (const_int 0)))] 12265 "" 12266 [(set (match_dup 0) (match_dup 1))] 12267{ 12268 operands[1] = shallow_copy_rtx (operands[1]); 12269 PUT_MODE (operands[1], QImode); 12270 PUT_CODE (operands[1], 12271 ix86_reverse_condition (GET_CODE (operands[1]), 12272 GET_MODE (XEXP (operands[1], 0)))); 12273 12274 /* Make sure that (a) the CCmode we have for the flags is strong 12275 enough for the reversed compare or (b) we have a valid FP compare. */ 12276 if (! ix86_comparison_operator (operands[1], VOIDmode)) 12277 FAIL; 12278}) 12279 12280;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 12281;; subsequent logical operations are used to imitate conditional moves. 12282;; 0xffffffff is NaN, but not in normalized form, so we can't represent 12283;; it directly. 12284 12285(define_insn "setcc_<mode>_sse" 12286 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 12287 (match_operator:MODEF 3 "sse_comparison_operator" 12288 [(match_operand:MODEF 1 "register_operand" "0,x") 12289 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 12290 "SSE_FLOAT_MODE_P (<MODE>mode)" 12291 "@ 12292 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2} 12293 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 12294 [(set_attr "isa" "noavx,avx") 12295 (set_attr "type" "ssecmp") 12296 (set_attr "length_immediate" "1") 12297 (set_attr "prefix" "orig,vex") 12298 (set_attr "mode" "<MODE>")]) 12299 12300;; Basic conditional jump instructions. 12301;; We ignore the overflow flag for signed branch instructions. 12302 12303(define_insn "*jcc" 12304 [(set (pc) 12305 (if_then_else (match_operator 1 "ix86_comparison_operator" 12306 [(reg FLAGS_REG) (const_int 0)]) 12307 (label_ref (match_operand 0)) 12308 (pc)))] 12309 "" 12310 "%!%+j%C1\t%l0" 12311 [(set_attr "type" "ibr") 12312 (set_attr "modrm" "0") 12313 (set (attr "length") 12314 (if_then_else 12315 (and (ge (minus (match_dup 0) (pc)) 12316 (const_int -126)) 12317 (lt (minus (match_dup 0) (pc)) 12318 (const_int 128))) 12319 (const_int 2) 12320 (const_int 6))) 12321 (set_attr "maybe_prefix_bnd" "1")]) 12322 12323;; In general it is not safe to assume too much about CCmode registers, 12324;; so simplify-rtx stops when it sees a second one. Under certain 12325;; conditions this is safe on x86, so help combine not create 12326;; 12327;; seta %al 12328;; testb %al, %al 12329;; je Lfoo 12330 12331(define_split 12332 [(set (pc) 12333 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 12334 [(reg FLAGS_REG) (const_int 0)]) 12335 (const_int 0)) 12336 (label_ref (match_operand 1)) 12337 (pc)))] 12338 "" 12339 [(set (pc) 12340 (if_then_else (match_dup 0) 12341 (label_ref (match_dup 1)) 12342 (pc)))] 12343{ 12344 operands[0] = shallow_copy_rtx (operands[0]); 12345 PUT_MODE (operands[0], VOIDmode); 12346}) 12347 12348(define_split 12349 [(set (pc) 12350 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 12351 [(reg FLAGS_REG) (const_int 0)]) 12352 (const_int 0)) 12353 (label_ref (match_operand 1)) 12354 (pc)))] 12355 "" 12356 [(set (pc) 12357 (if_then_else (match_dup 0) 12358 (label_ref (match_dup 1)) 12359 (pc)))] 12360{ 12361 operands[0] = shallow_copy_rtx (operands[0]); 12362 PUT_MODE (operands[0], VOIDmode); 12363 PUT_CODE (operands[0], 12364 ix86_reverse_condition (GET_CODE (operands[0]), 12365 GET_MODE (XEXP (operands[0], 0)))); 12366 12367 /* Make sure that (a) the CCmode we have for the flags is strong 12368 enough for the reversed compare or (b) we have a valid FP compare. */ 12369 if (! ix86_comparison_operator (operands[0], VOIDmode)) 12370 FAIL; 12371}) 12372 12373;; Unconditional and other jump instructions 12374 12375(define_insn "jump" 12376 [(set (pc) 12377 (label_ref (match_operand 0)))] 12378 "" 12379 "%!jmp\t%l0" 12380 [(set_attr "type" "ibr") 12381 (set_attr "modrm" "0") 12382 (set (attr "length") 12383 (if_then_else 12384 (and (ge (minus (match_dup 0) (pc)) 12385 (const_int -126)) 12386 (lt (minus (match_dup 0) (pc)) 12387 (const_int 128))) 12388 (const_int 2) 12389 (const_int 5))) 12390 (set_attr "maybe_prefix_bnd" "1")]) 12391 12392(define_expand "indirect_jump" 12393 [(set (pc) (match_operand 0 "indirect_branch_operand"))] 12394 "" 12395{ 12396 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) 12397 operands[0] = convert_memory_address (word_mode, operands[0]); 12398 cfun->machine->has_local_indirect_jump = true; 12399}) 12400 12401(define_insn "*indirect_jump" 12402 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] 12403 "" 12404 "* return ix86_output_indirect_jmp (operands[0]);" 12405 [(set (attr "type") 12406 (if_then_else (match_test "(cfun->machine->indirect_branch_type 12407 != indirect_branch_keep)") 12408 (const_string "multi") 12409 (const_string "ibr"))) 12410 (set_attr "length_immediate" "0") 12411 (set_attr "maybe_prefix_bnd" "1")]) 12412 12413(define_expand "tablejump" 12414 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand")) 12415 (use (label_ref (match_operand 1)))])] 12416 "" 12417{ 12418 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 12419 relative. Convert the relative address to an absolute address. */ 12420 if (flag_pic) 12421 { 12422 rtx op0, op1; 12423 enum rtx_code code; 12424 12425 /* We can't use @GOTOFF for text labels on VxWorks; 12426 see gotoff_operand. */ 12427 if (TARGET_64BIT || TARGET_VXWORKS_RTP) 12428 { 12429 code = PLUS; 12430 op0 = operands[0]; 12431 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 12432 } 12433 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 12434 { 12435 code = PLUS; 12436 op0 = operands[0]; 12437 op1 = pic_offset_table_rtx; 12438 } 12439 else 12440 { 12441 code = MINUS; 12442 op0 = pic_offset_table_rtx; 12443 op1 = operands[0]; 12444 } 12445 12446 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 12447 OPTAB_DIRECT); 12448 } 12449 12450 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) 12451 operands[0] = convert_memory_address (word_mode, operands[0]); 12452 cfun->machine->has_local_indirect_jump = true; 12453}) 12454 12455(define_insn "*tablejump_1" 12456 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) 12457 (use (label_ref (match_operand 1)))] 12458 "" 12459 "* return ix86_output_indirect_jmp (operands[0]);" 12460 [(set (attr "type") 12461 (if_then_else (match_test "(cfun->machine->indirect_branch_type 12462 != indirect_branch_keep)") 12463 (const_string "multi") 12464 (const_string "ibr"))) 12465 (set_attr "length_immediate" "0") 12466 (set_attr "maybe_prefix_bnd" "1")]) 12467 12468;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 12469 12470(define_peephole2 12471 [(set (reg FLAGS_REG) (match_operand 0)) 12472 (set (match_operand:QI 1 "register_operand") 12473 (match_operator:QI 2 "ix86_comparison_operator" 12474 [(reg FLAGS_REG) (const_int 0)])) 12475 (set (match_operand 3 "any_QIreg_operand") 12476 (zero_extend (match_dup 1)))] 12477 "(peep2_reg_dead_p (3, operands[1]) 12478 || operands_match_p (operands[1], operands[3])) 12479 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12480 && peep2_regno_dead_p (0, FLAGS_REG)" 12481 [(set (match_dup 4) (match_dup 0)) 12482 (set (strict_low_part (match_dup 5)) 12483 (match_dup 2))] 12484{ 12485 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12486 operands[5] = gen_lowpart (QImode, operands[3]); 12487 ix86_expand_clear (operands[3]); 12488}) 12489 12490(define_peephole2 12491 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 12492 (match_operand 4)]) 12493 (set (match_operand:QI 1 "register_operand") 12494 (match_operator:QI 2 "ix86_comparison_operator" 12495 [(reg FLAGS_REG) (const_int 0)])) 12496 (set (match_operand 3 "any_QIreg_operand") 12497 (zero_extend (match_dup 1)))] 12498 "(peep2_reg_dead_p (3, operands[1]) 12499 || operands_match_p (operands[1], operands[3])) 12500 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12501 && ! reg_overlap_mentioned_p (operands[3], operands[4]) 12502 && ! reg_set_p (operands[3], operands[4]) 12503 && peep2_regno_dead_p (0, FLAGS_REG)" 12504 [(parallel [(set (match_dup 5) (match_dup 0)) 12505 (match_dup 4)]) 12506 (set (strict_low_part (match_dup 6)) 12507 (match_dup 2))] 12508{ 12509 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12510 operands[6] = gen_lowpart (QImode, operands[3]); 12511 ix86_expand_clear (operands[3]); 12512}) 12513 12514(define_peephole2 12515 [(set (reg FLAGS_REG) (match_operand 0)) 12516 (parallel [(set (reg FLAGS_REG) (match_operand 1)) 12517 (match_operand 5)]) 12518 (set (match_operand:QI 2 "register_operand") 12519 (match_operator:QI 3 "ix86_comparison_operator" 12520 [(reg FLAGS_REG) (const_int 0)])) 12521 (set (match_operand 4 "any_QIreg_operand") 12522 (zero_extend (match_dup 2)))] 12523 "(peep2_reg_dead_p (4, operands[2]) 12524 || operands_match_p (operands[2], operands[4])) 12525 && ! reg_overlap_mentioned_p (operands[4], operands[0]) 12526 && ! reg_overlap_mentioned_p (operands[4], operands[1]) 12527 && ! reg_overlap_mentioned_p (operands[4], operands[5]) 12528 && ! reg_set_p (operands[4], operands[5]) 12529 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) 12530 && peep2_regno_dead_p (0, FLAGS_REG)" 12531 [(set (match_dup 6) (match_dup 0)) 12532 (parallel [(set (match_dup 7) (match_dup 1)) 12533 (match_dup 5)]) 12534 (set (strict_low_part (match_dup 8)) 12535 (match_dup 3))] 12536{ 12537 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12538 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); 12539 operands[8] = gen_lowpart (QImode, operands[4]); 12540 ix86_expand_clear (operands[4]); 12541}) 12542 12543;; Similar, but match zero extend with andsi3. 12544 12545(define_peephole2 12546 [(set (reg FLAGS_REG) (match_operand 0)) 12547 (set (match_operand:QI 1 "register_operand") 12548 (match_operator:QI 2 "ix86_comparison_operator" 12549 [(reg FLAGS_REG) (const_int 0)])) 12550 (parallel [(set (match_operand:SI 3 "any_QIreg_operand") 12551 (and:SI (match_dup 3) (const_int 255))) 12552 (clobber (reg:CC FLAGS_REG))])] 12553 "REGNO (operands[1]) == REGNO (operands[3]) 12554 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12555 && peep2_regno_dead_p (0, FLAGS_REG)" 12556 [(set (match_dup 4) (match_dup 0)) 12557 (set (strict_low_part (match_dup 5)) 12558 (match_dup 2))] 12559{ 12560 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12561 operands[5] = gen_lowpart (QImode, operands[3]); 12562 ix86_expand_clear (operands[3]); 12563}) 12564 12565(define_peephole2 12566 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 12567 (match_operand 4)]) 12568 (set (match_operand:QI 1 "register_operand") 12569 (match_operator:QI 2 "ix86_comparison_operator" 12570 [(reg FLAGS_REG) (const_int 0)])) 12571 (parallel [(set (match_operand 3 "any_QIreg_operand") 12572 (zero_extend (match_dup 1))) 12573 (clobber (reg:CC FLAGS_REG))])] 12574 "(peep2_reg_dead_p (3, operands[1]) 12575 || operands_match_p (operands[1], operands[3])) 12576 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12577 && ! reg_overlap_mentioned_p (operands[3], operands[4]) 12578 && ! reg_set_p (operands[3], operands[4]) 12579 && peep2_regno_dead_p (0, FLAGS_REG)" 12580 [(parallel [(set (match_dup 5) (match_dup 0)) 12581 (match_dup 4)]) 12582 (set (strict_low_part (match_dup 6)) 12583 (match_dup 2))] 12584{ 12585 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12586 operands[6] = gen_lowpart (QImode, operands[3]); 12587 ix86_expand_clear (operands[3]); 12588}) 12589 12590(define_peephole2 12591 [(set (reg FLAGS_REG) (match_operand 0)) 12592 (parallel [(set (reg FLAGS_REG) (match_operand 1)) 12593 (match_operand 5)]) 12594 (set (match_operand:QI 2 "register_operand") 12595 (match_operator:QI 3 "ix86_comparison_operator" 12596 [(reg FLAGS_REG) (const_int 0)])) 12597 (parallel [(set (match_operand 4 "any_QIreg_operand") 12598 (zero_extend (match_dup 2))) 12599 (clobber (reg:CC FLAGS_REG))])] 12600 "(peep2_reg_dead_p (4, operands[2]) 12601 || operands_match_p (operands[2], operands[4])) 12602 && ! reg_overlap_mentioned_p (operands[4], operands[0]) 12603 && ! reg_overlap_mentioned_p (operands[4], operands[1]) 12604 && ! reg_overlap_mentioned_p (operands[4], operands[5]) 12605 && ! reg_set_p (operands[4], operands[5]) 12606 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) 12607 && peep2_regno_dead_p (0, FLAGS_REG)" 12608 [(set (match_dup 6) (match_dup 0)) 12609 (parallel [(set (match_dup 7) (match_dup 1)) 12610 (match_dup 5)]) 12611 (set (strict_low_part (match_dup 8)) 12612 (match_dup 3))] 12613{ 12614 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12615 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); 12616 operands[8] = gen_lowpart (QImode, operands[4]); 12617 ix86_expand_clear (operands[4]); 12618}) 12619 12620;; Call instructions. 12621 12622;; The predicates normally associated with named expanders are not properly 12623;; checked for calls. This is a bug in the generic code, but it isn't that 12624;; easy to fix. Ignore it for now and be prepared to fix things up. 12625 12626;; P6 processors will jump to the address after the decrement when %esp 12627;; is used as a call operand, so they will execute return address as a code. 12628;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 12629 12630;; Register constraint for call instruction. 12631(define_mode_attr c [(SI "l") (DI "r")]) 12632 12633;; Call subroutine returning no value. 12634 12635(define_expand "call" 12636 [(call (match_operand:QI 0) 12637 (match_operand 1)) 12638 (use (match_operand 2))] 12639 "" 12640{ 12641 ix86_expand_call (NULL, operands[0], operands[1], 12642 operands[2], NULL, false); 12643 DONE; 12644}) 12645 12646(define_expand "sibcall" 12647 [(call (match_operand:QI 0) 12648 (match_operand 1)) 12649 (use (match_operand 2))] 12650 "" 12651{ 12652 ix86_expand_call (NULL, operands[0], operands[1], 12653 operands[2], NULL, true); 12654 DONE; 12655}) 12656 12657(define_insn "*call" 12658 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz")) 12659 (match_operand 1))] 12660 "!SIBLING_CALL_P (insn)" 12661 "* return ix86_output_call_insn (insn, operands[0]);" 12662 [(set_attr "type" "call")]) 12663 12664;; This covers both call and sibcall since only GOT slot is allowed. 12665(define_insn "*call_got_x32" 12666 [(call (mem:QI (zero_extend:DI 12667 (match_operand:SI 0 "GOT_memory_operand" "Bg"))) 12668 (match_operand 1))] 12669 "TARGET_X32" 12670{ 12671 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0)); 12672 return ix86_output_call_insn (insn, fnaddr); 12673} 12674 [(set_attr "type" "call")]) 12675 12676;; Since sibcall never returns, we can only use call-clobbered register 12677;; as GOT base. 12678(define_insn "*sibcall_GOT_32" 12679 [(call (mem:QI 12680 (mem:SI (plus:SI 12681 (match_operand:SI 0 "register_no_elim_operand" "U") 12682 (match_operand:SI 1 "GOT32_symbol_operand")))) 12683 (match_operand 2))] 12684 "!TARGET_MACHO 12685 && !TARGET_64BIT 12686 && !TARGET_INDIRECT_BRANCH_REGISTER 12687 && SIBLING_CALL_P (insn)" 12688{ 12689 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]); 12690 fnaddr = gen_const_mem (SImode, fnaddr); 12691 return ix86_output_call_insn (insn, fnaddr); 12692} 12693 [(set_attr "type" "call")]) 12694 12695(define_insn "*sibcall" 12696 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz")) 12697 (match_operand 1))] 12698 "SIBLING_CALL_P (insn)" 12699 "* return ix86_output_call_insn (insn, operands[0]);" 12700 [(set_attr "type" "call")]) 12701 12702(define_insn "*sibcall_memory" 12703 [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) 12704 (match_operand 1)) 12705 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12706 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" 12707 "* return ix86_output_call_insn (insn, operands[0]);" 12708 [(set_attr "type" "call")]) 12709 12710(define_peephole2 12711 [(set (match_operand:W 0 "register_operand") 12712 (match_operand:W 1 "memory_operand")) 12713 (call (mem:QI (match_dup 0)) 12714 (match_operand 3))] 12715 "!TARGET_X32 12716 && !TARGET_INDIRECT_BRANCH_REGISTER 12717 && SIBLING_CALL_P (peep2_next_insn (1)) 12718 && !reg_mentioned_p (operands[0], 12719 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12720 [(parallel [(call (mem:QI (match_dup 1)) 12721 (match_dup 3)) 12722 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12723 12724(define_peephole2 12725 [(set (match_operand:W 0 "register_operand") 12726 (match_operand:W 1 "memory_operand")) 12727 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12728 (call (mem:QI (match_dup 0)) 12729 (match_operand 3))] 12730 "!TARGET_X32 12731 && !TARGET_INDIRECT_BRANCH_REGISTER 12732 && SIBLING_CALL_P (peep2_next_insn (2)) 12733 && !reg_mentioned_p (operands[0], 12734 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12735 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12736 (parallel [(call (mem:QI (match_dup 1)) 12737 (match_dup 3)) 12738 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12739 12740(define_expand "call_pop" 12741 [(parallel [(call (match_operand:QI 0) 12742 (match_operand:SI 1)) 12743 (set (reg:SI SP_REG) 12744 (plus:SI (reg:SI SP_REG) 12745 (match_operand:SI 3)))])] 12746 "!TARGET_64BIT" 12747{ 12748 ix86_expand_call (NULL, operands[0], operands[1], 12749 operands[2], operands[3], false); 12750 DONE; 12751}) 12752 12753(define_insn "*call_pop" 12754 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) 12755 (match_operand 1)) 12756 (set (reg:SI SP_REG) 12757 (plus:SI (reg:SI SP_REG) 12758 (match_operand:SI 2 "immediate_operand" "i")))] 12759 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 12760 "* return ix86_output_call_insn (insn, operands[0]);" 12761 [(set_attr "type" "call")]) 12762 12763(define_insn "*sibcall_pop" 12764 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz")) 12765 (match_operand 1)) 12766 (set (reg:SI SP_REG) 12767 (plus:SI (reg:SI SP_REG) 12768 (match_operand:SI 2 "immediate_operand" "i")))] 12769 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 12770 "* return ix86_output_call_insn (insn, operands[0]);" 12771 [(set_attr "type" "call")]) 12772 12773(define_insn "*sibcall_pop_memory" 12774 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) 12775 (match_operand 1)) 12776 (set (reg:SI SP_REG) 12777 (plus:SI (reg:SI SP_REG) 12778 (match_operand:SI 2 "immediate_operand" "i"))) 12779 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12780 "!TARGET_64BIT" 12781 "* return ix86_output_call_insn (insn, operands[0]);" 12782 [(set_attr "type" "call")]) 12783 12784(define_peephole2 12785 [(set (match_operand:SI 0 "register_operand") 12786 (match_operand:SI 1 "memory_operand")) 12787 (parallel [(call (mem:QI (match_dup 0)) 12788 (match_operand 3)) 12789 (set (reg:SI SP_REG) 12790 (plus:SI (reg:SI SP_REG) 12791 (match_operand:SI 4 "immediate_operand")))])] 12792 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 12793 && !reg_mentioned_p (operands[0], 12794 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12795 [(parallel [(call (mem:QI (match_dup 1)) 12796 (match_dup 3)) 12797 (set (reg:SI SP_REG) 12798 (plus:SI (reg:SI SP_REG) 12799 (match_dup 4))) 12800 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12801 12802(define_peephole2 12803 [(set (match_operand:SI 0 "register_operand") 12804 (match_operand:SI 1 "memory_operand")) 12805 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12806 (parallel [(call (mem:QI (match_dup 0)) 12807 (match_operand 3)) 12808 (set (reg:SI SP_REG) 12809 (plus:SI (reg:SI SP_REG) 12810 (match_operand:SI 4 "immediate_operand")))])] 12811 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 12812 && !reg_mentioned_p (operands[0], 12813 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12814 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12815 (parallel [(call (mem:QI (match_dup 1)) 12816 (match_dup 3)) 12817 (set (reg:SI SP_REG) 12818 (plus:SI (reg:SI SP_REG) 12819 (match_dup 4))) 12820 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12821 12822;; Combining simple memory jump instruction 12823 12824(define_peephole2 12825 [(set (match_operand:W 0 "register_operand") 12826 (match_operand:W 1 "memory_operand")) 12827 (set (pc) (match_dup 0))] 12828 "!TARGET_X32 12829 && !TARGET_INDIRECT_BRANCH_REGISTER 12830 && peep2_reg_dead_p (2, operands[0])" 12831 [(set (pc) (match_dup 1))]) 12832 12833;; Call subroutine, returning value in operand 0 12834 12835(define_expand "call_value" 12836 [(set (match_operand 0) 12837 (call (match_operand:QI 1) 12838 (match_operand 2))) 12839 (use (match_operand 3))] 12840 "" 12841{ 12842 ix86_expand_call (operands[0], operands[1], operands[2], 12843 operands[3], NULL, false); 12844 DONE; 12845}) 12846 12847(define_expand "sibcall_value" 12848 [(set (match_operand 0) 12849 (call (match_operand:QI 1) 12850 (match_operand 2))) 12851 (use (match_operand 3))] 12852 "" 12853{ 12854 ix86_expand_call (operands[0], operands[1], operands[2], 12855 operands[3], NULL, true); 12856 DONE; 12857}) 12858 12859(define_insn "*call_value" 12860 [(set (match_operand 0) 12861 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz")) 12862 (match_operand 2)))] 12863 "!SIBLING_CALL_P (insn)" 12864 "* return ix86_output_call_insn (insn, operands[1]);" 12865 [(set_attr "type" "callv")]) 12866 12867;; This covers both call and sibcall since only GOT slot is allowed. 12868(define_insn "*call_value_got_x32" 12869 [(set (match_operand 0) 12870 (call (mem:QI 12871 (zero_extend:DI 12872 (match_operand:SI 1 "GOT_memory_operand" "Bg"))) 12873 (match_operand 2)))] 12874 "TARGET_X32" 12875{ 12876 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0)); 12877 return ix86_output_call_insn (insn, fnaddr); 12878} 12879 [(set_attr "type" "callv")]) 12880 12881;; Since sibcall never returns, we can only use call-clobbered register 12882;; as GOT base. 12883(define_insn "*sibcall_value_GOT_32" 12884 [(set (match_operand 0) 12885 (call (mem:QI 12886 (mem:SI (plus:SI 12887 (match_operand:SI 1 "register_no_elim_operand" "U") 12888 (match_operand:SI 2 "GOT32_symbol_operand")))) 12889 (match_operand 3)))] 12890 "!TARGET_MACHO 12891 && !TARGET_64BIT 12892 && !TARGET_INDIRECT_BRANCH_REGISTER 12893 && SIBLING_CALL_P (insn)" 12894{ 12895 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]); 12896 fnaddr = gen_const_mem (SImode, fnaddr); 12897 return ix86_output_call_insn (insn, fnaddr); 12898} 12899 [(set_attr "type" "callv")]) 12900 12901(define_insn "*sibcall_value" 12902 [(set (match_operand 0) 12903 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz")) 12904 (match_operand 2)))] 12905 "SIBLING_CALL_P (insn)" 12906 "* return ix86_output_call_insn (insn, operands[1]);" 12907 [(set_attr "type" "callv")]) 12908 12909(define_insn "*sibcall_value_memory" 12910 [(set (match_operand 0) 12911 (call (mem:QI (match_operand:W 1 "memory_operand" "m")) 12912 (match_operand 2))) 12913 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12914 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" 12915 "* return ix86_output_call_insn (insn, operands[1]);" 12916 [(set_attr "type" "callv")]) 12917 12918(define_peephole2 12919 [(set (match_operand:W 0 "register_operand") 12920 (match_operand:W 1 "memory_operand")) 12921 (set (match_operand 2) 12922 (call (mem:QI (match_dup 0)) 12923 (match_operand 3)))] 12924 "!TARGET_X32 12925 && !TARGET_INDIRECT_BRANCH_REGISTER 12926 && SIBLING_CALL_P (peep2_next_insn (1)) 12927 && !reg_mentioned_p (operands[0], 12928 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12929 [(parallel [(set (match_dup 2) 12930 (call (mem:QI (match_dup 1)) 12931 (match_dup 3))) 12932 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12933 12934(define_peephole2 12935 [(set (match_operand:W 0 "register_operand") 12936 (match_operand:W 1 "memory_operand")) 12937 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12938 (set (match_operand 2) 12939 (call (mem:QI (match_dup 0)) 12940 (match_operand 3)))] 12941 "!TARGET_X32 12942 && !TARGET_INDIRECT_BRANCH_REGISTER 12943 && SIBLING_CALL_P (peep2_next_insn (2)) 12944 && !reg_mentioned_p (operands[0], 12945 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12946 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12947 (parallel [(set (match_dup 2) 12948 (call (mem:QI (match_dup 1)) 12949 (match_dup 3))) 12950 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12951 12952(define_expand "call_value_pop" 12953 [(parallel [(set (match_operand 0) 12954 (call (match_operand:QI 1) 12955 (match_operand:SI 2))) 12956 (set (reg:SI SP_REG) 12957 (plus:SI (reg:SI SP_REG) 12958 (match_operand:SI 4)))])] 12959 "!TARGET_64BIT" 12960{ 12961 ix86_expand_call (operands[0], operands[1], operands[2], 12962 operands[3], operands[4], false); 12963 DONE; 12964}) 12965 12966(define_insn "*call_value_pop" 12967 [(set (match_operand 0) 12968 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) 12969 (match_operand 2))) 12970 (set (reg:SI SP_REG) 12971 (plus:SI (reg:SI SP_REG) 12972 (match_operand:SI 3 "immediate_operand" "i")))] 12973 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 12974 "* return ix86_output_call_insn (insn, operands[1]);" 12975 [(set_attr "type" "callv")]) 12976 12977(define_insn "*sibcall_value_pop" 12978 [(set (match_operand 0) 12979 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz")) 12980 (match_operand 2))) 12981 (set (reg:SI SP_REG) 12982 (plus:SI (reg:SI SP_REG) 12983 (match_operand:SI 3 "immediate_operand" "i")))] 12984 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 12985 "* return ix86_output_call_insn (insn, operands[1]);" 12986 [(set_attr "type" "callv")]) 12987 12988(define_insn "*sibcall_value_pop_memory" 12989 [(set (match_operand 0) 12990 (call (mem:QI (match_operand:SI 1 "memory_operand" "m")) 12991 (match_operand 2))) 12992 (set (reg:SI SP_REG) 12993 (plus:SI (reg:SI SP_REG) 12994 (match_operand:SI 3 "immediate_operand" "i"))) 12995 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12996 "!TARGET_64BIT" 12997 "* return ix86_output_call_insn (insn, operands[1]);" 12998 [(set_attr "type" "callv")]) 12999 13000(define_peephole2 13001 [(set (match_operand:SI 0 "register_operand") 13002 (match_operand:SI 1 "memory_operand")) 13003 (parallel [(set (match_operand 2) 13004 (call (mem:QI (match_dup 0)) 13005 (match_operand 3))) 13006 (set (reg:SI SP_REG) 13007 (plus:SI (reg:SI SP_REG) 13008 (match_operand:SI 4 "immediate_operand")))])] 13009 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 13010 && !reg_mentioned_p (operands[0], 13011 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 13012 [(parallel [(set (match_dup 2) 13013 (call (mem:QI (match_dup 1)) 13014 (match_dup 3))) 13015 (set (reg:SI SP_REG) 13016 (plus:SI (reg:SI SP_REG) 13017 (match_dup 4))) 13018 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13019 13020(define_peephole2 13021 [(set (match_operand:SI 0 "register_operand") 13022 (match_operand:SI 1 "memory_operand")) 13023 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13024 (parallel [(set (match_operand 2) 13025 (call (mem:QI (match_dup 0)) 13026 (match_operand 3))) 13027 (set (reg:SI SP_REG) 13028 (plus:SI (reg:SI SP_REG) 13029 (match_operand:SI 4 "immediate_operand")))])] 13030 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 13031 && !reg_mentioned_p (operands[0], 13032 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 13033 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13034 (parallel [(set (match_dup 2) 13035 (call (mem:QI (match_dup 1)) 13036 (match_dup 3))) 13037 (set (reg:SI SP_REG) 13038 (plus:SI (reg:SI SP_REG) 13039 (match_dup 4))) 13040 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13041 13042;; Call subroutine returning any type. 13043 13044(define_expand "untyped_call" 13045 [(parallel [(call (match_operand 0) 13046 (const_int 0)) 13047 (match_operand 1) 13048 (match_operand 2)])] 13049 "" 13050{ 13051 int i; 13052 13053 /* In order to give reg-stack an easier job in validating two 13054 coprocessor registers as containing a possible return value, 13055 simply pretend the untyped call returns a complex long double 13056 value. 13057 13058 We can't use SSE_REGPARM_MAX here since callee is unprototyped 13059 and should have the default ABI. */ 13060 13061 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 13062 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 13063 operands[0], const0_rtx, 13064 GEN_INT ((TARGET_64BIT 13065 ? (ix86_abi == SYSV_ABI 13066 ? X86_64_SSE_REGPARM_MAX 13067 : X86_64_MS_SSE_REGPARM_MAX) 13068 : X86_32_SSE_REGPARM_MAX) 13069 - 1), 13070 NULL, false); 13071 13072 for (i = 0; i < XVECLEN (operands[2], 0); i++) 13073 { 13074 rtx set = XVECEXP (operands[2], 0, i); 13075 emit_move_insn (SET_DEST (set), SET_SRC (set)); 13076 } 13077 13078 /* The optimizer does not know that the call sets the function value 13079 registers we stored in the result block. We avoid problems by 13080 claiming that all hard registers are used and clobbered at this 13081 point. */ 13082 emit_insn (gen_blockage ()); 13083 13084 DONE; 13085}) 13086 13087;; Prologue and epilogue instructions 13088 13089;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 13090;; all of memory. This blocks insns from being moved across this point. 13091 13092(define_insn "blockage" 13093 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 13094 "" 13095 "" 13096 [(set_attr "length" "0")]) 13097 13098;; Do not schedule instructions accessing memory across this point. 13099 13100(define_expand "memory_blockage" 13101 [(set (match_dup 0) 13102 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 13103 "" 13104{ 13105 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 13106 MEM_VOLATILE_P (operands[0]) = 1; 13107}) 13108 13109(define_insn "*memory_blockage" 13110 [(set (match_operand:BLK 0) 13111 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 13112 "" 13113 "" 13114 [(set_attr "length" "0")]) 13115 13116;; As USE insns aren't meaningful after reload, this is used instead 13117;; to prevent deleting instructions setting registers for PIC code 13118(define_insn "prologue_use" 13119 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)] 13120 "" 13121 "" 13122 [(set_attr "length" "0")]) 13123 13124;; Insn emitted into the body of a function to return from a function. 13125;; This is only done if the function's epilogue is known to be simple. 13126;; See comments for ix86_can_use_return_insn_p in i386.c. 13127 13128(define_expand "return" 13129 [(simple_return)] 13130 "ix86_can_use_return_insn_p ()" 13131{ 13132 if (crtl->args.pops_args) 13133 { 13134 rtx popc = GEN_INT (crtl->args.pops_args); 13135 emit_jump_insn (gen_simple_return_pop_internal (popc)); 13136 DONE; 13137 } 13138}) 13139 13140;; We need to disable this for TARGET_SEH, as otherwise 13141;; shrink-wrapped prologue gets enabled too. This might exceed 13142;; the maximum size of prologue in unwind information. 13143;; Also disallow shrink-wrapping if using stack slot to pass the 13144;; static chain pointer - the first instruction has to be pushl %esi 13145;; and it can't be moved around, as we use alternate entry points 13146;; in that case. 13147 13148(define_expand "simple_return" 13149 [(simple_return)] 13150 "!TARGET_SEH && !ix86_static_chain_on_stack" 13151{ 13152 if (crtl->args.pops_args) 13153 { 13154 rtx popc = GEN_INT (crtl->args.pops_args); 13155 emit_jump_insn (gen_simple_return_pop_internal (popc)); 13156 DONE; 13157 } 13158}) 13159 13160(define_insn "simple_return_internal" 13161 [(simple_return)] 13162 "reload_completed" 13163 "* return ix86_output_function_return (false);" 13164 [(set_attr "length" "1") 13165 (set_attr "atom_unit" "jeu") 13166 (set_attr "length_immediate" "0") 13167 (set_attr "modrm" "0") 13168 (set_attr "maybe_prefix_bnd" "1")]) 13169 13170(define_insn "interrupt_return" 13171 [(simple_return) 13172 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)] 13173 "reload_completed" 13174{ 13175 return TARGET_64BIT ? "iretq" : "iret"; 13176}) 13177 13178;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 13179;; instruction Athlon and K8 have. 13180 13181(define_insn "simple_return_internal_long" 13182 [(simple_return) 13183 (unspec [(const_int 0)] UNSPEC_REP)] 13184 "reload_completed" 13185 "* return ix86_output_function_return (true);" 13186 [(set_attr "length" "2") 13187 (set_attr "atom_unit" "jeu") 13188 (set_attr "length_immediate" "0") 13189 (set_attr "prefix_rep" "1") 13190 (set_attr "modrm" "0")]) 13191 13192(define_insn_and_split "simple_return_pop_internal" 13193 [(simple_return) 13194 (use (match_operand:SI 0 "const_int_operand"))] 13195 "reload_completed" 13196 "%!ret\t%0" 13197 "&& cfun->machine->function_return_type != indirect_branch_keep" 13198 [(const_int 0)] 13199 "ix86_split_simple_return_pop_internal (operands[0]); DONE;" 13200 [(set_attr "length" "3") 13201 (set_attr "atom_unit" "jeu") 13202 (set_attr "length_immediate" "2") 13203 (set_attr "modrm" "0") 13204 (set_attr "maybe_prefix_bnd" "1")]) 13205 13206(define_insn "simple_return_indirect_internal" 13207 [(simple_return) 13208 (use (match_operand 0 "register_operand" "r"))] 13209 "reload_completed" 13210 "* return ix86_output_indirect_function_return (operands[0]);" 13211 [(set (attr "type") 13212 (if_then_else (match_test "(cfun->machine->indirect_branch_type 13213 != indirect_branch_keep)") 13214 (const_string "multi") 13215 (const_string "ibr"))) 13216 (set_attr "length_immediate" "0") 13217 (set_attr "maybe_prefix_bnd" "1")]) 13218 13219(define_insn "nop" 13220 [(const_int 0)] 13221 "" 13222 "nop" 13223 [(set_attr "length" "1") 13224 (set_attr "length_immediate" "0") 13225 (set_attr "modrm" "0")]) 13226 13227;; Generate nops. Operand 0 is the number of nops, up to 8. 13228(define_insn "nops" 13229 [(unspec_volatile [(match_operand 0 "const_int_operand")] 13230 UNSPECV_NOPS)] 13231 "reload_completed" 13232{ 13233 int num = INTVAL (operands[0]); 13234 13235 gcc_assert (IN_RANGE (num, 1, 8)); 13236 13237 while (num--) 13238 fputs ("\tnop\n", asm_out_file); 13239 13240 return ""; 13241} 13242 [(set (attr "length") (symbol_ref "INTVAL (operands[0])")) 13243 (set_attr "length_immediate" "0") 13244 (set_attr "modrm" "0")]) 13245 13246;; Pad to 16-byte boundary, max skip in op0. Used to avoid 13247;; branch prediction penalty for the third jump in a 16-byte 13248;; block on K8. 13249 13250(define_insn "pad" 13251 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)] 13252 "" 13253{ 13254#ifdef ASM_OUTPUT_MAX_SKIP_PAD 13255 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); 13256#else 13257 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 13258 The align insn is used to avoid 3 jump instructions in the row to improve 13259 branch prediction and the benefits hardly outweigh the cost of extra 8 13260 nops on the average inserted by full alignment pseudo operation. */ 13261#endif 13262 return ""; 13263} 13264 [(set_attr "length" "16")]) 13265 13266(define_expand "prologue" 13267 [(const_int 0)] 13268 "" 13269 "ix86_expand_prologue (); DONE;") 13270 13271(define_expand "set_got" 13272 [(parallel 13273 [(set (match_operand:SI 0 "register_operand") 13274 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 13275 (clobber (reg:CC FLAGS_REG))])] 13276 "!TARGET_64BIT" 13277{ 13278 if (flag_pic && !TARGET_VXWORKS_RTP) 13279 ix86_pc_thunk_call_expanded = true; 13280}) 13281 13282(define_insn "*set_got" 13283 [(set (match_operand:SI 0 "register_operand" "=r") 13284 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 13285 (clobber (reg:CC FLAGS_REG))] 13286 "!TARGET_64BIT" 13287 "* return output_set_got (operands[0], NULL_RTX);" 13288 [(set_attr "type" "multi") 13289 (set_attr "length" "12")]) 13290 13291(define_expand "set_got_labelled" 13292 [(parallel 13293 [(set (match_operand:SI 0 "register_operand") 13294 (unspec:SI [(label_ref (match_operand 1))] 13295 UNSPEC_SET_GOT)) 13296 (clobber (reg:CC FLAGS_REG))])] 13297 "!TARGET_64BIT" 13298{ 13299 if (flag_pic && !TARGET_VXWORKS_RTP) 13300 ix86_pc_thunk_call_expanded = true; 13301}) 13302 13303(define_insn "*set_got_labelled" 13304 [(set (match_operand:SI 0 "register_operand" "=r") 13305 (unspec:SI [(label_ref (match_operand 1))] 13306 UNSPEC_SET_GOT)) 13307 (clobber (reg:CC FLAGS_REG))] 13308 "!TARGET_64BIT" 13309 "* return output_set_got (operands[0], operands[1]);" 13310 [(set_attr "type" "multi") 13311 (set_attr "length" "12")]) 13312 13313(define_insn "set_got_rex64" 13314 [(set (match_operand:DI 0 "register_operand" "=r") 13315 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 13316 "TARGET_64BIT" 13317 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" 13318 [(set_attr "type" "lea") 13319 (set_attr "length_address" "4") 13320 (set_attr "modrm_class" "unknown") 13321 (set_attr "mode" "DI")]) 13322 13323(define_insn "set_rip_rex64" 13324 [(set (match_operand:DI 0 "register_operand" "=r") 13325 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))] 13326 "TARGET_64BIT" 13327 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" 13328 [(set_attr "type" "lea") 13329 (set_attr "length_address" "4") 13330 (set_attr "mode" "DI")]) 13331 13332(define_insn "set_got_offset_rex64" 13333 [(set (match_operand:DI 0 "register_operand" "=r") 13334 (unspec:DI 13335 [(label_ref (match_operand 1))] 13336 UNSPEC_SET_GOT_OFFSET))] 13337 "TARGET_LP64" 13338 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" 13339 [(set_attr "type" "imov") 13340 (set_attr "length_immediate" "0") 13341 (set_attr "length_address" "8") 13342 (set_attr "mode" "DI")]) 13343 13344(define_expand "epilogue" 13345 [(const_int 0)] 13346 "" 13347 "ix86_expand_epilogue (1); DONE;") 13348 13349(define_expand "sibcall_epilogue" 13350 [(const_int 0)] 13351 "" 13352 "ix86_expand_epilogue (0); DONE;") 13353 13354(define_expand "eh_return" 13355 [(use (match_operand 0 "register_operand"))] 13356 "" 13357{ 13358 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 13359 13360 /* Tricky bit: we write the address of the handler to which we will 13361 be returning into someone else's stack frame, one word below the 13362 stack address we wish to restore. */ 13363 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 13364 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD); 13365 /* Return address is always in word_mode. */ 13366 tmp = gen_rtx_MEM (word_mode, tmp); 13367 if (GET_MODE (ra) != word_mode) 13368 ra = convert_to_mode (word_mode, ra, 1); 13369 emit_move_insn (tmp, ra); 13370 13371 emit_jump_insn (gen_eh_return_internal ()); 13372 emit_barrier (); 13373 DONE; 13374}) 13375 13376(define_insn_and_split "eh_return_internal" 13377 [(eh_return)] 13378 "" 13379 "#" 13380 "epilogue_completed" 13381 [(const_int 0)] 13382 "ix86_expand_epilogue (2); DONE;") 13383 13384(define_insn "leave" 13385 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 13386 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 13387 (clobber (mem:BLK (scratch)))] 13388 "!TARGET_64BIT" 13389 "leave" 13390 [(set_attr "type" "leave")]) 13391 13392(define_insn "leave_rex64" 13393 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 13394 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 13395 (clobber (mem:BLK (scratch)))] 13396 "TARGET_64BIT" 13397 "leave" 13398 [(set_attr "type" "leave")]) 13399 13400;; Handle -fsplit-stack. 13401 13402(define_expand "split_stack_prologue" 13403 [(const_int 0)] 13404 "" 13405{ 13406 ix86_expand_split_stack_prologue (); 13407 DONE; 13408}) 13409 13410;; In order to support the call/return predictor, we use a return 13411;; instruction which the middle-end doesn't see. 13412(define_insn "split_stack_return" 13413 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] 13414 UNSPECV_SPLIT_STACK_RETURN)] 13415 "" 13416{ 13417 if (operands[0] == const0_rtx) 13418 return "ret"; 13419 else 13420 return "ret\t%0"; 13421} 13422 [(set_attr "atom_unit" "jeu") 13423 (set_attr "modrm" "0") 13424 (set (attr "length") 13425 (if_then_else (match_operand:SI 0 "const0_operand") 13426 (const_int 1) 13427 (const_int 3))) 13428 (set (attr "length_immediate") 13429 (if_then_else (match_operand:SI 0 "const0_operand") 13430 (const_int 0) 13431 (const_int 2)))]) 13432 13433;; If there are operand 0 bytes available on the stack, jump to 13434;; operand 1. 13435 13436(define_expand "split_stack_space_check" 13437 [(set (pc) (if_then_else 13438 (ltu (minus (reg SP_REG) 13439 (match_operand 0 "register_operand")) 13440 (match_dup 2)) 13441 (label_ref (match_operand 1)) 13442 (pc)))] 13443 "" 13444{ 13445 rtx reg = gen_reg_rtx (Pmode); 13446 13447 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0])); 13448 13449 operands[2] = ix86_split_stack_guard (); 13450 ix86_expand_branch (GEU, reg, operands[2], operands[1]); 13451 13452 DONE; 13453}) 13454 13455;; Bit manipulation instructions. 13456 13457(define_expand "ffs<mode>2" 13458 [(set (match_dup 2) (const_int -1)) 13459 (parallel [(set (match_dup 3) (match_dup 4)) 13460 (set (match_operand:SWI48 0 "register_operand") 13461 (ctz:SWI48 13462 (match_operand:SWI48 1 "nonimmediate_operand")))]) 13463 (set (match_dup 0) (if_then_else:SWI48 13464 (eq (match_dup 3) (const_int 0)) 13465 (match_dup 2) 13466 (match_dup 0))) 13467 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) 13468 (clobber (reg:CC FLAGS_REG))])] 13469 "" 13470{ 13471 machine_mode flags_mode; 13472 13473 if (<MODE>mode == SImode && !TARGET_CMOVE) 13474 { 13475 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); 13476 DONE; 13477 } 13478 13479 flags_mode = TARGET_BMI ? CCCmode : CCZmode; 13480 13481 operands[2] = gen_reg_rtx (<MODE>mode); 13482 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG); 13483 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 13484}) 13485 13486(define_insn_and_split "ffssi2_no_cmove" 13487 [(set (match_operand:SI 0 "register_operand" "=r") 13488 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 13489 (clobber (match_scratch:SI 2 "=&q")) 13490 (clobber (reg:CC FLAGS_REG))] 13491 "!TARGET_CMOVE" 13492 "#" 13493 "&& reload_completed" 13494 [(parallel [(set (match_dup 4) (match_dup 5)) 13495 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 13496 (set (strict_low_part (match_dup 3)) 13497 (eq:QI (match_dup 4) (const_int 0))) 13498 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 13499 (clobber (reg:CC FLAGS_REG))]) 13500 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 13501 (clobber (reg:CC FLAGS_REG))]) 13502 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 13503 (clobber (reg:CC FLAGS_REG))])] 13504{ 13505 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode; 13506 13507 operands[3] = gen_lowpart (QImode, operands[2]); 13508 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG); 13509 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 13510 13511 ix86_expand_clear (operands[2]); 13512}) 13513 13514(define_insn_and_split "*tzcnt<mode>_1" 13515 [(set (reg:CCC FLAGS_REG) 13516 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13517 (const_int 0))) 13518 (set (match_operand:SWI48 0 "register_operand" "=r") 13519 (ctz:SWI48 (match_dup 1)))] 13520 "TARGET_BMI" 13521 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13522 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13523 && optimize_function_for_speed_p (cfun) 13524 && !reg_mentioned_p (operands[0], operands[1])" 13525 [(parallel 13526 [(set (reg:CCC FLAGS_REG) 13527 (compare:CCC (match_dup 1) (const_int 0))) 13528 (set (match_dup 0) 13529 (ctz:SWI48 (match_dup 1))) 13530 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] 13531 "ix86_expand_clear (operands[0]);" 13532 [(set_attr "type" "alu1") 13533 (set_attr "prefix_0f" "1") 13534 (set_attr "prefix_rep" "1") 13535 (set_attr "btver2_decode" "double") 13536 (set_attr "mode" "<MODE>")]) 13537 13538; False dependency happens when destination is only updated by tzcnt, 13539; lzcnt or popcnt. There is no false dependency when destination is 13540; also used in source. 13541(define_insn "*tzcnt<mode>_1_falsedep" 13542 [(set (reg:CCC FLAGS_REG) 13543 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13544 (const_int 0))) 13545 (set (match_operand:SWI48 0 "register_operand" "=r") 13546 (ctz:SWI48 (match_dup 1))) 13547 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13548 UNSPEC_INSN_FALSE_DEP)] 13549 "TARGET_BMI" 13550 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13551 [(set_attr "type" "alu1") 13552 (set_attr "prefix_0f" "1") 13553 (set_attr "prefix_rep" "1") 13554 (set_attr "btver2_decode" "double") 13555 (set_attr "mode" "<MODE>")]) 13556 13557(define_insn "*bsf<mode>_1" 13558 [(set (reg:CCZ FLAGS_REG) 13559 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13560 (const_int 0))) 13561 (set (match_operand:SWI48 0 "register_operand" "=r") 13562 (ctz:SWI48 (match_dup 1)))] 13563 "" 13564 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" 13565 [(set_attr "type" "alu1") 13566 (set_attr "prefix_0f" "1") 13567 (set_attr "btver2_decode" "double") 13568 (set_attr "znver1_decode" "vector") 13569 (set_attr "mode" "<MODE>")]) 13570 13571(define_insn_and_split "ctz<mode>2" 13572 [(set (match_operand:SWI48 0 "register_operand" "=r") 13573 (ctz:SWI48 13574 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13575 (clobber (reg:CC FLAGS_REG))] 13576 "" 13577{ 13578 if (TARGET_BMI) 13579 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13580 else if (optimize_function_for_size_p (cfun)) 13581 ; 13582 else if (TARGET_GENERIC) 13583 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 13584 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13585 13586 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13587} 13588 "(TARGET_BMI || TARGET_GENERIC) 13589 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13590 && optimize_function_for_speed_p (cfun) 13591 && !reg_mentioned_p (operands[0], operands[1])" 13592 [(parallel 13593 [(set (match_dup 0) 13594 (ctz:SWI48 (match_dup 1))) 13595 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13596 (clobber (reg:CC FLAGS_REG))])] 13597 "ix86_expand_clear (operands[0]);" 13598 [(set_attr "type" "alu1") 13599 (set_attr "prefix_0f" "1") 13600 (set (attr "prefix_rep") 13601 (if_then_else 13602 (ior (match_test "TARGET_BMI") 13603 (and (not (match_test "optimize_function_for_size_p (cfun)")) 13604 (match_test "TARGET_GENERIC"))) 13605 (const_string "1") 13606 (const_string "0"))) 13607 (set_attr "mode" "<MODE>")]) 13608 13609; False dependency happens when destination is only updated by tzcnt, 13610; lzcnt or popcnt. There is no false dependency when destination is 13611; also used in source. 13612(define_insn "*ctz<mode>2_falsedep" 13613 [(set (match_operand:SWI48 0 "register_operand" "=r") 13614 (ctz:SWI48 13615 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13616 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13617 UNSPEC_INSN_FALSE_DEP) 13618 (clobber (reg:CC FLAGS_REG))] 13619 "" 13620{ 13621 if (TARGET_BMI) 13622 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13623 else if (TARGET_GENERIC) 13624 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 13625 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13626 else 13627 gcc_unreachable (); 13628} 13629 [(set_attr "type" "alu1") 13630 (set_attr "prefix_0f" "1") 13631 (set_attr "prefix_rep" "1") 13632 (set_attr "mode" "<MODE>")]) 13633 13634(define_insn "bsr_rex64" 13635 [(set (match_operand:DI 0 "register_operand" "=r") 13636 (minus:DI (const_int 63) 13637 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 13638 (clobber (reg:CC FLAGS_REG))] 13639 "TARGET_64BIT" 13640 "bsr{q}\t{%1, %0|%0, %1}" 13641 [(set_attr "type" "alu1") 13642 (set_attr "prefix_0f" "1") 13643 (set_attr "znver1_decode" "vector") 13644 (set_attr "mode" "DI")]) 13645 13646(define_insn "bsr" 13647 [(set (match_operand:SI 0 "register_operand" "=r") 13648 (minus:SI (const_int 31) 13649 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 13650 (clobber (reg:CC FLAGS_REG))] 13651 "" 13652 "bsr{l}\t{%1, %0|%0, %1}" 13653 [(set_attr "type" "alu1") 13654 (set_attr "prefix_0f" "1") 13655 (set_attr "znver1_decode" "vector") 13656 (set_attr "mode" "SI")]) 13657 13658(define_insn "*bsrhi" 13659 [(set (match_operand:HI 0 "register_operand" "=r") 13660 (minus:HI (const_int 15) 13661 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 13662 (clobber (reg:CC FLAGS_REG))] 13663 "" 13664 "bsr{w}\t{%1, %0|%0, %1}" 13665 [(set_attr "type" "alu1") 13666 (set_attr "prefix_0f" "1") 13667 (set_attr "znver1_decode" "vector") 13668 (set_attr "mode" "HI")]) 13669 13670(define_expand "clz<mode>2" 13671 [(parallel 13672 [(set (match_operand:SWI48 0 "register_operand") 13673 (minus:SWI48 13674 (match_dup 2) 13675 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")))) 13676 (clobber (reg:CC FLAGS_REG))]) 13677 (parallel 13678 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2))) 13679 (clobber (reg:CC FLAGS_REG))])] 13680 "" 13681{ 13682 if (TARGET_LZCNT) 13683 { 13684 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1])); 13685 DONE; 13686 } 13687 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 13688}) 13689 13690(define_insn_and_split "clz<mode>2_lzcnt" 13691 [(set (match_operand:SWI48 0 "register_operand" "=r") 13692 (clz:SWI48 13693 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13694 (clobber (reg:CC FLAGS_REG))] 13695 "TARGET_LZCNT" 13696 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 13697 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13698 && optimize_function_for_speed_p (cfun) 13699 && !reg_mentioned_p (operands[0], operands[1])" 13700 [(parallel 13701 [(set (match_dup 0) 13702 (clz:SWI48 (match_dup 1))) 13703 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13704 (clobber (reg:CC FLAGS_REG))])] 13705 "ix86_expand_clear (operands[0]);" 13706 [(set_attr "prefix_rep" "1") 13707 (set_attr "type" "bitmanip") 13708 (set_attr "mode" "<MODE>")]) 13709 13710; False dependency happens when destination is only updated by tzcnt, 13711; lzcnt or popcnt. There is no false dependency when destination is 13712; also used in source. 13713(define_insn "*clz<mode>2_lzcnt_falsedep" 13714 [(set (match_operand:SWI48 0 "register_operand" "=r") 13715 (clz:SWI48 13716 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13717 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13718 UNSPEC_INSN_FALSE_DEP) 13719 (clobber (reg:CC FLAGS_REG))] 13720 "TARGET_LZCNT" 13721 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 13722 [(set_attr "prefix_rep" "1") 13723 (set_attr "type" "bitmanip") 13724 (set_attr "mode" "<MODE>")]) 13725 13726(define_int_iterator LT_ZCNT 13727 [(UNSPEC_TZCNT "TARGET_BMI") 13728 (UNSPEC_LZCNT "TARGET_LZCNT")]) 13729 13730(define_int_attr lt_zcnt 13731 [(UNSPEC_TZCNT "tzcnt") 13732 (UNSPEC_LZCNT "lzcnt")]) 13733 13734(define_int_attr lt_zcnt_type 13735 [(UNSPEC_TZCNT "alu1") 13736 (UNSPEC_LZCNT "bitmanip")]) 13737 13738;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version 13739;; provides operand size as output when source operand is zero. 13740 13741(define_insn_and_split "<lt_zcnt>_<mode>" 13742 [(set (match_operand:SWI48 0 "register_operand" "=r") 13743 (unspec:SWI48 13744 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13745 (clobber (reg:CC FLAGS_REG))] 13746 "" 13747 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" 13748 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13749 && optimize_function_for_speed_p (cfun) 13750 && !reg_mentioned_p (operands[0], operands[1])" 13751 [(parallel 13752 [(set (match_dup 0) 13753 (unspec:SWI48 [(match_dup 1)] LT_ZCNT)) 13754 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13755 (clobber (reg:CC FLAGS_REG))])] 13756 "ix86_expand_clear (operands[0]);" 13757 [(set_attr "type" "<lt_zcnt_type>") 13758 (set_attr "prefix_0f" "1") 13759 (set_attr "prefix_rep" "1") 13760 (set_attr "mode" "<MODE>")]) 13761 13762; False dependency happens when destination is only updated by tzcnt, 13763; lzcnt or popcnt. There is no false dependency when destination is 13764; also used in source. 13765(define_insn "*<lt_zcnt>_<mode>_falsedep" 13766 [(set (match_operand:SWI48 0 "register_operand" "=r") 13767 (unspec:SWI48 13768 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13769 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13770 UNSPEC_INSN_FALSE_DEP) 13771 (clobber (reg:CC FLAGS_REG))] 13772 "" 13773 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" 13774 [(set_attr "type" "<lt_zcnt_type>") 13775 (set_attr "prefix_0f" "1") 13776 (set_attr "prefix_rep" "1") 13777 (set_attr "mode" "<MODE>")]) 13778 13779(define_insn "<lt_zcnt>_hi" 13780 [(set (match_operand:HI 0 "register_operand" "=r") 13781 (unspec:HI 13782 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13783 (clobber (reg:CC FLAGS_REG))] 13784 "" 13785 "<lt_zcnt>{w}\t{%1, %0|%0, %1}" 13786 [(set_attr "type" "<lt_zcnt_type>") 13787 (set_attr "prefix_0f" "1") 13788 (set_attr "prefix_rep" "1") 13789 (set_attr "mode" "HI")]) 13790 13791;; BMI instructions. 13792 13793(define_insn "bmi_bextr_<mode>" 13794 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 13795 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 13796 (match_operand:SWI48 2 "register_operand" "r,r")] 13797 UNSPEC_BEXTR)) 13798 (clobber (reg:CC FLAGS_REG))] 13799 "TARGET_BMI" 13800 "bextr\t{%2, %1, %0|%0, %1, %2}" 13801 [(set_attr "type" "bitmanip") 13802 (set_attr "btver2_decode" "direct, double") 13803 (set_attr "mode" "<MODE>")]) 13804 13805(define_insn "*bmi_bextr_<mode>_ccz" 13806 [(set (reg:CCZ FLAGS_REG) 13807 (compare:CCZ 13808 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 13809 (match_operand:SWI48 2 "register_operand" "r,r")] 13810 UNSPEC_BEXTR) 13811 (const_int 0))) 13812 (clobber (match_scratch:SWI48 0 "=r,r"))] 13813 "TARGET_BMI" 13814 "bextr\t{%2, %1, %0|%0, %1, %2}" 13815 [(set_attr "type" "bitmanip") 13816 (set_attr "btver2_decode" "direct, double") 13817 (set_attr "mode" "<MODE>")]) 13818 13819(define_insn "*bmi_blsi_<mode>" 13820 [(set (match_operand:SWI48 0 "register_operand" "=r") 13821 (and:SWI48 13822 (neg:SWI48 13823 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 13824 (match_dup 1))) 13825 (clobber (reg:CC FLAGS_REG))] 13826 "TARGET_BMI" 13827 "blsi\t{%1, %0|%0, %1}" 13828 [(set_attr "type" "bitmanip") 13829 (set_attr "btver2_decode" "double") 13830 (set_attr "mode" "<MODE>")]) 13831 13832(define_insn "*bmi_blsmsk_<mode>" 13833 [(set (match_operand:SWI48 0 "register_operand" "=r") 13834 (xor:SWI48 13835 (plus:SWI48 13836 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13837 (const_int -1)) 13838 (match_dup 1))) 13839 (clobber (reg:CC FLAGS_REG))] 13840 "TARGET_BMI" 13841 "blsmsk\t{%1, %0|%0, %1}" 13842 [(set_attr "type" "bitmanip") 13843 (set_attr "btver2_decode" "double") 13844 (set_attr "mode" "<MODE>")]) 13845 13846(define_insn "*bmi_blsr_<mode>" 13847 [(set (match_operand:SWI48 0 "register_operand" "=r") 13848 (and:SWI48 13849 (plus:SWI48 13850 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13851 (const_int -1)) 13852 (match_dup 1))) 13853 (clobber (reg:CC FLAGS_REG))] 13854 "TARGET_BMI" 13855 "blsr\t{%1, %0|%0, %1}" 13856 [(set_attr "type" "bitmanip") 13857 (set_attr "btver2_decode" "double") 13858 (set_attr "mode" "<MODE>")]) 13859 13860(define_insn "*bmi_blsr_<mode>_cmp" 13861 [(set (reg:CCZ FLAGS_REG) 13862 (compare:CCZ 13863 (and:SWI48 13864 (plus:SWI48 13865 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13866 (const_int -1)) 13867 (match_dup 1)) 13868 (const_int 0))) 13869 (set (match_operand:SWI48 0 "register_operand" "=r") 13870 (and:SWI48 13871 (plus:SWI48 13872 (match_dup 1) 13873 (const_int -1)) 13874 (match_dup 1)))] 13875 "TARGET_BMI" 13876 "blsr\t{%1, %0|%0, %1}" 13877 [(set_attr "type" "bitmanip") 13878 (set_attr "btver2_decode" "double") 13879 (set_attr "mode" "<MODE>")]) 13880 13881(define_insn "*bmi_blsr_<mode>_ccz" 13882 [(set (reg:CCZ FLAGS_REG) 13883 (compare:CCZ 13884 (and:SWI48 13885 (plus:SWI48 13886 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13887 (const_int -1)) 13888 (match_dup 1)) 13889 (const_int 0))) 13890 (clobber (match_scratch:SWI48 0 "=r"))] 13891 "TARGET_BMI" 13892 "blsr\t{%1, %0|%0, %1}" 13893 [(set_attr "type" "bitmanip") 13894 (set_attr "btver2_decode" "double") 13895 (set_attr "mode" "<MODE>")]) 13896 13897;; BMI2 instructions. 13898(define_expand "bmi2_bzhi_<mode>3" 13899 [(parallel 13900 [(set (match_operand:SWI48 0 "register_operand") 13901 (zero_extract:SWI48 13902 (match_operand:SWI48 1 "nonimmediate_operand") 13903 (umin:SWI48 13904 (and:SWI48 (match_operand:SWI48 2 "register_operand") 13905 (const_int 255)) 13906 (match_dup 3)) 13907 (const_int 0))) 13908 (clobber (reg:CC FLAGS_REG))])] 13909 "TARGET_BMI2" 13910 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);") 13911 13912(define_insn "*bmi2_bzhi_<mode>3" 13913 [(set (match_operand:SWI48 0 "register_operand" "=r") 13914 (zero_extract:SWI48 13915 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13916 (umin:SWI48 13917 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r") 13918 (const_int 255)) 13919 (match_operand:SWI48 3 "const_int_operand" "n")) 13920 (const_int 0))) 13921 (clobber (reg:CC FLAGS_REG))] 13922 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13923 "bzhi\t{%2, %1, %0|%0, %1, %2}" 13924 [(set_attr "type" "bitmanip") 13925 (set_attr "prefix" "vex") 13926 (set_attr "mode" "<MODE>")]) 13927 13928(define_insn "*bmi2_bzhi_<mode>3_1" 13929 [(set (match_operand:SWI48 0 "register_operand" "=r") 13930 (zero_extract:SWI48 13931 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13932 (umin:SWI48 13933 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r")) 13934 (match_operand:SWI48 3 "const_int_operand" "n")) 13935 (const_int 0))) 13936 (clobber (reg:CC FLAGS_REG))] 13937 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13938 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 13939 [(set_attr "type" "bitmanip") 13940 (set_attr "prefix" "vex") 13941 (set_attr "mode" "<MODE>")]) 13942 13943(define_insn "*bmi2_bzhi_<mode>3_1_ccz" 13944 [(set (reg:CCZ FLAGS_REG) 13945 (compare:CCZ 13946 (zero_extract:SWI48 13947 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13948 (umin:SWI48 13949 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r")) 13950 (match_operand:SWI48 3 "const_int_operand" "n")) 13951 (const_int 0)) 13952 (const_int 0))) 13953 (clobber (match_scratch:SWI48 0 "=r"))] 13954 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13955 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 13956 [(set_attr "type" "bitmanip") 13957 (set_attr "prefix" "vex") 13958 (set_attr "mode" "<MODE>")]) 13959 13960(define_insn "bmi2_pdep_<mode>3" 13961 [(set (match_operand:SWI48 0 "register_operand" "=r") 13962 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 13963 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 13964 UNSPEC_PDEP))] 13965 "TARGET_BMI2" 13966 "pdep\t{%2, %1, %0|%0, %1, %2}" 13967 [(set_attr "type" "bitmanip") 13968 (set_attr "prefix" "vex") 13969 (set_attr "mode" "<MODE>")]) 13970 13971(define_insn "bmi2_pext_<mode>3" 13972 [(set (match_operand:SWI48 0 "register_operand" "=r") 13973 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 13974 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 13975 UNSPEC_PEXT))] 13976 "TARGET_BMI2" 13977 "pext\t{%2, %1, %0|%0, %1, %2}" 13978 [(set_attr "type" "bitmanip") 13979 (set_attr "prefix" "vex") 13980 (set_attr "mode" "<MODE>")]) 13981 13982;; TBM instructions. 13983(define_insn "tbm_bextri_<mode>" 13984 [(set (match_operand:SWI48 0 "register_operand" "=r") 13985 (zero_extract:SWI48 13986 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13987 (match_operand 2 "const_0_to_255_operand" "N") 13988 (match_operand 3 "const_0_to_255_operand" "N"))) 13989 (clobber (reg:CC FLAGS_REG))] 13990 "TARGET_TBM" 13991{ 13992 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); 13993 return "bextr\t{%2, %1, %0|%0, %1, %2}"; 13994} 13995 [(set_attr "type" "bitmanip") 13996 (set_attr "mode" "<MODE>")]) 13997 13998(define_insn "*tbm_blcfill_<mode>" 13999 [(set (match_operand:SWI48 0 "register_operand" "=r") 14000 (and:SWI48 14001 (plus:SWI48 14002 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14003 (const_int 1)) 14004 (match_dup 1))) 14005 (clobber (reg:CC FLAGS_REG))] 14006 "TARGET_TBM" 14007 "blcfill\t{%1, %0|%0, %1}" 14008 [(set_attr "type" "bitmanip") 14009 (set_attr "mode" "<MODE>")]) 14010 14011(define_insn "*tbm_blci_<mode>" 14012 [(set (match_operand:SWI48 0 "register_operand" "=r") 14013 (ior:SWI48 14014 (not:SWI48 14015 (plus:SWI48 14016 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14017 (const_int 1))) 14018 (match_dup 1))) 14019 (clobber (reg:CC FLAGS_REG))] 14020 "TARGET_TBM" 14021 "blci\t{%1, %0|%0, %1}" 14022 [(set_attr "type" "bitmanip") 14023 (set_attr "mode" "<MODE>")]) 14024 14025(define_insn "*tbm_blcic_<mode>" 14026 [(set (match_operand:SWI48 0 "register_operand" "=r") 14027 (and:SWI48 14028 (plus:SWI48 14029 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14030 (const_int 1)) 14031 (not:SWI48 14032 (match_dup 1)))) 14033 (clobber (reg:CC FLAGS_REG))] 14034 "TARGET_TBM" 14035 "blcic\t{%1, %0|%0, %1}" 14036 [(set_attr "type" "bitmanip") 14037 (set_attr "mode" "<MODE>")]) 14038 14039(define_insn "*tbm_blcmsk_<mode>" 14040 [(set (match_operand:SWI48 0 "register_operand" "=r") 14041 (xor:SWI48 14042 (plus:SWI48 14043 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14044 (const_int 1)) 14045 (match_dup 1))) 14046 (clobber (reg:CC FLAGS_REG))] 14047 "TARGET_TBM" 14048 "blcmsk\t{%1, %0|%0, %1}" 14049 [(set_attr "type" "bitmanip") 14050 (set_attr "mode" "<MODE>")]) 14051 14052(define_insn "*tbm_blcs_<mode>" 14053 [(set (match_operand:SWI48 0 "register_operand" "=r") 14054 (ior:SWI48 14055 (plus:SWI48 14056 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14057 (const_int 1)) 14058 (match_dup 1))) 14059 (clobber (reg:CC FLAGS_REG))] 14060 "TARGET_TBM" 14061 "blcs\t{%1, %0|%0, %1}" 14062 [(set_attr "type" "bitmanip") 14063 (set_attr "mode" "<MODE>")]) 14064 14065(define_insn "*tbm_blsfill_<mode>" 14066 [(set (match_operand:SWI48 0 "register_operand" "=r") 14067 (ior:SWI48 14068 (plus:SWI48 14069 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14070 (const_int -1)) 14071 (match_dup 1))) 14072 (clobber (reg:CC FLAGS_REG))] 14073 "TARGET_TBM" 14074 "blsfill\t{%1, %0|%0, %1}" 14075 [(set_attr "type" "bitmanip") 14076 (set_attr "mode" "<MODE>")]) 14077 14078(define_insn "*tbm_blsic_<mode>" 14079 [(set (match_operand:SWI48 0 "register_operand" "=r") 14080 (ior:SWI48 14081 (plus:SWI48 14082 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14083 (const_int -1)) 14084 (not:SWI48 14085 (match_dup 1)))) 14086 (clobber (reg:CC FLAGS_REG))] 14087 "TARGET_TBM" 14088 "blsic\t{%1, %0|%0, %1}" 14089 [(set_attr "type" "bitmanip") 14090 (set_attr "mode" "<MODE>")]) 14091 14092(define_insn "*tbm_t1mskc_<mode>" 14093 [(set (match_operand:SWI48 0 "register_operand" "=r") 14094 (ior:SWI48 14095 (plus:SWI48 14096 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14097 (const_int 1)) 14098 (not:SWI48 14099 (match_dup 1)))) 14100 (clobber (reg:CC FLAGS_REG))] 14101 "TARGET_TBM" 14102 "t1mskc\t{%1, %0|%0, %1}" 14103 [(set_attr "type" "bitmanip") 14104 (set_attr "mode" "<MODE>")]) 14105 14106(define_insn "*tbm_tzmsk_<mode>" 14107 [(set (match_operand:SWI48 0 "register_operand" "=r") 14108 (and:SWI48 14109 (plus:SWI48 14110 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14111 (const_int -1)) 14112 (not:SWI48 14113 (match_dup 1)))) 14114 (clobber (reg:CC FLAGS_REG))] 14115 "TARGET_TBM" 14116 "tzmsk\t{%1, %0|%0, %1}" 14117 [(set_attr "type" "bitmanip") 14118 (set_attr "mode" "<MODE>")]) 14119 14120(define_insn_and_split "popcount<mode>2" 14121 [(set (match_operand:SWI48 0 "register_operand" "=r") 14122 (popcount:SWI48 14123 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14124 (clobber (reg:CC FLAGS_REG))] 14125 "TARGET_POPCNT" 14126{ 14127#if TARGET_MACHO 14128 return "popcnt\t{%1, %0|%0, %1}"; 14129#else 14130 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 14131#endif 14132} 14133 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 14134 && optimize_function_for_speed_p (cfun) 14135 && !reg_mentioned_p (operands[0], operands[1])" 14136 [(parallel 14137 [(set (match_dup 0) 14138 (popcount:SWI48 (match_dup 1))) 14139 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 14140 (clobber (reg:CC FLAGS_REG))])] 14141 "ix86_expand_clear (operands[0]);" 14142 [(set_attr "prefix_rep" "1") 14143 (set_attr "type" "bitmanip") 14144 (set_attr "mode" "<MODE>")]) 14145 14146; False dependency happens when destination is only updated by tzcnt, 14147; lzcnt or popcnt. There is no false dependency when destination is 14148; also used in source. 14149(define_insn "*popcount<mode>2_falsedep" 14150 [(set (match_operand:SWI48 0 "register_operand" "=r") 14151 (popcount:SWI48 14152 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14153 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 14154 UNSPEC_INSN_FALSE_DEP) 14155 (clobber (reg:CC FLAGS_REG))] 14156 "TARGET_POPCNT" 14157{ 14158#if TARGET_MACHO 14159 return "popcnt\t{%1, %0|%0, %1}"; 14160#else 14161 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 14162#endif 14163} 14164 [(set_attr "prefix_rep" "1") 14165 (set_attr "type" "bitmanip") 14166 (set_attr "mode" "<MODE>")]) 14167 14168(define_insn_and_split "*popcounthi2_1" 14169 [(set (match_operand:SI 0 "register_operand") 14170 (popcount:SI 14171 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))) 14172 (clobber (reg:CC FLAGS_REG))] 14173 "TARGET_POPCNT 14174 && can_create_pseudo_p ()" 14175 "#" 14176 "&& 1" 14177 [(const_int 0)] 14178{ 14179 rtx tmp = gen_reg_rtx (HImode); 14180 14181 emit_insn (gen_popcounthi2 (tmp, operands[1])); 14182 emit_insn (gen_zero_extendhisi2 (operands[0], tmp)); 14183 DONE; 14184}) 14185 14186(define_insn "popcounthi2" 14187 [(set (match_operand:HI 0 "register_operand" "=r") 14188 (popcount:HI 14189 (match_operand:HI 1 "nonimmediate_operand" "rm"))) 14190 (clobber (reg:CC FLAGS_REG))] 14191 "TARGET_POPCNT" 14192{ 14193#if TARGET_MACHO 14194 return "popcnt\t{%1, %0|%0, %1}"; 14195#else 14196 return "popcnt{w}\t{%1, %0|%0, %1}"; 14197#endif 14198} 14199 [(set_attr "prefix_rep" "1") 14200 (set_attr "type" "bitmanip") 14201 (set_attr "mode" "HI")]) 14202 14203(define_expand "bswapdi2" 14204 [(set (match_operand:DI 0 "register_operand") 14205 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))] 14206 "TARGET_64BIT" 14207{ 14208 if (!TARGET_MOVBE) 14209 operands[1] = force_reg (DImode, operands[1]); 14210}) 14211 14212(define_expand "bswapsi2" 14213 [(set (match_operand:SI 0 "register_operand") 14214 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))] 14215 "" 14216{ 14217 if (TARGET_MOVBE) 14218 ; 14219 else if (TARGET_BSWAP) 14220 operands[1] = force_reg (SImode, operands[1]); 14221 else 14222 { 14223 rtx x = operands[0]; 14224 14225 emit_move_insn (x, operands[1]); 14226 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 14227 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 14228 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 14229 DONE; 14230 } 14231}) 14232 14233(define_insn "*bswap<mode>2_movbe" 14234 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") 14235 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] 14236 "TARGET_MOVBE 14237 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 14238 "@ 14239 bswap\t%0 14240 movbe{<imodesuffix>}\t{%1, %0|%0, %1} 14241 movbe{<imodesuffix>}\t{%1, %0|%0, %1}" 14242 [(set_attr "type" "bitmanip,imov,imov") 14243 (set_attr "modrm" "0,1,1") 14244 (set_attr "prefix_0f" "*,1,1") 14245 (set_attr "prefix_extra" "*,1,1") 14246 (set_attr "mode" "<MODE>")]) 14247 14248(define_insn "*bswap<mode>2" 14249 [(set (match_operand:SWI48 0 "register_operand" "=r") 14250 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] 14251 "TARGET_BSWAP" 14252 "bswap\t%0" 14253 [(set_attr "type" "bitmanip") 14254 (set_attr "modrm" "0") 14255 (set_attr "mode" "<MODE>")]) 14256 14257(define_expand "bswaphi2" 14258 [(set (match_operand:HI 0 "register_operand") 14259 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))] 14260 "TARGET_MOVBE") 14261 14262(define_insn "*bswaphi2_movbe" 14263 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m") 14264 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))] 14265 "TARGET_MOVBE 14266 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 14267 "@ 14268 xchg{b}\t{%h0, %b0|%b0, %h0} 14269 movbe{w}\t{%1, %0|%0, %1} 14270 movbe{w}\t{%1, %0|%0, %1}" 14271 [(set_attr "type" "imov") 14272 (set_attr "modrm" "*,1,1") 14273 (set_attr "prefix_0f" "*,1,1") 14274 (set_attr "prefix_extra" "*,1,1") 14275 (set_attr "pent_pair" "np,*,*") 14276 (set_attr "athlon_decode" "vector,*,*") 14277 (set_attr "amdfam10_decode" "double,*,*") 14278 (set_attr "bdver1_decode" "double,*,*") 14279 (set_attr "mode" "QI,HI,HI")]) 14280 14281(define_peephole2 14282 [(set (match_operand:HI 0 "general_reg_operand") 14283 (bswap:HI (match_dup 0)))] 14284 "TARGET_MOVBE 14285 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)) 14286 && peep2_regno_dead_p (0, FLAGS_REG)" 14287 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8))) 14288 (clobber (reg:CC FLAGS_REG))])]) 14289 14290(define_insn "bswaphi_lowpart" 14291 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) 14292 (bswap:HI (match_dup 0))) 14293 (clobber (reg:CC FLAGS_REG))] 14294 "" 14295 "@ 14296 xchg{b}\t{%h0, %b0|%b0, %h0} 14297 rol{w}\t{$8, %0|%0, 8}" 14298 [(set (attr "preferred_for_size") 14299 (cond [(eq_attr "alternative" "0") 14300 (symbol_ref "true")] 14301 (symbol_ref "false"))) 14302 (set (attr "preferred_for_speed") 14303 (cond [(eq_attr "alternative" "0") 14304 (symbol_ref "TARGET_USE_XCHGB")] 14305 (symbol_ref "!TARGET_USE_XCHGB"))) 14306 (set_attr "length" "2,4") 14307 (set_attr "mode" "QI,HI")]) 14308 14309(define_expand "paritydi2" 14310 [(set (match_operand:DI 0 "register_operand") 14311 (parity:DI (match_operand:DI 1 "register_operand")))] 14312 "! TARGET_POPCNT" 14313{ 14314 rtx scratch = gen_reg_rtx (QImode); 14315 14316 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, 14317 NULL_RTX, operands[1])); 14318 14319 ix86_expand_setcc (scratch, ORDERED, 14320 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 14321 14322 if (TARGET_64BIT) 14323 emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); 14324 else 14325 { 14326 rtx tmp = gen_reg_rtx (SImode); 14327 14328 emit_insn (gen_zero_extendqisi2 (tmp, scratch)); 14329 emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); 14330 } 14331 DONE; 14332}) 14333 14334(define_expand "paritysi2" 14335 [(set (match_operand:SI 0 "register_operand") 14336 (parity:SI (match_operand:SI 1 "register_operand")))] 14337 "! TARGET_POPCNT" 14338{ 14339 rtx scratch = gen_reg_rtx (QImode); 14340 14341 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); 14342 14343 ix86_expand_setcc (scratch, ORDERED, 14344 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 14345 14346 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 14347 DONE; 14348}) 14349 14350(define_insn_and_split "paritydi2_cmp" 14351 [(set (reg:CC FLAGS_REG) 14352 (unspec:CC [(match_operand:DI 3 "register_operand" "0")] 14353 UNSPEC_PARITY)) 14354 (clobber (match_scratch:DI 0 "=r")) 14355 (clobber (match_scratch:SI 1 "=&r")) 14356 (clobber (match_scratch:HI 2 "=Q"))] 14357 "! TARGET_POPCNT" 14358 "#" 14359 "&& reload_completed" 14360 [(parallel 14361 [(set (match_dup 1) 14362 (xor:SI (match_dup 1) (match_dup 4))) 14363 (clobber (reg:CC FLAGS_REG))]) 14364 (parallel 14365 [(set (reg:CC FLAGS_REG) 14366 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 14367 (clobber (match_dup 1)) 14368 (clobber (match_dup 2))])] 14369{ 14370 operands[4] = gen_lowpart (SImode, operands[3]); 14371 14372 if (TARGET_64BIT) 14373 { 14374 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); 14375 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); 14376 } 14377 else 14378 operands[1] = gen_highpart (SImode, operands[3]); 14379}) 14380 14381(define_insn_and_split "paritysi2_cmp" 14382 [(set (reg:CC FLAGS_REG) 14383 (unspec:CC [(match_operand:SI 2 "register_operand" "0")] 14384 UNSPEC_PARITY)) 14385 (clobber (match_scratch:SI 0 "=r")) 14386 (clobber (match_scratch:HI 1 "=&Q"))] 14387 "! TARGET_POPCNT" 14388 "#" 14389 "&& reload_completed" 14390 [(parallel 14391 [(set (match_dup 1) 14392 (xor:HI (match_dup 1) (match_dup 3))) 14393 (clobber (reg:CC FLAGS_REG))]) 14394 (parallel 14395 [(set (reg:CC FLAGS_REG) 14396 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 14397 (clobber (match_dup 1))])] 14398{ 14399 operands[3] = gen_lowpart (HImode, operands[2]); 14400 14401 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); 14402 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); 14403}) 14404 14405(define_insn "*parityhi2_cmp" 14406 [(set (reg:CC FLAGS_REG) 14407 (unspec:CC [(match_operand:HI 1 "register_operand" "0")] 14408 UNSPEC_PARITY)) 14409 (clobber (match_scratch:HI 0 "=Q"))] 14410 "! TARGET_POPCNT" 14411 "xor{b}\t{%h0, %b0|%b0, %h0}" 14412 [(set_attr "length" "2") 14413 (set_attr "mode" "HI")]) 14414 14415 14416;; Thread-local storage patterns for ELF. 14417;; 14418;; Note that these code sequences must appear exactly as shown 14419;; in order to allow linker relaxation. 14420 14421(define_insn "*tls_global_dynamic_32_gnu" 14422 [(set (match_operand:SI 0 "register_operand" "=a") 14423 (unspec:SI 14424 [(match_operand:SI 1 "register_operand" "Yb") 14425 (match_operand 2 "tls_symbolic_operand") 14426 (match_operand 3 "constant_call_address_operand" "Bz") 14427 (reg:SI SP_REG)] 14428 UNSPEC_TLS_GD)) 14429 (clobber (match_scratch:SI 4 "=d")) 14430 (clobber (match_scratch:SI 5 "=c")) 14431 (clobber (reg:CC FLAGS_REG))] 14432 "!TARGET_64BIT && TARGET_GNU_TLS" 14433{ 14434 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14435 output_asm_insn 14436 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); 14437 else 14438 output_asm_insn 14439 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands); 14440 if (TARGET_SUN_TLS) 14441#ifdef HAVE_AS_IX86_TLSGDPLT 14442 return "call\t%a2@tlsgdplt"; 14443#else 14444 return "call\t%p3@plt"; 14445#endif 14446 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14447 return "call\t%P3"; 14448 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}"; 14449} 14450 [(set_attr "type" "multi") 14451 (set_attr "length" "12")]) 14452 14453(define_expand "tls_global_dynamic_32" 14454 [(parallel 14455 [(set (match_operand:SI 0 "register_operand") 14456 (unspec:SI [(match_operand:SI 2 "register_operand") 14457 (match_operand 1 "tls_symbolic_operand") 14458 (match_operand 3 "constant_call_address_operand") 14459 (reg:SI SP_REG)] 14460 UNSPEC_TLS_GD)) 14461 (clobber (match_scratch:SI 4)) 14462 (clobber (match_scratch:SI 5)) 14463 (clobber (reg:CC FLAGS_REG))])] 14464 "" 14465 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14466 14467(define_insn "*tls_global_dynamic_64_<mode>" 14468 [(set (match_operand:P 0 "register_operand" "=a") 14469 (call:P 14470 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz")) 14471 (match_operand 3))) 14472 (unspec:P [(match_operand 1 "tls_symbolic_operand") 14473 (reg:P SP_REG)] 14474 UNSPEC_TLS_GD)] 14475 "TARGET_64BIT" 14476{ 14477 if (!TARGET_X32) 14478 fputs (ASM_BYTE "0x66\n", asm_out_file); 14479 output_asm_insn 14480 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 14481 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14482 fputs (ASM_SHORT "0x6666\n", asm_out_file); 14483 else 14484 fputs (ASM_BYTE "0x66\n", asm_out_file); 14485 fputs ("\trex64\n", asm_out_file); 14486 if (TARGET_SUN_TLS) 14487 return "call\t%p2@plt"; 14488 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14489 return "call\t%P2"; 14490 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}"; 14491} 14492 [(set_attr "type" "multi") 14493 (set (attr "length") 14494 (symbol_ref "TARGET_X32 ? 15 : 16"))]) 14495 14496(define_insn "*tls_global_dynamic_64_largepic" 14497 [(set (match_operand:DI 0 "register_operand" "=a") 14498 (call:DI 14499 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b") 14500 (match_operand:DI 3 "immediate_operand" "i"))) 14501 (match_operand 4))) 14502 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 14503 (reg:DI SP_REG)] 14504 UNSPEC_TLS_GD)] 14505 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 14506 && GET_CODE (operands[3]) == CONST 14507 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC 14508 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF" 14509{ 14510 output_asm_insn 14511 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 14512 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands); 14513 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands); 14514 return "call\t{*%%rax|rax}"; 14515} 14516 [(set_attr "type" "multi") 14517 (set_attr "length" "22")]) 14518 14519(define_expand "tls_global_dynamic_64_<mode>" 14520 [(parallel 14521 [(set (match_operand:P 0 "register_operand") 14522 (call:P 14523 (mem:QI (match_operand 2)) 14524 (const_int 0))) 14525 (unspec:P [(match_operand 1 "tls_symbolic_operand") 14526 (reg:P SP_REG)] 14527 UNSPEC_TLS_GD)])] 14528 "TARGET_64BIT" 14529 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14530 14531(define_insn "*tls_local_dynamic_base_32_gnu" 14532 [(set (match_operand:SI 0 "register_operand" "=a") 14533 (unspec:SI 14534 [(match_operand:SI 1 "register_operand" "Yb") 14535 (match_operand 2 "constant_call_address_operand" "Bz") 14536 (reg:SI SP_REG)] 14537 UNSPEC_TLS_LD_BASE)) 14538 (clobber (match_scratch:SI 3 "=d")) 14539 (clobber (match_scratch:SI 4 "=c")) 14540 (clobber (reg:CC FLAGS_REG))] 14541 "!TARGET_64BIT && TARGET_GNU_TLS" 14542{ 14543 output_asm_insn 14544 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); 14545 if (TARGET_SUN_TLS) 14546 { 14547 if (HAVE_AS_IX86_TLSLDMPLT) 14548 return "call\t%&@tlsldmplt"; 14549 else 14550 return "call\t%p2@plt"; 14551 } 14552 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14553 return "call\t%P2"; 14554 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}"; 14555} 14556 [(set_attr "type" "multi") 14557 (set_attr "length" "11")]) 14558 14559(define_expand "tls_local_dynamic_base_32" 14560 [(parallel 14561 [(set (match_operand:SI 0 "register_operand") 14562 (unspec:SI 14563 [(match_operand:SI 1 "register_operand") 14564 (match_operand 2 "constant_call_address_operand") 14565 (reg:SI SP_REG)] 14566 UNSPEC_TLS_LD_BASE)) 14567 (clobber (match_scratch:SI 3)) 14568 (clobber (match_scratch:SI 4)) 14569 (clobber (reg:CC FLAGS_REG))])] 14570 "" 14571 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14572 14573(define_insn "*tls_local_dynamic_base_64_<mode>" 14574 [(set (match_operand:P 0 "register_operand" "=a") 14575 (call:P 14576 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz")) 14577 (match_operand 2))) 14578 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)] 14579 "TARGET_64BIT" 14580{ 14581 output_asm_insn 14582 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 14583 if (TARGET_SUN_TLS) 14584 return "call\t%p1@plt"; 14585 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14586 return "call\t%P1"; 14587 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}"; 14588} 14589 [(set_attr "type" "multi") 14590 (set_attr "length" "12")]) 14591 14592(define_insn "*tls_local_dynamic_base_64_largepic" 14593 [(set (match_operand:DI 0 "register_operand" "=a") 14594 (call:DI 14595 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b") 14596 (match_operand:DI 2 "immediate_operand" "i"))) 14597 (match_operand 3))) 14598 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)] 14599 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 14600 && GET_CODE (operands[2]) == CONST 14601 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC 14602 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF" 14603{ 14604 output_asm_insn 14605 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 14606 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands); 14607 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands); 14608 return "call\t{*%%rax|rax}"; 14609} 14610 [(set_attr "type" "multi") 14611 (set_attr "length" "22")]) 14612 14613(define_expand "tls_local_dynamic_base_64_<mode>" 14614 [(parallel 14615 [(set (match_operand:P 0 "register_operand") 14616 (call:P 14617 (mem:QI (match_operand 1)) 14618 (const_int 0))) 14619 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])] 14620 "TARGET_64BIT" 14621 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14622 14623;; Local dynamic of a single variable is a lose. Show combine how 14624;; to convert that back to global dynamic. 14625 14626(define_insn_and_split "*tls_local_dynamic_32_once" 14627 [(set (match_operand:SI 0 "register_operand" "=a") 14628 (plus:SI 14629 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14630 (match_operand 2 "constant_call_address_operand" "Bz") 14631 (reg:SI SP_REG)] 14632 UNSPEC_TLS_LD_BASE) 14633 (const:SI (unspec:SI 14634 [(match_operand 3 "tls_symbolic_operand")] 14635 UNSPEC_DTPOFF)))) 14636 (clobber (match_scratch:SI 4 "=d")) 14637 (clobber (match_scratch:SI 5 "=c")) 14638 (clobber (reg:CC FLAGS_REG))] 14639 "" 14640 "#" 14641 "" 14642 [(parallel 14643 [(set (match_dup 0) 14644 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2) 14645 (reg:SI SP_REG)] 14646 UNSPEC_TLS_GD)) 14647 (clobber (match_dup 4)) 14648 (clobber (match_dup 5)) 14649 (clobber (reg:CC FLAGS_REG))])]) 14650 14651;; Load and add the thread base pointer from %<tp_seg>:0. 14652(define_insn_and_split "*load_tp_<mode>" 14653 [(set (match_operand:PTR 0 "register_operand" "=r") 14654 (unspec:PTR [(const_int 0)] UNSPEC_TP))] 14655 "" 14656 "#" 14657 "" 14658 [(set (match_dup 0) 14659 (match_dup 1))] 14660{ 14661 addr_space_t as = DEFAULT_TLS_SEG_REG; 14662 14663 operands[1] = gen_const_mem (<MODE>mode, const0_rtx); 14664 set_mem_addr_space (operands[1], as); 14665}) 14666 14667(define_insn_and_split "*load_tp_x32_zext" 14668 [(set (match_operand:DI 0 "register_operand" "=r") 14669 (zero_extend:DI 14670 (unspec:SI [(const_int 0)] UNSPEC_TP)))] 14671 "TARGET_X32" 14672 "#" 14673 "" 14674 [(set (match_dup 0) 14675 (zero_extend:DI (match_dup 1)))] 14676{ 14677 addr_space_t as = DEFAULT_TLS_SEG_REG; 14678 14679 operands[1] = gen_const_mem (SImode, const0_rtx); 14680 set_mem_addr_space (operands[1], as); 14681}) 14682 14683(define_insn_and_split "*add_tp_<mode>" 14684 [(set (match_operand:PTR 0 "register_operand" "=r") 14685 (plus:PTR 14686 (unspec:PTR [(const_int 0)] UNSPEC_TP) 14687 (match_operand:PTR 1 "register_operand" "0"))) 14688 (clobber (reg:CC FLAGS_REG))] 14689 "" 14690 "#" 14691 "" 14692 [(parallel 14693 [(set (match_dup 0) 14694 (plus:PTR (match_dup 1) (match_dup 2))) 14695 (clobber (reg:CC FLAGS_REG))])] 14696{ 14697 addr_space_t as = DEFAULT_TLS_SEG_REG; 14698 14699 operands[2] = gen_const_mem (<MODE>mode, const0_rtx); 14700 set_mem_addr_space (operands[2], as); 14701}) 14702 14703(define_insn_and_split "*add_tp_x32_zext" 14704 [(set (match_operand:DI 0 "register_operand" "=r") 14705 (zero_extend:DI 14706 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 14707 (match_operand:SI 1 "register_operand" "0")))) 14708 (clobber (reg:CC FLAGS_REG))] 14709 "TARGET_X32" 14710 "#" 14711 "" 14712 [(parallel 14713 [(set (match_dup 0) 14714 (zero_extend:DI 14715 (plus:SI (match_dup 1) (match_dup 2)))) 14716 (clobber (reg:CC FLAGS_REG))])] 14717{ 14718 addr_space_t as = DEFAULT_TLS_SEG_REG; 14719 14720 operands[2] = gen_const_mem (SImode, const0_rtx); 14721 set_mem_addr_space (operands[2], as); 14722}) 14723 14724;; The Sun linker took the AMD64 TLS spec literally and can only handle 14725;; %rax as destination of the initial executable code sequence. 14726(define_insn "tls_initial_exec_64_sun" 14727 [(set (match_operand:DI 0 "register_operand" "=a") 14728 (unspec:DI 14729 [(match_operand 1 "tls_symbolic_operand")] 14730 UNSPEC_TLS_IE_SUN)) 14731 (clobber (reg:CC FLAGS_REG))] 14732 "TARGET_64BIT && TARGET_SUN_TLS" 14733{ 14734 output_asm_insn 14735 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); 14736 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; 14737} 14738 [(set_attr "type" "multi")]) 14739 14740;; GNU2 TLS patterns can be split. 14741 14742(define_expand "tls_dynamic_gnu2_32" 14743 [(set (match_dup 3) 14744 (plus:SI (match_operand:SI 2 "register_operand") 14745 (const:SI 14746 (unspec:SI [(match_operand 1 "tls_symbolic_operand")] 14747 UNSPEC_TLSDESC)))) 14748 (parallel 14749 [(set (match_operand:SI 0 "register_operand") 14750 (unspec:SI [(match_dup 1) (match_dup 3) 14751 (match_dup 2) (reg:SI SP_REG)] 14752 UNSPEC_TLSDESC)) 14753 (clobber (reg:CC FLAGS_REG))])] 14754 "!TARGET_64BIT && TARGET_GNU2_TLS" 14755{ 14756 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14757 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14758}) 14759 14760(define_insn "*tls_dynamic_gnu2_lea_32" 14761 [(set (match_operand:SI 0 "register_operand" "=r") 14762 (plus:SI (match_operand:SI 1 "register_operand" "b") 14763 (const:SI 14764 (unspec:SI [(match_operand 2 "tls_symbolic_operand")] 14765 UNSPEC_TLSDESC))))] 14766 "!TARGET_64BIT && TARGET_GNU2_TLS" 14767 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" 14768 [(set_attr "type" "lea") 14769 (set_attr "mode" "SI") 14770 (set_attr "length" "6") 14771 (set_attr "length_address" "4")]) 14772 14773(define_insn "*tls_dynamic_gnu2_call_32" 14774 [(set (match_operand:SI 0 "register_operand" "=a") 14775 (unspec:SI [(match_operand 1 "tls_symbolic_operand") 14776 (match_operand:SI 2 "register_operand" "0") 14777 ;; we have to make sure %ebx still points to the GOT 14778 (match_operand:SI 3 "register_operand" "b") 14779 (reg:SI SP_REG)] 14780 UNSPEC_TLSDESC)) 14781 (clobber (reg:CC FLAGS_REG))] 14782 "!TARGET_64BIT && TARGET_GNU2_TLS" 14783 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 14784 [(set_attr "type" "call") 14785 (set_attr "length" "2") 14786 (set_attr "length_address" "0")]) 14787 14788(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 14789 [(set (match_operand:SI 0 "register_operand" "=&a") 14790 (plus:SI 14791 (unspec:SI [(match_operand 3 "tls_modbase_operand") 14792 (match_operand:SI 4) 14793 (match_operand:SI 2 "register_operand" "b") 14794 (reg:SI SP_REG)] 14795 UNSPEC_TLSDESC) 14796 (const:SI (unspec:SI 14797 [(match_operand 1 "tls_symbolic_operand")] 14798 UNSPEC_DTPOFF)))) 14799 (clobber (reg:CC FLAGS_REG))] 14800 "!TARGET_64BIT && TARGET_GNU2_TLS" 14801 "#" 14802 "" 14803 [(set (match_dup 0) (match_dup 5))] 14804{ 14805 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14806 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 14807}) 14808 14809(define_expand "tls_dynamic_gnu2_64" 14810 [(set (match_dup 2) 14811 (unspec:DI [(match_operand 1 "tls_symbolic_operand")] 14812 UNSPEC_TLSDESC)) 14813 (parallel 14814 [(set (match_operand:DI 0 "register_operand") 14815 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 14816 UNSPEC_TLSDESC)) 14817 (clobber (reg:CC FLAGS_REG))])] 14818 "TARGET_64BIT && TARGET_GNU2_TLS" 14819{ 14820 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14821 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14822}) 14823 14824(define_insn "*tls_dynamic_gnu2_lea_64" 14825 [(set (match_operand:DI 0 "register_operand" "=r") 14826 (unspec:DI [(match_operand 1 "tls_symbolic_operand")] 14827 UNSPEC_TLSDESC))] 14828 "TARGET_64BIT && TARGET_GNU2_TLS" 14829 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" 14830 [(set_attr "type" "lea") 14831 (set_attr "mode" "DI") 14832 (set_attr "length" "7") 14833 (set_attr "length_address" "4")]) 14834 14835(define_insn "*tls_dynamic_gnu2_call_64" 14836 [(set (match_operand:DI 0 "register_operand" "=a") 14837 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 14838 (match_operand:DI 2 "register_operand" "0") 14839 (reg:DI SP_REG)] 14840 UNSPEC_TLSDESC)) 14841 (clobber (reg:CC FLAGS_REG))] 14842 "TARGET_64BIT && TARGET_GNU2_TLS" 14843 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 14844 [(set_attr "type" "call") 14845 (set_attr "length" "2") 14846 (set_attr "length_address" "0")]) 14847 14848(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 14849 [(set (match_operand:DI 0 "register_operand" "=&a") 14850 (plus:DI 14851 (unspec:DI [(match_operand 2 "tls_modbase_operand") 14852 (match_operand:DI 3) 14853 (reg:DI SP_REG)] 14854 UNSPEC_TLSDESC) 14855 (const:DI (unspec:DI 14856 [(match_operand 1 "tls_symbolic_operand")] 14857 UNSPEC_DTPOFF)))) 14858 (clobber (reg:CC FLAGS_REG))] 14859 "TARGET_64BIT && TARGET_GNU2_TLS" 14860 "#" 14861 "" 14862 [(set (match_dup 0) (match_dup 4))] 14863{ 14864 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14865 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 14866}) 14867 14868(define_split 14869 [(match_operand 0 "tls_address_pattern")] 14870 "TARGET_TLS_DIRECT_SEG_REFS" 14871 [(match_dup 0)] 14872 "operands[0] = ix86_rewrite_tls_address (operands[0]);") 14873 14874 14875;; These patterns match the binary 387 instructions for addM3, subM3, 14876;; mulM3 and divM3. There are three patterns for each of DFmode and 14877;; SFmode. The first is the normal insn, the second the same insn but 14878;; with one operand a conversion, and the third the same insn but with 14879;; the other operand a conversion. The conversion may be SFmode or 14880;; SImode if the target mode DFmode, but only SImode if the target mode 14881;; is SFmode. 14882 14883;; Gcc is slightly more smart about handling normal two address instructions 14884;; so use special patterns for add and mull. 14885 14886(define_insn "*fop_<mode>_comm" 14887 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v") 14888 (match_operator:MODEF 3 "binary_fp_operator" 14889 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v") 14890 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))] 14891 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14892 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))) 14893 && COMMUTATIVE_ARITH_P (operands[3]) 14894 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 14895 "* return output_387_binary_op (insn, operands);" 14896 [(set (attr "type") 14897 (if_then_else (eq_attr "alternative" "1,2") 14898 (if_then_else (match_operand:MODEF 3 "mult_operator") 14899 (const_string "ssemul") 14900 (const_string "sseadd")) 14901 (if_then_else (match_operand:MODEF 3 "mult_operator") 14902 (const_string "fmul") 14903 (const_string "fop")))) 14904 (set_attr "isa" "*,noavx,avx") 14905 (set_attr "prefix" "orig,orig,vex") 14906 (set_attr "mode" "<MODE>") 14907 (set (attr "enabled") 14908 (if_then_else 14909 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 14910 (if_then_else 14911 (eq_attr "alternative" "0") 14912 (symbol_ref "TARGET_MIX_SSE_I387 14913 && X87_ENABLE_ARITH (<MODE>mode)") 14914 (const_string "*")) 14915 (if_then_else 14916 (eq_attr "alternative" "0") 14917 (symbol_ref "true") 14918 (symbol_ref "false"))))]) 14919 14920(define_insn "*rcpsf2_sse" 14921 [(set (match_operand:SF 0 "register_operand" "=x") 14922 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 14923 UNSPEC_RCP))] 14924 "TARGET_SSE && TARGET_SSE_MATH" 14925 "%vrcpss\t{%1, %d0|%d0, %1}" 14926 [(set_attr "type" "sse") 14927 (set_attr "atom_sse_attr" "rcp") 14928 (set_attr "btver2_sse_attr" "rcp") 14929 (set_attr "prefix" "maybe_vex") 14930 (set_attr "mode" "SF")]) 14931 14932(define_insn "*fop_<mode>_1" 14933 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v") 14934 (match_operator:MODEF 3 "binary_fp_operator" 14935 [(match_operand:MODEF 1 14936 "x87nonimm_ssenomem_operand" "0,fm,0,v") 14937 (match_operand:MODEF 2 14938 "nonimmediate_operand" "fm,0,xm,vm")]))] 14939 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14940 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))) 14941 && !COMMUTATIVE_ARITH_P (operands[3]) 14942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 14943 "* return output_387_binary_op (insn, operands);" 14944 [(set (attr "type") 14945 (if_then_else (eq_attr "alternative" "2,3") 14946 (if_then_else (match_operand:MODEF 3 "div_operator") 14947 (const_string "ssediv") 14948 (const_string "sseadd")) 14949 (if_then_else (match_operand:MODEF 3 "div_operator") 14950 (const_string "fdiv") 14951 (const_string "fop")))) 14952 (set_attr "isa" "*,*,noavx,avx") 14953 (set_attr "prefix" "orig,orig,orig,vex") 14954 (set_attr "mode" "<MODE>") 14955 (set (attr "enabled") 14956 (if_then_else 14957 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 14958 (if_then_else 14959 (eq_attr "alternative" "0,1") 14960 (symbol_ref "TARGET_MIX_SSE_I387 14961 && X87_ENABLE_ARITH (<MODE>mode)") 14962 (const_string "*")) 14963 (if_then_else 14964 (eq_attr "alternative" "0,1") 14965 (symbol_ref "true") 14966 (symbol_ref "false"))))]) 14967 14968;; ??? Add SSE splitters for these! 14969(define_insn "*fop_<MODEF:mode>_2_i387" 14970 [(set (match_operand:MODEF 0 "register_operand" "=f") 14971 (match_operator:MODEF 3 "binary_fp_operator" 14972 [(float:MODEF 14973 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 14974 (match_operand:MODEF 2 "register_operand" "0")]))] 14975 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 14976 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 14977 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 14978 || optimize_function_for_size_p (cfun))" 14979 "* return output_387_binary_op (insn, operands);" 14980 [(set (attr "type") 14981 (cond [(match_operand:MODEF 3 "mult_operator") 14982 (const_string "fmul") 14983 (match_operand:MODEF 3 "div_operator") 14984 (const_string "fdiv") 14985 ] 14986 (const_string "fop"))) 14987 (set_attr "fp_int_src" "true") 14988 (set_attr "mode" "<SWI24:MODE>")]) 14989 14990(define_insn "*fop_<MODEF:mode>_3_i387" 14991 [(set (match_operand:MODEF 0 "register_operand" "=f") 14992 (match_operator:MODEF 3 "binary_fp_operator" 14993 [(match_operand:MODEF 1 "register_operand" "0") 14994 (float:MODEF 14995 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 14996 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 14997 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 14998 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 14999 || optimize_function_for_size_p (cfun))" 15000 "* return output_387_binary_op (insn, operands);" 15001 [(set (attr "type") 15002 (cond [(match_operand:MODEF 3 "mult_operator") 15003 (const_string "fmul") 15004 (match_operand:MODEF 3 "div_operator") 15005 (const_string "fdiv") 15006 ] 15007 (const_string "fop"))) 15008 (set_attr "fp_int_src" "true") 15009 (set_attr "mode" "<MODE>")]) 15010 15011(define_insn "*fop_df_4_i387" 15012 [(set (match_operand:DF 0 "register_operand" "=f,f") 15013 (match_operator:DF 3 "binary_fp_operator" 15014 [(float_extend:DF 15015 (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 15016 (match_operand:DF 2 "register_operand" "0,f")]))] 15017 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15018 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15019 "* return output_387_binary_op (insn, operands);" 15020 [(set (attr "type") 15021 (cond [(match_operand:DF 3 "mult_operator") 15022 (const_string "fmul") 15023 (match_operand:DF 3 "div_operator") 15024 (const_string "fdiv") 15025 ] 15026 (const_string "fop"))) 15027 (set_attr "mode" "SF")]) 15028 15029(define_insn "*fop_df_5_i387" 15030 [(set (match_operand:DF 0 "register_operand" "=f,f") 15031 (match_operator:DF 3 "binary_fp_operator" 15032 [(match_operand:DF 1 "register_operand" "0,f") 15033 (float_extend:DF 15034 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15035 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15036 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15037 "* return output_387_binary_op (insn, operands);" 15038 [(set (attr "type") 15039 (cond [(match_operand:DF 3 "mult_operator") 15040 (const_string "fmul") 15041 (match_operand:DF 3 "div_operator") 15042 (const_string "fdiv") 15043 ] 15044 (const_string "fop"))) 15045 (set_attr "mode" "SF")]) 15046 15047(define_insn "*fop_df_6_i387" 15048 [(set (match_operand:DF 0 "register_operand" "=f,f") 15049 (match_operator:DF 3 "binary_fp_operator" 15050 [(float_extend:DF 15051 (match_operand:SF 1 "register_operand" "0,f")) 15052 (float_extend:DF 15053 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15054 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15055 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15056 "* return output_387_binary_op (insn, operands);" 15057 [(set (attr "type") 15058 (cond [(match_operand:DF 3 "mult_operator") 15059 (const_string "fmul") 15060 (match_operand:DF 3 "div_operator") 15061 (const_string "fdiv") 15062 ] 15063 (const_string "fop"))) 15064 (set_attr "mode" "SF")]) 15065 15066(define_insn "*fop_xf_comm_i387" 15067 [(set (match_operand:XF 0 "register_operand" "=f") 15068 (match_operator:XF 3 "binary_fp_operator" 15069 [(match_operand:XF 1 "register_operand" "%0") 15070 (match_operand:XF 2 "register_operand" "f")]))] 15071 "TARGET_80387 15072 && COMMUTATIVE_ARITH_P (operands[3])" 15073 "* return output_387_binary_op (insn, operands);" 15074 [(set (attr "type") 15075 (if_then_else (match_operand:XF 3 "mult_operator") 15076 (const_string "fmul") 15077 (const_string "fop"))) 15078 (set_attr "mode" "XF")]) 15079 15080(define_insn "*fop_xf_1_i387" 15081 [(set (match_operand:XF 0 "register_operand" "=f,f") 15082 (match_operator:XF 3 "binary_fp_operator" 15083 [(match_operand:XF 1 "register_operand" "0,f") 15084 (match_operand:XF 2 "register_operand" "f,0")]))] 15085 "TARGET_80387 15086 && !COMMUTATIVE_ARITH_P (operands[3])" 15087 "* return output_387_binary_op (insn, operands);" 15088 [(set (attr "type") 15089 (if_then_else (match_operand:XF 3 "div_operator") 15090 (const_string "fdiv") 15091 (const_string "fop"))) 15092 (set_attr "mode" "XF")]) 15093 15094(define_insn "*fop_xf_2_i387" 15095 [(set (match_operand:XF 0 "register_operand" "=f") 15096 (match_operator:XF 3 "binary_fp_operator" 15097 [(float:XF 15098 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 15099 (match_operand:XF 2 "register_operand" "0")]))] 15100 "TARGET_80387 15101 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 15102 "* return output_387_binary_op (insn, operands);" 15103 [(set (attr "type") 15104 (cond [(match_operand:XF 3 "mult_operator") 15105 (const_string "fmul") 15106 (match_operand:XF 3 "div_operator") 15107 (const_string "fdiv") 15108 ] 15109 (const_string "fop"))) 15110 (set_attr "fp_int_src" "true") 15111 (set_attr "mode" "<MODE>")]) 15112 15113(define_insn "*fop_xf_3_i387" 15114 [(set (match_operand:XF 0 "register_operand" "=f") 15115 (match_operator:XF 3 "binary_fp_operator" 15116 [(match_operand:XF 1 "register_operand" "0") 15117 (float:XF 15118 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 15119 "TARGET_80387 15120 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 15121 "* return output_387_binary_op (insn, operands);" 15122 [(set (attr "type") 15123 (cond [(match_operand:XF 3 "mult_operator") 15124 (const_string "fmul") 15125 (match_operand:XF 3 "div_operator") 15126 (const_string "fdiv") 15127 ] 15128 (const_string "fop"))) 15129 (set_attr "fp_int_src" "true") 15130 (set_attr "mode" "<MODE>")]) 15131 15132(define_insn "*fop_xf_4_i387" 15133 [(set (match_operand:XF 0 "register_operand" "=f,f") 15134 (match_operator:XF 3 "binary_fp_operator" 15135 [(float_extend:XF 15136 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) 15137 (match_operand:XF 2 "register_operand" "0,f")]))] 15138 "TARGET_80387" 15139 "* return output_387_binary_op (insn, operands);" 15140 [(set (attr "type") 15141 (cond [(match_operand:XF 3 "mult_operator") 15142 (const_string "fmul") 15143 (match_operand:XF 3 "div_operator") 15144 (const_string "fdiv") 15145 ] 15146 (const_string "fop"))) 15147 (set_attr "mode" "<MODE>")]) 15148 15149(define_insn "*fop_xf_5_i387" 15150 [(set (match_operand:XF 0 "register_operand" "=f,f") 15151 (match_operator:XF 3 "binary_fp_operator" 15152 [(match_operand:XF 1 "register_operand" "0,f") 15153 (float_extend:XF 15154 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 15155 "TARGET_80387" 15156 "* return output_387_binary_op (insn, operands);" 15157 [(set (attr "type") 15158 (cond [(match_operand:XF 3 "mult_operator") 15159 (const_string "fmul") 15160 (match_operand:XF 3 "div_operator") 15161 (const_string "fdiv") 15162 ] 15163 (const_string "fop"))) 15164 (set_attr "mode" "<MODE>")]) 15165 15166(define_insn "*fop_xf_6_i387" 15167 [(set (match_operand:XF 0 "register_operand" "=f,f") 15168 (match_operator:XF 3 "binary_fp_operator" 15169 [(float_extend:XF 15170 (match_operand:MODEF 1 "register_operand" "0,f")) 15171 (float_extend:XF 15172 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 15173 "TARGET_80387" 15174 "* return output_387_binary_op (insn, operands);" 15175 [(set (attr "type") 15176 (cond [(match_operand:XF 3 "mult_operator") 15177 (const_string "fmul") 15178 (match_operand:XF 3 "div_operator") 15179 (const_string "fdiv") 15180 ] 15181 (const_string "fop"))) 15182 (set_attr "mode" "<MODE>")]) 15183 15184;; FPU special functions. 15185 15186;; This pattern implements a no-op XFmode truncation for 15187;; all fancy i386 XFmode math functions. 15188 15189(define_insn "truncxf<mode>2_i387_noop_unspec" 15190 [(set (match_operand:MODEF 0 "register_operand" "=f") 15191 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] 15192 UNSPEC_TRUNC_NOOP))] 15193 "TARGET_USE_FANCY_MATH_387" 15194 "* return output_387_reg_move (insn, operands);" 15195 [(set_attr "type" "fmov") 15196 (set_attr "mode" "<MODE>")]) 15197 15198(define_insn "sqrtxf2" 15199 [(set (match_operand:XF 0 "register_operand" "=f") 15200 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15201 "TARGET_USE_FANCY_MATH_387" 15202 "fsqrt" 15203 [(set_attr "type" "fpspc") 15204 (set_attr "mode" "XF") 15205 (set_attr "athlon_decode" "direct") 15206 (set_attr "amdfam10_decode" "direct") 15207 (set_attr "bdver1_decode" "direct")]) 15208 15209(define_insn "sqrt_extend<mode>xf2_i387" 15210 [(set (match_operand:XF 0 "register_operand" "=f") 15211 (sqrt:XF 15212 (float_extend:XF 15213 (match_operand:MODEF 1 "register_operand" "0"))))] 15214 "TARGET_USE_FANCY_MATH_387" 15215 "fsqrt" 15216 [(set_attr "type" "fpspc") 15217 (set_attr "mode" "XF") 15218 (set_attr "athlon_decode" "direct") 15219 (set_attr "amdfam10_decode" "direct") 15220 (set_attr "bdver1_decode" "direct")]) 15221 15222(define_insn "*rsqrtsf2_sse" 15223 [(set (match_operand:SF 0 "register_operand" "=x") 15224 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 15225 UNSPEC_RSQRT))] 15226 "TARGET_SSE && TARGET_SSE_MATH" 15227 "%vrsqrtss\t{%1, %d0|%d0, %1}" 15228 [(set_attr "type" "sse") 15229 (set_attr "atom_sse_attr" "rcp") 15230 (set_attr "btver2_sse_attr" "rcp") 15231 (set_attr "prefix" "maybe_vex") 15232 (set_attr "mode" "SF")]) 15233 15234(define_expand "rsqrtsf2" 15235 [(set (match_operand:SF 0 "register_operand") 15236 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")] 15237 UNSPEC_RSQRT))] 15238 "TARGET_SSE && TARGET_SSE_MATH" 15239{ 15240 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); 15241 DONE; 15242}) 15243 15244(define_insn "*sqrt<mode>2_sse" 15245 [(set (match_operand:MODEF 0 "register_operand" "=v") 15246 (sqrt:MODEF 15247 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))] 15248 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 15249 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}" 15250 [(set_attr "type" "sse") 15251 (set_attr "atom_sse_attr" "sqrt") 15252 (set_attr "btver2_sse_attr" "sqrt") 15253 (set_attr "prefix" "maybe_vex") 15254 (set_attr "mode" "<MODE>") 15255 (set_attr "athlon_decode" "*") 15256 (set_attr "amdfam10_decode" "*") 15257 (set_attr "bdver1_decode" "*")]) 15258 15259(define_expand "sqrt<mode>2" 15260 [(set (match_operand:MODEF 0 "register_operand") 15261 (sqrt:MODEF 15262 (match_operand:MODEF 1 "nonimmediate_operand")))] 15263 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) 15264 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 15265{ 15266 if (<MODE>mode == SFmode 15267 && TARGET_SSE && TARGET_SSE_MATH 15268 && TARGET_RECIP_SQRT 15269 && !optimize_function_for_size_p (cfun) 15270 && flag_finite_math_only && !flag_trapping_math 15271 && flag_unsafe_math_optimizations) 15272 { 15273 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); 15274 DONE; 15275 } 15276 15277 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 15278 { 15279 rtx op0 = gen_reg_rtx (XFmode); 15280 rtx op1 = force_reg (<MODE>mode, operands[1]); 15281 15282 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1)); 15283 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 15284 DONE; 15285 } 15286}) 15287 15288(define_insn "fpremxf4_i387" 15289 [(set (match_operand:XF 0 "register_operand" "=f") 15290 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15291 (match_operand:XF 3 "register_operand" "1")] 15292 UNSPEC_FPREM_F)) 15293 (set (match_operand:XF 1 "register_operand" "=u") 15294 (unspec:XF [(match_dup 2) (match_dup 3)] 15295 UNSPEC_FPREM_U)) 15296 (set (reg:CCFP FPSR_REG) 15297 (unspec:CCFP [(match_dup 2) (match_dup 3)] 15298 UNSPEC_C2_FLAG))] 15299 "TARGET_USE_FANCY_MATH_387 15300 && flag_finite_math_only" 15301 "fprem" 15302 [(set_attr "type" "fpspc") 15303 (set_attr "znver1_decode" "vector") 15304 (set_attr "mode" "XF")]) 15305 15306(define_expand "fmodxf3" 15307 [(use (match_operand:XF 0 "register_operand")) 15308 (use (match_operand:XF 1 "general_operand")) 15309 (use (match_operand:XF 2 "general_operand"))] 15310 "TARGET_USE_FANCY_MATH_387 15311 && flag_finite_math_only" 15312{ 15313 rtx_code_label *label = gen_label_rtx (); 15314 15315 rtx op1 = gen_reg_rtx (XFmode); 15316 rtx op2 = gen_reg_rtx (XFmode); 15317 15318 emit_move_insn (op2, operands[2]); 15319 emit_move_insn (op1, operands[1]); 15320 15321 emit_label (label); 15322 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 15323 ix86_emit_fp_unordered_jump (label); 15324 LABEL_NUSES (label) = 1; 15325 15326 emit_move_insn (operands[0], op1); 15327 DONE; 15328}) 15329 15330(define_expand "fmod<mode>3" 15331 [(use (match_operand:MODEF 0 "register_operand")) 15332 (use (match_operand:MODEF 1 "general_operand")) 15333 (use (match_operand:MODEF 2 "general_operand"))] 15334 "TARGET_USE_FANCY_MATH_387 15335 && flag_finite_math_only" 15336{ 15337 rtx (*gen_truncxf) (rtx, rtx); 15338 15339 rtx_code_label *label = gen_label_rtx (); 15340 15341 rtx op1 = gen_reg_rtx (XFmode); 15342 rtx op2 = gen_reg_rtx (XFmode); 15343 15344 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15345 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15346 15347 emit_label (label); 15348 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 15349 ix86_emit_fp_unordered_jump (label); 15350 LABEL_NUSES (label) = 1; 15351 15352 /* Truncate the result properly for strict SSE math. */ 15353 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15354 && !TARGET_MIX_SSE_I387) 15355 gen_truncxf = gen_truncxf<mode>2; 15356 else 15357 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 15358 15359 emit_insn (gen_truncxf (operands[0], op1)); 15360 DONE; 15361}) 15362 15363(define_insn "fprem1xf4_i387" 15364 [(set (match_operand:XF 0 "register_operand" "=f") 15365 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15366 (match_operand:XF 3 "register_operand" "1")] 15367 UNSPEC_FPREM1_F)) 15368 (set (match_operand:XF 1 "register_operand" "=u") 15369 (unspec:XF [(match_dup 2) (match_dup 3)] 15370 UNSPEC_FPREM1_U)) 15371 (set (reg:CCFP FPSR_REG) 15372 (unspec:CCFP [(match_dup 2) (match_dup 3)] 15373 UNSPEC_C2_FLAG))] 15374 "TARGET_USE_FANCY_MATH_387 15375 && flag_finite_math_only" 15376 "fprem1" 15377 [(set_attr "type" "fpspc") 15378 (set_attr "znver1_decode" "vector") 15379 (set_attr "mode" "XF")]) 15380 15381(define_expand "remainderxf3" 15382 [(use (match_operand:XF 0 "register_operand")) 15383 (use (match_operand:XF 1 "general_operand")) 15384 (use (match_operand:XF 2 "general_operand"))] 15385 "TARGET_USE_FANCY_MATH_387 15386 && flag_finite_math_only" 15387{ 15388 rtx_code_label *label = gen_label_rtx (); 15389 15390 rtx op1 = gen_reg_rtx (XFmode); 15391 rtx op2 = gen_reg_rtx (XFmode); 15392 15393 emit_move_insn (op2, operands[2]); 15394 emit_move_insn (op1, operands[1]); 15395 15396 emit_label (label); 15397 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 15398 ix86_emit_fp_unordered_jump (label); 15399 LABEL_NUSES (label) = 1; 15400 15401 emit_move_insn (operands[0], op1); 15402 DONE; 15403}) 15404 15405(define_expand "remainder<mode>3" 15406 [(use (match_operand:MODEF 0 "register_operand")) 15407 (use (match_operand:MODEF 1 "general_operand")) 15408 (use (match_operand:MODEF 2 "general_operand"))] 15409 "TARGET_USE_FANCY_MATH_387 15410 && flag_finite_math_only" 15411{ 15412 rtx (*gen_truncxf) (rtx, rtx); 15413 15414 rtx_code_label *label = gen_label_rtx (); 15415 15416 rtx op1 = gen_reg_rtx (XFmode); 15417 rtx op2 = gen_reg_rtx (XFmode); 15418 15419 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15420 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15421 15422 emit_label (label); 15423 15424 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 15425 ix86_emit_fp_unordered_jump (label); 15426 LABEL_NUSES (label) = 1; 15427 15428 /* Truncate the result properly for strict SSE math. */ 15429 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15430 && !TARGET_MIX_SSE_I387) 15431 gen_truncxf = gen_truncxf<mode>2; 15432 else 15433 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 15434 15435 emit_insn (gen_truncxf (operands[0], op1)); 15436 DONE; 15437}) 15438 15439(define_int_iterator SINCOS 15440 [UNSPEC_SIN 15441 UNSPEC_COS]) 15442 15443(define_int_attr sincos 15444 [(UNSPEC_SIN "sin") 15445 (UNSPEC_COS "cos")]) 15446 15447(define_insn "*<sincos>xf2_i387" 15448 [(set (match_operand:XF 0 "register_operand" "=f") 15449 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15450 SINCOS))] 15451 "TARGET_USE_FANCY_MATH_387 15452 && flag_unsafe_math_optimizations" 15453 "f<sincos>" 15454 [(set_attr "type" "fpspc") 15455 (set_attr "znver1_decode" "vector") 15456 (set_attr "mode" "XF")]) 15457 15458(define_insn "*<sincos>_extend<mode>xf2_i387" 15459 [(set (match_operand:XF 0 "register_operand" "=f") 15460 (unspec:XF [(float_extend:XF 15461 (match_operand:MODEF 1 "register_operand" "0"))] 15462 SINCOS))] 15463 "TARGET_USE_FANCY_MATH_387 15464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15465 || TARGET_MIX_SSE_I387) 15466 && flag_unsafe_math_optimizations" 15467 "f<sincos>" 15468 [(set_attr "type" "fpspc") 15469 (set_attr "znver1_decode" "vector") 15470 (set_attr "mode" "XF")]) 15471 15472;; When sincos pattern is defined, sin and cos builtin functions will be 15473;; expanded to sincos pattern with one of its outputs left unused. 15474;; CSE pass will figure out if two sincos patterns can be combined, 15475;; otherwise sincos pattern will be split back to sin or cos pattern, 15476;; depending on the unused output. 15477 15478(define_insn "sincosxf3" 15479 [(set (match_operand:XF 0 "register_operand" "=f") 15480 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15481 UNSPEC_SINCOS_COS)) 15482 (set (match_operand:XF 1 "register_operand" "=u") 15483 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15484 "TARGET_USE_FANCY_MATH_387 15485 && flag_unsafe_math_optimizations" 15486 "fsincos" 15487 [(set_attr "type" "fpspc") 15488 (set_attr "znver1_decode" "vector") 15489 (set_attr "mode" "XF")]) 15490 15491(define_split 15492 [(set (match_operand:XF 0 "register_operand") 15493 (unspec:XF [(match_operand:XF 2 "register_operand")] 15494 UNSPEC_SINCOS_COS)) 15495 (set (match_operand:XF 1 "register_operand") 15496 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15497 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15498 && can_create_pseudo_p ()" 15499 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]) 15500 15501(define_split 15502 [(set (match_operand:XF 0 "register_operand") 15503 (unspec:XF [(match_operand:XF 2 "register_operand")] 15504 UNSPEC_SINCOS_COS)) 15505 (set (match_operand:XF 1 "register_operand") 15506 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15507 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15508 && can_create_pseudo_p ()" 15509 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]) 15510 15511(define_insn "sincos_extend<mode>xf3_i387" 15512 [(set (match_operand:XF 0 "register_operand" "=f") 15513 (unspec:XF [(float_extend:XF 15514 (match_operand:MODEF 2 "register_operand" "0"))] 15515 UNSPEC_SINCOS_COS)) 15516 (set (match_operand:XF 1 "register_operand" "=u") 15517 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15518 "TARGET_USE_FANCY_MATH_387 15519 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15520 || TARGET_MIX_SSE_I387) 15521 && flag_unsafe_math_optimizations" 15522 "fsincos" 15523 [(set_attr "type" "fpspc") 15524 (set_attr "znver1_decode" "vector") 15525 (set_attr "mode" "XF")]) 15526 15527(define_split 15528 [(set (match_operand:XF 0 "register_operand") 15529 (unspec:XF [(float_extend:XF 15530 (match_operand:MODEF 2 "register_operand"))] 15531 UNSPEC_SINCOS_COS)) 15532 (set (match_operand:XF 1 "register_operand") 15533 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15534 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15535 && can_create_pseudo_p ()" 15536 [(set (match_dup 1) 15537 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]) 15538 15539(define_split 15540 [(set (match_operand:XF 0 "register_operand") 15541 (unspec:XF [(float_extend:XF 15542 (match_operand:MODEF 2 "register_operand"))] 15543 UNSPEC_SINCOS_COS)) 15544 (set (match_operand:XF 1 "register_operand") 15545 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15546 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15547 && can_create_pseudo_p ()" 15548 [(set (match_dup 0) 15549 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]) 15550 15551(define_expand "sincos<mode>3" 15552 [(use (match_operand:MODEF 0 "register_operand")) 15553 (use (match_operand:MODEF 1 "register_operand")) 15554 (use (match_operand:MODEF 2 "register_operand"))] 15555 "TARGET_USE_FANCY_MATH_387 15556 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15557 || TARGET_MIX_SSE_I387) 15558 && flag_unsafe_math_optimizations" 15559{ 15560 rtx op0 = gen_reg_rtx (XFmode); 15561 rtx op1 = gen_reg_rtx (XFmode); 15562 15563 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2])); 15564 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15565 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1)); 15566 DONE; 15567}) 15568 15569(define_insn "fptanxf4_i387" 15570 [(set (match_operand:XF 0 "register_operand" "=f") 15571 (match_operand:XF 3 "const_double_operand" "F")) 15572 (set (match_operand:XF 1 "register_operand" "=u") 15573 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15574 UNSPEC_TAN))] 15575 "TARGET_USE_FANCY_MATH_387 15576 && flag_unsafe_math_optimizations 15577 && standard_80387_constant_p (operands[3]) == 2" 15578 "fptan" 15579 [(set_attr "type" "fpspc") 15580 (set_attr "znver1_decode" "vector") 15581 (set_attr "mode" "XF")]) 15582 15583(define_insn "fptan_extend<mode>xf4_i387" 15584 [(set (match_operand:MODEF 0 "register_operand" "=f") 15585 (match_operand:MODEF 3 "const_double_operand" "F")) 15586 (set (match_operand:XF 1 "register_operand" "=u") 15587 (unspec:XF [(float_extend:XF 15588 (match_operand:MODEF 2 "register_operand" "0"))] 15589 UNSPEC_TAN))] 15590 "TARGET_USE_FANCY_MATH_387 15591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15592 || TARGET_MIX_SSE_I387) 15593 && flag_unsafe_math_optimizations 15594 && standard_80387_constant_p (operands[3]) == 2" 15595 "fptan" 15596 [(set_attr "type" "fpspc") 15597 (set_attr "znver1_decode" "vector") 15598 (set_attr "mode" "XF")]) 15599 15600(define_expand "tanxf2" 15601 [(use (match_operand:XF 0 "register_operand")) 15602 (use (match_operand:XF 1 "register_operand"))] 15603 "TARGET_USE_FANCY_MATH_387 15604 && flag_unsafe_math_optimizations" 15605{ 15606 rtx one = gen_reg_rtx (XFmode); 15607 rtx op2 = CONST1_RTX (XFmode); /* fld1 */ 15608 15609 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2)); 15610 DONE; 15611}) 15612 15613(define_expand "tan<mode>2" 15614 [(use (match_operand:MODEF 0 "register_operand")) 15615 (use (match_operand:MODEF 1 "register_operand"))] 15616 "TARGET_USE_FANCY_MATH_387 15617 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15618 || TARGET_MIX_SSE_I387) 15619 && flag_unsafe_math_optimizations" 15620{ 15621 rtx op0 = gen_reg_rtx (XFmode); 15622 15623 rtx one = gen_reg_rtx (<MODE>mode); 15624 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */ 15625 15626 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0, 15627 operands[1], op2)); 15628 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15629 DONE; 15630}) 15631 15632(define_insn "*fpatanxf3_i387" 15633 [(set (match_operand:XF 0 "register_operand" "=f") 15634 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15635 (match_operand:XF 2 "register_operand" "u")] 15636 UNSPEC_FPATAN)) 15637 (clobber (match_scratch:XF 3 "=2"))] 15638 "TARGET_USE_FANCY_MATH_387 15639 && flag_unsafe_math_optimizations" 15640 "fpatan" 15641 [(set_attr "type" "fpspc") 15642 (set_attr "znver1_decode" "vector") 15643 (set_attr "mode" "XF")]) 15644 15645(define_insn "fpatan_extend<mode>xf3_i387" 15646 [(set (match_operand:XF 0 "register_operand" "=f") 15647 (unspec:XF [(float_extend:XF 15648 (match_operand:MODEF 1 "register_operand" "0")) 15649 (float_extend:XF 15650 (match_operand:MODEF 2 "register_operand" "u"))] 15651 UNSPEC_FPATAN)) 15652 (clobber (match_scratch:XF 3 "=2"))] 15653 "TARGET_USE_FANCY_MATH_387 15654 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15655 || TARGET_MIX_SSE_I387) 15656 && flag_unsafe_math_optimizations" 15657 "fpatan" 15658 [(set_attr "type" "fpspc") 15659 (set_attr "znver1_decode" "vector") 15660 (set_attr "mode" "XF")]) 15661 15662(define_expand "atan2xf3" 15663 [(parallel [(set (match_operand:XF 0 "register_operand") 15664 (unspec:XF [(match_operand:XF 2 "register_operand") 15665 (match_operand:XF 1 "register_operand")] 15666 UNSPEC_FPATAN)) 15667 (clobber (match_scratch:XF 3))])] 15668 "TARGET_USE_FANCY_MATH_387 15669 && flag_unsafe_math_optimizations") 15670 15671(define_expand "atan2<mode>3" 15672 [(use (match_operand:MODEF 0 "register_operand")) 15673 (use (match_operand:MODEF 1 "register_operand")) 15674 (use (match_operand:MODEF 2 "register_operand"))] 15675 "TARGET_USE_FANCY_MATH_387 15676 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15677 || TARGET_MIX_SSE_I387) 15678 && flag_unsafe_math_optimizations" 15679{ 15680 rtx op0 = gen_reg_rtx (XFmode); 15681 15682 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1])); 15683 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15684 DONE; 15685}) 15686 15687(define_expand "atanxf2" 15688 [(parallel [(set (match_operand:XF 0 "register_operand") 15689 (unspec:XF [(match_dup 2) 15690 (match_operand:XF 1 "register_operand")] 15691 UNSPEC_FPATAN)) 15692 (clobber (match_scratch:XF 3))])] 15693 "TARGET_USE_FANCY_MATH_387 15694 && flag_unsafe_math_optimizations" 15695{ 15696 operands[2] = gen_reg_rtx (XFmode); 15697 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 15698}) 15699 15700(define_expand "atan<mode>2" 15701 [(use (match_operand:MODEF 0 "register_operand")) 15702 (use (match_operand:MODEF 1 "register_operand"))] 15703 "TARGET_USE_FANCY_MATH_387 15704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15705 || TARGET_MIX_SSE_I387) 15706 && flag_unsafe_math_optimizations" 15707{ 15708 rtx op0 = gen_reg_rtx (XFmode); 15709 15710 rtx op2 = gen_reg_rtx (<MODE>mode); 15711 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */ 15712 15713 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1])); 15714 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15715 DONE; 15716}) 15717 15718(define_expand "asinxf2" 15719 [(set (match_dup 2) 15720 (mult:XF (match_operand:XF 1 "register_operand") 15721 (match_dup 1))) 15722 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 15723 (set (match_dup 5) (sqrt:XF (match_dup 4))) 15724 (parallel [(set (match_operand:XF 0 "register_operand") 15725 (unspec:XF [(match_dup 5) (match_dup 1)] 15726 UNSPEC_FPATAN)) 15727 (clobber (match_scratch:XF 6))])] 15728 "TARGET_USE_FANCY_MATH_387 15729 && flag_unsafe_math_optimizations" 15730{ 15731 int i; 15732 15733 for (i = 2; i < 6; i++) 15734 operands[i] = gen_reg_rtx (XFmode); 15735 15736 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 15737}) 15738 15739(define_expand "asin<mode>2" 15740 [(use (match_operand:MODEF 0 "register_operand")) 15741 (use (match_operand:MODEF 1 "general_operand"))] 15742 "TARGET_USE_FANCY_MATH_387 15743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15744 || TARGET_MIX_SSE_I387) 15745 && flag_unsafe_math_optimizations" 15746{ 15747 rtx op0 = gen_reg_rtx (XFmode); 15748 rtx op1 = gen_reg_rtx (XFmode); 15749 15750 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15751 emit_insn (gen_asinxf2 (op0, op1)); 15752 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15753 DONE; 15754}) 15755 15756(define_expand "acosxf2" 15757 [(set (match_dup 2) 15758 (mult:XF (match_operand:XF 1 "register_operand") 15759 (match_dup 1))) 15760 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 15761 (set (match_dup 5) (sqrt:XF (match_dup 4))) 15762 (parallel [(set (match_operand:XF 0 "register_operand") 15763 (unspec:XF [(match_dup 1) (match_dup 5)] 15764 UNSPEC_FPATAN)) 15765 (clobber (match_scratch:XF 6))])] 15766 "TARGET_USE_FANCY_MATH_387 15767 && flag_unsafe_math_optimizations" 15768{ 15769 int i; 15770 15771 for (i = 2; i < 6; i++) 15772 operands[i] = gen_reg_rtx (XFmode); 15773 15774 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 15775}) 15776 15777(define_expand "acos<mode>2" 15778 [(use (match_operand:MODEF 0 "register_operand")) 15779 (use (match_operand:MODEF 1 "general_operand"))] 15780 "TARGET_USE_FANCY_MATH_387 15781 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15782 || TARGET_MIX_SSE_I387) 15783 && flag_unsafe_math_optimizations" 15784{ 15785 rtx op0 = gen_reg_rtx (XFmode); 15786 rtx op1 = gen_reg_rtx (XFmode); 15787 15788 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15789 emit_insn (gen_acosxf2 (op0, op1)); 15790 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15791 DONE; 15792}) 15793 15794(define_insn "fyl2xxf3_i387" 15795 [(set (match_operand:XF 0 "register_operand" "=f") 15796 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15797 (match_operand:XF 2 "register_operand" "u")] 15798 UNSPEC_FYL2X)) 15799 (clobber (match_scratch:XF 3 "=2"))] 15800 "TARGET_USE_FANCY_MATH_387 15801 && flag_unsafe_math_optimizations" 15802 "fyl2x" 15803 [(set_attr "type" "fpspc") 15804 (set_attr "znver1_decode" "vector") 15805 (set_attr "mode" "XF")]) 15806 15807(define_insn "fyl2x_extend<mode>xf3_i387" 15808 [(set (match_operand:XF 0 "register_operand" "=f") 15809 (unspec:XF [(float_extend:XF 15810 (match_operand:MODEF 1 "register_operand" "0")) 15811 (match_operand:XF 2 "register_operand" "u")] 15812 UNSPEC_FYL2X)) 15813 (clobber (match_scratch:XF 3 "=2"))] 15814 "TARGET_USE_FANCY_MATH_387 15815 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15816 || TARGET_MIX_SSE_I387) 15817 && flag_unsafe_math_optimizations" 15818 "fyl2x" 15819 [(set_attr "type" "fpspc") 15820 (set_attr "znver1_decode" "vector") 15821 (set_attr "mode" "XF")]) 15822 15823(define_expand "logxf2" 15824 [(parallel [(set (match_operand:XF 0 "register_operand") 15825 (unspec:XF [(match_operand:XF 1 "register_operand") 15826 (match_dup 2)] UNSPEC_FYL2X)) 15827 (clobber (match_scratch:XF 3))])] 15828 "TARGET_USE_FANCY_MATH_387 15829 && flag_unsafe_math_optimizations" 15830{ 15831 operands[2] = gen_reg_rtx (XFmode); 15832 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */ 15833}) 15834 15835(define_expand "log<mode>2" 15836 [(use (match_operand:MODEF 0 "register_operand")) 15837 (use (match_operand:MODEF 1 "register_operand"))] 15838 "TARGET_USE_FANCY_MATH_387 15839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15840 || TARGET_MIX_SSE_I387) 15841 && flag_unsafe_math_optimizations" 15842{ 15843 rtx op0 = gen_reg_rtx (XFmode); 15844 15845 rtx op2 = gen_reg_rtx (XFmode); 15846 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */ 15847 15848 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15849 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15850 DONE; 15851}) 15852 15853(define_expand "log10xf2" 15854 [(parallel [(set (match_operand:XF 0 "register_operand") 15855 (unspec:XF [(match_operand:XF 1 "register_operand") 15856 (match_dup 2)] UNSPEC_FYL2X)) 15857 (clobber (match_scratch:XF 3))])] 15858 "TARGET_USE_FANCY_MATH_387 15859 && flag_unsafe_math_optimizations" 15860{ 15861 operands[2] = gen_reg_rtx (XFmode); 15862 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */ 15863}) 15864 15865(define_expand "log10<mode>2" 15866 [(use (match_operand:MODEF 0 "register_operand")) 15867 (use (match_operand:MODEF 1 "register_operand"))] 15868 "TARGET_USE_FANCY_MATH_387 15869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15870 || TARGET_MIX_SSE_I387) 15871 && flag_unsafe_math_optimizations" 15872{ 15873 rtx op0 = gen_reg_rtx (XFmode); 15874 15875 rtx op2 = gen_reg_rtx (XFmode); 15876 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */ 15877 15878 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15879 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15880 DONE; 15881}) 15882 15883(define_expand "log2xf2" 15884 [(parallel [(set (match_operand:XF 0 "register_operand") 15885 (unspec:XF [(match_operand:XF 1 "register_operand") 15886 (match_dup 2)] UNSPEC_FYL2X)) 15887 (clobber (match_scratch:XF 3))])] 15888 "TARGET_USE_FANCY_MATH_387 15889 && flag_unsafe_math_optimizations" 15890{ 15891 operands[2] = gen_reg_rtx (XFmode); 15892 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 15893}) 15894 15895(define_expand "log2<mode>2" 15896 [(use (match_operand:MODEF 0 "register_operand")) 15897 (use (match_operand:MODEF 1 "register_operand"))] 15898 "TARGET_USE_FANCY_MATH_387 15899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15900 || TARGET_MIX_SSE_I387) 15901 && flag_unsafe_math_optimizations" 15902{ 15903 rtx op0 = gen_reg_rtx (XFmode); 15904 15905 rtx op2 = gen_reg_rtx (XFmode); 15906 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 15907 15908 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15909 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15910 DONE; 15911}) 15912 15913(define_insn "fyl2xp1xf3_i387" 15914 [(set (match_operand:XF 0 "register_operand" "=f") 15915 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15916 (match_operand:XF 2 "register_operand" "u")] 15917 UNSPEC_FYL2XP1)) 15918 (clobber (match_scratch:XF 3 "=2"))] 15919 "TARGET_USE_FANCY_MATH_387 15920 && flag_unsafe_math_optimizations" 15921 "fyl2xp1" 15922 [(set_attr "type" "fpspc") 15923 (set_attr "znver1_decode" "vector") 15924 (set_attr "mode" "XF")]) 15925 15926(define_insn "fyl2xp1_extend<mode>xf3_i387" 15927 [(set (match_operand:XF 0 "register_operand" "=f") 15928 (unspec:XF [(float_extend:XF 15929 (match_operand:MODEF 1 "register_operand" "0")) 15930 (match_operand:XF 2 "register_operand" "u")] 15931 UNSPEC_FYL2XP1)) 15932 (clobber (match_scratch:XF 3 "=2"))] 15933 "TARGET_USE_FANCY_MATH_387 15934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15935 || TARGET_MIX_SSE_I387) 15936 && flag_unsafe_math_optimizations" 15937 "fyl2xp1" 15938 [(set_attr "type" "fpspc") 15939 (set_attr "znver1_decode" "vector") 15940 (set_attr "mode" "XF")]) 15941 15942(define_expand "log1pxf2" 15943 [(use (match_operand:XF 0 "register_operand")) 15944 (use (match_operand:XF 1 "register_operand"))] 15945 "TARGET_USE_FANCY_MATH_387 15946 && flag_unsafe_math_optimizations" 15947{ 15948 ix86_emit_i387_log1p (operands[0], operands[1]); 15949 DONE; 15950}) 15951 15952(define_expand "log1p<mode>2" 15953 [(use (match_operand:MODEF 0 "register_operand")) 15954 (use (match_operand:MODEF 1 "register_operand"))] 15955 "TARGET_USE_FANCY_MATH_387 15956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15957 || TARGET_MIX_SSE_I387) 15958 && flag_unsafe_math_optimizations" 15959{ 15960 rtx op0; 15961 15962 op0 = gen_reg_rtx (XFmode); 15963 15964 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]); 15965 15966 ix86_emit_i387_log1p (op0, operands[1]); 15967 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15968 DONE; 15969}) 15970 15971(define_insn "fxtractxf3_i387" 15972 [(set (match_operand:XF 0 "register_operand" "=f") 15973 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15974 UNSPEC_XTRACT_FRACT)) 15975 (set (match_operand:XF 1 "register_operand" "=u") 15976 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 15977 "TARGET_USE_FANCY_MATH_387 15978 && flag_unsafe_math_optimizations" 15979 "fxtract" 15980 [(set_attr "type" "fpspc") 15981 (set_attr "znver1_decode" "vector") 15982 (set_attr "mode" "XF")]) 15983 15984(define_insn "fxtract_extend<mode>xf3_i387" 15985 [(set (match_operand:XF 0 "register_operand" "=f") 15986 (unspec:XF [(float_extend:XF 15987 (match_operand:MODEF 2 "register_operand" "0"))] 15988 UNSPEC_XTRACT_FRACT)) 15989 (set (match_operand:XF 1 "register_operand" "=u") 15990 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))] 15991 "TARGET_USE_FANCY_MATH_387 15992 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15993 || TARGET_MIX_SSE_I387) 15994 && flag_unsafe_math_optimizations" 15995 "fxtract" 15996 [(set_attr "type" "fpspc") 15997 (set_attr "znver1_decode" "vector") 15998 (set_attr "mode" "XF")]) 15999 16000(define_expand "logbxf2" 16001 [(parallel [(set (match_dup 2) 16002 (unspec:XF [(match_operand:XF 1 "register_operand")] 16003 UNSPEC_XTRACT_FRACT)) 16004 (set (match_operand:XF 0 "register_operand") 16005 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16006 "TARGET_USE_FANCY_MATH_387 16007 && flag_unsafe_math_optimizations" 16008 "operands[2] = gen_reg_rtx (XFmode);") 16009 16010(define_expand "logb<mode>2" 16011 [(use (match_operand:MODEF 0 "register_operand")) 16012 (use (match_operand:MODEF 1 "register_operand"))] 16013 "TARGET_USE_FANCY_MATH_387 16014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16015 || TARGET_MIX_SSE_I387) 16016 && flag_unsafe_math_optimizations" 16017{ 16018 rtx op0 = gen_reg_rtx (XFmode); 16019 rtx op1 = gen_reg_rtx (XFmode); 16020 16021 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 16022 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1)); 16023 DONE; 16024}) 16025 16026(define_expand "ilogbxf2" 16027 [(use (match_operand:SI 0 "register_operand")) 16028 (use (match_operand:XF 1 "register_operand"))] 16029 "TARGET_USE_FANCY_MATH_387 16030 && flag_unsafe_math_optimizations" 16031{ 16032 rtx op0, op1; 16033 16034 if (optimize_insn_for_size_p ()) 16035 FAIL; 16036 16037 op0 = gen_reg_rtx (XFmode); 16038 op1 = gen_reg_rtx (XFmode); 16039 16040 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); 16041 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 16042 DONE; 16043}) 16044 16045(define_expand "ilogb<mode>2" 16046 [(use (match_operand:SI 0 "register_operand")) 16047 (use (match_operand:MODEF 1 "register_operand"))] 16048 "TARGET_USE_FANCY_MATH_387 16049 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16050 || TARGET_MIX_SSE_I387) 16051 && flag_unsafe_math_optimizations" 16052{ 16053 rtx op0, op1; 16054 16055 if (optimize_insn_for_size_p ()) 16056 FAIL; 16057 16058 op0 = gen_reg_rtx (XFmode); 16059 op1 = gen_reg_rtx (XFmode); 16060 16061 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 16062 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 16063 DONE; 16064}) 16065 16066(define_insn "*f2xm1xf2_i387" 16067 [(set (match_operand:XF 0 "register_operand" "=f") 16068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16069 UNSPEC_F2XM1))] 16070 "TARGET_USE_FANCY_MATH_387 16071 && flag_unsafe_math_optimizations" 16072 "f2xm1" 16073 [(set_attr "type" "fpspc") 16074 (set_attr "znver1_decode" "vector") 16075 (set_attr "mode" "XF")]) 16076 16077(define_insn "fscalexf4_i387" 16078 [(set (match_operand:XF 0 "register_operand" "=f") 16079 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16080 (match_operand:XF 3 "register_operand" "1")] 16081 UNSPEC_FSCALE_FRACT)) 16082 (set (match_operand:XF 1 "register_operand" "=u") 16083 (unspec:XF [(match_dup 2) (match_dup 3)] 16084 UNSPEC_FSCALE_EXP))] 16085 "TARGET_USE_FANCY_MATH_387 16086 && flag_unsafe_math_optimizations" 16087 "fscale" 16088 [(set_attr "type" "fpspc") 16089 (set_attr "znver1_decode" "vector") 16090 (set_attr "mode" "XF")]) 16091 16092(define_expand "expNcorexf3" 16093 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 16094 (match_operand:XF 2 "register_operand"))) 16095 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16096 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16097 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16098 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16099 (parallel [(set (match_operand:XF 0 "register_operand") 16100 (unspec:XF [(match_dup 8) (match_dup 4)] 16101 UNSPEC_FSCALE_FRACT)) 16102 (set (match_dup 9) 16103 (unspec:XF [(match_dup 8) (match_dup 4)] 16104 UNSPEC_FSCALE_EXP))])] 16105 "TARGET_USE_FANCY_MATH_387 16106 && flag_unsafe_math_optimizations" 16107{ 16108 int i; 16109 16110 for (i = 3; i < 10; i++) 16111 operands[i] = gen_reg_rtx (XFmode); 16112 16113 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16114}) 16115 16116(define_expand "expxf2" 16117 [(use (match_operand:XF 0 "register_operand")) 16118 (use (match_operand:XF 1 "register_operand"))] 16119 "TARGET_USE_FANCY_MATH_387 16120 && flag_unsafe_math_optimizations" 16121{ 16122 rtx op2; 16123 16124 op2 = gen_reg_rtx (XFmode); 16125 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */ 16126 16127 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16128 DONE; 16129}) 16130 16131(define_expand "exp<mode>2" 16132 [(use (match_operand:MODEF 0 "register_operand")) 16133 (use (match_operand:MODEF 1 "general_operand"))] 16134 "TARGET_USE_FANCY_MATH_387 16135 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16136 || TARGET_MIX_SSE_I387) 16137 && flag_unsafe_math_optimizations" 16138{ 16139 rtx op0, op1; 16140 16141 op0 = gen_reg_rtx (XFmode); 16142 op1 = gen_reg_rtx (XFmode); 16143 16144 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16145 emit_insn (gen_expxf2 (op0, op1)); 16146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16147 DONE; 16148}) 16149 16150(define_expand "exp10xf2" 16151 [(use (match_operand:XF 0 "register_operand")) 16152 (use (match_operand:XF 1 "register_operand"))] 16153 "TARGET_USE_FANCY_MATH_387 16154 && flag_unsafe_math_optimizations" 16155{ 16156 rtx op2; 16157 16158 op2 = gen_reg_rtx (XFmode); 16159 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */ 16160 16161 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16162 DONE; 16163}) 16164 16165(define_expand "exp10<mode>2" 16166 [(use (match_operand:MODEF 0 "register_operand")) 16167 (use (match_operand:MODEF 1 "general_operand"))] 16168 "TARGET_USE_FANCY_MATH_387 16169 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16170 || TARGET_MIX_SSE_I387) 16171 && flag_unsafe_math_optimizations" 16172{ 16173 rtx op0, op1; 16174 16175 op0 = gen_reg_rtx (XFmode); 16176 op1 = gen_reg_rtx (XFmode); 16177 16178 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16179 emit_insn (gen_exp10xf2 (op0, op1)); 16180 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16181 DONE; 16182}) 16183 16184(define_expand "exp2xf2" 16185 [(use (match_operand:XF 0 "register_operand")) 16186 (use (match_operand:XF 1 "register_operand"))] 16187 "TARGET_USE_FANCY_MATH_387 16188 && flag_unsafe_math_optimizations" 16189{ 16190 rtx op2; 16191 16192 op2 = gen_reg_rtx (XFmode); 16193 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 16194 16195 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16196 DONE; 16197}) 16198 16199(define_expand "exp2<mode>2" 16200 [(use (match_operand:MODEF 0 "register_operand")) 16201 (use (match_operand:MODEF 1 "general_operand"))] 16202 "TARGET_USE_FANCY_MATH_387 16203 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16204 || TARGET_MIX_SSE_I387) 16205 && flag_unsafe_math_optimizations" 16206{ 16207 rtx op0, op1; 16208 16209 op0 = gen_reg_rtx (XFmode); 16210 op1 = gen_reg_rtx (XFmode); 16211 16212 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16213 emit_insn (gen_exp2xf2 (op0, op1)); 16214 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16215 DONE; 16216}) 16217 16218(define_expand "expm1xf2" 16219 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 16220 (match_dup 2))) 16221 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16222 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16223 (set (match_dup 9) (float_extend:XF (match_dup 13))) 16224 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16225 (parallel [(set (match_dup 7) 16226 (unspec:XF [(match_dup 6) (match_dup 4)] 16227 UNSPEC_FSCALE_FRACT)) 16228 (set (match_dup 8) 16229 (unspec:XF [(match_dup 6) (match_dup 4)] 16230 UNSPEC_FSCALE_EXP))]) 16231 (parallel [(set (match_dup 10) 16232 (unspec:XF [(match_dup 9) (match_dup 8)] 16233 UNSPEC_FSCALE_FRACT)) 16234 (set (match_dup 11) 16235 (unspec:XF [(match_dup 9) (match_dup 8)] 16236 UNSPEC_FSCALE_EXP))]) 16237 (set (match_dup 12) (minus:XF (match_dup 10) 16238 (float_extend:XF (match_dup 13)))) 16239 (set (match_operand:XF 0 "register_operand") 16240 (plus:XF (match_dup 12) (match_dup 7)))] 16241 "TARGET_USE_FANCY_MATH_387 16242 && flag_unsafe_math_optimizations" 16243{ 16244 int i; 16245 16246 for (i = 2; i < 13; i++) 16247 operands[i] = gen_reg_rtx (XFmode); 16248 16249 operands[13] 16250 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */ 16251 16252 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ 16253}) 16254 16255(define_expand "expm1<mode>2" 16256 [(use (match_operand:MODEF 0 "register_operand")) 16257 (use (match_operand:MODEF 1 "general_operand"))] 16258 "TARGET_USE_FANCY_MATH_387 16259 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16260 || TARGET_MIX_SSE_I387) 16261 && flag_unsafe_math_optimizations" 16262{ 16263 rtx op0, op1; 16264 16265 op0 = gen_reg_rtx (XFmode); 16266 op1 = gen_reg_rtx (XFmode); 16267 16268 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16269 emit_insn (gen_expm1xf2 (op0, op1)); 16270 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16271 DONE; 16272}) 16273 16274(define_expand "ldexpxf3" 16275 [(match_operand:XF 0 "register_operand") 16276 (match_operand:XF 1 "register_operand") 16277 (match_operand:SI 2 "register_operand")] 16278 "TARGET_USE_FANCY_MATH_387 16279 && flag_unsafe_math_optimizations" 16280{ 16281 rtx tmp1, tmp2; 16282 16283 tmp1 = gen_reg_rtx (XFmode); 16284 tmp2 = gen_reg_rtx (XFmode); 16285 16286 emit_insn (gen_floatsixf2 (tmp1, operands[2])); 16287 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2, 16288 operands[1], tmp1)); 16289 DONE; 16290}) 16291 16292(define_expand "ldexp<mode>3" 16293 [(use (match_operand:MODEF 0 "register_operand")) 16294 (use (match_operand:MODEF 1 "general_operand")) 16295 (use (match_operand:SI 2 "register_operand"))] 16296 "TARGET_USE_FANCY_MATH_387 16297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16298 || TARGET_MIX_SSE_I387) 16299 && flag_unsafe_math_optimizations" 16300{ 16301 rtx op0, op1; 16302 16303 op0 = gen_reg_rtx (XFmode); 16304 op1 = gen_reg_rtx (XFmode); 16305 16306 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16307 emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); 16308 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16309 DONE; 16310}) 16311 16312(define_expand "scalbxf3" 16313 [(parallel [(set (match_operand:XF 0 " register_operand") 16314 (unspec:XF [(match_operand:XF 1 "register_operand") 16315 (match_operand:XF 2 "register_operand")] 16316 UNSPEC_FSCALE_FRACT)) 16317 (set (match_dup 3) 16318 (unspec:XF [(match_dup 1) (match_dup 2)] 16319 UNSPEC_FSCALE_EXP))])] 16320 "TARGET_USE_FANCY_MATH_387 16321 && flag_unsafe_math_optimizations" 16322{ 16323 operands[3] = gen_reg_rtx (XFmode); 16324}) 16325 16326(define_expand "scalb<mode>3" 16327 [(use (match_operand:MODEF 0 "register_operand")) 16328 (use (match_operand:MODEF 1 "general_operand")) 16329 (use (match_operand:MODEF 2 "general_operand"))] 16330 "TARGET_USE_FANCY_MATH_387 16331 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16332 || TARGET_MIX_SSE_I387) 16333 && flag_unsafe_math_optimizations" 16334{ 16335 rtx op0, op1, op2; 16336 16337 op0 = gen_reg_rtx (XFmode); 16338 op1 = gen_reg_rtx (XFmode); 16339 op2 = gen_reg_rtx (XFmode); 16340 16341 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16342 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 16343 emit_insn (gen_scalbxf3 (op0, op1, op2)); 16344 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16345 DONE; 16346}) 16347 16348(define_expand "significandxf2" 16349 [(parallel [(set (match_operand:XF 0 "register_operand") 16350 (unspec:XF [(match_operand:XF 1 "register_operand")] 16351 UNSPEC_XTRACT_FRACT)) 16352 (set (match_dup 2) 16353 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16354 "TARGET_USE_FANCY_MATH_387 16355 && flag_unsafe_math_optimizations" 16356 "operands[2] = gen_reg_rtx (XFmode);") 16357 16358(define_expand "significand<mode>2" 16359 [(use (match_operand:MODEF 0 "register_operand")) 16360 (use (match_operand:MODEF 1 "register_operand"))] 16361 "TARGET_USE_FANCY_MATH_387 16362 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16363 || TARGET_MIX_SSE_I387) 16364 && flag_unsafe_math_optimizations" 16365{ 16366 rtx op0 = gen_reg_rtx (XFmode); 16367 rtx op1 = gen_reg_rtx (XFmode); 16368 16369 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 16370 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16371 DONE; 16372}) 16373 16374 16375(define_insn "sse4_1_round<mode>2" 16376 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 16377 (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm") 16378 (match_operand:SI 2 "const_0_to_15_operand" "n,n")] 16379 UNSPEC_ROUND))] 16380 "TARGET_SSE4_1" 16381 "@ 16382 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2} 16383 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}" 16384 [(set_attr "type" "ssecvt") 16385 (set_attr "prefix_extra" "1,*") 16386 (set_attr "length_immediate" "*,1") 16387 (set_attr "prefix" "maybe_vex,evex") 16388 (set_attr "isa" "noavx512f,avx512f") 16389 (set_attr "mode" "<MODE>")]) 16390 16391(define_insn "rintxf2" 16392 [(set (match_operand:XF 0 "register_operand" "=f") 16393 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16394 UNSPEC_FRNDINT))] 16395 "TARGET_USE_FANCY_MATH_387" 16396 "frndint" 16397 [(set_attr "type" "fpspc") 16398 (set_attr "znver1_decode" "vector") 16399 (set_attr "mode" "XF")]) 16400 16401(define_insn "rint<mode>2_frndint" 16402 [(set (match_operand:MODEF 0 "register_operand" "=f") 16403 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")] 16404 UNSPEC_FRNDINT))] 16405 "TARGET_USE_FANCY_MATH_387" 16406 "frndint" 16407 [(set_attr "type" "fpspc") 16408 (set_attr "znver1_decode" "vector") 16409 (set_attr "mode" "<MODE>")]) 16410 16411(define_expand "rint<mode>2" 16412 [(use (match_operand:MODEF 0 "register_operand")) 16413 (use (match_operand:MODEF 1 "register_operand"))] 16414 "(TARGET_USE_FANCY_MATH_387 16415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16416 || TARGET_MIX_SSE_I387)) 16417 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 16418{ 16419 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16420 { 16421 if (TARGET_SSE4_1) 16422 emit_insn (gen_sse4_1_round<mode>2 16423 (operands[0], operands[1], GEN_INT (ROUND_MXCSR))); 16424 else 16425 ix86_expand_rint (operands[0], operands[1]); 16426 } 16427 else 16428 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1])); 16429 DONE; 16430}) 16431 16432(define_expand "round<mode>2" 16433 [(match_operand:X87MODEF 0 "register_operand") 16434 (match_operand:X87MODEF 1 "nonimmediate_operand")] 16435 "(TARGET_USE_FANCY_MATH_387 16436 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16437 || TARGET_MIX_SSE_I387) 16438 && flag_unsafe_math_optimizations 16439 && (flag_fp_int_builtin_inexact || !flag_trapping_math)) 16440 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16441 && !flag_trapping_math && !flag_rounding_math)" 16442{ 16443 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16444 && !flag_trapping_math && !flag_rounding_math) 16445 { 16446 if (TARGET_SSE4_1) 16447 { 16448 operands[1] = force_reg (<MODE>mode, operands[1]); 16449 ix86_expand_round_sse4 (operands[0], operands[1]); 16450 } 16451 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 16452 ix86_expand_round (operands[0], operands[1]); 16453 else 16454 ix86_expand_rounddf_32 (operands[0], operands[1]); 16455 } 16456 else 16457 { 16458 operands[1] = force_reg (<MODE>mode, operands[1]); 16459 ix86_emit_i387_round (operands[0], operands[1]); 16460 } 16461 DONE; 16462}) 16463 16464(define_insn_and_split "*fistdi2_1" 16465 [(set (match_operand:DI 0 "nonimmediate_operand") 16466 (unspec:DI [(match_operand:XF 1 "register_operand")] 16467 UNSPEC_FIST))] 16468 "TARGET_USE_FANCY_MATH_387 16469 && can_create_pseudo_p ()" 16470 "#" 16471 "&& 1" 16472 [(const_int 0)] 16473{ 16474 if (memory_operand (operands[0], VOIDmode)) 16475 emit_insn (gen_fistdi2 (operands[0], operands[1])); 16476 else 16477 { 16478 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 16479 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 16480 operands[2])); 16481 } 16482 DONE; 16483} 16484 [(set_attr "type" "fpspc") 16485 (set_attr "mode" "DI")]) 16486 16487(define_insn "fistdi2" 16488 [(set (match_operand:DI 0 "memory_operand" "=m") 16489 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 16490 UNSPEC_FIST)) 16491 (clobber (match_scratch:XF 2 "=&1f"))] 16492 "TARGET_USE_FANCY_MATH_387" 16493 "* return output_fix_trunc (insn, operands, false);" 16494 [(set_attr "type" "fpspc") 16495 (set_attr "mode" "DI")]) 16496 16497(define_insn "fistdi2_with_temp" 16498 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 16499 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 16500 UNSPEC_FIST)) 16501 (clobber (match_operand:DI 2 "memory_operand" "=X,m")) 16502 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 16503 "TARGET_USE_FANCY_MATH_387" 16504 "#" 16505 [(set_attr "type" "fpspc") 16506 (set_attr "mode" "DI")]) 16507 16508(define_split 16509 [(set (match_operand:DI 0 "register_operand") 16510 (unspec:DI [(match_operand:XF 1 "register_operand")] 16511 UNSPEC_FIST)) 16512 (clobber (match_operand:DI 2 "memory_operand")) 16513 (clobber (match_scratch 3))] 16514 "reload_completed" 16515 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 16516 (clobber (match_dup 3))]) 16517 (set (match_dup 0) (match_dup 2))]) 16518 16519(define_split 16520 [(set (match_operand:DI 0 "memory_operand") 16521 (unspec:DI [(match_operand:XF 1 "register_operand")] 16522 UNSPEC_FIST)) 16523 (clobber (match_operand:DI 2 "memory_operand")) 16524 (clobber (match_scratch 3))] 16525 "reload_completed" 16526 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 16527 (clobber (match_dup 3))])]) 16528 16529(define_insn_and_split "*fist<mode>2_1" 16530 [(set (match_operand:SWI24 0 "register_operand") 16531 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16532 UNSPEC_FIST))] 16533 "TARGET_USE_FANCY_MATH_387 16534 && can_create_pseudo_p ()" 16535 "#" 16536 "&& 1" 16537 [(const_int 0)] 16538{ 16539 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 16540 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 16541 operands[2])); 16542 DONE; 16543} 16544 [(set_attr "type" "fpspc") 16545 (set_attr "mode" "<MODE>")]) 16546 16547(define_insn "fist<mode>2" 16548 [(set (match_operand:SWI24 0 "memory_operand" "=m") 16549 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16550 UNSPEC_FIST))] 16551 "TARGET_USE_FANCY_MATH_387" 16552 "* return output_fix_trunc (insn, operands, false);" 16553 [(set_attr "type" "fpspc") 16554 (set_attr "mode" "<MODE>")]) 16555 16556(define_insn "fist<mode>2_with_temp" 16557 [(set (match_operand:SWI24 0 "register_operand" "=r") 16558 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16559 UNSPEC_FIST)) 16560 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))] 16561 "TARGET_USE_FANCY_MATH_387" 16562 "#" 16563 [(set_attr "type" "fpspc") 16564 (set_attr "mode" "<MODE>")]) 16565 16566(define_split 16567 [(set (match_operand:SWI24 0 "register_operand") 16568 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16569 UNSPEC_FIST)) 16570 (clobber (match_operand:SWI24 2 "memory_operand"))] 16571 "reload_completed" 16572 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST)) 16573 (set (match_dup 0) (match_dup 2))]) 16574 16575(define_split 16576 [(set (match_operand:SWI24 0 "memory_operand") 16577 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16578 UNSPEC_FIST)) 16579 (clobber (match_operand:SWI24 2 "memory_operand"))] 16580 "reload_completed" 16581 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))]) 16582 16583(define_expand "lrintxf<mode>2" 16584 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16585 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16586 UNSPEC_FIST))] 16587 "TARGET_USE_FANCY_MATH_387") 16588 16589(define_expand "lrint<MODEF:mode><SWI48:mode>2" 16590 [(set (match_operand:SWI48 0 "nonimmediate_operand") 16591 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 16592 UNSPEC_FIX_NOTRUNC))] 16593 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH") 16594 16595(define_expand "lround<X87MODEF:mode><SWI248x:mode>2" 16596 [(match_operand:SWI248x 0 "nonimmediate_operand") 16597 (match_operand:X87MODEF 1 "register_operand")] 16598 "(TARGET_USE_FANCY_MATH_387 16599 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 16600 || TARGET_MIX_SSE_I387) 16601 && flag_unsafe_math_optimizations) 16602 || (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{ 16607 if (optimize_insn_for_size_p ()) 16608 FAIL; 16609 16610 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 16611 && <SWI248x:MODE>mode != HImode 16612 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 16613 && !flag_trapping_math && !flag_rounding_math) 16614 ix86_expand_lround (operands[0], operands[1]); 16615 else 16616 ix86_emit_i387_round (operands[0], operands[1]); 16617 DONE; 16618}) 16619 16620(define_int_iterator FRNDINT_ROUNDING 16621 [UNSPEC_FRNDINT_FLOOR 16622 UNSPEC_FRNDINT_CEIL 16623 UNSPEC_FRNDINT_TRUNC]) 16624 16625(define_int_iterator FIST_ROUNDING 16626 [UNSPEC_FIST_FLOOR 16627 UNSPEC_FIST_CEIL]) 16628 16629;; Base name for define_insn 16630(define_int_attr rounding_insn 16631 [(UNSPEC_FRNDINT_FLOOR "floor") 16632 (UNSPEC_FRNDINT_CEIL "ceil") 16633 (UNSPEC_FRNDINT_TRUNC "btrunc") 16634 (UNSPEC_FIST_FLOOR "floor") 16635 (UNSPEC_FIST_CEIL "ceil")]) 16636 16637(define_int_attr rounding 16638 [(UNSPEC_FRNDINT_FLOOR "floor") 16639 (UNSPEC_FRNDINT_CEIL "ceil") 16640 (UNSPEC_FRNDINT_TRUNC "trunc") 16641 (UNSPEC_FIST_FLOOR "floor") 16642 (UNSPEC_FIST_CEIL "ceil")]) 16643 16644(define_int_attr ROUNDING 16645 [(UNSPEC_FRNDINT_FLOOR "FLOOR") 16646 (UNSPEC_FRNDINT_CEIL "CEIL") 16647 (UNSPEC_FRNDINT_TRUNC "TRUNC") 16648 (UNSPEC_FIST_FLOOR "FLOOR") 16649 (UNSPEC_FIST_CEIL "CEIL")]) 16650 16651;; Rounding mode control word calculation could clobber FLAGS_REG. 16652(define_insn_and_split "frndint<mode>2_<rounding>" 16653 [(set (match_operand:X87MODEF 0 "register_operand") 16654 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")] 16655 FRNDINT_ROUNDING)) 16656 (clobber (reg:CC FLAGS_REG))] 16657 "TARGET_USE_FANCY_MATH_387 16658 && (flag_fp_int_builtin_inexact || !flag_trapping_math) 16659 && can_create_pseudo_p ()" 16660 "#" 16661 "&& 1" 16662 [(const_int 0)] 16663{ 16664 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 16665 16666 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16667 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 16668 16669 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1], 16670 operands[2], operands[3])); 16671 DONE; 16672} 16673 [(set_attr "type" "frndint") 16674 (set_attr "i387_cw" "<rounding>") 16675 (set_attr "mode" "<MODE>")]) 16676 16677(define_insn "frndint<mode>2_<rounding>_i387" 16678 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 16679 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")] 16680 FRNDINT_ROUNDING)) 16681 (use (match_operand:HI 2 "memory_operand" "m")) 16682 (use (match_operand:HI 3 "memory_operand" "m"))] 16683 "TARGET_USE_FANCY_MATH_387 16684 && (flag_fp_int_builtin_inexact || !flag_trapping_math)" 16685 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 16686 [(set_attr "type" "frndint") 16687 (set_attr "i387_cw" "<rounding>") 16688 (set_attr "mode" "<MODE>")]) 16689 16690(define_expand "<rounding_insn>xf2" 16691 [(parallel [(set (match_operand:XF 0 "register_operand") 16692 (unspec:XF [(match_operand:XF 1 "register_operand")] 16693 FRNDINT_ROUNDING)) 16694 (clobber (reg:CC FLAGS_REG))])] 16695 "TARGET_USE_FANCY_MATH_387 16696 && (flag_fp_int_builtin_inexact || !flag_trapping_math)") 16697 16698(define_expand "<rounding_insn><mode>2" 16699 [(parallel [(set (match_operand:MODEF 0 "register_operand") 16700 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")] 16701 FRNDINT_ROUNDING)) 16702 (clobber (reg:CC FLAGS_REG))])] 16703 "(TARGET_USE_FANCY_MATH_387 16704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16705 || TARGET_MIX_SSE_I387) 16706 && (flag_fp_int_builtin_inexact || !flag_trapping_math)) 16707 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16708 && (TARGET_SSE4_1 || !flag_trapping_math 16709 || flag_fp_int_builtin_inexact))" 16710{ 16711 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16712 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact)) 16713 { 16714 if (TARGET_SSE4_1) 16715 emit_insn (gen_sse4_1_round<mode>2 16716 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING> 16717 | ROUND_NO_EXC))); 16718 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 16719 { 16720 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16721 ix86_expand_floorceil (operands[0], operands[1], true); 16722 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16723 ix86_expand_floorceil (operands[0], operands[1], false); 16724 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 16725 ix86_expand_trunc (operands[0], operands[1]); 16726 else 16727 gcc_unreachable (); 16728 } 16729 else 16730 { 16731 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16732 ix86_expand_floorceildf_32 (operands[0], operands[1], true); 16733 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16734 ix86_expand_floorceildf_32 (operands[0], operands[1], false); 16735 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 16736 ix86_expand_truncdf_32 (operands[0], operands[1]); 16737 else 16738 gcc_unreachable (); 16739 } 16740 } 16741 else 16742 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1])); 16743 DONE; 16744}) 16745 16746;; Rounding mode control word calculation could clobber FLAGS_REG. 16747(define_insn_and_split "frndintxf2_mask_pm" 16748 [(set (match_operand:XF 0 "register_operand") 16749 (unspec:XF [(match_operand:XF 1 "register_operand")] 16750 UNSPEC_FRNDINT_MASK_PM)) 16751 (clobber (reg:CC FLAGS_REG))] 16752 "TARGET_USE_FANCY_MATH_387 16753 && flag_unsafe_math_optimizations 16754 && can_create_pseudo_p ()" 16755 "#" 16756 "&& 1" 16757 [(const_int 0)] 16758{ 16759 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 16760 16761 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16762 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 16763 16764 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 16765 operands[2], operands[3])); 16766 DONE; 16767} 16768 [(set_attr "type" "frndint") 16769 (set_attr "i387_cw" "mask_pm") 16770 (set_attr "mode" "XF")]) 16771 16772(define_insn "frndintxf2_mask_pm_i387" 16773 [(set (match_operand:XF 0 "register_operand" "=f") 16774 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16775 UNSPEC_FRNDINT_MASK_PM)) 16776 (use (match_operand:HI 2 "memory_operand" "m")) 16777 (use (match_operand:HI 3 "memory_operand" "m"))] 16778 "TARGET_USE_FANCY_MATH_387 16779 && flag_unsafe_math_optimizations" 16780 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 16781 [(set_attr "type" "frndint") 16782 (set_attr "i387_cw" "mask_pm") 16783 (set_attr "mode" "XF")]) 16784 16785(define_expand "nearbyintxf2" 16786 [(parallel [(set (match_operand:XF 0 "register_operand") 16787 (unspec:XF [(match_operand:XF 1 "register_operand")] 16788 UNSPEC_FRNDINT_MASK_PM)) 16789 (clobber (reg:CC FLAGS_REG))])] 16790 "TARGET_USE_FANCY_MATH_387 16791 && flag_unsafe_math_optimizations") 16792 16793(define_expand "nearbyint<mode>2" 16794 [(use (match_operand:MODEF 0 "register_operand")) 16795 (use (match_operand:MODEF 1 "register_operand"))] 16796 "TARGET_USE_FANCY_MATH_387 16797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16798 || TARGET_MIX_SSE_I387) 16799 && flag_unsafe_math_optimizations" 16800{ 16801 rtx op0 = gen_reg_rtx (XFmode); 16802 rtx op1 = gen_reg_rtx (XFmode); 16803 16804 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16805 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 16806 16807 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16808 DONE; 16809}) 16810 16811;; Rounding mode control word calculation could clobber FLAGS_REG. 16812(define_insn_and_split "*fist<mode>2_<rounding>_1" 16813 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16814 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16815 FIST_ROUNDING)) 16816 (clobber (reg:CC FLAGS_REG))] 16817 "TARGET_USE_FANCY_MATH_387 16818 && flag_unsafe_math_optimizations 16819 && can_create_pseudo_p ()" 16820 "#" 16821 "&& 1" 16822 [(const_int 0)] 16823{ 16824 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 16825 16826 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16827 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 16828 if (memory_operand (operands[0], VOIDmode)) 16829 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1], 16830 operands[2], operands[3])); 16831 else 16832 { 16833 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 16834 emit_insn (gen_fist<mode>2_<rounding>_with_temp 16835 (operands[0], operands[1], operands[2], 16836 operands[3], operands[4])); 16837 } 16838 DONE; 16839} 16840 [(set_attr "type" "fistp") 16841 (set_attr "i387_cw" "<rounding>") 16842 (set_attr "mode" "<MODE>")]) 16843 16844(define_insn "fistdi2_<rounding>" 16845 [(set (match_operand:DI 0 "memory_operand" "=m") 16846 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 16847 FIST_ROUNDING)) 16848 (use (match_operand:HI 2 "memory_operand" "m")) 16849 (use (match_operand:HI 3 "memory_operand" "m")) 16850 (clobber (match_scratch:XF 4 "=&1f"))] 16851 "TARGET_USE_FANCY_MATH_387 16852 && flag_unsafe_math_optimizations" 16853 "* return output_fix_trunc (insn, operands, false);" 16854 [(set_attr "type" "fistp") 16855 (set_attr "i387_cw" "<rounding>") 16856 (set_attr "mode" "DI")]) 16857 16858(define_insn "fistdi2_<rounding>_with_temp" 16859 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 16860 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 16861 FIST_ROUNDING)) 16862 (use (match_operand:HI 2 "memory_operand" "m,m")) 16863 (use (match_operand:HI 3 "memory_operand" "m,m")) 16864 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 16865 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 16866 "TARGET_USE_FANCY_MATH_387 16867 && flag_unsafe_math_optimizations" 16868 "#" 16869 [(set_attr "type" "fistp") 16870 (set_attr "i387_cw" "<rounding>") 16871 (set_attr "mode" "DI")]) 16872 16873(define_split 16874 [(set (match_operand:DI 0 "register_operand") 16875 (unspec:DI [(match_operand:XF 1 "register_operand")] 16876 FIST_ROUNDING)) 16877 (use (match_operand:HI 2 "memory_operand")) 16878 (use (match_operand:HI 3 "memory_operand")) 16879 (clobber (match_operand:DI 4 "memory_operand")) 16880 (clobber (match_scratch 5))] 16881 "reload_completed" 16882 [(parallel [(set (match_dup 4) 16883 (unspec:DI [(match_dup 1)] FIST_ROUNDING)) 16884 (use (match_dup 2)) 16885 (use (match_dup 3)) 16886 (clobber (match_dup 5))]) 16887 (set (match_dup 0) (match_dup 4))]) 16888 16889(define_split 16890 [(set (match_operand:DI 0 "memory_operand") 16891 (unspec:DI [(match_operand:XF 1 "register_operand")] 16892 FIST_ROUNDING)) 16893 (use (match_operand:HI 2 "memory_operand")) 16894 (use (match_operand:HI 3 "memory_operand")) 16895 (clobber (match_operand:DI 4 "memory_operand")) 16896 (clobber (match_scratch 5))] 16897 "reload_completed" 16898 [(parallel [(set (match_dup 0) 16899 (unspec:DI [(match_dup 1)] FIST_ROUNDING)) 16900 (use (match_dup 2)) 16901 (use (match_dup 3)) 16902 (clobber (match_dup 5))])]) 16903 16904(define_insn "fist<mode>2_<rounding>" 16905 [(set (match_operand:SWI24 0 "memory_operand" "=m") 16906 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16907 FIST_ROUNDING)) 16908 (use (match_operand:HI 2 "memory_operand" "m")) 16909 (use (match_operand:HI 3 "memory_operand" "m"))] 16910 "TARGET_USE_FANCY_MATH_387 16911 && flag_unsafe_math_optimizations" 16912 "* return output_fix_trunc (insn, operands, false);" 16913 [(set_attr "type" "fistp") 16914 (set_attr "i387_cw" "<rounding>") 16915 (set_attr "mode" "<MODE>")]) 16916 16917(define_insn "fist<mode>2_<rounding>_with_temp" 16918 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 16919 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 16920 FIST_ROUNDING)) 16921 (use (match_operand:HI 2 "memory_operand" "m,m")) 16922 (use (match_operand:HI 3 "memory_operand" "m,m")) 16923 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 16924 "TARGET_USE_FANCY_MATH_387 16925 && flag_unsafe_math_optimizations" 16926 "#" 16927 [(set_attr "type" "fistp") 16928 (set_attr "i387_cw" "<rounding>") 16929 (set_attr "mode" "<MODE>")]) 16930 16931(define_split 16932 [(set (match_operand:SWI24 0 "register_operand") 16933 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16934 FIST_ROUNDING)) 16935 (use (match_operand:HI 2 "memory_operand")) 16936 (use (match_operand:HI 3 "memory_operand")) 16937 (clobber (match_operand:SWI24 4 "memory_operand"))] 16938 "reload_completed" 16939 [(parallel [(set (match_dup 4) 16940 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) 16941 (use (match_dup 2)) 16942 (use (match_dup 3))]) 16943 (set (match_dup 0) (match_dup 4))]) 16944 16945(define_split 16946 [(set (match_operand:SWI24 0 "memory_operand") 16947 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16948 FIST_ROUNDING)) 16949 (use (match_operand:HI 2 "memory_operand")) 16950 (use (match_operand:HI 3 "memory_operand")) 16951 (clobber (match_operand:SWI24 4 "memory_operand"))] 16952 "reload_completed" 16953 [(parallel [(set (match_dup 0) 16954 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) 16955 (use (match_dup 2)) 16956 (use (match_dup 3))])]) 16957 16958(define_expand "l<rounding_insn>xf<mode>2" 16959 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16960 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16961 FIST_ROUNDING)) 16962 (clobber (reg:CC FLAGS_REG))])] 16963 "TARGET_USE_FANCY_MATH_387 16964 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16965 && flag_unsafe_math_optimizations") 16966 16967(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2" 16968 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand") 16969 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 16970 FIST_ROUNDING)) 16971 (clobber (reg:CC FLAGS_REG))])] 16972 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 16973 && (TARGET_SSE4_1 || !flag_trapping_math)" 16974{ 16975 if (TARGET_SSE4_1) 16976 { 16977 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode); 16978 16979 emit_insn (gen_sse4_1_round<mode>2 16980 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING> 16981 | ROUND_NO_EXC))); 16982 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2 16983 (operands[0], tmp)); 16984 } 16985 else if (ROUND_<ROUNDING> == ROUND_FLOOR) 16986 ix86_expand_lfloorceil (operands[0], operands[1], true); 16987 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16988 ix86_expand_lfloorceil (operands[0], operands[1], false); 16989 else 16990 gcc_unreachable (); 16991 16992 DONE; 16993}) 16994 16995(define_insn "fxam<mode>2_i387" 16996 [(set (match_operand:HI 0 "register_operand" "=a") 16997 (unspec:HI 16998 [(match_operand:X87MODEF 1 "register_operand" "f")] 16999 UNSPEC_FXAM))] 17000 "TARGET_USE_FANCY_MATH_387" 17001 "fxam\n\tfnstsw\t%0" 17002 [(set_attr "type" "multi") 17003 (set_attr "length" "4") 17004 (set_attr "unit" "i387") 17005 (set_attr "mode" "<MODE>")]) 17006 17007(define_insn_and_split "fxam<mode>2_i387_with_temp" 17008 [(set (match_operand:HI 0 "register_operand") 17009 (unspec:HI 17010 [(match_operand:MODEF 1 "memory_operand")] 17011 UNSPEC_FXAM_MEM))] 17012 "TARGET_USE_FANCY_MATH_387 17013 && can_create_pseudo_p ()" 17014 "#" 17015 "&& 1" 17016 [(set (match_dup 2)(match_dup 1)) 17017 (set (match_dup 0) 17018 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))] 17019{ 17020 operands[2] = gen_reg_rtx (<MODE>mode); 17021 17022 MEM_VOLATILE_P (operands[1]) = 1; 17023} 17024 [(set_attr "type" "multi") 17025 (set_attr "unit" "i387") 17026 (set_attr "mode" "<MODE>")]) 17027 17028(define_expand "isinfxf2" 17029 [(use (match_operand:SI 0 "register_operand")) 17030 (use (match_operand:XF 1 "register_operand"))] 17031 "TARGET_USE_FANCY_MATH_387 17032 && ix86_libc_has_function (function_c99_misc)" 17033{ 17034 rtx mask = GEN_INT (0x45); 17035 rtx val = GEN_INT (0x05); 17036 17037 rtx scratch = gen_reg_rtx (HImode); 17038 rtx res = gen_reg_rtx (QImode); 17039 17040 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 17041 17042 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask)); 17043 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 17044 ix86_expand_setcc (res, EQ, 17045 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 17046 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 17047 DONE; 17048}) 17049 17050(define_expand "isinf<mode>2" 17051 [(use (match_operand:SI 0 "register_operand")) 17052 (use (match_operand:MODEF 1 "nonimmediate_operand"))] 17053 "TARGET_USE_FANCY_MATH_387 17054 && ix86_libc_has_function (function_c99_misc) 17055 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 17056{ 17057 rtx mask = GEN_INT (0x45); 17058 rtx val = GEN_INT (0x05); 17059 17060 rtx scratch = gen_reg_rtx (HImode); 17061 rtx res = gen_reg_rtx (QImode); 17062 17063 /* Remove excess precision by forcing value through memory. */ 17064 if (memory_operand (operands[1], VOIDmode)) 17065 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1])); 17066 else 17067 { 17068 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17069 17070 emit_move_insn (temp, operands[1]); 17071 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp)); 17072 } 17073 17074 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask)); 17075 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 17076 ix86_expand_setcc (res, EQ, 17077 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 17078 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 17079 DONE; 17080}) 17081 17082(define_expand "signbittf2" 17083 [(use (match_operand:SI 0 "register_operand")) 17084 (use (match_operand:TF 1 "register_operand"))] 17085 "TARGET_SSE" 17086{ 17087 if (TARGET_SSE4_1) 17088 { 17089 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0); 17090 rtx scratch = gen_reg_rtx (QImode); 17091 17092 emit_insn (gen_ptesttf2 (operands[1], mask)); 17093 ix86_expand_setcc (scratch, NE, 17094 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 17095 17096 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 17097 } 17098 else 17099 { 17100 emit_insn (gen_sse_movmskps (operands[0], 17101 gen_lowpart (V4SFmode, operands[1]))); 17102 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8))); 17103 } 17104 DONE; 17105}) 17106 17107(define_expand "signbitxf2" 17108 [(use (match_operand:SI 0 "register_operand")) 17109 (use (match_operand:XF 1 "register_operand"))] 17110 "TARGET_USE_FANCY_MATH_387" 17111{ 17112 rtx scratch = gen_reg_rtx (HImode); 17113 17114 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 17115 emit_insn (gen_andsi3 (operands[0], 17116 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17117 DONE; 17118}) 17119 17120(define_insn "movmsk_df" 17121 [(set (match_operand:SI 0 "register_operand" "=r") 17122 (unspec:SI 17123 [(match_operand:DF 1 "register_operand" "x")] 17124 UNSPEC_MOVMSK))] 17125 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH" 17126 "%vmovmskpd\t{%1, %0|%0, %1}" 17127 [(set_attr "type" "ssemov") 17128 (set_attr "prefix" "maybe_vex") 17129 (set_attr "mode" "DF")]) 17130 17131;; Use movmskpd in SSE mode to avoid store forwarding stall 17132;; for 32bit targets and movq+shrq sequence for 64bit targets. 17133(define_expand "signbitdf2" 17134 [(use (match_operand:SI 0 "register_operand")) 17135 (use (match_operand:DF 1 "register_operand"))] 17136 "TARGET_USE_FANCY_MATH_387 17137 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 17138{ 17139 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH) 17140 { 17141 emit_insn (gen_movmsk_df (operands[0], operands[1])); 17142 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx)); 17143 } 17144 else 17145 { 17146 rtx scratch = gen_reg_rtx (HImode); 17147 17148 emit_insn (gen_fxamdf2_i387 (scratch, operands[1])); 17149 emit_insn (gen_andsi3 (operands[0], 17150 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17151 } 17152 DONE; 17153}) 17154 17155(define_expand "signbitsf2" 17156 [(use (match_operand:SI 0 "register_operand")) 17157 (use (match_operand:SF 1 "register_operand"))] 17158 "TARGET_USE_FANCY_MATH_387 17159 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)" 17160{ 17161 rtx scratch = gen_reg_rtx (HImode); 17162 17163 emit_insn (gen_fxamsf2_i387 (scratch, operands[1])); 17164 emit_insn (gen_andsi3 (operands[0], 17165 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17166 DONE; 17167}) 17168 17169;; Block operation instructions 17170 17171(define_insn "cld" 17172 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] 17173 "" 17174 "cld" 17175 [(set_attr "length" "1") 17176 (set_attr "length_immediate" "0") 17177 (set_attr "modrm" "0")]) 17178 17179(define_expand "movmem<mode>" 17180 [(use (match_operand:BLK 0 "memory_operand")) 17181 (use (match_operand:BLK 1 "memory_operand")) 17182 (use (match_operand:SWI48 2 "nonmemory_operand")) 17183 (use (match_operand:SWI48 3 "const_int_operand")) 17184 (use (match_operand:SI 4 "const_int_operand")) 17185 (use (match_operand:SI 5 "const_int_operand")) 17186 (use (match_operand:SI 6 "")) 17187 (use (match_operand:SI 7 "")) 17188 (use (match_operand:SI 8 ""))] 17189 "" 17190{ 17191 if (ix86_expand_set_or_movmem (operands[0], operands[1], 17192 operands[2], NULL, operands[3], 17193 operands[4], operands[5], 17194 operands[6], operands[7], 17195 operands[8], false)) 17196 DONE; 17197 else 17198 FAIL; 17199}) 17200 17201;; Most CPUs don't like single string operations 17202;; Handle this case here to simplify previous expander. 17203 17204(define_expand "strmov" 17205 [(set (match_dup 4) (match_operand 3 "memory_operand")) 17206 (set (match_operand 1 "memory_operand") (match_dup 4)) 17207 (parallel [(set (match_operand 0 "register_operand") (match_dup 5)) 17208 (clobber (reg:CC FLAGS_REG))]) 17209 (parallel [(set (match_operand 2 "register_operand") (match_dup 6)) 17210 (clobber (reg:CC FLAGS_REG))])] 17211 "" 17212{ 17213 /* Can't use this for non-default address spaces. */ 17214 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3]))) 17215 FAIL; 17216 17217 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 17218 17219 /* If .md ever supports :P for Pmode, these can be directly 17220 in the pattern above. */ 17221 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 17222 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 17223 17224 /* Can't use this if the user has appropriated esi or edi. */ 17225 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 17226 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])) 17227 { 17228 emit_insn (gen_strmov_singleop (operands[0], operands[1], 17229 operands[2], operands[3], 17230 operands[5], operands[6])); 17231 DONE; 17232 } 17233 17234 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 17235}) 17236 17237(define_expand "strmov_singleop" 17238 [(parallel [(set (match_operand 1 "memory_operand") 17239 (match_operand 3 "memory_operand")) 17240 (set (match_operand 0 "register_operand") 17241 (match_operand 4)) 17242 (set (match_operand 2 "register_operand") 17243 (match_operand 5))])] 17244 "" 17245{ 17246 if (TARGET_CLD) 17247 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17248}) 17249 17250(define_insn "*strmovdi_rex_1" 17251 [(set (mem:DI (match_operand:P 2 "register_operand" "0")) 17252 (mem:DI (match_operand:P 3 "register_operand" "1"))) 17253 (set (match_operand:P 0 "register_operand" "=D") 17254 (plus:P (match_dup 2) 17255 (const_int 8))) 17256 (set (match_operand:P 1 "register_operand" "=S") 17257 (plus:P (match_dup 3) 17258 (const_int 8)))] 17259 "TARGET_64BIT 17260 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17261 && ix86_check_no_addr_space (insn)" 17262 "%^movsq" 17263 [(set_attr "type" "str") 17264 (set_attr "memory" "both") 17265 (set_attr "mode" "DI")]) 17266 17267(define_insn "*strmovsi_1" 17268 [(set (mem:SI (match_operand:P 2 "register_operand" "0")) 17269 (mem:SI (match_operand:P 3 "register_operand" "1"))) 17270 (set (match_operand:P 0 "register_operand" "=D") 17271 (plus:P (match_dup 2) 17272 (const_int 4))) 17273 (set (match_operand:P 1 "register_operand" "=S") 17274 (plus:P (match_dup 3) 17275 (const_int 4)))] 17276 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17277 && ix86_check_no_addr_space (insn)" 17278 "%^movs{l|d}" 17279 [(set_attr "type" "str") 17280 (set_attr "memory" "both") 17281 (set_attr "mode" "SI")]) 17282 17283(define_insn "*strmovhi_1" 17284 [(set (mem:HI (match_operand:P 2 "register_operand" "0")) 17285 (mem:HI (match_operand:P 3 "register_operand" "1"))) 17286 (set (match_operand:P 0 "register_operand" "=D") 17287 (plus:P (match_dup 2) 17288 (const_int 2))) 17289 (set (match_operand:P 1 "register_operand" "=S") 17290 (plus:P (match_dup 3) 17291 (const_int 2)))] 17292 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17293 && ix86_check_no_addr_space (insn)" 17294 "%^movsw" 17295 [(set_attr "type" "str") 17296 (set_attr "memory" "both") 17297 (set_attr "mode" "HI")]) 17298 17299(define_insn "*strmovqi_1" 17300 [(set (mem:QI (match_operand:P 2 "register_operand" "0")) 17301 (mem:QI (match_operand:P 3 "register_operand" "1"))) 17302 (set (match_operand:P 0 "register_operand" "=D") 17303 (plus:P (match_dup 2) 17304 (const_int 1))) 17305 (set (match_operand:P 1 "register_operand" "=S") 17306 (plus:P (match_dup 3) 17307 (const_int 1)))] 17308 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17309 && ix86_check_no_addr_space (insn)" 17310 "%^movsb" 17311 [(set_attr "type" "str") 17312 (set_attr "memory" "both") 17313 (set (attr "prefix_rex") 17314 (if_then_else 17315 (match_test "<P:MODE>mode == DImode") 17316 (const_string "0") 17317 (const_string "*"))) 17318 (set_attr "mode" "QI")]) 17319 17320(define_expand "rep_mov" 17321 [(parallel [(set (match_operand 4 "register_operand") (const_int 0)) 17322 (set (match_operand 0 "register_operand") 17323 (match_operand 5)) 17324 (set (match_operand 2 "register_operand") 17325 (match_operand 6)) 17326 (set (match_operand 1 "memory_operand") 17327 (match_operand 3 "memory_operand")) 17328 (use (match_dup 4))])] 17329 "" 17330{ 17331 if (TARGET_CLD) 17332 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17333}) 17334 17335(define_insn "*rep_movdi_rex64" 17336 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17337 (set (match_operand:P 0 "register_operand" "=D") 17338 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 17339 (const_int 3)) 17340 (match_operand:P 3 "register_operand" "0"))) 17341 (set (match_operand:P 1 "register_operand" "=S") 17342 (plus:P (ashift:P (match_dup 5) (const_int 3)) 17343 (match_operand:P 4 "register_operand" "1"))) 17344 (set (mem:BLK (match_dup 3)) 17345 (mem:BLK (match_dup 4))) 17346 (use (match_dup 5))] 17347 "TARGET_64BIT 17348 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17349 && ix86_check_no_addr_space (insn)" 17350 "%^rep{%;} movsq" 17351 [(set_attr "type" "str") 17352 (set_attr "prefix_rep" "1") 17353 (set_attr "memory" "both") 17354 (set_attr "mode" "DI")]) 17355 17356(define_insn "*rep_movsi" 17357 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17358 (set (match_operand:P 0 "register_operand" "=D") 17359 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 17360 (const_int 2)) 17361 (match_operand:P 3 "register_operand" "0"))) 17362 (set (match_operand:P 1 "register_operand" "=S") 17363 (plus:P (ashift:P (match_dup 5) (const_int 2)) 17364 (match_operand:P 4 "register_operand" "1"))) 17365 (set (mem:BLK (match_dup 3)) 17366 (mem:BLK (match_dup 4))) 17367 (use (match_dup 5))] 17368 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17369 && ix86_check_no_addr_space (insn)" 17370 "%^rep{%;} movs{l|d}" 17371 [(set_attr "type" "str") 17372 (set_attr "prefix_rep" "1") 17373 (set_attr "memory" "both") 17374 (set_attr "mode" "SI")]) 17375 17376(define_insn "*rep_movqi" 17377 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17378 (set (match_operand:P 0 "register_operand" "=D") 17379 (plus:P (match_operand:P 3 "register_operand" "0") 17380 (match_operand:P 5 "register_operand" "2"))) 17381 (set (match_operand:P 1 "register_operand" "=S") 17382 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5))) 17383 (set (mem:BLK (match_dup 3)) 17384 (mem:BLK (match_dup 4))) 17385 (use (match_dup 5))] 17386 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17387 && ix86_check_no_addr_space (insn)" 17388 "%^rep{%;} movsb" 17389 [(set_attr "type" "str") 17390 (set_attr "prefix_rep" "1") 17391 (set_attr "memory" "both") 17392 (set_attr "mode" "QI")]) 17393 17394(define_expand "setmem<mode>" 17395 [(use (match_operand:BLK 0 "memory_operand")) 17396 (use (match_operand:SWI48 1 "nonmemory_operand")) 17397 (use (match_operand:QI 2 "nonmemory_operand")) 17398 (use (match_operand 3 "const_int_operand")) 17399 (use (match_operand:SI 4 "const_int_operand")) 17400 (use (match_operand:SI 5 "const_int_operand")) 17401 (use (match_operand:SI 6 "")) 17402 (use (match_operand:SI 7 "")) 17403 (use (match_operand:SI 8 ""))] 17404 "" 17405{ 17406 if (ix86_expand_set_or_movmem (operands[0], NULL, 17407 operands[1], operands[2], 17408 operands[3], operands[4], 17409 operands[5], operands[6], 17410 operands[7], operands[8], true)) 17411 DONE; 17412 else 17413 FAIL; 17414}) 17415 17416;; Most CPUs don't like single string operations 17417;; Handle this case here to simplify previous expander. 17418 17419(define_expand "strset" 17420 [(set (match_operand 1 "memory_operand") 17421 (match_operand 2 "register_operand")) 17422 (parallel [(set (match_operand 0 "register_operand") 17423 (match_dup 3)) 17424 (clobber (reg:CC FLAGS_REG))])] 17425 "" 17426{ 17427 /* Can't use this for non-default address spaces. */ 17428 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1]))) 17429 FAIL; 17430 17431 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 17432 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 17433 17434 /* If .md ever supports :P for Pmode, this can be directly 17435 in the pattern above. */ 17436 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 17437 GEN_INT (GET_MODE_SIZE (GET_MODE 17438 (operands[2])))); 17439 /* Can't use this if the user has appropriated eax or edi. */ 17440 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 17441 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])) 17442 { 17443 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 17444 operands[3])); 17445 DONE; 17446 } 17447}) 17448 17449(define_expand "strset_singleop" 17450 [(parallel [(set (match_operand 1 "memory_operand") 17451 (match_operand 2 "register_operand")) 17452 (set (match_operand 0 "register_operand") 17453 (match_operand 3)) 17454 (unspec [(const_int 0)] UNSPEC_STOS)])] 17455 "" 17456{ 17457 if (TARGET_CLD) 17458 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17459}) 17460 17461(define_insn "*strsetdi_rex_1" 17462 [(set (mem:DI (match_operand:P 1 "register_operand" "0")) 17463 (match_operand:DI 2 "register_operand" "a")) 17464 (set (match_operand:P 0 "register_operand" "=D") 17465 (plus:P (match_dup 1) 17466 (const_int 8))) 17467 (unspec [(const_int 0)] UNSPEC_STOS)] 17468 "TARGET_64BIT 17469 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17470 && ix86_check_no_addr_space (insn)" 17471 "%^stosq" 17472 [(set_attr "type" "str") 17473 (set_attr "memory" "store") 17474 (set_attr "mode" "DI")]) 17475 17476(define_insn "*strsetsi_1" 17477 [(set (mem:SI (match_operand:P 1 "register_operand" "0")) 17478 (match_operand:SI 2 "register_operand" "a")) 17479 (set (match_operand:P 0 "register_operand" "=D") 17480 (plus:P (match_dup 1) 17481 (const_int 4))) 17482 (unspec [(const_int 0)] UNSPEC_STOS)] 17483 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17484 && ix86_check_no_addr_space (insn)" 17485 "%^stos{l|d}" 17486 [(set_attr "type" "str") 17487 (set_attr "memory" "store") 17488 (set_attr "mode" "SI")]) 17489 17490(define_insn "*strsethi_1" 17491 [(set (mem:HI (match_operand:P 1 "register_operand" "0")) 17492 (match_operand:HI 2 "register_operand" "a")) 17493 (set (match_operand:P 0 "register_operand" "=D") 17494 (plus:P (match_dup 1) 17495 (const_int 2))) 17496 (unspec [(const_int 0)] UNSPEC_STOS)] 17497 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17498 && ix86_check_no_addr_space (insn)" 17499 "%^stosw" 17500 [(set_attr "type" "str") 17501 (set_attr "memory" "store") 17502 (set_attr "mode" "HI")]) 17503 17504(define_insn "*strsetqi_1" 17505 [(set (mem:QI (match_operand:P 1 "register_operand" "0")) 17506 (match_operand:QI 2 "register_operand" "a")) 17507 (set (match_operand:P 0 "register_operand" "=D") 17508 (plus:P (match_dup 1) 17509 (const_int 1))) 17510 (unspec [(const_int 0)] UNSPEC_STOS)] 17511 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17512 && ix86_check_no_addr_space (insn)" 17513 "%^stosb" 17514 [(set_attr "type" "str") 17515 (set_attr "memory" "store") 17516 (set (attr "prefix_rex") 17517 (if_then_else 17518 (match_test "<P:MODE>mode == DImode") 17519 (const_string "0") 17520 (const_string "*"))) 17521 (set_attr "mode" "QI")]) 17522 17523(define_expand "rep_stos" 17524 [(parallel [(set (match_operand 1 "register_operand") (const_int 0)) 17525 (set (match_operand 0 "register_operand") 17526 (match_operand 4)) 17527 (set (match_operand 2 "memory_operand") (const_int 0)) 17528 (use (match_operand 3 "register_operand")) 17529 (use (match_dup 1))])] 17530 "" 17531{ 17532 if (TARGET_CLD) 17533 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17534}) 17535 17536(define_insn "*rep_stosdi_rex64" 17537 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17538 (set (match_operand:P 0 "register_operand" "=D") 17539 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 17540 (const_int 3)) 17541 (match_operand:P 3 "register_operand" "0"))) 17542 (set (mem:BLK (match_dup 3)) 17543 (const_int 0)) 17544 (use (match_operand:DI 2 "register_operand" "a")) 17545 (use (match_dup 4))] 17546 "TARGET_64BIT 17547 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17548 && ix86_check_no_addr_space (insn)" 17549 "%^rep{%;} stosq" 17550 [(set_attr "type" "str") 17551 (set_attr "prefix_rep" "1") 17552 (set_attr "memory" "store") 17553 (set_attr "mode" "DI")]) 17554 17555(define_insn "*rep_stossi" 17556 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17557 (set (match_operand:P 0 "register_operand" "=D") 17558 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 17559 (const_int 2)) 17560 (match_operand:P 3 "register_operand" "0"))) 17561 (set (mem:BLK (match_dup 3)) 17562 (const_int 0)) 17563 (use (match_operand:SI 2 "register_operand" "a")) 17564 (use (match_dup 4))] 17565 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17566 && ix86_check_no_addr_space (insn)" 17567 "%^rep{%;} stos{l|d}" 17568 [(set_attr "type" "str") 17569 (set_attr "prefix_rep" "1") 17570 (set_attr "memory" "store") 17571 (set_attr "mode" "SI")]) 17572 17573(define_insn "*rep_stosqi" 17574 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17575 (set (match_operand:P 0 "register_operand" "=D") 17576 (plus:P (match_operand:P 3 "register_operand" "0") 17577 (match_operand:P 4 "register_operand" "1"))) 17578 (set (mem:BLK (match_dup 3)) 17579 (const_int 0)) 17580 (use (match_operand:QI 2 "register_operand" "a")) 17581 (use (match_dup 4))] 17582 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17583 && ix86_check_no_addr_space (insn)" 17584 "%^rep{%;} stosb" 17585 [(set_attr "type" "str") 17586 (set_attr "prefix_rep" "1") 17587 (set_attr "memory" "store") 17588 (set (attr "prefix_rex") 17589 (if_then_else 17590 (match_test "<P:MODE>mode == DImode") 17591 (const_string "0") 17592 (const_string "*"))) 17593 (set_attr "mode" "QI")]) 17594 17595(define_expand "cmpstrnsi" 17596 [(set (match_operand:SI 0 "register_operand") 17597 (compare:SI (match_operand:BLK 1 "general_operand") 17598 (match_operand:BLK 2 "general_operand"))) 17599 (use (match_operand 3 "general_operand")) 17600 (use (match_operand 4 "immediate_operand"))] 17601 "" 17602{ 17603 rtx addr1, addr2, out, outlow, count, countreg, align; 17604 17605 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) 17606 FAIL; 17607 17608 /* Can't use this if the user has appropriated ecx, esi or edi. */ 17609 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17610 FAIL; 17611 17612 /* One of the strings must be a constant. If so, expand_builtin_strncmp() 17613 will have rewritten the length arg to be the minimum of the const string 17614 length and the actual length arg. If both strings are the same and 17615 shorter than the length arg, repz cmpsb will not stop at the 0 byte and 17616 will incorrectly base the results on chars past the 0 byte. */ 17617 tree t1 = MEM_EXPR (operands[1]); 17618 tree t2 = MEM_EXPR (operands[2]); 17619 if (!((t1 && TREE_CODE (t1) == MEM_REF 17620 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR 17621 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST) 17622 || (t2 && TREE_CODE (t2) == MEM_REF 17623 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR 17624 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST))) 17625 FAIL; 17626 17627 out = operands[0]; 17628 if (!REG_P (out)) 17629 out = gen_reg_rtx (SImode); 17630 17631 addr1 = copy_addr_to_reg (XEXP (operands[1], 0)); 17632 addr2 = copy_addr_to_reg (XEXP (operands[2], 0)); 17633 if (addr1 != XEXP (operands[1], 0)) 17634 operands[1] = replace_equiv_address_nv (operands[1], addr1); 17635 if (addr2 != XEXP (operands[2], 0)) 17636 operands[2] = replace_equiv_address_nv (operands[2], addr2); 17637 17638 count = operands[3]; 17639 countreg = ix86_zero_extend_to_Pmode (count); 17640 17641 /* %%% Iff we are testing strict equality, we can use known alignment 17642 to good advantage. This may be possible with combine, particularly 17643 once cc0 is dead. */ 17644 align = operands[4]; 17645 17646 if (CONST_INT_P (count)) 17647 { 17648 if (INTVAL (count) == 0) 17649 { 17650 emit_move_insn (operands[0], const0_rtx); 17651 DONE; 17652 } 17653 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 17654 operands[1], operands[2])); 17655 } 17656 else 17657 { 17658 rtx (*gen_cmp) (rtx, rtx); 17659 17660 gen_cmp = (TARGET_64BIT 17661 ? gen_cmpdi_1 : gen_cmpsi_1); 17662 17663 emit_insn (gen_cmp (countreg, countreg)); 17664 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 17665 operands[1], operands[2])); 17666 } 17667 17668 outlow = gen_lowpart (QImode, out); 17669 emit_insn (gen_cmpintqi (outlow)); 17670 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 17671 17672 if (operands[0] != out) 17673 emit_move_insn (operands[0], out); 17674 17675 DONE; 17676}) 17677 17678;; Produce a tri-state integer (-1, 0, 1) from condition codes. 17679 17680(define_expand "cmpintqi" 17681 [(set (match_dup 1) 17682 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17683 (set (match_dup 2) 17684 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17685 (parallel [(set (match_operand:QI 0 "register_operand") 17686 (minus:QI (match_dup 1) 17687 (match_dup 2))) 17688 (clobber (reg:CC FLAGS_REG))])] 17689 "" 17690{ 17691 operands[1] = gen_reg_rtx (QImode); 17692 operands[2] = gen_reg_rtx (QImode); 17693}) 17694 17695;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 17696;; zero. Emit extra code to make sure that a zero-length compare is EQ. 17697 17698(define_expand "cmpstrnqi_nz_1" 17699 [(parallel [(set (reg:CC FLAGS_REG) 17700 (compare:CC (match_operand 4 "memory_operand") 17701 (match_operand 5 "memory_operand"))) 17702 (use (match_operand 2 "register_operand")) 17703 (use (match_operand:SI 3 "immediate_operand")) 17704 (clobber (match_operand 0 "register_operand")) 17705 (clobber (match_operand 1 "register_operand")) 17706 (clobber (match_dup 2))])] 17707 "" 17708{ 17709 if (TARGET_CLD) 17710 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17711}) 17712 17713(define_insn "*cmpstrnqi_nz_1" 17714 [(set (reg:CC FLAGS_REG) 17715 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 17716 (mem:BLK (match_operand:P 5 "register_operand" "1")))) 17717 (use (match_operand:P 6 "register_operand" "2")) 17718 (use (match_operand:SI 3 "immediate_operand" "i")) 17719 (clobber (match_operand:P 0 "register_operand" "=S")) 17720 (clobber (match_operand:P 1 "register_operand" "=D")) 17721 (clobber (match_operand:P 2 "register_operand" "=c"))] 17722 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17723 && ix86_check_no_addr_space (insn)" 17724 "%^repz{%;} cmpsb" 17725 [(set_attr "type" "str") 17726 (set_attr "mode" "QI") 17727 (set (attr "prefix_rex") 17728 (if_then_else 17729 (match_test "<P:MODE>mode == DImode") 17730 (const_string "0") 17731 (const_string "*"))) 17732 (set_attr "prefix_rep" "1")]) 17733 17734;; The same, but the count is not known to not be zero. 17735 17736(define_expand "cmpstrnqi_1" 17737 [(parallel [(set (reg:CC FLAGS_REG) 17738 (if_then_else:CC (ne (match_operand 2 "register_operand") 17739 (const_int 0)) 17740 (compare:CC (match_operand 4 "memory_operand") 17741 (match_operand 5 "memory_operand")) 17742 (const_int 0))) 17743 (use (match_operand:SI 3 "immediate_operand")) 17744 (use (reg:CC FLAGS_REG)) 17745 (clobber (match_operand 0 "register_operand")) 17746 (clobber (match_operand 1 "register_operand")) 17747 (clobber (match_dup 2))])] 17748 "" 17749{ 17750 if (TARGET_CLD) 17751 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17752}) 17753 17754(define_insn "*cmpstrnqi_1" 17755 [(set (reg:CC FLAGS_REG) 17756 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2") 17757 (const_int 0)) 17758 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 17759 (mem:BLK (match_operand:P 5 "register_operand" "1"))) 17760 (const_int 0))) 17761 (use (match_operand:SI 3 "immediate_operand" "i")) 17762 (use (reg:CC FLAGS_REG)) 17763 (clobber (match_operand:P 0 "register_operand" "=S")) 17764 (clobber (match_operand:P 1 "register_operand" "=D")) 17765 (clobber (match_operand:P 2 "register_operand" "=c"))] 17766 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17767 && ix86_check_no_addr_space (insn)" 17768 "%^repz{%;} cmpsb" 17769 [(set_attr "type" "str") 17770 (set_attr "mode" "QI") 17771 (set (attr "prefix_rex") 17772 (if_then_else 17773 (match_test "<P:MODE>mode == DImode") 17774 (const_string "0") 17775 (const_string "*"))) 17776 (set_attr "prefix_rep" "1")]) 17777 17778(define_expand "strlen<mode>" 17779 [(set (match_operand:P 0 "register_operand") 17780 (unspec:P [(match_operand:BLK 1 "general_operand") 17781 (match_operand:QI 2 "immediate_operand") 17782 (match_operand 3 "immediate_operand")] 17783 UNSPEC_SCAS))] 17784 "" 17785{ 17786 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 17787 DONE; 17788 else 17789 FAIL; 17790}) 17791 17792(define_expand "strlenqi_1" 17793 [(parallel [(set (match_operand 0 "register_operand") 17794 (match_operand 2)) 17795 (clobber (match_operand 1 "register_operand")) 17796 (clobber (reg:CC FLAGS_REG))])] 17797 "" 17798{ 17799 if (TARGET_CLD) 17800 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17801}) 17802 17803(define_insn "*strlenqi_1" 17804 [(set (match_operand:P 0 "register_operand" "=&c") 17805 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1")) 17806 (match_operand:QI 2 "register_operand" "a") 17807 (match_operand:P 3 "immediate_operand" "i") 17808 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS)) 17809 (clobber (match_operand:P 1 "register_operand" "=D")) 17810 (clobber (reg:CC FLAGS_REG))] 17811 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17812 && ix86_check_no_addr_space (insn)" 17813 "%^repnz{%;} scasb" 17814 [(set_attr "type" "str") 17815 (set_attr "mode" "QI") 17816 (set (attr "prefix_rex") 17817 (if_then_else 17818 (match_test "<P:MODE>mode == DImode") 17819 (const_string "0") 17820 (const_string "*"))) 17821 (set_attr "prefix_rep" "1")]) 17822 17823;; Peephole optimizations to clean up after cmpstrn*. This should be 17824;; handled in combine, but it is not currently up to the task. 17825;; When used for their truth value, the cmpstrn* expanders generate 17826;; code like this: 17827;; 17828;; repz cmpsb 17829;; seta %al 17830;; setb %dl 17831;; cmpb %al, %dl 17832;; jcc label 17833;; 17834;; The intermediate three instructions are unnecessary. 17835 17836;; This one handles cmpstrn*_nz_1... 17837(define_peephole2 17838 [(parallel[ 17839 (set (reg:CC FLAGS_REG) 17840 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 17841 (mem:BLK (match_operand 5 "register_operand")))) 17842 (use (match_operand 6 "register_operand")) 17843 (use (match_operand:SI 3 "immediate_operand")) 17844 (clobber (match_operand 0 "register_operand")) 17845 (clobber (match_operand 1 "register_operand")) 17846 (clobber (match_operand 2 "register_operand"))]) 17847 (set (match_operand:QI 7 "register_operand") 17848 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17849 (set (match_operand:QI 8 "register_operand") 17850 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17851 (set (reg FLAGS_REG) 17852 (compare (match_dup 7) (match_dup 8))) 17853 ] 17854 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 17855 [(parallel[ 17856 (set (reg:CC FLAGS_REG) 17857 (compare:CC (mem:BLK (match_dup 4)) 17858 (mem:BLK (match_dup 5)))) 17859 (use (match_dup 6)) 17860 (use (match_dup 3)) 17861 (clobber (match_dup 0)) 17862 (clobber (match_dup 1)) 17863 (clobber (match_dup 2))])]) 17864 17865;; ...and this one handles cmpstrn*_1. 17866(define_peephole2 17867 [(parallel[ 17868 (set (reg:CC FLAGS_REG) 17869 (if_then_else:CC (ne (match_operand 6 "register_operand") 17870 (const_int 0)) 17871 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 17872 (mem:BLK (match_operand 5 "register_operand"))) 17873 (const_int 0))) 17874 (use (match_operand:SI 3 "immediate_operand")) 17875 (use (reg:CC FLAGS_REG)) 17876 (clobber (match_operand 0 "register_operand")) 17877 (clobber (match_operand 1 "register_operand")) 17878 (clobber (match_operand 2 "register_operand"))]) 17879 (set (match_operand:QI 7 "register_operand") 17880 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17881 (set (match_operand:QI 8 "register_operand") 17882 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17883 (set (reg FLAGS_REG) 17884 (compare (match_dup 7) (match_dup 8))) 17885 ] 17886 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 17887 [(parallel[ 17888 (set (reg:CC FLAGS_REG) 17889 (if_then_else:CC (ne (match_dup 6) 17890 (const_int 0)) 17891 (compare:CC (mem:BLK (match_dup 4)) 17892 (mem:BLK (match_dup 5))) 17893 (const_int 0))) 17894 (use (match_dup 3)) 17895 (use (reg:CC FLAGS_REG)) 17896 (clobber (match_dup 0)) 17897 (clobber (match_dup 1)) 17898 (clobber (match_dup 2))])]) 17899 17900;; Conditional move instructions. 17901 17902(define_expand "mov<mode>cc" 17903 [(set (match_operand:SWIM 0 "register_operand") 17904 (if_then_else:SWIM (match_operand 1 "comparison_operator") 17905 (match_operand:SWIM 2 "<general_operand>") 17906 (match_operand:SWIM 3 "<general_operand>")))] 17907 "" 17908 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") 17909 17910;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 17911;; the register first winds up with `sbbl $0,reg', which is also weird. 17912;; So just document what we're doing explicitly. 17913 17914(define_expand "x86_mov<mode>cc_0_m1" 17915 [(parallel 17916 [(set (match_operand:SWI48 0 "register_operand") 17917 (if_then_else:SWI48 17918 (match_operator:SWI48 2 "ix86_carry_flag_operator" 17919 [(match_operand 1 "flags_reg_operand") 17920 (const_int 0)]) 17921 (const_int -1) 17922 (const_int 0))) 17923 (clobber (reg:CC FLAGS_REG))])]) 17924 17925(define_insn "*x86_mov<mode>cc_0_m1" 17926 [(set (match_operand:SWI48 0 "register_operand" "=r") 17927 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17928 [(reg FLAGS_REG) (const_int 0)]) 17929 (const_int -1) 17930 (const_int 0))) 17931 (clobber (reg:CC FLAGS_REG))] 17932 "" 17933 "sbb{<imodesuffix>}\t%0, %0" 17934 ; Since we don't have the proper number of operands for an alu insn, 17935 ; fill in all the blanks. 17936 [(set_attr "type" "alu") 17937 (set_attr "modrm_class" "op0") 17938 (set_attr "use_carry" "1") 17939 (set_attr "pent_pair" "pu") 17940 (set_attr "memory" "none") 17941 (set_attr "imm_disp" "false") 17942 (set_attr "mode" "<MODE>") 17943 (set_attr "length_immediate" "0")]) 17944 17945(define_insn "*x86_mov<mode>cc_0_m1_se" 17946 [(set (match_operand:SWI48 0 "register_operand" "=r") 17947 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17948 [(reg FLAGS_REG) (const_int 0)]) 17949 (const_int 1) 17950 (const_int 0))) 17951 (clobber (reg:CC FLAGS_REG))] 17952 "" 17953 "sbb{<imodesuffix>}\t%0, %0" 17954 [(set_attr "type" "alu") 17955 (set_attr "modrm_class" "op0") 17956 (set_attr "use_carry" "1") 17957 (set_attr "pent_pair" "pu") 17958 (set_attr "memory" "none") 17959 (set_attr "imm_disp" "false") 17960 (set_attr "mode" "<MODE>") 17961 (set_attr "length_immediate" "0")]) 17962 17963(define_insn "*x86_mov<mode>cc_0_m1_neg" 17964 [(set (match_operand:SWI48 0 "register_operand" "=r") 17965 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17966 [(reg FLAGS_REG) (const_int 0)]))) 17967 (clobber (reg:CC FLAGS_REG))] 17968 "" 17969 "sbb{<imodesuffix>}\t%0, %0" 17970 [(set_attr "type" "alu") 17971 (set_attr "modrm_class" "op0") 17972 (set_attr "use_carry" "1") 17973 (set_attr "pent_pair" "pu") 17974 (set_attr "memory" "none") 17975 (set_attr "imm_disp" "false") 17976 (set_attr "mode" "<MODE>") 17977 (set_attr "length_immediate" "0")]) 17978 17979(define_insn "*mov<mode>cc_noc" 17980 [(set (match_operand:SWI248 0 "register_operand" "=r,r") 17981 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 17982 [(reg FLAGS_REG) (const_int 0)]) 17983 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0") 17984 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))] 17985 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 17986 "@ 17987 cmov%O2%C1\t{%2, %0|%0, %2} 17988 cmov%O2%c1\t{%3, %0|%0, %3}" 17989 [(set_attr "type" "icmov") 17990 (set_attr "mode" "<MODE>")]) 17991 17992(define_insn "*movsicc_noc_zext" 17993 [(set (match_operand:DI 0 "register_operand" "=r,r") 17994 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 17995 [(reg FLAGS_REG) (const_int 0)]) 17996 (zero_extend:DI 17997 (match_operand:SI 2 "nonimmediate_operand" "rm,0")) 17998 (zero_extend:DI 17999 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))] 18000 "TARGET_64BIT 18001 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18002 "@ 18003 cmov%O2%C1\t{%2, %k0|%k0, %2} 18004 cmov%O2%c1\t{%3, %k0|%k0, %3}" 18005 [(set_attr "type" "icmov") 18006 (set_attr "mode" "SI")]) 18007 18008;; Don't do conditional moves with memory inputs. This splitter helps 18009;; register starved x86_32 by forcing inputs into registers before reload. 18010(define_split 18011 [(set (match_operand:SWI248 0 "register_operand") 18012 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 18013 [(reg FLAGS_REG) (const_int 0)]) 18014 (match_operand:SWI248 2 "nonimmediate_operand") 18015 (match_operand:SWI248 3 "nonimmediate_operand")))] 18016 "!TARGET_64BIT && TARGET_CMOVE 18017 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18018 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18019 && can_create_pseudo_p () 18020 && optimize_insn_for_speed_p ()" 18021 [(set (match_dup 0) 18022 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 18023{ 18024 if (MEM_P (operands[2])) 18025 operands[2] = force_reg (<MODE>mode, operands[2]); 18026 if (MEM_P (operands[3])) 18027 operands[3] = force_reg (<MODE>mode, operands[3]); 18028}) 18029 18030(define_insn "*movqicc_noc" 18031 [(set (match_operand:QI 0 "register_operand" "=r,r") 18032 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 18033 [(reg FLAGS_REG) (const_int 0)]) 18034 (match_operand:QI 2 "register_operand" "r,0") 18035 (match_operand:QI 3 "register_operand" "0,r")))] 18036 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 18037 "#" 18038 [(set_attr "type" "icmov") 18039 (set_attr "mode" "QI")]) 18040 18041(define_split 18042 [(set (match_operand:SWI12 0 "register_operand") 18043 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator" 18044 [(reg FLAGS_REG) (const_int 0)]) 18045 (match_operand:SWI12 2 "register_operand") 18046 (match_operand:SWI12 3 "register_operand")))] 18047 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL 18048 && reload_completed" 18049 [(set (match_dup 0) 18050 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 18051{ 18052 operands[0] = gen_lowpart (SImode, operands[0]); 18053 operands[2] = gen_lowpart (SImode, operands[2]); 18054 operands[3] = gen_lowpart (SImode, operands[3]); 18055}) 18056 18057;; Don't do conditional moves with memory inputs 18058(define_peephole2 18059 [(match_scratch:SWI248 4 "r") 18060 (set (match_operand:SWI248 0 "register_operand") 18061 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 18062 [(reg FLAGS_REG) (const_int 0)]) 18063 (match_operand:SWI248 2 "nonimmediate_operand") 18064 (match_operand:SWI248 3 "nonimmediate_operand")))] 18065 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18066 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18067 && optimize_insn_for_speed_p ()" 18068 [(set (match_dup 4) (match_dup 5)) 18069 (set (match_dup 0) 18070 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 18071{ 18072 if (MEM_P (operands[2])) 18073 { 18074 operands[5] = operands[2]; 18075 operands[2] = operands[4]; 18076 } 18077 else if (MEM_P (operands[3])) 18078 { 18079 operands[5] = operands[3]; 18080 operands[3] = operands[4]; 18081 } 18082 else 18083 gcc_unreachable (); 18084}) 18085 18086(define_peephole2 18087 [(match_scratch:SI 4 "r") 18088 (set (match_operand:DI 0 "register_operand") 18089 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 18090 [(reg FLAGS_REG) (const_int 0)]) 18091 (zero_extend:DI 18092 (match_operand:SI 2 "nonimmediate_operand")) 18093 (zero_extend:DI 18094 (match_operand:SI 3 "nonimmediate_operand"))))] 18095 "TARGET_64BIT 18096 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18097 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18098 && optimize_insn_for_speed_p ()" 18099 [(set (match_dup 4) (match_dup 5)) 18100 (set (match_dup 0) 18101 (if_then_else:DI (match_dup 1) 18102 (zero_extend:DI (match_dup 2)) 18103 (zero_extend:DI (match_dup 3))))] 18104{ 18105 if (MEM_P (operands[2])) 18106 { 18107 operands[5] = operands[2]; 18108 operands[2] = operands[4]; 18109 } 18110 else if (MEM_P (operands[3])) 18111 { 18112 operands[5] = operands[3]; 18113 operands[3] = operands[4]; 18114 } 18115 else 18116 gcc_unreachable (); 18117}) 18118 18119(define_expand "mov<mode>cc" 18120 [(set (match_operand:X87MODEF 0 "register_operand") 18121 (if_then_else:X87MODEF 18122 (match_operand 1 "comparison_operator") 18123 (match_operand:X87MODEF 2 "register_operand") 18124 (match_operand:X87MODEF 3 "register_operand")))] 18125 "(TARGET_80387 && TARGET_CMOVE) 18126 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 18127 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;") 18128 18129(define_insn "*movxfcc_1" 18130 [(set (match_operand:XF 0 "register_operand" "=f,f") 18131 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 18132 [(reg FLAGS_REG) (const_int 0)]) 18133 (match_operand:XF 2 "register_operand" "f,0") 18134 (match_operand:XF 3 "register_operand" "0,f")))] 18135 "TARGET_80387 && TARGET_CMOVE" 18136 "@ 18137 fcmov%F1\t{%2, %0|%0, %2} 18138 fcmov%f1\t{%3, %0|%0, %3}" 18139 [(set_attr "type" "fcmov") 18140 (set_attr "mode" "XF")]) 18141 18142(define_insn "*movdfcc_1" 18143 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r") 18144 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18145 [(reg FLAGS_REG) (const_int 0)]) 18146 (match_operand:DF 2 "nonimmediate_operand" 18147 "f ,0,rm,0 ,rm,0") 18148 (match_operand:DF 3 "nonimmediate_operand" 18149 "0 ,f,0 ,rm,0, rm")))] 18150 "TARGET_80387 && TARGET_CMOVE 18151 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18152 "@ 18153 fcmov%F1\t{%2, %0|%0, %2} 18154 fcmov%f1\t{%3, %0|%0, %3} 18155 # 18156 # 18157 cmov%O2%C1\t{%2, %0|%0, %2} 18158 cmov%O2%c1\t{%3, %0|%0, %3}" 18159 [(set_attr "isa" "*,*,nox64,nox64,x64,x64") 18160 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov") 18161 (set_attr "mode" "DF,DF,DI,DI,DI,DI")]) 18162 18163(define_split 18164 [(set (match_operand:DF 0 "general_reg_operand") 18165 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18166 [(reg FLAGS_REG) (const_int 0)]) 18167 (match_operand:DF 2 "nonimmediate_operand") 18168 (match_operand:DF 3 "nonimmediate_operand")))] 18169 "!TARGET_64BIT && reload_completed" 18170 [(set (match_dup 2) 18171 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5))) 18172 (set (match_dup 3) 18173 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))] 18174{ 18175 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]); 18176 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]); 18177}) 18178 18179(define_insn "*movsfcc_1_387" 18180 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 18181 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 18182 [(reg FLAGS_REG) (const_int 0)]) 18183 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 18184 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 18185 "TARGET_80387 && TARGET_CMOVE 18186 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18187 "@ 18188 fcmov%F1\t{%2, %0|%0, %2} 18189 fcmov%f1\t{%3, %0|%0, %3} 18190 cmov%O2%C1\t{%2, %0|%0, %2} 18191 cmov%O2%c1\t{%3, %0|%0, %3}" 18192 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 18193 (set_attr "mode" "SF,SF,SI,SI")]) 18194 18195;; Don't do conditional moves with memory inputs. This splitter helps 18196;; register starved x86_32 by forcing inputs into registers before reload. 18197(define_split 18198 [(set (match_operand:MODEF 0 "register_operand") 18199 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator" 18200 [(reg FLAGS_REG) (const_int 0)]) 18201 (match_operand:MODEF 2 "nonimmediate_operand") 18202 (match_operand:MODEF 3 "nonimmediate_operand")))] 18203 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 18204 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18205 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18206 && can_create_pseudo_p () 18207 && optimize_insn_for_speed_p ()" 18208 [(set (match_dup 0) 18209 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 18210{ 18211 if (MEM_P (operands[2])) 18212 operands[2] = force_reg (<MODE>mode, operands[2]); 18213 if (MEM_P (operands[3])) 18214 operands[3] = force_reg (<MODE>mode, operands[3]); 18215}) 18216 18217;; Don't do conditional moves with memory inputs 18218(define_peephole2 18219 [(match_scratch:MODEF 4 "r") 18220 (set (match_operand:MODEF 0 "general_reg_operand") 18221 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator" 18222 [(reg FLAGS_REG) (const_int 0)]) 18223 (match_operand:MODEF 2 "nonimmediate_operand") 18224 (match_operand:MODEF 3 "nonimmediate_operand")))] 18225 "(<MODE>mode != DFmode || TARGET_64BIT) 18226 && TARGET_80387 && TARGET_CMOVE 18227 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18228 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18229 && optimize_insn_for_speed_p ()" 18230 [(set (match_dup 4) (match_dup 5)) 18231 (set (match_dup 0) 18232 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 18233{ 18234 if (MEM_P (operands[2])) 18235 { 18236 operands[5] = operands[2]; 18237 operands[2] = operands[4]; 18238 } 18239 else if (MEM_P (operands[3])) 18240 { 18241 operands[5] = operands[3]; 18242 operands[3] = operands[4]; 18243 } 18244 else 18245 gcc_unreachable (); 18246}) 18247 18248;; All moves in XOP pcmov instructions are 128 bits and hence we restrict 18249;; the scalar versions to have only XMM registers as operands. 18250 18251;; XOP conditional move 18252(define_insn "*xop_pcmov_<mode>" 18253 [(set (match_operand:MODEF 0 "register_operand" "=x") 18254 (if_then_else:MODEF 18255 (match_operand:MODEF 1 "register_operand" "x") 18256 (match_operand:MODEF 2 "register_operand" "x") 18257 (match_operand:MODEF 3 "register_operand" "x")))] 18258 "TARGET_XOP" 18259 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}" 18260 [(set_attr "type" "sse4arg")]) 18261 18262;; These versions of the min/max patterns are intentionally ignorant of 18263;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 18264;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 18265;; are undefined in this condition, we're certain this is correct. 18266 18267(define_insn "<code><mode>3" 18268 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 18269 (smaxmin:MODEF 18270 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v") 18271 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))] 18272 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 18273 "@ 18274 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2} 18275 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 18276 [(set_attr "isa" "noavx,avx") 18277 (set_attr "prefix" "orig,vex") 18278 (set_attr "type" "sseadd") 18279 (set_attr "mode" "<MODE>")]) 18280 18281;; These versions of the min/max patterns implement exactly the operations 18282;; min = (op1 < op2 ? op1 : op2) 18283;; max = (!(op1 < op2) ? op1 : op2) 18284;; Their operands are not commutative, and thus they may be used in the 18285;; presence of -0.0 and NaN. 18286 18287(define_insn "*ieee_s<ieee_maxmin><mode>3" 18288 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 18289 (unspec:MODEF 18290 [(match_operand:MODEF 1 "register_operand" "0,v") 18291 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")] 18292 IEEE_MAXMIN))] 18293 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 18294 "@ 18295 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2} 18296 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 18297 [(set_attr "isa" "noavx,avx") 18298 (set_attr "prefix" "orig,maybe_evex") 18299 (set_attr "type" "sseadd") 18300 (set_attr "mode" "<MODE>")]) 18301 18302;; Make two stack loads independent: 18303;; fld aa fld aa 18304;; fld %st(0) -> fld bb 18305;; fmul bb fmul %st(1), %st 18306;; 18307;; Actually we only match the last two instructions for simplicity. 18308 18309(define_peephole2 18310 [(set (match_operand 0 "fp_register_operand") 18311 (match_operand 1 "fp_register_operand")) 18312 (set (match_dup 0) 18313 (match_operator 2 "binary_fp_operator" 18314 [(match_dup 0) 18315 (match_operand 3 "memory_operand")]))] 18316 "REGNO (operands[0]) != REGNO (operands[1])" 18317 [(set (match_dup 0) (match_dup 3)) 18318 (set (match_dup 0) 18319 (match_op_dup 2 18320 [(match_dup 5) (match_dup 4)]))] 18321{ 18322 operands[4] = operands[0]; 18323 operands[5] = operands[1]; 18324 18325 /* The % modifier is not operational anymore in peephole2's, so we have to 18326 swap the operands manually in the case of addition and multiplication. */ 18327 if (COMMUTATIVE_ARITH_P (operands[2])) 18328 std::swap (operands[4], operands[5]); 18329}) 18330 18331(define_peephole2 18332 [(set (match_operand 0 "fp_register_operand") 18333 (match_operand 1 "fp_register_operand")) 18334 (set (match_dup 0) 18335 (match_operator 2 "binary_fp_operator" 18336 [(match_operand 3 "memory_operand") 18337 (match_dup 0)]))] 18338 "REGNO (operands[0]) != REGNO (operands[1])" 18339 [(set (match_dup 0) (match_dup 3)) 18340 (set (match_dup 0) 18341 (match_op_dup 2 18342 [(match_dup 4) (match_dup 5)]))] 18343{ 18344 operands[4] = operands[0]; 18345 operands[5] = operands[1]; 18346 18347 /* The % modifier is not operational anymore in peephole2's, so we have to 18348 swap the operands manually in the case of addition and multiplication. */ 18349 if (COMMUTATIVE_ARITH_P (operands[2])) 18350 std::swap (operands[4], operands[5]); 18351}) 18352 18353;; Conditional addition patterns 18354(define_expand "add<mode>cc" 18355 [(match_operand:SWI 0 "register_operand") 18356 (match_operand 1 "ordered_comparison_operator") 18357 (match_operand:SWI 2 "register_operand") 18358 (match_operand:SWI 3 "const_int_operand")] 18359 "" 18360 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;") 18361 18362;; Misc patterns (?) 18363 18364;; This pattern exists to put a dependency on all ebp-based memory accesses. 18365;; Otherwise there will be nothing to keep 18366;; 18367;; [(set (reg ebp) (reg esp))] 18368;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 18369;; (clobber (eflags)] 18370;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 18371;; 18372;; in proper program order. 18373 18374(define_insn "pro_epilogue_adjust_stack_<mode>_add" 18375 [(set (match_operand:P 0 "register_operand" "=r,r") 18376 (plus:P (match_operand:P 1 "register_operand" "0,r") 18377 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>"))) 18378 (clobber (reg:CC FLAGS_REG)) 18379 (clobber (mem:BLK (scratch)))] 18380 "" 18381{ 18382 switch (get_attr_type (insn)) 18383 { 18384 case TYPE_IMOV: 18385 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 18386 18387 case TYPE_ALU: 18388 gcc_assert (rtx_equal_p (operands[0], operands[1])); 18389 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 18390 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 18391 18392 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 18393 18394 default: 18395 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 18396 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}"; 18397 } 18398} 18399 [(set (attr "type") 18400 (cond [(and (eq_attr "alternative" "0") 18401 (not (match_test "TARGET_OPT_AGU"))) 18402 (const_string "alu") 18403 (match_operand:<MODE> 2 "const0_operand") 18404 (const_string "imov") 18405 ] 18406 (const_string "lea"))) 18407 (set (attr "length_immediate") 18408 (cond [(eq_attr "type" "imov") 18409 (const_string "0") 18410 (and (eq_attr "type" "alu") 18411 (match_operand 2 "const128_operand")) 18412 (const_string "1") 18413 ] 18414 (const_string "*"))) 18415 (set_attr "mode" "<MODE>")]) 18416 18417(define_insn "pro_epilogue_adjust_stack_<mode>_sub" 18418 [(set (match_operand:P 0 "register_operand" "=r") 18419 (minus:P (match_operand:P 1 "register_operand" "0") 18420 (match_operand:P 2 "register_operand" "r"))) 18421 (clobber (reg:CC FLAGS_REG)) 18422 (clobber (mem:BLK (scratch)))] 18423 "" 18424 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 18425 [(set_attr "type" "alu") 18426 (set_attr "mode" "<MODE>")]) 18427 18428(define_insn "allocate_stack_worker_probe_<mode>" 18429 [(set (match_operand:P 0 "register_operand" "=a") 18430 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 18431 UNSPECV_STACK_PROBE)) 18432 (clobber (reg:CC FLAGS_REG))] 18433 "ix86_target_stack_probe ()" 18434 "call\t___chkstk_ms" 18435 [(set_attr "type" "multi") 18436 (set_attr "length" "5")]) 18437 18438(define_expand "allocate_stack" 18439 [(match_operand 0 "register_operand") 18440 (match_operand 1 "general_operand")] 18441 "ix86_target_stack_probe ()" 18442{ 18443 rtx x; 18444 18445#ifndef CHECK_STACK_LIMIT 18446#define CHECK_STACK_LIMIT 0 18447#endif 18448 18449 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1]) 18450 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 18451 x = operands[1]; 18452 else 18453 { 18454 rtx (*insn) (rtx, rtx); 18455 18456 x = copy_to_mode_reg (Pmode, operands[1]); 18457 18458 insn = (TARGET_64BIT 18459 ? gen_allocate_stack_worker_probe_di 18460 : gen_allocate_stack_worker_probe_si); 18461 18462 emit_insn (insn (x, x)); 18463 } 18464 18465 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x, 18466 stack_pointer_rtx, 0, OPTAB_DIRECT); 18467 18468 if (x != stack_pointer_rtx) 18469 emit_move_insn (stack_pointer_rtx, x); 18470 18471 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 18472 DONE; 18473}) 18474 18475(define_expand "probe_stack" 18476 [(match_operand 0 "memory_operand")] 18477 "" 18478{ 18479 rtx (*insn) (rtx, rtx) 18480 = (GET_MODE (operands[0]) == DImode 18481 ? gen_probe_stack_di : gen_probe_stack_si); 18482 18483 emit_insn (insn (operands[0], const0_rtx)); 18484 DONE; 18485}) 18486 18487;; Use OR for stack probes, this is shorter. 18488(define_insn "probe_stack_<mode>" 18489 [(set (match_operand:W 0 "memory_operand" "=m") 18490 (unspec:W [(match_operand:W 1 "const0_operand")] 18491 UNSPEC_PROBE_STACK)) 18492 (clobber (reg:CC FLAGS_REG))] 18493 "" 18494 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 18495 [(set_attr "type" "alu1") 18496 (set_attr "mode" "<MODE>") 18497 (set_attr "length_immediate" "1")]) 18498 18499(define_insn "adjust_stack_and_probe<mode>" 18500 [(set (match_operand:P 0 "register_operand" "=r") 18501 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 18502 UNSPECV_PROBE_STACK_RANGE)) 18503 (set (reg:P SP_REG) 18504 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n"))) 18505 (clobber (reg:CC FLAGS_REG)) 18506 (clobber (mem:BLK (scratch)))] 18507 "" 18508 "* return output_adjust_stack_and_probe (operands[0]);" 18509 [(set_attr "type" "multi")]) 18510 18511(define_insn "probe_stack_range<mode>" 18512 [(set (match_operand:P 0 "register_operand" "=r") 18513 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 18514 (match_operand:P 2 "const_int_operand" "n")] 18515 UNSPECV_PROBE_STACK_RANGE)) 18516 (clobber (reg:CC FLAGS_REG))] 18517 "" 18518 "* return output_probe_stack_range (operands[0], operands[2]);" 18519 [(set_attr "type" "multi")]) 18520 18521(define_expand "builtin_setjmp_receiver" 18522 [(label_ref (match_operand 0))] 18523 "!TARGET_64BIT && flag_pic" 18524{ 18525#if TARGET_MACHO 18526 if (TARGET_MACHO) 18527 { 18528 rtx xops[3]; 18529 rtx_code_label *label_rtx = gen_label_rtx (); 18530 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 18531 xops[0] = xops[1] = pic_offset_table_rtx; 18532 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx)); 18533 ix86_expand_binary_operator (MINUS, SImode, xops); 18534 } 18535 else 18536#endif 18537 emit_insn (gen_set_got (pic_offset_table_rtx)); 18538 DONE; 18539}) 18540 18541(define_expand "save_stack_nonlocal" 18542 [(set (match_operand 0 "memory_operand") 18543 (match_operand 1 "register_operand"))] 18544 "" 18545{ 18546 rtx stack_slot; 18547 if ((flag_cf_protection & CF_RETURN)) 18548 { 18549 /* Copy shadow stack pointer to the first slot and stack ppointer 18550 to the second slot. */ 18551 rtx ssp_slot = adjust_address (operands[0], word_mode, 0); 18552 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD); 18553 rtx ssp = gen_reg_rtx (word_mode); 18554 emit_insn ((word_mode == SImode) 18555 ? gen_rdsspsi (ssp) 18556 : gen_rdsspdi (ssp)); 18557 emit_move_insn (ssp_slot, ssp); 18558 } 18559 else 18560 stack_slot = adjust_address (operands[0], Pmode, 0); 18561 emit_move_insn (stack_slot, operands[1]); 18562 DONE; 18563}) 18564 18565(define_expand "restore_stack_nonlocal" 18566 [(set (match_operand 0 "register_operand" "") 18567 (match_operand 1 "memory_operand" ""))] 18568 "" 18569{ 18570 rtx stack_slot; 18571 if ((flag_cf_protection & CF_RETURN)) 18572 { 18573 /* Restore shadow stack pointer from the first slot and stack 18574 pointer from the second slot. */ 18575 rtx ssp_slot = adjust_address (operands[1], word_mode, 0); 18576 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD); 18577 18578 rtx flags, jump, noadj_label, inc_label, loop_label; 18579 rtx reg_adj, reg_ssp, tmp, clob; 18580 18581 /* Get the current shadow stack pointer. The code below will check if 18582 SHSTK feature is enabled. If it is not enabled the RDSSP instruction 18583 is a NOP. */ 18584 reg_ssp = gen_reg_rtx (word_mode); 18585 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx)); 18586 emit_insn ((word_mode == SImode) 18587 ? gen_rdsspsi (reg_ssp) 18588 : gen_rdsspdi (reg_ssp)); 18589 18590 /* Compare through substraction the saved and the current ssp to decide 18591 if ssp has to be adjusted. */ 18592 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp, 18593 ssp_slot)); 18594 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18595 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18596 emit_insn (tmp); 18597 18598 /* Compare and jump over adjustment code. */ 18599 noadj_label = gen_label_rtx (); 18600 flags = gen_rtx_REG (CCZmode, FLAGS_REG); 18601 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx); 18602 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18603 gen_rtx_LABEL_REF (VOIDmode, noadj_label), 18604 pc_rtx); 18605 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18606 JUMP_LABEL (jump) = noadj_label; 18607 18608 /* Compute the numebr of frames to adjust. */ 18609 reg_adj = gen_lowpart (ptr_mode, reg_ssp); 18610 tmp = gen_rtx_SET (reg_adj, 18611 gen_rtx_LSHIFTRT (ptr_mode, 18612 negate_rtx (ptr_mode, reg_adj), 18613 GEN_INT ((word_mode == SImode) 18614 ? 2 18615 : 3))); 18616 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18617 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18618 emit_insn (tmp); 18619 18620 /* Check if number of frames <= 255 so no loop is needed. */ 18621 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255)); 18622 flags = gen_rtx_REG (CCmode, FLAGS_REG); 18623 emit_insn (gen_rtx_SET (flags, tmp)); 18624 18625 inc_label = gen_label_rtx (); 18626 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx); 18627 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18628 gen_rtx_LABEL_REF (VOIDmode, inc_label), 18629 pc_rtx); 18630 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18631 JUMP_LABEL (jump) = inc_label; 18632 18633 rtx reg_255 = gen_reg_rtx (word_mode); 18634 emit_move_insn (reg_255, GEN_INT (255)); 18635 18636 /* Adjust the ssp in a loop. */ 18637 loop_label = gen_label_rtx (); 18638 emit_label (loop_label); 18639 LABEL_NUSES (loop_label) = 1; 18640 18641 emit_insn ((word_mode == SImode) 18642 ? gen_incsspsi (reg_255) 18643 : gen_incsspdi (reg_255)); 18644 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode, 18645 reg_adj, 18646 GEN_INT (255))); 18647 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18648 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18649 emit_insn (tmp); 18650 18651 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255)); 18652 flags = gen_rtx_REG (CCmode, FLAGS_REG); 18653 emit_insn (gen_rtx_SET (flags, tmp)); 18654 18655 /* Jump to the loop label. */ 18656 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx); 18657 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18658 gen_rtx_LABEL_REF (VOIDmode, loop_label), 18659 pc_rtx); 18660 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18661 JUMP_LABEL (jump) = loop_label; 18662 18663 emit_label (inc_label); 18664 LABEL_NUSES (inc_label) = 1; 18665 emit_insn ((word_mode == SImode) 18666 ? gen_incsspsi (reg_ssp) 18667 : gen_incsspdi (reg_ssp)); 18668 18669 emit_label (noadj_label); 18670 LABEL_NUSES (noadj_label) = 1; 18671 } 18672 else 18673 stack_slot = adjust_address (operands[1], Pmode, 0); 18674 emit_move_insn (operands[0], stack_slot); 18675 DONE; 18676}) 18677 18678 18679;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 18680;; Do not split instructions with mask registers. 18681(define_split 18682 [(set (match_operand 0 "general_reg_operand") 18683 (match_operator 3 "promotable_binary_operator" 18684 [(match_operand 1 "general_reg_operand") 18685 (match_operand 2 "aligned_operand")])) 18686 (clobber (reg:CC FLAGS_REG))] 18687 "! TARGET_PARTIAL_REG_STALL && reload_completed 18688 && ((GET_MODE (operands[0]) == HImode 18689 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX) 18690 /* ??? next two lines just !satisfies_constraint_K (...) */ 18691 || !CONST_INT_P (operands[2]) 18692 || satisfies_constraint_K (operands[2]))) 18693 || (GET_MODE (operands[0]) == QImode 18694 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))" 18695 [(parallel [(set (match_dup 0) 18696 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 18697 (clobber (reg:CC FLAGS_REG))])] 18698{ 18699 operands[0] = gen_lowpart (SImode, operands[0]); 18700 operands[1] = gen_lowpart (SImode, operands[1]); 18701 if (GET_CODE (operands[3]) != ASHIFT) 18702 operands[2] = gen_lowpart (SImode, operands[2]); 18703 operands[3] = shallow_copy_rtx (operands[3]); 18704 PUT_MODE (operands[3], SImode); 18705}) 18706 18707; Promote the QImode tests, as i386 has encoding of the AND 18708; instruction with 32-bit sign-extended immediate and thus the 18709; instruction size is unchanged, except in the %eax case for 18710; which it is increased by one byte, hence the ! optimize_size. 18711(define_split 18712 [(set (match_operand 0 "flags_reg_operand") 18713 (match_operator 2 "compare_operator" 18714 [(and (match_operand 3 "aligned_operand") 18715 (match_operand 4 "const_int_operand")) 18716 (const_int 0)])) 18717 (set (match_operand 1 "register_operand") 18718 (and (match_dup 3) (match_dup 4)))] 18719 "! TARGET_PARTIAL_REG_STALL && reload_completed 18720 && optimize_insn_for_speed_p () 18721 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 18722 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode)) 18723 /* Ensure that the operand will remain sign-extended immediate. */ 18724 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)" 18725 [(parallel [(set (match_dup 0) 18726 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 18727 (const_int 0)])) 18728 (set (match_dup 1) 18729 (and:SI (match_dup 3) (match_dup 4)))])] 18730{ 18731 operands[4] 18732 = gen_int_mode (INTVAL (operands[4]) 18733 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 18734 operands[1] = gen_lowpart (SImode, operands[1]); 18735 operands[3] = gen_lowpart (SImode, operands[3]); 18736}) 18737 18738; Don't promote the QImode tests, as i386 doesn't have encoding of 18739; the TEST instruction with 32-bit sign-extended immediate and thus 18740; the instruction size would at least double, which is not what we 18741; want even with ! optimize_size. 18742(define_split 18743 [(set (match_operand 0 "flags_reg_operand") 18744 (match_operator 1 "compare_operator" 18745 [(and (match_operand:HI 2 "aligned_operand") 18746 (match_operand:HI 3 "const_int_operand")) 18747 (const_int 0)]))] 18748 "! TARGET_PARTIAL_REG_STALL && reload_completed 18749 && ! TARGET_FAST_PREFIX 18750 && optimize_insn_for_speed_p () 18751 /* Ensure that the operand will remain sign-extended immediate. */ 18752 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)" 18753 [(set (match_dup 0) 18754 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 18755 (const_int 0)]))] 18756{ 18757 operands[3] 18758 = gen_int_mode (INTVAL (operands[3]) 18759 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 18760 operands[2] = gen_lowpart (SImode, operands[2]); 18761}) 18762 18763(define_split 18764 [(set (match_operand 0 "register_operand") 18765 (neg (match_operand 1 "register_operand"))) 18766 (clobber (reg:CC FLAGS_REG))] 18767 "! TARGET_PARTIAL_REG_STALL && reload_completed 18768 && (GET_MODE (operands[0]) == HImode 18769 || (GET_MODE (operands[0]) == QImode 18770 && (TARGET_PROMOTE_QImode 18771 || optimize_insn_for_size_p ())))" 18772 [(parallel [(set (match_dup 0) 18773 (neg:SI (match_dup 1))) 18774 (clobber (reg:CC FLAGS_REG))])] 18775{ 18776 operands[0] = gen_lowpart (SImode, operands[0]); 18777 operands[1] = gen_lowpart (SImode, operands[1]); 18778}) 18779 18780;; Do not split instructions with mask regs. 18781(define_split 18782 [(set (match_operand 0 "general_reg_operand") 18783 (not (match_operand 1 "general_reg_operand")))] 18784 "! TARGET_PARTIAL_REG_STALL && reload_completed 18785 && (GET_MODE (operands[0]) == HImode 18786 || (GET_MODE (operands[0]) == QImode 18787 && (TARGET_PROMOTE_QImode 18788 || optimize_insn_for_size_p ())))" 18789 [(set (match_dup 0) 18790 (not:SI (match_dup 1)))] 18791{ 18792 operands[0] = gen_lowpart (SImode, operands[0]); 18793 operands[1] = gen_lowpart (SImode, operands[1]); 18794}) 18795 18796;; RTL Peephole optimizations, run before sched2. These primarily look to 18797;; transform a complex memory operation into two memory to register operations. 18798 18799;; Don't push memory operands 18800(define_peephole2 18801 [(set (match_operand:SWI 0 "push_operand") 18802 (match_operand:SWI 1 "memory_operand")) 18803 (match_scratch:SWI 2 "<r>")] 18804 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 18805 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 18806 [(set (match_dup 2) (match_dup 1)) 18807 (set (match_dup 0) (match_dup 2))]) 18808 18809;; We need to handle SFmode only, because DFmode and XFmode are split to 18810;; SImode pushes. 18811(define_peephole2 18812 [(set (match_operand:SF 0 "push_operand") 18813 (match_operand:SF 1 "memory_operand")) 18814 (match_scratch:SF 2 "r")] 18815 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 18816 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 18817 [(set (match_dup 2) (match_dup 1)) 18818 (set (match_dup 0) (match_dup 2))]) 18819 18820;; Don't move an immediate directly to memory when the instruction 18821;; gets too big, or if LCP stalls are a problem for 16-bit moves. 18822(define_peephole2 18823 [(match_scratch:SWI124 1 "<r>") 18824 (set (match_operand:SWI124 0 "memory_operand") 18825 (const_int 0))] 18826 "optimize_insn_for_speed_p () 18827 && ((<MODE>mode == HImode 18828 && TARGET_LCP_STALL) 18829 || (!TARGET_USE_MOV0 18830 && TARGET_SPLIT_LONG_MOVES 18831 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn)) 18832 && peep2_regno_dead_p (0, FLAGS_REG)" 18833 [(parallel [(set (match_dup 2) (const_int 0)) 18834 (clobber (reg:CC FLAGS_REG))]) 18835 (set (match_dup 0) (match_dup 1))] 18836 "operands[2] = gen_lowpart (SImode, operands[1]);") 18837 18838(define_peephole2 18839 [(match_scratch:SWI124 2 "<r>") 18840 (set (match_operand:SWI124 0 "memory_operand") 18841 (match_operand:SWI124 1 "immediate_operand"))] 18842 "optimize_insn_for_speed_p () 18843 && ((<MODE>mode == HImode 18844 && TARGET_LCP_STALL) 18845 || (TARGET_SPLIT_LONG_MOVES 18846 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))" 18847 [(set (match_dup 2) (match_dup 1)) 18848 (set (match_dup 0) (match_dup 2))]) 18849 18850;; Don't compare memory with zero, load and use a test instead. 18851(define_peephole2 18852 [(set (match_operand 0 "flags_reg_operand") 18853 (match_operator 1 "compare_operator" 18854 [(match_operand:SI 2 "memory_operand") 18855 (const_int 0)])) 18856 (match_scratch:SI 3 "r")] 18857 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)" 18858 [(set (match_dup 3) (match_dup 2)) 18859 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]) 18860 18861;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 18862;; Don't split NOTs with a displacement operand, because resulting XOR 18863;; will not be pairable anyway. 18864;; 18865;; On AMD K6, NOT is vector decoded with memory operand that cannot be 18866;; represented using a modRM byte. The XOR replacement is long decoded, 18867;; so this split helps here as well. 18868;; 18869;; Note: Can't do this as a regular split because we can't get proper 18870;; lifetime information then. 18871 18872(define_peephole2 18873 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand") 18874 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))] 18875 "optimize_insn_for_speed_p () 18876 && ((TARGET_NOT_UNPAIRABLE 18877 && (!MEM_P (operands[0]) 18878 || !memory_displacement_operand (operands[0], <MODE>mode))) 18879 || (TARGET_NOT_VECTORMODE 18880 && long_memory_operand (operands[0], <MODE>mode))) 18881 && peep2_regno_dead_p (0, FLAGS_REG)" 18882 [(parallel [(set (match_dup 0) 18883 (xor:SWI124 (match_dup 1) (const_int -1))) 18884 (clobber (reg:CC FLAGS_REG))])]) 18885 18886;; Non pairable "test imm, reg" instructions can be translated to 18887;; "and imm, reg" if reg dies. The "and" form is also shorter (one 18888;; byte opcode instead of two, have a short form for byte operands), 18889;; so do it for other CPUs as well. Given that the value was dead, 18890;; this should not create any new dependencies. Pass on the sub-word 18891;; versions if we're concerned about partial register stalls. 18892 18893(define_peephole2 18894 [(set (match_operand 0 "flags_reg_operand") 18895 (match_operator 1 "compare_operator" 18896 [(and:SI (match_operand:SI 2 "register_operand") 18897 (match_operand:SI 3 "immediate_operand")) 18898 (const_int 0)]))] 18899 "ix86_match_ccmode (insn, CCNOmode) 18900 && (REGNO (operands[2]) != AX_REG 18901 || satisfies_constraint_K (operands[3])) 18902 && peep2_reg_dead_p (1, operands[2])" 18903 [(parallel 18904 [(set (match_dup 0) 18905 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 18906 (const_int 0)])) 18907 (set (match_dup 2) 18908 (and:SI (match_dup 2) (match_dup 3)))])]) 18909 18910;; We don't need to handle HImode case, because it will be promoted to SImode 18911;; on ! TARGET_PARTIAL_REG_STALL 18912 18913(define_peephole2 18914 [(set (match_operand 0 "flags_reg_operand") 18915 (match_operator 1 "compare_operator" 18916 [(and:QI (match_operand:QI 2 "register_operand") 18917 (match_operand:QI 3 "immediate_operand")) 18918 (const_int 0)]))] 18919 "! TARGET_PARTIAL_REG_STALL 18920 && ix86_match_ccmode (insn, CCNOmode) 18921 && REGNO (operands[2]) != AX_REG 18922 && peep2_reg_dead_p (1, operands[2])" 18923 [(parallel 18924 [(set (match_dup 0) 18925 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 18926 (const_int 0)])) 18927 (set (match_dup 2) 18928 (and:QI (match_dup 2) (match_dup 3)))])]) 18929 18930(define_peephole2 18931 [(set (match_operand 0 "flags_reg_operand") 18932 (match_operator 1 "compare_operator" 18933 [(and:QI 18934 (subreg:QI 18935 (zero_extract:SI (match_operand 2 "QIreg_operand") 18936 (const_int 8) 18937 (const_int 8)) 0) 18938 (match_operand 3 "const_int_operand")) 18939 (const_int 0)]))] 18940 "! TARGET_PARTIAL_REG_STALL 18941 && ix86_match_ccmode (insn, CCNOmode) 18942 && REGNO (operands[2]) != AX_REG 18943 && peep2_reg_dead_p (1, operands[2])" 18944 [(parallel 18945 [(set (match_dup 0) 18946 (match_op_dup 1 18947 [(and:QI 18948 (subreg:QI 18949 (zero_extract:SI (match_dup 2) 18950 (const_int 8) 18951 (const_int 8)) 0) 18952 (match_dup 3)) 18953 (const_int 0)])) 18954 (set (zero_extract:SI (match_dup 2) 18955 (const_int 8) 18956 (const_int 8)) 18957 (subreg:SI 18958 (and:QI 18959 (subreg:QI 18960 (zero_extract:SI (match_dup 2) 18961 (const_int 8) 18962 (const_int 8)) 0) 18963 (match_dup 3)) 0))])]) 18964 18965;; Don't do logical operations with memory inputs. 18966(define_peephole2 18967 [(match_scratch:SWI 2 "<r>") 18968 (parallel [(set (match_operand:SWI 0 "register_operand") 18969 (match_operator:SWI 3 "arith_or_logical_operator" 18970 [(match_dup 0) 18971 (match_operand:SWI 1 "memory_operand")])) 18972 (clobber (reg:CC FLAGS_REG))])] 18973 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 18974 [(set (match_dup 2) (match_dup 1)) 18975 (parallel [(set (match_dup 0) 18976 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 18977 (clobber (reg:CC FLAGS_REG))])]) 18978 18979(define_peephole2 18980 [(match_scratch:SWI 2 "<r>") 18981 (parallel [(set (match_operand:SWI 0 "register_operand") 18982 (match_operator:SWI 3 "arith_or_logical_operator" 18983 [(match_operand:SWI 1 "memory_operand") 18984 (match_dup 0)])) 18985 (clobber (reg:CC FLAGS_REG))])] 18986 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 18987 [(set (match_dup 2) (match_dup 1)) 18988 (parallel [(set (match_dup 0) 18989 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 18990 (clobber (reg:CC FLAGS_REG))])]) 18991 18992;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when 18993;; the memory address refers to the destination of the load! 18994 18995(define_peephole2 18996 [(set (match_operand:SWI 0 "general_reg_operand") 18997 (match_operand:SWI 1 "general_reg_operand")) 18998 (parallel [(set (match_dup 0) 18999 (match_operator:SWI 3 "commutative_operator" 19000 [(match_dup 0) 19001 (match_operand:SWI 2 "memory_operand")])) 19002 (clobber (reg:CC FLAGS_REG))])] 19003 "REGNO (operands[0]) != REGNO (operands[1]) 19004 && (<MODE>mode != QImode 19005 || any_QIreg_operand (operands[1], QImode))" 19006 [(set (match_dup 0) (match_dup 4)) 19007 (parallel [(set (match_dup 0) 19008 (match_op_dup 3 [(match_dup 0) (match_dup 1)])) 19009 (clobber (reg:CC FLAGS_REG))])] 19010 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);") 19011 19012(define_peephole2 19013 [(set (match_operand 0 "mmx_reg_operand") 19014 (match_operand 1 "mmx_reg_operand")) 19015 (set (match_dup 0) 19016 (match_operator 3 "commutative_operator" 19017 [(match_dup 0) 19018 (match_operand 2 "memory_operand")]))] 19019 "REGNO (operands[0]) != REGNO (operands[1])" 19020 [(set (match_dup 0) (match_dup 2)) 19021 (set (match_dup 0) 19022 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 19023 19024(define_peephole2 19025 [(set (match_operand 0 "sse_reg_operand") 19026 (match_operand 1 "sse_reg_operand")) 19027 (set (match_dup 0) 19028 (match_operator 3 "commutative_operator" 19029 [(match_dup 0) 19030 (match_operand 2 "memory_operand")]))] 19031 "REGNO (operands[0]) != REGNO (operands[1])" 19032 [(set (match_dup 0) (match_dup 2)) 19033 (set (match_dup 0) 19034 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 19035 19036; Don't do logical operations with memory outputs 19037; 19038; These two don't make sense for PPro/PII -- we're expanding a 4-uop 19039; instruction into two 1-uop insns plus a 2-uop insn. That last has 19040; the same decoder scheduling characteristics as the original. 19041 19042(define_peephole2 19043 [(match_scratch:SWI 2 "<r>") 19044 (parallel [(set (match_operand:SWI 0 "memory_operand") 19045 (match_operator:SWI 3 "arith_or_logical_operator" 19046 [(match_dup 0) 19047 (match_operand:SWI 1 "<nonmemory_operand>")])) 19048 (clobber (reg:CC FLAGS_REG))])] 19049 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())" 19050 [(set (match_dup 2) (match_dup 0)) 19051 (parallel [(set (match_dup 2) 19052 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 19053 (clobber (reg:CC FLAGS_REG))]) 19054 (set (match_dup 0) (match_dup 2))]) 19055 19056(define_peephole2 19057 [(match_scratch:SWI 2 "<r>") 19058 (parallel [(set (match_operand:SWI 0 "memory_operand") 19059 (match_operator:SWI 3 "arith_or_logical_operator" 19060 [(match_operand:SWI 1 "<nonmemory_operand>") 19061 (match_dup 0)])) 19062 (clobber (reg:CC FLAGS_REG))])] 19063 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())" 19064 [(set (match_dup 2) (match_dup 0)) 19065 (parallel [(set (match_dup 2) 19066 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19067 (clobber (reg:CC FLAGS_REG))]) 19068 (set (match_dup 0) (match_dup 2))]) 19069 19070;; Attempt to use arith or logical operations with memory outputs with 19071;; setting of flags. 19072(define_peephole2 19073 [(set (match_operand:SWI 0 "register_operand") 19074 (match_operand:SWI 1 "memory_operand")) 19075 (parallel [(set (match_dup 0) 19076 (match_operator:SWI 3 "plusminuslogic_operator" 19077 [(match_dup 0) 19078 (match_operand:SWI 2 "<nonmemory_operand>")])) 19079 (clobber (reg:CC FLAGS_REG))]) 19080 (set (match_dup 1) (match_dup 0)) 19081 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19082 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19083 && peep2_reg_dead_p (4, operands[0]) 19084 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19085 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19086 && (<MODE>mode != QImode 19087 || immediate_operand (operands[2], QImode) 19088 || any_QIreg_operand (operands[2], QImode)) 19089 && ix86_match_ccmode (peep2_next_insn (3), 19090 (GET_CODE (operands[3]) == PLUS 19091 || GET_CODE (operands[3]) == MINUS) 19092 ? CCGOCmode : CCNOmode)" 19093 [(parallel [(set (match_dup 4) (match_dup 6)) 19094 (set (match_dup 1) (match_dup 5))])] 19095{ 19096 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19097 operands[5] 19098 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19099 copy_rtx (operands[1]), 19100 operands[2]); 19101 operands[6] 19102 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19103 copy_rtx (operands[5]), 19104 const0_rtx); 19105}) 19106 19107;; Likewise for cmpelim optimized pattern. 19108(define_peephole2 19109 [(set (match_operand:SWI 0 "register_operand") 19110 (match_operand:SWI 1 "memory_operand")) 19111 (parallel [(set (reg FLAGS_REG) 19112 (compare (match_operator:SWI 3 "plusminuslogic_operator" 19113 [(match_dup 0) 19114 (match_operand:SWI 2 "<nonmemory_operand>")]) 19115 (const_int 0))) 19116 (set (match_dup 0) (match_dup 3))]) 19117 (set (match_dup 1) (match_dup 0))] 19118 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19119 && peep2_reg_dead_p (3, operands[0]) 19120 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19121 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19122 && ix86_match_ccmode (peep2_next_insn (1), 19123 (GET_CODE (operands[3]) == PLUS 19124 || GET_CODE (operands[3]) == MINUS) 19125 ? CCGOCmode : CCNOmode)" 19126 [(parallel [(set (match_dup 4) (match_dup 6)) 19127 (set (match_dup 1) (match_dup 5))])] 19128{ 19129 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0)); 19130 operands[5] 19131 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19132 copy_rtx (operands[1]), operands[2]); 19133 operands[6] 19134 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]), 19135 const0_rtx); 19136}) 19137 19138;; Likewise for instances where we have a lea pattern. 19139(define_peephole2 19140 [(set (match_operand:SWI 0 "register_operand") 19141 (match_operand:SWI 1 "memory_operand")) 19142 (set (match_operand:SWI 3 "register_operand") 19143 (plus:SWI (match_dup 0) 19144 (match_operand:SWI 2 "<nonmemory_operand>"))) 19145 (set (match_dup 1) (match_dup 3)) 19146 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))] 19147 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19148 && peep2_reg_dead_p (4, operands[3]) 19149 && (rtx_equal_p (operands[0], operands[3]) 19150 || peep2_reg_dead_p (2, operands[0])) 19151 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19152 && !reg_overlap_mentioned_p (operands[3], operands[1]) 19153 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19154 && (<MODE>mode != QImode 19155 || immediate_operand (operands[2], QImode) 19156 || any_QIreg_operand (operands[2], QImode)) 19157 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)" 19158 [(parallel [(set (match_dup 4) (match_dup 6)) 19159 (set (match_dup 1) (match_dup 5))])] 19160{ 19161 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19162 operands[5] 19163 = gen_rtx_PLUS (<MODE>mode, 19164 copy_rtx (operands[1]), 19165 operands[2]); 19166 operands[6] 19167 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19168 copy_rtx (operands[5]), 19169 const0_rtx); 19170}) 19171 19172(define_peephole2 19173 [(parallel [(set (match_operand:SWI 0 "register_operand") 19174 (match_operator:SWI 2 "plusminuslogic_operator" 19175 [(match_dup 0) 19176 (match_operand:SWI 1 "memory_operand")])) 19177 (clobber (reg:CC FLAGS_REG))]) 19178 (set (match_dup 1) (match_dup 0)) 19179 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19180 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19181 && COMMUTATIVE_ARITH_P (operands[2]) 19182 && peep2_reg_dead_p (3, operands[0]) 19183 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19184 && ix86_match_ccmode (peep2_next_insn (2), 19185 GET_CODE (operands[2]) == PLUS 19186 ? CCGOCmode : CCNOmode)" 19187 [(parallel [(set (match_dup 3) (match_dup 5)) 19188 (set (match_dup 1) (match_dup 4))])] 19189{ 19190 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); 19191 operands[4] 19192 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19193 copy_rtx (operands[1]), 19194 operands[0]); 19195 operands[5] 19196 = gen_rtx_COMPARE (GET_MODE (operands[3]), 19197 copy_rtx (operands[4]), 19198 const0_rtx); 19199}) 19200 19201;; Likewise for cmpelim optimized pattern. 19202(define_peephole2 19203 [(parallel [(set (reg FLAGS_REG) 19204 (compare (match_operator:SWI 2 "plusminuslogic_operator" 19205 [(match_operand:SWI 0 "register_operand") 19206 (match_operand:SWI 1 "memory_operand")]) 19207 (const_int 0))) 19208 (set (match_dup 0) (match_dup 2))]) 19209 (set (match_dup 1) (match_dup 0))] 19210 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19211 && COMMUTATIVE_ARITH_P (operands[2]) 19212 && peep2_reg_dead_p (2, operands[0]) 19213 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19214 && ix86_match_ccmode (peep2_next_insn (0), 19215 GET_CODE (operands[2]) == PLUS 19216 ? CCGOCmode : CCNOmode)" 19217 [(parallel [(set (match_dup 3) (match_dup 5)) 19218 (set (match_dup 1) (match_dup 4))])] 19219{ 19220 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0)); 19221 operands[4] 19222 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19223 copy_rtx (operands[1]), operands[0]); 19224 operands[5] 19225 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]), 19226 const0_rtx); 19227}) 19228 19229(define_peephole2 19230 [(set (match_operand:SWI12 0 "register_operand") 19231 (match_operand:SWI12 1 "memory_operand")) 19232 (parallel [(set (match_operand:SI 4 "register_operand") 19233 (match_operator:SI 3 "plusminuslogic_operator" 19234 [(match_dup 4) 19235 (match_operand:SI 2 "nonmemory_operand")])) 19236 (clobber (reg:CC FLAGS_REG))]) 19237 (set (match_dup 1) (match_dup 0)) 19238 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19239 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19240 && REGNO (operands[0]) == REGNO (operands[4]) 19241 && peep2_reg_dead_p (4, operands[0]) 19242 && (<MODE>mode != QImode 19243 || immediate_operand (operands[2], SImode) 19244 || any_QIreg_operand (operands[2], SImode)) 19245 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19246 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19247 && ix86_match_ccmode (peep2_next_insn (3), 19248 (GET_CODE (operands[3]) == PLUS 19249 || GET_CODE (operands[3]) == MINUS) 19250 ? CCGOCmode : CCNOmode)" 19251 [(parallel [(set (match_dup 4) (match_dup 6)) 19252 (set (match_dup 1) (match_dup 5))])] 19253{ 19254 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19255 operands[5] 19256 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 19257 copy_rtx (operands[1]), 19258 gen_lowpart (<MODE>mode, operands[2])); 19259 operands[6] 19260 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19261 copy_rtx (operands[5]), 19262 const0_rtx); 19263}) 19264 19265;; Attempt to always use XOR for zeroing registers (including FP modes). 19266(define_peephole2 19267 [(set (match_operand 0 "general_reg_operand") 19268 (match_operand 1 "const0_operand"))] 19269 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 19270 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 19271 && peep2_regno_dead_p (0, FLAGS_REG)" 19272 [(parallel [(set (match_dup 0) (const_int 0)) 19273 (clobber (reg:CC FLAGS_REG))])] 19274 "operands[0] = gen_lowpart (word_mode, operands[0]);") 19275 19276(define_peephole2 19277 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand")) 19278 (const_int 0))] 19279 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 19280 && peep2_regno_dead_p (0, FLAGS_REG)" 19281 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 19282 (clobber (reg:CC FLAGS_REG))])]) 19283 19284;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg. 19285(define_peephole2 19286 [(set (match_operand:SWI248 0 "general_reg_operand") 19287 (const_int -1))] 19288 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ()) 19289 && peep2_regno_dead_p (0, FLAGS_REG)" 19290 [(parallel [(set (match_dup 0) (const_int -1)) 19291 (clobber (reg:CC FLAGS_REG))])] 19292{ 19293 if (<MODE_SIZE> < GET_MODE_SIZE (SImode)) 19294 operands[0] = gen_lowpart (SImode, operands[0]); 19295}) 19296 19297;; Attempt to convert simple lea to add/shift. 19298;; These can be created by move expanders. 19299;; Disable PLUS peepholes on TARGET_OPT_AGU, since all 19300;; relevant lea instructions were already split. 19301 19302(define_peephole2 19303 [(set (match_operand:SWI48 0 "register_operand") 19304 (plus:SWI48 (match_dup 0) 19305 (match_operand:SWI48 1 "<nonmemory_operand>")))] 19306 "!TARGET_OPT_AGU 19307 && peep2_regno_dead_p (0, FLAGS_REG)" 19308 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 19309 (clobber (reg:CC FLAGS_REG))])]) 19310 19311(define_peephole2 19312 [(set (match_operand:SWI48 0 "register_operand") 19313 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>") 19314 (match_dup 0)))] 19315 "!TARGET_OPT_AGU 19316 && peep2_regno_dead_p (0, FLAGS_REG)" 19317 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 19318 (clobber (reg:CC FLAGS_REG))])]) 19319 19320(define_peephole2 19321 [(set (match_operand:DI 0 "register_operand") 19322 (zero_extend:DI 19323 (plus:SI (match_operand:SI 1 "register_operand") 19324 (match_operand:SI 2 "nonmemory_operand"))))] 19325 "TARGET_64BIT && !TARGET_OPT_AGU 19326 && REGNO (operands[0]) == REGNO (operands[1]) 19327 && peep2_regno_dead_p (0, FLAGS_REG)" 19328 [(parallel [(set (match_dup 0) 19329 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))) 19330 (clobber (reg:CC FLAGS_REG))])]) 19331 19332(define_peephole2 19333 [(set (match_operand:DI 0 "register_operand") 19334 (zero_extend:DI 19335 (plus:SI (match_operand:SI 1 "nonmemory_operand") 19336 (match_operand:SI 2 "register_operand"))))] 19337 "TARGET_64BIT && !TARGET_OPT_AGU 19338 && REGNO (operands[0]) == REGNO (operands[2]) 19339 && peep2_regno_dead_p (0, FLAGS_REG)" 19340 [(parallel [(set (match_dup 0) 19341 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1)))) 19342 (clobber (reg:CC FLAGS_REG))])]) 19343 19344(define_peephole2 19345 [(set (match_operand:SWI48 0 "register_operand") 19346 (mult:SWI48 (match_dup 0) 19347 (match_operand:SWI48 1 "const_int_operand")))] 19348 "pow2p_hwi (INTVAL (operands[1])) 19349 && peep2_regno_dead_p (0, FLAGS_REG)" 19350 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1))) 19351 (clobber (reg:CC FLAGS_REG))])] 19352 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 19353 19354(define_peephole2 19355 [(set (match_operand:DI 0 "register_operand") 19356 (zero_extend:DI 19357 (mult:SI (match_operand:SI 1 "register_operand") 19358 (match_operand:SI 2 "const_int_operand"))))] 19359 "TARGET_64BIT 19360 && pow2p_hwi (INTVAL (operands[2])) 19361 && REGNO (operands[0]) == REGNO (operands[1]) 19362 && peep2_regno_dead_p (0, FLAGS_REG)" 19363 [(parallel [(set (match_dup 0) 19364 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2)))) 19365 (clobber (reg:CC FLAGS_REG))])] 19366 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 19367 19368;; The ESP adjustments can be done by the push and pop instructions. Resulting 19369;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes. 19370;; On many CPUs it is also faster, since special hardware to avoid esp 19371;; dependencies is present. 19372 19373;; While some of these conversions may be done using splitters, we use 19374;; peepholes in order to allow combine_stack_adjustments pass to see 19375;; nonobfuscated RTL. 19376 19377;; Convert prologue esp subtractions to push. 19378;; We need register to push. In order to keep verify_flow_info happy we have 19379;; two choices 19380;; - use scratch and clobber it in order to avoid dependencies 19381;; - use already live register 19382;; We can't use the second way right now, since there is no reliable way how to 19383;; verify that given register is live. First choice will also most likely in 19384;; fewer dependencies. On the place of esp adjustments it is very likely that 19385;; call clobbered registers are dead. We may want to use base pointer as an 19386;; alternative when no register is available later. 19387 19388(define_peephole2 19389 [(match_scratch:W 1 "r") 19390 (parallel [(set (reg:P SP_REG) 19391 (plus:P (reg:P SP_REG) 19392 (match_operand:P 0 "const_int_operand"))) 19393 (clobber (reg:CC FLAGS_REG)) 19394 (clobber (mem:BLK (scratch)))])] 19395 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 19396 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) 19397 && ix86_red_zone_size == 0" 19398 [(clobber (match_dup 1)) 19399 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19400 (clobber (mem:BLK (scratch)))])]) 19401 19402(define_peephole2 19403 [(match_scratch:W 1 "r") 19404 (parallel [(set (reg:P SP_REG) 19405 (plus:P (reg:P SP_REG) 19406 (match_operand:P 0 "const_int_operand"))) 19407 (clobber (reg:CC FLAGS_REG)) 19408 (clobber (mem:BLK (scratch)))])] 19409 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 19410 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) 19411 && ix86_red_zone_size == 0" 19412 [(clobber (match_dup 1)) 19413 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19414 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19415 (clobber (mem:BLK (scratch)))])]) 19416 19417;; Convert esp subtractions to push. 19418(define_peephole2 19419 [(match_scratch:W 1 "r") 19420 (parallel [(set (reg:P SP_REG) 19421 (plus:P (reg:P SP_REG) 19422 (match_operand:P 0 "const_int_operand"))) 19423 (clobber (reg:CC FLAGS_REG))])] 19424 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 19425 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) 19426 && ix86_red_zone_size == 0" 19427 [(clobber (match_dup 1)) 19428 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 19429 19430(define_peephole2 19431 [(match_scratch:W 1 "r") 19432 (parallel [(set (reg:P SP_REG) 19433 (plus:P (reg:P SP_REG) 19434 (match_operand:P 0 "const_int_operand"))) 19435 (clobber (reg:CC FLAGS_REG))])] 19436 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 19437 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) 19438 && ix86_red_zone_size == 0" 19439 [(clobber (match_dup 1)) 19440 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19441 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 19442 19443;; Convert epilogue deallocator to pop. 19444(define_peephole2 19445 [(match_scratch:W 1 "r") 19446 (parallel [(set (reg:P SP_REG) 19447 (plus:P (reg:P SP_REG) 19448 (match_operand:P 0 "const_int_operand"))) 19449 (clobber (reg:CC FLAGS_REG)) 19450 (clobber (mem:BLK (scratch)))])] 19451 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ()) 19452 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 19453 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19454 (clobber (mem:BLK (scratch)))])]) 19455 19456;; Two pops case is tricky, since pop causes dependency 19457;; on destination register. We use two registers if available. 19458(define_peephole2 19459 [(match_scratch:W 1 "r") 19460 (match_scratch:W 2 "r") 19461 (parallel [(set (reg:P SP_REG) 19462 (plus:P (reg:P SP_REG) 19463 (match_operand:P 0 "const_int_operand"))) 19464 (clobber (reg:CC FLAGS_REG)) 19465 (clobber (mem:BLK (scratch)))])] 19466 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ()) 19467 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19468 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19469 (clobber (mem:BLK (scratch)))]) 19470 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 19471 19472(define_peephole2 19473 [(match_scratch:W 1 "r") 19474 (parallel [(set (reg:P SP_REG) 19475 (plus:P (reg:P SP_REG) 19476 (match_operand:P 0 "const_int_operand"))) 19477 (clobber (reg:CC FLAGS_REG)) 19478 (clobber (mem:BLK (scratch)))])] 19479 "optimize_insn_for_size_p () 19480 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19481 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19482 (clobber (mem:BLK (scratch)))]) 19483 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19484 19485;; Convert esp additions to pop. 19486(define_peephole2 19487 [(match_scratch:W 1 "r") 19488 (parallel [(set (reg:P SP_REG) 19489 (plus:P (reg:P SP_REG) 19490 (match_operand:P 0 "const_int_operand"))) 19491 (clobber (reg:CC FLAGS_REG))])] 19492 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 19493 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19494 19495;; Two pops case is tricky, since pop causes dependency 19496;; on destination register. We use two registers if available. 19497(define_peephole2 19498 [(match_scratch:W 1 "r") 19499 (match_scratch:W 2 "r") 19500 (parallel [(set (reg:P SP_REG) 19501 (plus:P (reg:P SP_REG) 19502 (match_operand:P 0 "const_int_operand"))) 19503 (clobber (reg:CC FLAGS_REG))])] 19504 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19505 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19506 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 19507 19508(define_peephole2 19509 [(match_scratch:W 1 "r") 19510 (parallel [(set (reg:P SP_REG) 19511 (plus:P (reg:P SP_REG) 19512 (match_operand:P 0 "const_int_operand"))) 19513 (clobber (reg:CC FLAGS_REG))])] 19514 "optimize_insn_for_size_p () 19515 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19516 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19517 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19518 19519;; Convert compares with 1 to shorter inc/dec operations when CF is not 19520;; required and register dies. Similarly for 128 to -128. 19521(define_peephole2 19522 [(set (match_operand 0 "flags_reg_operand") 19523 (match_operator 1 "compare_operator" 19524 [(match_operand 2 "register_operand") 19525 (match_operand 3 "const_int_operand")]))] 19526 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ()) 19527 && incdec_operand (operands[3], GET_MODE (operands[3]))) 19528 || (!TARGET_FUSE_CMP_AND_BRANCH 19529 && INTVAL (operands[3]) == 128)) 19530 && ix86_match_ccmode (insn, CCGCmode) 19531 && peep2_reg_dead_p (1, operands[2])" 19532 [(parallel [(set (match_dup 0) 19533 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 19534 (clobber (match_dup 2))])]) 19535 19536;; Convert imul by three, five and nine into lea 19537(define_peephole2 19538 [(parallel 19539 [(set (match_operand:SWI48 0 "register_operand") 19540 (mult:SWI48 (match_operand:SWI48 1 "register_operand") 19541 (match_operand:SWI48 2 "const359_operand"))) 19542 (clobber (reg:CC FLAGS_REG))])] 19543 "!TARGET_PARTIAL_REG_STALL 19544 || <MODE>mode == SImode 19545 || optimize_function_for_size_p (cfun)" 19546 [(set (match_dup 0) 19547 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2)) 19548 (match_dup 1)))] 19549 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 19550 19551(define_peephole2 19552 [(parallel 19553 [(set (match_operand:SWI48 0 "register_operand") 19554 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 19555 (match_operand:SWI48 2 "const359_operand"))) 19556 (clobber (reg:CC FLAGS_REG))])] 19557 "optimize_insn_for_speed_p () 19558 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)" 19559 [(set (match_dup 0) (match_dup 1)) 19560 (set (match_dup 0) 19561 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2)) 19562 (match_dup 0)))] 19563 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 19564 19565;; imul $32bit_imm, mem, reg is vector decoded, while 19566;; imul $32bit_imm, reg, reg is direct decoded. 19567(define_peephole2 19568 [(match_scratch:SWI48 3 "r") 19569 (parallel [(set (match_operand:SWI48 0 "register_operand") 19570 (mult:SWI48 (match_operand:SWI48 1 "memory_operand") 19571 (match_operand:SWI48 2 "immediate_operand"))) 19572 (clobber (reg:CC FLAGS_REG))])] 19573 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 19574 && !satisfies_constraint_K (operands[2])" 19575 [(set (match_dup 3) (match_dup 1)) 19576 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2))) 19577 (clobber (reg:CC FLAGS_REG))])]) 19578 19579(define_peephole2 19580 [(match_scratch:SI 3 "r") 19581 (parallel [(set (match_operand:DI 0 "register_operand") 19582 (zero_extend:DI 19583 (mult:SI (match_operand:SI 1 "memory_operand") 19584 (match_operand:SI 2 "immediate_operand")))) 19585 (clobber (reg:CC FLAGS_REG))])] 19586 "TARGET_64BIT 19587 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 19588 && !satisfies_constraint_K (operands[2])" 19589 [(set (match_dup 3) (match_dup 1)) 19590 (parallel [(set (match_dup 0) 19591 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 19592 (clobber (reg:CC FLAGS_REG))])]) 19593 19594;; imul $8/16bit_imm, regmem, reg is vector decoded. 19595;; Convert it into imul reg, reg 19596;; It would be better to force assembler to encode instruction using long 19597;; immediate, but there is apparently no way to do so. 19598(define_peephole2 19599 [(parallel [(set (match_operand:SWI248 0 "register_operand") 19600 (mult:SWI248 19601 (match_operand:SWI248 1 "nonimmediate_operand") 19602 (match_operand:SWI248 2 "const_int_operand"))) 19603 (clobber (reg:CC FLAGS_REG))]) 19604 (match_scratch:SWI248 3 "r")] 19605 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () 19606 && satisfies_constraint_K (operands[2])" 19607 [(set (match_dup 3) (match_dup 2)) 19608 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3))) 19609 (clobber (reg:CC FLAGS_REG))])] 19610{ 19611 if (!rtx_equal_p (operands[0], operands[1])) 19612 emit_move_insn (operands[0], operands[1]); 19613}) 19614 19615;; After splitting up read-modify operations, array accesses with memory 19616;; operands might end up in form: 19617;; sall $2, %eax 19618;; movl 4(%esp), %edx 19619;; addl %edx, %eax 19620;; instead of pre-splitting: 19621;; sall $2, %eax 19622;; addl 4(%esp), %eax 19623;; Turn it into: 19624;; movl 4(%esp), %edx 19625;; leal (%edx,%eax,4), %eax 19626 19627(define_peephole2 19628 [(match_scratch:W 5 "r") 19629 (parallel [(set (match_operand 0 "register_operand") 19630 (ashift (match_operand 1 "register_operand") 19631 (match_operand 2 "const_int_operand"))) 19632 (clobber (reg:CC FLAGS_REG))]) 19633 (parallel [(set (match_operand 3 "register_operand") 19634 (plus (match_dup 0) 19635 (match_operand 4 "x86_64_general_operand"))) 19636 (clobber (reg:CC FLAGS_REG))])] 19637 "IN_RANGE (INTVAL (operands[2]), 1, 3) 19638 /* Validate MODE for lea. */ 19639 && ((!TARGET_PARTIAL_REG_STALL 19640 && (GET_MODE (operands[0]) == QImode 19641 || GET_MODE (operands[0]) == HImode)) 19642 || GET_MODE (operands[0]) == SImode 19643 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 19644 && (rtx_equal_p (operands[0], operands[3]) 19645 || peep2_reg_dead_p (2, operands[0])) 19646 /* We reorder load and the shift. */ 19647 && !reg_overlap_mentioned_p (operands[0], operands[4])" 19648 [(set (match_dup 5) (match_dup 4)) 19649 (set (match_dup 0) (match_dup 1))] 19650{ 19651 machine_mode op1mode = GET_MODE (operands[1]); 19652 machine_mode mode = op1mode == DImode ? DImode : SImode; 19653 int scale = 1 << INTVAL (operands[2]); 19654 rtx index = gen_lowpart (word_mode, operands[1]); 19655 rtx base = gen_lowpart (word_mode, operands[5]); 19656 rtx dest = gen_lowpart (mode, operands[3]); 19657 19658 operands[1] = gen_rtx_PLUS (word_mode, base, 19659 gen_rtx_MULT (word_mode, index, GEN_INT (scale))); 19660 if (mode != word_mode) 19661 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 19662 19663 operands[5] = base; 19664 if (op1mode != word_mode) 19665 operands[5] = gen_lowpart (op1mode, operands[5]); 19666 19667 operands[0] = dest; 19668}) 19669 19670;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 19671;; That, however, is usually mapped by the OS to SIGSEGV, which is often 19672;; caught for use by garbage collectors and the like. Using an insn that 19673;; maps to SIGILL makes it more likely the program will rightfully die. 19674;; Keeping with tradition, "6" is in honor of #UD. 19675(define_insn "trap" 19676 [(trap_if (const_int 1) (const_int 6))] 19677 "" 19678{ 19679#ifdef HAVE_AS_IX86_UD2 19680 return "ud2"; 19681#else 19682 return ASM_SHORT "0x0b0f"; 19683#endif 19684} 19685 [(set_attr "length" "2")]) 19686 19687(define_insn "ud2" 19688 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)] 19689 "" 19690{ 19691#ifdef HAVE_AS_IX86_UD2 19692 return "ud2"; 19693#else 19694 return ASM_SHORT "0x0b0f"; 19695#endif 19696} 19697 [(set_attr "length" "2")]) 19698 19699(define_expand "prefetch" 19700 [(prefetch (match_operand 0 "address_operand") 19701 (match_operand:SI 1 "const_int_operand") 19702 (match_operand:SI 2 "const_int_operand"))] 19703 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1" 19704{ 19705 bool write = INTVAL (operands[1]) != 0; 19706 int locality = INTVAL (operands[2]); 19707 19708 gcc_assert (IN_RANGE (locality, 0, 3)); 19709 19710 /* Use 3dNOW prefetch in case we are asking for write prefetch not 19711 supported by SSE counterpart (non-SSE2 athlon machines) or the 19712 SSE prefetch is not available (K6 machines). Otherwise use SSE 19713 prefetch as it allows specifying of locality. */ 19714 19715 if (write) 19716 { 19717 if (TARGET_PREFETCHWT1) 19718 operands[2] = GEN_INT (MAX (locality, 2)); 19719 else if (TARGET_PRFCHW) 19720 operands[2] = GEN_INT (3); 19721 else if (TARGET_3DNOW && !TARGET_SSE2) 19722 operands[2] = GEN_INT (3); 19723 else if (TARGET_PREFETCH_SSE) 19724 operands[1] = const0_rtx; 19725 else 19726 { 19727 gcc_assert (TARGET_3DNOW); 19728 operands[2] = GEN_INT (3); 19729 } 19730 } 19731 else 19732 { 19733 if (TARGET_PREFETCH_SSE) 19734 ; 19735 else 19736 { 19737 gcc_assert (TARGET_3DNOW); 19738 operands[2] = GEN_INT (3); 19739 } 19740 } 19741}) 19742 19743(define_insn "*prefetch_sse" 19744 [(prefetch (match_operand 0 "address_operand" "p") 19745 (const_int 0) 19746 (match_operand:SI 1 "const_int_operand"))] 19747 "TARGET_PREFETCH_SSE" 19748{ 19749 static const char * const patterns[4] = { 19750 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 19751 }; 19752 19753 int locality = INTVAL (operands[1]); 19754 gcc_assert (IN_RANGE (locality, 0, 3)); 19755 19756 return patterns[locality]; 19757} 19758 [(set_attr "type" "sse") 19759 (set_attr "atom_sse_attr" "prefetch") 19760 (set (attr "length_address") 19761 (symbol_ref "memory_address_length (operands[0], false)")) 19762 (set_attr "memory" "none")]) 19763 19764(define_insn "*prefetch_3dnow" 19765 [(prefetch (match_operand 0 "address_operand" "p") 19766 (match_operand:SI 1 "const_int_operand" "n") 19767 (const_int 3))] 19768 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1" 19769{ 19770 if (INTVAL (operands[1]) == 0) 19771 return "prefetch\t%a0"; 19772 else 19773 return "prefetchw\t%a0"; 19774} 19775 [(set_attr "type" "mmx") 19776 (set (attr "length_address") 19777 (symbol_ref "memory_address_length (operands[0], false)")) 19778 (set_attr "memory" "none")]) 19779 19780(define_insn "*prefetch_prefetchwt1" 19781 [(prefetch (match_operand 0 "address_operand" "p") 19782 (const_int 1) 19783 (const_int 2))] 19784 "TARGET_PREFETCHWT1" 19785 "prefetchwt1\t%a0"; 19786 [(set_attr "type" "sse") 19787 (set (attr "length_address") 19788 (symbol_ref "memory_address_length (operands[0], false)")) 19789 (set_attr "memory" "none")]) 19790 19791(define_expand "stack_protect_set" 19792 [(match_operand 0 "memory_operand") 19793 (match_operand 1 "memory_operand")] 19794 "" 19795{ 19796 rtx (*insn)(rtx, rtx); 19797 19798 insn = (TARGET_LP64 19799 ? gen_stack_protect_set_di 19800 : gen_stack_protect_set_si); 19801 19802 emit_insn (insn (operands[0], operands[1])); 19803 DONE; 19804}) 19805 19806(define_insn "stack_protect_set_<mode>" 19807 [(set (match_operand:PTR 0 "memory_operand" "=m") 19808 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] 19809 UNSPEC_SP_SET)) 19810 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 19811 (clobber (reg:CC FLAGS_REG))] 19812 "" 19813 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 19814 [(set_attr "type" "multi")]) 19815 19816(define_expand "stack_protect_test" 19817 [(match_operand 0 "memory_operand") 19818 (match_operand 1 "memory_operand") 19819 (match_operand 2)] 19820 "" 19821{ 19822 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 19823 19824 rtx (*insn)(rtx, rtx, rtx); 19825 19826 insn = (TARGET_LP64 19827 ? gen_stack_protect_test_di 19828 : gen_stack_protect_test_si); 19829 19830 emit_insn (insn (flags, operands[0], operands[1])); 19831 19832 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx), 19833 flags, const0_rtx, operands[2])); 19834 DONE; 19835}) 19836 19837(define_insn "stack_protect_test_<mode>" 19838 [(set (match_operand:CCZ 0 "flags_reg_operand") 19839 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 19840 (match_operand:PTR 2 "memory_operand" "m")] 19841 UNSPEC_SP_TEST)) 19842 (clobber (match_scratch:PTR 3 "=&r"))] 19843 "" 19844 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}" 19845 [(set_attr "type" "multi")]) 19846 19847(define_insn "sse4_2_crc32<mode>" 19848 [(set (match_operand:SI 0 "register_operand" "=r") 19849 (unspec:SI 19850 [(match_operand:SI 1 "register_operand" "0") 19851 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")] 19852 UNSPEC_CRC32))] 19853 "TARGET_SSE4_2 || TARGET_CRC32" 19854 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}" 19855 [(set_attr "type" "sselog1") 19856 (set_attr "prefix_rep" "1") 19857 (set_attr "prefix_extra" "1") 19858 (set (attr "prefix_data16") 19859 (if_then_else (match_operand:HI 2) 19860 (const_string "1") 19861 (const_string "*"))) 19862 (set (attr "prefix_rex") 19863 (if_then_else (match_operand:QI 2 "ext_QIreg_operand") 19864 (const_string "1") 19865 (const_string "*"))) 19866 (set_attr "mode" "SI")]) 19867 19868(define_insn "sse4_2_crc32di" 19869 [(set (match_operand:DI 0 "register_operand" "=r") 19870 (unspec:DI 19871 [(match_operand:DI 1 "register_operand" "0") 19872 (match_operand:DI 2 "nonimmediate_operand" "rm")] 19873 UNSPEC_CRC32))] 19874 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)" 19875 "crc32{q}\t{%2, %0|%0, %2}" 19876 [(set_attr "type" "sselog1") 19877 (set_attr "prefix_rep" "1") 19878 (set_attr "prefix_extra" "1") 19879 (set_attr "mode" "DI")]) 19880 19881(define_insn "rdpmc" 19882 [(set (match_operand:DI 0 "register_operand" "=A") 19883 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 19884 UNSPECV_RDPMC))] 19885 "!TARGET_64BIT" 19886 "rdpmc" 19887 [(set_attr "type" "other") 19888 (set_attr "length" "2")]) 19889 19890(define_insn "rdpmc_rex64" 19891 [(set (match_operand:DI 0 "register_operand" "=a") 19892 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 19893 UNSPECV_RDPMC)) 19894 (set (match_operand:DI 1 "register_operand" "=d") 19895 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))] 19896 "TARGET_64BIT" 19897 "rdpmc" 19898 [(set_attr "type" "other") 19899 (set_attr "length" "2")]) 19900 19901(define_insn "rdtsc" 19902 [(set (match_operand:DI 0 "register_operand" "=A") 19903 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 19904 "!TARGET_64BIT" 19905 "rdtsc" 19906 [(set_attr "type" "other") 19907 (set_attr "length" "2")]) 19908 19909(define_insn "rdtsc_rex64" 19910 [(set (match_operand:DI 0 "register_operand" "=a") 19911 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC)) 19912 (set (match_operand:DI 1 "register_operand" "=d") 19913 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 19914 "TARGET_64BIT" 19915 "rdtsc" 19916 [(set_attr "type" "other") 19917 (set_attr "length" "2")]) 19918 19919(define_insn "rdtscp" 19920 [(set (match_operand:DI 0 "register_operand" "=A") 19921 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19922 (set (match_operand:SI 1 "register_operand" "=c") 19923 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 19924 "!TARGET_64BIT" 19925 "rdtscp" 19926 [(set_attr "type" "other") 19927 (set_attr "length" "3")]) 19928 19929(define_insn "rdtscp_rex64" 19930 [(set (match_operand:DI 0 "register_operand" "=a") 19931 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19932 (set (match_operand:DI 1 "register_operand" "=d") 19933 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19934 (set (match_operand:SI 2 "register_operand" "=c") 19935 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 19936 "TARGET_64BIT" 19937 "rdtscp" 19938 [(set_attr "type" "other") 19939 (set_attr "length" "3")]) 19940 19941;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19942;; 19943;; FXSR, XSAVE and XSAVEOPT instructions 19944;; 19945;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19946 19947(define_insn "fxsave" 19948 [(set (match_operand:BLK 0 "memory_operand" "=m") 19949 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))] 19950 "TARGET_FXSR" 19951 "fxsave\t%0" 19952 [(set_attr "type" "other") 19953 (set_attr "memory" "store") 19954 (set (attr "length") 19955 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19956 19957(define_insn "fxsave64" 19958 [(set (match_operand:BLK 0 "memory_operand" "=m") 19959 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))] 19960 "TARGET_64BIT && TARGET_FXSR" 19961 "fxsave64\t%0" 19962 [(set_attr "type" "other") 19963 (set_attr "memory" "store") 19964 (set (attr "length") 19965 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 19966 19967(define_insn "fxrstor" 19968 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 19969 UNSPECV_FXRSTOR)] 19970 "TARGET_FXSR" 19971 "fxrstor\t%0" 19972 [(set_attr "type" "other") 19973 (set_attr "memory" "load") 19974 (set (attr "length") 19975 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19976 19977(define_insn "fxrstor64" 19978 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 19979 UNSPECV_FXRSTOR64)] 19980 "TARGET_64BIT && TARGET_FXSR" 19981 "fxrstor64\t%0" 19982 [(set_attr "type" "other") 19983 (set_attr "memory" "load") 19984 (set (attr "length") 19985 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 19986 19987(define_int_iterator ANY_XSAVE 19988 [UNSPECV_XSAVE 19989 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT") 19990 (UNSPECV_XSAVEC "TARGET_XSAVEC") 19991 (UNSPECV_XSAVES "TARGET_XSAVES")]) 19992 19993(define_int_iterator ANY_XSAVE64 19994 [UNSPECV_XSAVE64 19995 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT") 19996 (UNSPECV_XSAVEC64 "TARGET_XSAVEC") 19997 (UNSPECV_XSAVES64 "TARGET_XSAVES")]) 19998 19999(define_int_attr xsave 20000 [(UNSPECV_XSAVE "xsave") 20001 (UNSPECV_XSAVE64 "xsave64") 20002 (UNSPECV_XSAVEOPT "xsaveopt") 20003 (UNSPECV_XSAVEOPT64 "xsaveopt64") 20004 (UNSPECV_XSAVEC "xsavec") 20005 (UNSPECV_XSAVEC64 "xsavec64") 20006 (UNSPECV_XSAVES "xsaves") 20007 (UNSPECV_XSAVES64 "xsaves64")]) 20008 20009(define_int_iterator ANY_XRSTOR 20010 [UNSPECV_XRSTOR 20011 (UNSPECV_XRSTORS "TARGET_XSAVES")]) 20012 20013(define_int_iterator ANY_XRSTOR64 20014 [UNSPECV_XRSTOR64 20015 (UNSPECV_XRSTORS64 "TARGET_XSAVES")]) 20016 20017(define_int_attr xrstor 20018 [(UNSPECV_XRSTOR "xrstor") 20019 (UNSPECV_XRSTOR64 "xrstor") 20020 (UNSPECV_XRSTORS "xrstors") 20021 (UNSPECV_XRSTORS64 "xrstors")]) 20022 20023(define_insn "<xsave>" 20024 [(set (match_operand:BLK 0 "memory_operand" "=m") 20025 (unspec_volatile:BLK 20026 [(match_operand:DI 1 "register_operand" "A")] 20027 ANY_XSAVE))] 20028 "!TARGET_64BIT && TARGET_XSAVE" 20029 "<xsave>\t%0" 20030 [(set_attr "type" "other") 20031 (set_attr "memory" "store") 20032 (set (attr "length") 20033 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20034 20035(define_insn "<xsave>_rex64" 20036 [(set (match_operand:BLK 0 "memory_operand" "=m") 20037 (unspec_volatile:BLK 20038 [(match_operand:SI 1 "register_operand" "a") 20039 (match_operand:SI 2 "register_operand" "d")] 20040 ANY_XSAVE))] 20041 "TARGET_64BIT && TARGET_XSAVE" 20042 "<xsave>\t%0" 20043 [(set_attr "type" "other") 20044 (set_attr "memory" "store") 20045 (set (attr "length") 20046 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20047 20048(define_insn "<xsave>" 20049 [(set (match_operand:BLK 0 "memory_operand" "=m") 20050 (unspec_volatile:BLK 20051 [(match_operand:SI 1 "register_operand" "a") 20052 (match_operand:SI 2 "register_operand" "d")] 20053 ANY_XSAVE64))] 20054 "TARGET_64BIT && TARGET_XSAVE" 20055 "<xsave>\t%0" 20056 [(set_attr "type" "other") 20057 (set_attr "memory" "store") 20058 (set (attr "length") 20059 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20060 20061(define_insn "<xrstor>" 20062 [(unspec_volatile:BLK 20063 [(match_operand:BLK 0 "memory_operand" "m") 20064 (match_operand:DI 1 "register_operand" "A")] 20065 ANY_XRSTOR)] 20066 "!TARGET_64BIT && TARGET_XSAVE" 20067 "<xrstor>\t%0" 20068 [(set_attr "type" "other") 20069 (set_attr "memory" "load") 20070 (set (attr "length") 20071 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20072 20073(define_insn "<xrstor>_rex64" 20074 [(unspec_volatile:BLK 20075 [(match_operand:BLK 0 "memory_operand" "m") 20076 (match_operand:SI 1 "register_operand" "a") 20077 (match_operand:SI 2 "register_operand" "d")] 20078 ANY_XRSTOR)] 20079 "TARGET_64BIT && TARGET_XSAVE" 20080 "<xrstor>\t%0" 20081 [(set_attr "type" "other") 20082 (set_attr "memory" "load") 20083 (set (attr "length") 20084 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20085 20086(define_insn "<xrstor>64" 20087 [(unspec_volatile:BLK 20088 [(match_operand:BLK 0 "memory_operand" "m") 20089 (match_operand:SI 1 "register_operand" "a") 20090 (match_operand:SI 2 "register_operand" "d")] 20091 ANY_XRSTOR64)] 20092 "TARGET_64BIT && TARGET_XSAVE" 20093 "<xrstor>64\t%0" 20094 [(set_attr "type" "other") 20095 (set_attr "memory" "load") 20096 (set (attr "length") 20097 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20098 20099(define_insn "xsetbv" 20100 [(unspec_volatile:SI 20101 [(match_operand:SI 0 "register_operand" "c") 20102 (match_operand:DI 1 "register_operand" "A")] 20103 UNSPECV_XSETBV)] 20104 "!TARGET_64BIT && TARGET_XSAVE" 20105 "xsetbv" 20106 [(set_attr "type" "other")]) 20107 20108(define_insn "xsetbv_rex64" 20109 [(unspec_volatile:SI 20110 [(match_operand:SI 0 "register_operand" "c") 20111 (match_operand:SI 1 "register_operand" "a") 20112 (match_operand:SI 2 "register_operand" "d")] 20113 UNSPECV_XSETBV)] 20114 "TARGET_64BIT && TARGET_XSAVE" 20115 "xsetbv" 20116 [(set_attr "type" "other")]) 20117 20118(define_insn "xgetbv" 20119 [(set (match_operand:DI 0 "register_operand" "=A") 20120 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 20121 UNSPECV_XGETBV))] 20122 "!TARGET_64BIT && TARGET_XSAVE" 20123 "xgetbv" 20124 [(set_attr "type" "other")]) 20125 20126(define_insn "xgetbv_rex64" 20127 [(set (match_operand:DI 0 "register_operand" "=a") 20128 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 20129 UNSPECV_XGETBV)) 20130 (set (match_operand:DI 1 "register_operand" "=d") 20131 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))] 20132 "TARGET_64BIT && TARGET_XSAVE" 20133 "xgetbv" 20134 [(set_attr "type" "other")]) 20135 20136;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20137;; 20138;; Floating-point instructions for atomic compound assignments 20139;; 20140;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20141 20142; Clobber all floating-point registers on environment save and restore 20143; to ensure that the TOS value saved at fnstenv is valid after fldenv. 20144(define_insn "fnstenv" 20145 [(set (match_operand:BLK 0 "memory_operand" "=m") 20146 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV)) 20147 (clobber (reg:HI FPCR_REG)) 20148 (clobber (reg:XF ST0_REG)) 20149 (clobber (reg:XF ST1_REG)) 20150 (clobber (reg:XF ST2_REG)) 20151 (clobber (reg:XF ST3_REG)) 20152 (clobber (reg:XF ST4_REG)) 20153 (clobber (reg:XF ST5_REG)) 20154 (clobber (reg:XF ST6_REG)) 20155 (clobber (reg:XF ST7_REG))] 20156 "TARGET_80387" 20157 "fnstenv\t%0" 20158 [(set_attr "type" "other") 20159 (set_attr "memory" "store") 20160 (set (attr "length") 20161 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20162 20163(define_insn "fldenv" 20164 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 20165 UNSPECV_FLDENV) 20166 (clobber (reg:CCFP FPSR_REG)) 20167 (clobber (reg:HI FPCR_REG)) 20168 (clobber (reg:XF ST0_REG)) 20169 (clobber (reg:XF ST1_REG)) 20170 (clobber (reg:XF ST2_REG)) 20171 (clobber (reg:XF ST3_REG)) 20172 (clobber (reg:XF ST4_REG)) 20173 (clobber (reg:XF ST5_REG)) 20174 (clobber (reg:XF ST6_REG)) 20175 (clobber (reg:XF ST7_REG))] 20176 "TARGET_80387" 20177 "fldenv\t%0" 20178 [(set_attr "type" "other") 20179 (set_attr "memory" "load") 20180 (set (attr "length") 20181 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20182 20183(define_insn "fnstsw" 20184 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m") 20185 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))] 20186 "TARGET_80387" 20187 "fnstsw\t%0" 20188 [(set_attr "type" "other,other") 20189 (set_attr "memory" "none,store") 20190 (set (attr "length") 20191 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20192 20193(define_insn "fnclex" 20194 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)] 20195 "TARGET_80387" 20196 "fnclex" 20197 [(set_attr "type" "other") 20198 (set_attr "memory" "none") 20199 (set_attr "length" "2")]) 20200 20201;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20202;; 20203;; LWP instructions 20204;; 20205;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20206 20207(define_expand "lwp_llwpcb" 20208 [(unspec_volatile [(match_operand 0 "register_operand")] 20209 UNSPECV_LLWP_INTRINSIC)] 20210 "TARGET_LWP") 20211 20212(define_insn "*lwp_llwpcb<mode>1" 20213 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 20214 UNSPECV_LLWP_INTRINSIC)] 20215 "TARGET_LWP" 20216 "llwpcb\t%0" 20217 [(set_attr "type" "lwp") 20218 (set_attr "mode" "<MODE>") 20219 (set_attr "length" "5")]) 20220 20221(define_expand "lwp_slwpcb" 20222 [(set (match_operand 0 "register_operand") 20223 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 20224 "TARGET_LWP" 20225{ 20226 rtx (*insn)(rtx); 20227 20228 insn = (Pmode == DImode 20229 ? gen_lwp_slwpcbdi 20230 : gen_lwp_slwpcbsi); 20231 20232 emit_insn (insn (operands[0])); 20233 DONE; 20234}) 20235 20236(define_insn "lwp_slwpcb<mode>" 20237 [(set (match_operand:P 0 "register_operand" "=r") 20238 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 20239 "TARGET_LWP" 20240 "slwpcb\t%0" 20241 [(set_attr "type" "lwp") 20242 (set_attr "mode" "<MODE>") 20243 (set_attr "length" "5")]) 20244 20245(define_expand "lwp_lwpval<mode>3" 20246 [(unspec_volatile [(match_operand:SWI48 1 "register_operand") 20247 (match_operand:SI 2 "nonimmediate_operand") 20248 (match_operand:SI 3 "const_int_operand")] 20249 UNSPECV_LWPVAL_INTRINSIC)] 20250 "TARGET_LWP" 20251 ;; Avoid unused variable warning. 20252 "(void) operands[0];") 20253 20254(define_insn "*lwp_lwpval<mode>3_1" 20255 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") 20256 (match_operand:SI 1 "nonimmediate_operand" "rm") 20257 (match_operand:SI 2 "const_int_operand" "i")] 20258 UNSPECV_LWPVAL_INTRINSIC)] 20259 "TARGET_LWP" 20260 "lwpval\t{%2, %1, %0|%0, %1, %2}" 20261 [(set_attr "type" "lwp") 20262 (set_attr "mode" "<MODE>") 20263 (set (attr "length") 20264 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 20265 20266(define_expand "lwp_lwpins<mode>3" 20267 [(set (reg:CCC FLAGS_REG) 20268 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand") 20269 (match_operand:SI 2 "nonimmediate_operand") 20270 (match_operand:SI 3 "const_int_operand")] 20271 UNSPECV_LWPINS_INTRINSIC)) 20272 (set (match_operand:QI 0 "nonimmediate_operand") 20273 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] 20274 "TARGET_LWP") 20275 20276(define_insn "*lwp_lwpins<mode>3_1" 20277 [(set (reg:CCC FLAGS_REG) 20278 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r") 20279 (match_operand:SI 1 "nonimmediate_operand" "rm") 20280 (match_operand:SI 2 "const_int_operand" "i")] 20281 UNSPECV_LWPINS_INTRINSIC))] 20282 "TARGET_LWP" 20283 "lwpins\t{%2, %1, %0|%0, %1, %2}" 20284 [(set_attr "type" "lwp") 20285 (set_attr "mode" "<MODE>") 20286 (set (attr "length") 20287 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 20288 20289(define_int_iterator RDFSGSBASE 20290 [UNSPECV_RDFSBASE 20291 UNSPECV_RDGSBASE]) 20292 20293(define_int_iterator WRFSGSBASE 20294 [UNSPECV_WRFSBASE 20295 UNSPECV_WRGSBASE]) 20296 20297(define_int_attr fsgs 20298 [(UNSPECV_RDFSBASE "fs") 20299 (UNSPECV_RDGSBASE "gs") 20300 (UNSPECV_WRFSBASE "fs") 20301 (UNSPECV_WRGSBASE "gs")]) 20302 20303(define_insn "rd<fsgs>base<mode>" 20304 [(set (match_operand:SWI48 0 "register_operand" "=r") 20305 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))] 20306 "TARGET_64BIT && TARGET_FSGSBASE" 20307 "rd<fsgs>base\t%0" 20308 [(set_attr "type" "other") 20309 (set_attr "prefix_extra" "2")]) 20310 20311(define_insn "wr<fsgs>base<mode>" 20312 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 20313 WRFSGSBASE)] 20314 "TARGET_64BIT && TARGET_FSGSBASE" 20315 "wr<fsgs>base\t%0" 20316 [(set_attr "type" "other") 20317 (set_attr "prefix_extra" "2")]) 20318 20319(define_insn "rdrand<mode>_1" 20320 [(set (match_operand:SWI248 0 "register_operand" "=r") 20321 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND)) 20322 (set (reg:CCC FLAGS_REG) 20323 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))] 20324 "TARGET_RDRND" 20325 "rdrand\t%0" 20326 [(set_attr "type" "other") 20327 (set_attr "prefix_extra" "1")]) 20328 20329(define_insn "rdseed<mode>_1" 20330 [(set (match_operand:SWI248 0 "register_operand" "=r") 20331 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED)) 20332 (set (reg:CCC FLAGS_REG) 20333 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))] 20334 "TARGET_RDSEED" 20335 "rdseed\t%0" 20336 [(set_attr "type" "other") 20337 (set_attr "prefix_extra" "1")]) 20338 20339(define_expand "pause" 20340 [(set (match_dup 0) 20341 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 20342 "" 20343{ 20344 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 20345 MEM_VOLATILE_P (operands[0]) = 1; 20346}) 20347 20348;; Use "rep; nop", instead of "pause", to support older assemblers. 20349;; They have the same encoding. 20350(define_insn "*pause" 20351 [(set (match_operand:BLK 0) 20352 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 20353 "" 20354 "rep%; nop" 20355 [(set_attr "length" "2") 20356 (set_attr "memory" "unknown")]) 20357 20358;; CET instructions 20359(define_insn "rdssp<mode>" 20360 [(set (match_operand:SWI48x 0 "register_operand" "=r") 20361 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))] 20362 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" 20363 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0" 20364 [(set_attr "length" "6") 20365 (set_attr "type" "other")]) 20366 20367(define_insn "incssp<mode>" 20368 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")] 20369 UNSPECV_INCSSP)] 20370 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" 20371 "incssp<mskmodesuffix>\t%0" 20372 [(set_attr "length" "4") 20373 (set_attr "type" "other")]) 20374 20375(define_insn "saveprevssp" 20376 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)] 20377 "TARGET_SHSTK" 20378 "saveprevssp" 20379 [(set_attr "length" "5") 20380 (set_attr "type" "other")]) 20381 20382(define_insn "rstorssp" 20383 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 20384 UNSPECV_RSTORSSP)] 20385 "TARGET_SHSTK" 20386 "rstorssp\t%0" 20387 [(set_attr "length" "5") 20388 (set_attr "type" "other")]) 20389 20390(define_insn "wrss<mode>" 20391 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") 20392 (match_operand:SWI48x 1 "memory_operand" "m")] 20393 UNSPECV_WRSS)] 20394 "TARGET_SHSTK" 20395 "wrss<mskmodesuffix>\t%0, %1" 20396 [(set_attr "length" "3") 20397 (set_attr "type" "other")]) 20398 20399(define_insn "wruss<mode>" 20400 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") 20401 (match_operand:SWI48x 1 "memory_operand" "m")] 20402 UNSPECV_WRUSS)] 20403 "TARGET_SHSTK" 20404 "wruss<mskmodesuffix>\t%0, %1" 20405 [(set_attr "length" "4") 20406 (set_attr "type" "other")]) 20407 20408(define_insn "setssbsy" 20409 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)] 20410 "TARGET_SHSTK" 20411 "setssbsy" 20412 [(set_attr "length" "4") 20413 (set_attr "type" "other")]) 20414 20415(define_insn "clrssbsy" 20416 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 20417 UNSPECV_CLRSSBSY)] 20418 "TARGET_SHSTK" 20419 "clrssbsy\t%0" 20420 [(set_attr "length" "4") 20421 (set_attr "type" "other")]) 20422 20423(define_insn "nop_endbr" 20424 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)] 20425 "(flag_cf_protection & CF_BRANCH)" 20426 "* 20427{ return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }" 20428 [(set_attr "length" "4") 20429 (set_attr "length_immediate" "0") 20430 (set_attr "modrm" "0")]) 20431 20432;; For RTM support 20433(define_expand "xbegin" 20434 [(set (match_operand:SI 0 "register_operand") 20435 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))] 20436 "TARGET_RTM" 20437{ 20438 rtx_code_label *label = gen_label_rtx (); 20439 20440 /* xbegin is emitted as jump_insn, so reload won't be able 20441 to reload its operand. Force the value into AX hard register. */ 20442 rtx ax_reg = gen_rtx_REG (SImode, AX_REG); 20443 emit_move_insn (ax_reg, constm1_rtx); 20444 20445 emit_jump_insn (gen_xbegin_1 (ax_reg, label)); 20446 20447 emit_label (label); 20448 LABEL_NUSES (label) = 1; 20449 20450 emit_move_insn (operands[0], ax_reg); 20451 20452 DONE; 20453}) 20454 20455(define_insn "xbegin_1" 20456 [(set (pc) 20457 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT) 20458 (const_int 0)) 20459 (label_ref (match_operand 1)) 20460 (pc))) 20461 (set (match_operand:SI 0 "register_operand" "+a") 20462 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))] 20463 "TARGET_RTM" 20464 "xbegin\t%l1" 20465 [(set_attr "type" "other") 20466 (set_attr "length" "6")]) 20467 20468(define_insn "xend" 20469 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)] 20470 "TARGET_RTM" 20471 "xend" 20472 [(set_attr "type" "other") 20473 (set_attr "length" "3")]) 20474 20475(define_insn "xabort" 20476 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")] 20477 UNSPECV_XABORT)] 20478 "TARGET_RTM" 20479 "xabort\t%0" 20480 [(set_attr "type" "other") 20481 (set_attr "length" "3")]) 20482 20483(define_expand "xtest" 20484 [(set (match_operand:QI 0 "register_operand") 20485 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))] 20486 "TARGET_RTM" 20487{ 20488 emit_insn (gen_xtest_1 ()); 20489 20490 ix86_expand_setcc (operands[0], NE, 20491 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 20492 DONE; 20493}) 20494 20495(define_insn "xtest_1" 20496 [(set (reg:CCZ FLAGS_REG) 20497 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))] 20498 "TARGET_RTM" 20499 "xtest" 20500 [(set_attr "type" "other") 20501 (set_attr "length" "3")]) 20502 20503(define_insn "clwb" 20504 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 20505 UNSPECV_CLWB)] 20506 "TARGET_CLWB" 20507 "clwb\t%a0" 20508 [(set_attr "type" "sse") 20509 (set_attr "atom_sse_attr" "fence") 20510 (set_attr "memory" "unknown")]) 20511 20512(define_insn "clflushopt" 20513 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 20514 UNSPECV_CLFLUSHOPT)] 20515 "TARGET_CLFLUSHOPT" 20516 "clflushopt\t%a0" 20517 [(set_attr "type" "sse") 20518 (set_attr "atom_sse_attr" "fence") 20519 (set_attr "memory" "unknown")]) 20520 20521;; MONITORX and MWAITX 20522(define_insn "mwaitx" 20523 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c") 20524 (match_operand:SI 1 "register_operand" "a") 20525 (match_operand:SI 2 "register_operand" "b")] 20526 UNSPECV_MWAITX)] 20527 "TARGET_MWAITX" 20528;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used. 20529;; Since 32bit register operands are implicitly zero extended to 64bit, 20530;; we only need to set up 32bit registers. 20531 "mwaitx" 20532 [(set_attr "length" "3")]) 20533 20534(define_insn "monitorx_<mode>" 20535 [(unspec_volatile [(match_operand:P 0 "register_operand" "a") 20536 (match_operand:SI 1 "register_operand" "c") 20537 (match_operand:SI 2 "register_operand" "d")] 20538 UNSPECV_MONITORX)] 20539 "TARGET_MWAITX" 20540;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in 20541;; RCX and RDX are used. Since 32bit register operands are implicitly 20542;; zero extended to 64bit, we only need to set up 32bit registers. 20543 "%^monitorx" 20544 [(set (attr "length") 20545 (symbol_ref ("(Pmode != word_mode) + 3")))]) 20546 20547;; CLZERO 20548(define_insn "clzero_<mode>" 20549 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")] 20550 UNSPECV_CLZERO)] 20551 "TARGET_CLZERO" 20552 "clzero" 20553 [(set_attr "length" "3") 20554 (set_attr "memory" "unknown")]) 20555 20556;; MPX instructions 20557 20558(define_expand "<mode>_mk" 20559 [(set (match_operand:BND 0 "register_operand") 20560 (unspec:BND 20561 [(mem:<bnd_ptr> 20562 (match_par_dup 3 20563 [(match_operand:<bnd_ptr> 1 "register_operand") 20564 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))] 20565 UNSPEC_BNDMK))] 20566 "TARGET_MPX" 20567{ 20568 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], 20569 operands[2]), 20570 UNSPEC_BNDMK_ADDR); 20571}) 20572 20573(define_insn "*<mode>_mk" 20574 [(set (match_operand:BND 0 "register_operand" "=w") 20575 (unspec:BND 20576 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20577 [(unspec:<bnd_ptr> 20578 [(match_operand:<bnd_ptr> 1 "register_operand" "r") 20579 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")] 20580 UNSPEC_BNDMK_ADDR)])] 20581 UNSPEC_BNDMK))] 20582 "TARGET_MPX" 20583 "bndmk\t{%3, %0|%0, %3}" 20584 [(set_attr "type" "mpxmk")]) 20585 20586(define_expand "mov<mode>" 20587 [(set (match_operand:BND 0 "general_operand") 20588 (match_operand:BND 1 "general_operand"))] 20589 "TARGET_MPX" 20590 "ix86_expand_move (<MODE>mode, operands); DONE;") 20591 20592(define_insn "*mov<mode>_internal_mpx" 20593 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m") 20594 (match_operand:BND 1 "general_operand" "wm,w"))] 20595 "TARGET_MPX" 20596 "bndmov\t{%1, %0|%0, %1}" 20597 [(set_attr "type" "mpxmov")]) 20598 20599(define_expand "<mode>_<bndcheck>" 20600 [(parallel 20601 [(unspec 20602 [(match_operand:BND 0 "register_operand") 20603 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK) 20604 (set (match_dup 2) 20605 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])] 20606 "TARGET_MPX" 20607{ 20608 operands[2] = gen_rtx_MEM (BLKmode, operands[1]); 20609 MEM_VOLATILE_P (operands[2]) = 1; 20610}) 20611 20612(define_insn "*<mode>_<bndcheck>" 20613 [(unspec 20614 [(match_operand:BND 0 "register_operand" "w") 20615 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK) 20616 (set (match_operand:BLK 2 "bnd_mem_operator") 20617 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))] 20618 "TARGET_MPX" 20619 "bnd<bndcheck>\t{%a1, %0|%0, %a1}" 20620 [(set_attr "type" "mpxchk")]) 20621 20622(define_expand "<mode>_ldx" 20623 [(parallel 20624 [(set (match_operand:BND 0 "register_operand") 20625 (unspec:BND 20626 [(mem:<bnd_ptr> 20627 (match_par_dup 3 20628 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand") 20629 (match_operand:<bnd_ptr> 2 "register_operand")]))] 20630 UNSPEC_BNDLDX)) 20631 (use (mem:BLK (match_dup 1)))])] 20632 "TARGET_MPX" 20633{ 20634 /* Avoid registers which cannot be used as index. */ 20635 if (!index_register_operand (operands[2], Pmode)) 20636 operands[2] = copy_addr_to_reg (operands[2]); 20637 20638 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], 20639 operands[2]), 20640 UNSPEC_BNDLDX_ADDR); 20641}) 20642 20643(define_insn "*<mode>_ldx" 20644 [(set (match_operand:BND 0 "register_operand" "=w") 20645 (unspec:BND 20646 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20647 [(unspec:<bnd_ptr> 20648 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti") 20649 (match_operand:<bnd_ptr> 2 "register_operand" "l")] 20650 UNSPEC_BNDLDX_ADDR)])] 20651 UNSPEC_BNDLDX)) 20652 (use (mem:BLK (match_dup 1)))] 20653 "TARGET_MPX" 20654 "bndldx\t{%3, %0|%0, %3}" 20655 [(set_attr "type" "mpxld")]) 20656 20657(define_expand "<mode>_stx" 20658 [(parallel 20659 [(unspec 20660 [(mem:<bnd_ptr> 20661 (match_par_dup 3 20662 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand") 20663 (match_operand:<bnd_ptr> 1 "register_operand")])) 20664 (match_operand:BND 2 "register_operand")] 20665 UNSPEC_BNDSTX) 20666 (set (match_dup 4) 20667 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])] 20668 "TARGET_MPX" 20669{ 20670 /* Avoid registers which cannot be used as index. */ 20671 if (!index_register_operand (operands[1], Pmode)) 20672 operands[1] = copy_addr_to_reg (operands[1]); 20673 20674 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0], 20675 operands[1]), 20676 UNSPEC_BNDLDX_ADDR); 20677 operands[4] = gen_rtx_MEM (BLKmode, operands[0]); 20678 MEM_VOLATILE_P (operands[4]) = 1; 20679}) 20680 20681(define_insn "*<mode>_stx" 20682 [(unspec 20683 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20684 [(unspec:<bnd_ptr> 20685 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti") 20686 (match_operand:<bnd_ptr> 1 "register_operand" "l")] 20687 UNSPEC_BNDLDX_ADDR)]) 20688 (match_operand:BND 2 "register_operand" "w")] 20689 UNSPEC_BNDSTX) 20690 (set (match_operand:BLK 4 "bnd_mem_operator") 20691 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))] 20692 "TARGET_MPX" 20693 "bndstx\t{%2, %3|%3, %2}" 20694 [(set_attr "type" "mpxst")]) 20695 20696(define_insn "move_size_reloc_<mode>" 20697 [(set (match_operand:SWI48 0 "register_operand" "=r") 20698 (unspec:SWI48 20699 [(match_operand:SWI48 1 "symbol_operand")] 20700 UNSPEC_SIZEOF))] 20701 "TARGET_MPX" 20702{ 20703 if (x86_64_immediate_size_operand (operands[1], VOIDmode)) 20704 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}"; 20705 else 20706 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}"; 20707} 20708 [(set_attr "type" "imov") 20709 (set_attr "mode" "<MODE>")]) 20710 20711;; RDPKRU and WRPKRU 20712 20713(define_expand "rdpkru" 20714 [(parallel 20715 [(set (match_operand:SI 0 "register_operand") 20716 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU)) 20717 (set (match_dup 2) (const_int 0))])] 20718 "TARGET_PKU" 20719{ 20720 operands[1] = force_reg (SImode, const0_rtx); 20721 operands[2] = gen_reg_rtx (SImode); 20722}) 20723 20724(define_insn "*rdpkru" 20725 [(set (match_operand:SI 0 "register_operand" "=a") 20726 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")] 20727 UNSPECV_PKU)) 20728 (set (match_operand:SI 1 "register_operand" "=d") 20729 (const_int 0))] 20730 "TARGET_PKU" 20731 "rdpkru" 20732 [(set_attr "type" "other")]) 20733 20734(define_expand "wrpkru" 20735 [(unspec_volatile:SI 20736 [(match_operand:SI 0 "register_operand") 20737 (match_dup 1) (match_dup 2)] UNSPECV_PKU)] 20738 "TARGET_PKU" 20739{ 20740 operands[1] = force_reg (SImode, const0_rtx); 20741 operands[2] = force_reg (SImode, const0_rtx); 20742}) 20743 20744(define_insn "*wrpkru" 20745 [(unspec_volatile:SI 20746 [(match_operand:SI 0 "register_operand" "a") 20747 (match_operand:SI 1 "register_operand" "d") 20748 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)] 20749 "TARGET_PKU" 20750 "wrpkru" 20751 [(set_attr "type" "other")]) 20752 20753(define_insn "rdpid" 20754 [(set (match_operand:SI 0 "register_operand" "=r") 20755 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))] 20756 "!TARGET_64BIT && TARGET_RDPID" 20757 "rdpid\t%0" 20758 [(set_attr "type" "other")]) 20759 20760(define_insn "rdpid_rex64" 20761 [(set (match_operand:DI 0 "register_operand" "=r") 20762 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))] 20763 "TARGET_64BIT && TARGET_RDPID" 20764 "rdpid\t%0" 20765 [(set_attr "type" "other")]) 20766 20767;; Intirinsics for > i486 20768 20769(define_insn "wbinvd" 20770 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)] 20771 "" 20772 "wbinvd" 20773 [(set_attr "type" "other")]) 20774 20775(define_insn "wbnoinvd" 20776 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)] 20777 "TARGET_WBNOINVD" 20778 "wbnoinvd" 20779 [(set_attr "type" "other")]) 20780 20781(define_insn "movdiri<mode>" 20782 [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m") 20783 (match_operand:SWI48 1 "register_operand" "r")] 20784 UNSPECV_MOVDIRI)] 20785 "TARGET_MOVDIRI" 20786 "movdiri\t{%1, %0|%0, %1}" 20787 [(set_attr "type" "other")]) 20788 20789(define_insn "movdir64b_<mode>" 20790 [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r") 20791 (match_operand:XI 1 "memory_operand")] 20792 UNSPECV_MOVDIR64B)] 20793 "TARGET_MOVDIR64B" 20794 "movdir64b\t{%1, %0|%0, %1}" 20795 [(set_attr "type" "other")]) 20796 20797(include "mmx.md") 20798(include "sse.md") 20799(include "sync.md") 20800