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 "operands[2] = gen_lowpart (SImode, operands[2]);") 8946 8947;; See comment for addsi_1_zext why we do use nonimmediate_operand 8948(define_insn "*andsi_1_zext" 8949 [(set (match_operand:DI 0 "register_operand" "=r") 8950 (zero_extend:DI 8951 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8952 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 8953 (clobber (reg:CC FLAGS_REG))] 8954 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 8955 "and{l}\t{%2, %k0|%k0, %2}" 8956 [(set_attr "type" "alu") 8957 (set_attr "mode" "SI")]) 8958 8959(define_insn "*and<mode>_1" 8960 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya") 8961 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm") 8962 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L"))) 8963 (clobber (reg:CC FLAGS_REG))] 8964 "ix86_binary_operator_ok (AND, <MODE>mode, operands)" 8965 "@ 8966 and{<imodesuffix>}\t{%2, %0|%0, %2} 8967 and{<imodesuffix>}\t{%2, %0|%0, %2} 8968 #" 8969 [(set_attr "type" "alu,alu,imovx") 8970 (set_attr "length_immediate" "*,*,0") 8971 (set (attr "prefix_rex") 8972 (if_then_else 8973 (and (eq_attr "type" "imovx") 8974 (and (match_test "INTVAL (operands[2]) == 0xff") 8975 (match_operand 1 "ext_QIreg_operand"))) 8976 (const_string "1") 8977 (const_string "*"))) 8978 (set_attr "mode" "<MODE>,<MODE>,SI")]) 8979 8980(define_insn "*andqi_1" 8981 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 8982 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8983 (match_operand:QI 2 "general_operand" "qn,qmn,rn"))) 8984 (clobber (reg:CC FLAGS_REG))] 8985 "ix86_binary_operator_ok (AND, QImode, operands)" 8986 "@ 8987 and{b}\t{%2, %0|%0, %2} 8988 and{b}\t{%2, %0|%0, %2} 8989 and{l}\t{%k2, %k0|%k0, %k2}" 8990 [(set_attr "type" "alu") 8991 (set_attr "mode" "QI,QI,SI") 8992 ;; Potential partial reg stall on alternative 2. 8993 (set (attr "preferred_for_speed") 8994 (cond [(eq_attr "alternative" "2") 8995 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 8996 (symbol_ref "true")))]) 8997 8998(define_insn "*andqi_1_slp" 8999 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 9000 (and:QI (match_dup 0) 9001 (match_operand:QI 1 "general_operand" "qn,qmn"))) 9002 (clobber (reg:CC FLAGS_REG))] 9003 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9004 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9005 "and{b}\t{%1, %0|%0, %1}" 9006 [(set_attr "type" "alu1") 9007 (set_attr "mode" "QI")]) 9008 9009(define_split 9010 [(set (match_operand:SWI248 0 "register_operand") 9011 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand") 9012 (match_operand:SWI248 2 "const_int_operand"))) 9013 (clobber (reg:CC FLAGS_REG))] 9014 "reload_completed 9015 && (!REG_P (operands[1]) 9016 || REGNO (operands[0]) != REGNO (operands[1]))" 9017 [(const_int 0)] 9018{ 9019 HOST_WIDE_INT ival = INTVAL (operands[2]); 9020 machine_mode mode; 9021 rtx (*insn) (rtx, rtx); 9022 9023 if (ival == (HOST_WIDE_INT) 0xffffffff) 9024 mode = SImode; 9025 else if (ival == 0xffff) 9026 mode = HImode; 9027 else 9028 { 9029 gcc_assert (ival == 0xff); 9030 mode = QImode; 9031 } 9032 9033 if (<MODE>mode == DImode) 9034 insn = (mode == SImode) 9035 ? gen_zero_extendsidi2 9036 : (mode == HImode) 9037 ? gen_zero_extendhidi2 9038 : gen_zero_extendqidi2; 9039 else 9040 { 9041 if (<MODE>mode != SImode) 9042 /* Zero extend to SImode to avoid partial register stalls. */ 9043 operands[0] = gen_lowpart (SImode, operands[0]); 9044 9045 insn = (mode == HImode) 9046 ? gen_zero_extendhisi2 9047 : gen_zero_extendqisi2; 9048 } 9049 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1]))); 9050 DONE; 9051}) 9052 9053(define_split 9054 [(set (match_operand:SWI48 0 "register_operand") 9055 (and:SWI48 (match_dup 0) 9056 (const_int -65536))) 9057 (clobber (reg:CC FLAGS_REG))] 9058 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL) 9059 || optimize_function_for_size_p (cfun)" 9060 [(set (strict_low_part (match_dup 1)) (const_int 0))] 9061 "operands[1] = gen_lowpart (HImode, operands[0]);") 9062 9063(define_split 9064 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9065 (and:SWI248 (match_dup 0) 9066 (const_int -256))) 9067 (clobber (reg:CC FLAGS_REG))] 9068 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9069 && reload_completed" 9070 [(set (strict_low_part (match_dup 1)) (const_int 0))] 9071 "operands[1] = gen_lowpart (QImode, operands[0]);") 9072 9073(define_split 9074 [(set (match_operand:SWI248 0 "QIreg_operand") 9075 (and:SWI248 (match_dup 0) 9076 (const_int -65281))) 9077 (clobber (reg:CC FLAGS_REG))] 9078 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9079 && reload_completed" 9080 [(parallel 9081 [(set (zero_extract:SI (match_dup 0) 9082 (const_int 8) 9083 (const_int 8)) 9084 (subreg:SI 9085 (xor:QI 9086 (subreg:QI 9087 (zero_extract:SI (match_dup 0) 9088 (const_int 8) 9089 (const_int 8)) 0) 9090 (subreg:QI 9091 (zero_extract:SI (match_dup 0) 9092 (const_int 8) 9093 (const_int 8)) 0)) 0)) 9094 (clobber (reg:CC FLAGS_REG))])] 9095 "operands[0] = gen_lowpart (SImode, operands[0]);") 9096 9097(define_insn "*anddi_2" 9098 [(set (reg FLAGS_REG) 9099 (compare 9100 (and:DI 9101 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 9102 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 9103 (const_int 0))) 9104 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 9105 (and:DI (match_dup 1) (match_dup 2)))] 9106 "TARGET_64BIT 9107 && ix86_match_ccmode 9108 (insn, 9109 /* If we are going to emit andl instead of andq, and the operands[2] 9110 constant might have the SImode sign bit set, make sure the sign 9111 flag isn't tested, because the instruction will set the sign flag 9112 based on bit 31 rather than bit 63. If it isn't CONST_INT, 9113 conservatively assume it might have bit 31 set. */ 9114 (satisfies_constraint_Z (operands[2]) 9115 && (!CONST_INT_P (operands[2]) 9116 || val_signbit_known_set_p (SImode, INTVAL (operands[2])))) 9117 ? CCZmode : CCNOmode) 9118 && ix86_binary_operator_ok (AND, DImode, operands)" 9119 "@ 9120 and{l}\t{%k2, %k0|%k0, %k2} 9121 and{q}\t{%2, %0|%0, %2} 9122 and{q}\t{%2, %0|%0, %2}" 9123 [(set_attr "type" "alu") 9124 (set_attr "mode" "SI,DI,DI")]) 9125 9126;; See comment for addsi_1_zext why we do use nonimmediate_operand 9127(define_insn "*andsi_2_zext" 9128 [(set (reg FLAGS_REG) 9129 (compare (and:SI 9130 (match_operand:SI 1 "nonimmediate_operand" "%0") 9131 (match_operand:SI 2 "x86_64_general_operand" "rme")) 9132 (const_int 0))) 9133 (set (match_operand:DI 0 "register_operand" "=r") 9134 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 9135 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9136 && ix86_binary_operator_ok (AND, SImode, operands)" 9137 "and{l}\t{%2, %k0|%k0, %2}" 9138 [(set_attr "type" "alu") 9139 (set_attr "mode" "SI")]) 9140 9141(define_insn "*andqi_2_maybe_si" 9142 [(set (reg FLAGS_REG) 9143 (compare (and:QI 9144 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9145 (match_operand:QI 2 "general_operand" "qmn,qn,n")) 9146 (const_int 0))) 9147 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 9148 (and:QI (match_dup 1) (match_dup 2)))] 9149 "ix86_binary_operator_ok (AND, QImode, operands) 9150 && ix86_match_ccmode (insn, 9151 CONST_INT_P (operands[2]) 9152 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 9153{ 9154 if (which_alternative == 2) 9155 { 9156 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 9157 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 9158 return "and{l}\t{%2, %k0|%k0, %2}"; 9159 } 9160 return "and{b}\t{%2, %0|%0, %2}"; 9161} 9162 [(set_attr "type" "alu") 9163 (set_attr "mode" "QI,QI,SI")]) 9164 9165(define_insn "*and<mode>_2" 9166 [(set (reg FLAGS_REG) 9167 (compare (and:SWI124 9168 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") 9169 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>")) 9170 (const_int 0))) 9171 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m") 9172 (and:SWI124 (match_dup 1) (match_dup 2)))] 9173 "ix86_match_ccmode (insn, CCNOmode) 9174 && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 9175 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 9176 [(set_attr "type" "alu") 9177 (set_attr "mode" "<MODE>")]) 9178 9179(define_insn "*andqi_2_slp" 9180 [(set (reg FLAGS_REG) 9181 (compare (and:QI 9182 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9183 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) 9184 (const_int 0))) 9185 (set (strict_low_part (match_dup 0)) 9186 (and:QI (match_dup 0) (match_dup 1)))] 9187 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9188 && ix86_match_ccmode (insn, CCNOmode) 9189 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9190 "and{b}\t{%1, %0|%0, %1}" 9191 [(set_attr "type" "alu1") 9192 (set_attr "mode" "QI")]) 9193 9194(define_insn "andqi_ext_1" 9195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9196 (const_int 8) 9197 (const_int 8)) 9198 (subreg:SI 9199 (and:QI 9200 (subreg:QI 9201 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9202 (const_int 8) 9203 (const_int 8)) 0) 9204 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 9205 (clobber (reg:CC FLAGS_REG))] 9206 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9207 rtx_equal_p (operands[0], operands[1])" 9208 "and{b}\t{%2, %h0|%h0, %2}" 9209 [(set_attr "isa" "*,nox64") 9210 (set_attr "type" "alu") 9211 (set_attr "mode" "QI")]) 9212 9213;; Generated by peephole translating test to and. This shows up 9214;; often in fp comparisons. 9215(define_insn "*andqi_ext_1_cc" 9216 [(set (reg FLAGS_REG) 9217 (compare 9218 (and:QI 9219 (subreg:QI 9220 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9221 (const_int 8) 9222 (const_int 8)) 0) 9223 (match_operand:QI 2 "general_operand" "QnBc,m")) 9224 (const_int 0))) 9225 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9226 (const_int 8) 9227 (const_int 8)) 9228 (subreg:SI 9229 (and:QI 9230 (subreg:QI 9231 (zero_extract:SI (match_dup 1) 9232 (const_int 8) 9233 (const_int 8)) 0) 9234 (match_dup 2)) 0))] 9235 "ix86_match_ccmode (insn, CCNOmode) 9236 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9237 && rtx_equal_p (operands[0], operands[1])" 9238 "and{b}\t{%2, %h0|%h0, %2}" 9239 [(set_attr "isa" "*,nox64") 9240 (set_attr "type" "alu") 9241 (set_attr "mode" "QI")]) 9242 9243(define_insn "*andqi_ext_2" 9244 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 9245 (const_int 8) 9246 (const_int 8)) 9247 (subreg:SI 9248 (and:QI 9249 (subreg:QI 9250 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 9251 (const_int 8) 9252 (const_int 8)) 0) 9253 (subreg:QI 9254 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9255 (const_int 8) 9256 (const_int 8)) 0)) 0)) 9257 (clobber (reg:CC FLAGS_REG))] 9258 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9259 rtx_equal_p (operands[0], operands[1]) 9260 || rtx_equal_p (operands[0], operands[2])" 9261 "and{b}\t{%h2, %h0|%h0, %h2}" 9262 [(set_attr "type" "alu") 9263 (set_attr "mode" "QI")]) 9264 9265;; Convert wide AND instructions with immediate operand to shorter QImode 9266;; equivalents when possible. 9267;; Don't do the splitting with memory operands, since it introduces risk 9268;; of memory mismatch stalls. We may want to do the splitting for optimizing 9269;; for size, but that can (should?) be handled by generic code instead. 9270(define_split 9271 [(set (match_operand:SWI248 0 "QIreg_operand") 9272 (and:SWI248 (match_operand:SWI248 1 "register_operand") 9273 (match_operand:SWI248 2 "const_int_operand"))) 9274 (clobber (reg:CC FLAGS_REG))] 9275 "reload_completed 9276 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9277 && !(~INTVAL (operands[2]) & ~(255 << 8))" 9278 [(parallel 9279 [(set (zero_extract:SI (match_dup 0) 9280 (const_int 8) 9281 (const_int 8)) 9282 (subreg:SI 9283 (and:QI 9284 (subreg:QI 9285 (zero_extract:SI (match_dup 1) 9286 (const_int 8) 9287 (const_int 8)) 0) 9288 (match_dup 2)) 0)) 9289 (clobber (reg:CC FLAGS_REG))])] 9290{ 9291 operands[0] = gen_lowpart (SImode, operands[0]); 9292 operands[1] = gen_lowpart (SImode, operands[1]); 9293 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode); 9294}) 9295 9296;; Since AND can be encoded with sign extended immediate, this is only 9297;; profitable when 7th bit is not set. 9298(define_split 9299 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9300 (and:SWI248 (match_operand:SWI248 1 "general_operand") 9301 (match_operand:SWI248 2 "const_int_operand"))) 9302 (clobber (reg:CC FLAGS_REG))] 9303 "reload_completed 9304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9305 && !(~INTVAL (operands[2]) & ~255) 9306 && !(INTVAL (operands[2]) & 128)" 9307 [(parallel [(set (strict_low_part (match_dup 0)) 9308 (and:QI (match_dup 1) 9309 (match_dup 2))) 9310 (clobber (reg:CC FLAGS_REG))])] 9311{ 9312 operands[0] = gen_lowpart (QImode, operands[0]); 9313 operands[1] = gen_lowpart (QImode, operands[1]); 9314 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 9315}) 9316 9317(define_insn "*andndi3_doubleword" 9318 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r") 9319 (and:DI 9320 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0")) 9321 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm"))) 9322 (clobber (reg:CC FLAGS_REG))] 9323 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2" 9324 "#" 9325 [(set_attr "isa" "bmi,bmi,bmi,*")]) 9326 9327(define_split 9328 [(set (match_operand:DI 0 "register_operand") 9329 (and:DI 9330 (not:DI (match_operand:DI 1 "register_operand")) 9331 (match_operand:DI 2 "nonimmediate_operand"))) 9332 (clobber (reg:CC FLAGS_REG))] 9333 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2 9334 && reload_completed" 9335 [(parallel [(set (match_dup 0) 9336 (and:SI (not:SI (match_dup 1)) (match_dup 2))) 9337 (clobber (reg:CC FLAGS_REG))]) 9338 (parallel [(set (match_dup 3) 9339 (and:SI (not:SI (match_dup 4)) (match_dup 5))) 9340 (clobber (reg:CC FLAGS_REG))])] 9341 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);") 9342 9343(define_split 9344 [(set (match_operand:DI 0 "register_operand") 9345 (and:DI 9346 (not:DI (match_dup 0)) 9347 (match_operand:DI 1 "nonimmediate_operand"))) 9348 (clobber (reg:CC FLAGS_REG))] 9349 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2 9350 && reload_completed" 9351 [(set (match_dup 0) (not:SI (match_dup 0))) 9352 (parallel [(set (match_dup 0) 9353 (and:SI (match_dup 0) (match_dup 1))) 9354 (clobber (reg:CC FLAGS_REG))]) 9355 (set (match_dup 2) (not:SI (match_dup 2))) 9356 (parallel [(set (match_dup 2) 9357 (and:SI (match_dup 2) (match_dup 3))) 9358 (clobber (reg:CC FLAGS_REG))])] 9359 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);") 9360 9361(define_insn "*andn<mode>_1" 9362 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 9363 (and:SWI48 9364 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r")) 9365 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))) 9366 (clobber (reg:CC FLAGS_REG))] 9367 "TARGET_BMI" 9368 "andn\t{%2, %1, %0|%0, %1, %2}" 9369 [(set_attr "type" "bitmanip") 9370 (set_attr "btver2_decode" "direct, double") 9371 (set_attr "mode" "<MODE>")]) 9372 9373(define_insn "*andn<mode>_1" 9374 [(set (match_operand:SWI12 0 "register_operand" "=r") 9375 (and:SWI12 9376 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r")) 9377 (match_operand:SWI12 2 "register_operand" "r"))) 9378 (clobber (reg:CC FLAGS_REG))] 9379 "TARGET_BMI" 9380 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}" 9381 [(set_attr "type" "bitmanip") 9382 (set_attr "btver2_decode" "direct") 9383 (set_attr "mode" "SI")]) 9384 9385(define_insn "*andn_<mode>_ccno" 9386 [(set (reg FLAGS_REG) 9387 (compare 9388 (and:SWI48 9389 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r")) 9390 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")) 9391 (const_int 0))) 9392 (clobber (match_scratch:SWI48 0 "=r,r"))] 9393 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)" 9394 "andn\t{%2, %1, %0|%0, %1, %2}" 9395 [(set_attr "type" "bitmanip") 9396 (set_attr "btver2_decode" "direct, double") 9397 (set_attr "mode" "<MODE>")]) 9398 9399;; Logical inclusive and exclusive OR instructions 9400 9401;; %%% This used to optimize known byte-wide and operations to memory. 9402;; If this is considered useful, it should be done with splitters. 9403 9404(define_expand "<code><mode>3" 9405 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand") 9406 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand") 9407 (match_operand:SWIM1248x 2 "<general_operand>")))] 9408 "" 9409 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 9410 9411(define_insn_and_split "*<code>di3_doubleword" 9412 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 9413 (any_or:DI 9414 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 9415 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm"))) 9416 (clobber (reg:CC FLAGS_REG))] 9417 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 9418 && ix86_binary_operator_ok (<CODE>, DImode, operands)" 9419 "#" 9420 "&& reload_completed" 9421 [(const_int 0)] 9422{ 9423 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); 9424 if (operands[2] == constm1_rtx) 9425 { 9426 if (<CODE> == IOR) 9427 { 9428 operands[1] = constm1_rtx; 9429 ix86_expand_move (SImode, &operands[0]); 9430 } 9431 else 9432 ix86_expand_unary_operator (NOT, SImode, &operands[0]); 9433 } 9434 else if (operands[2] != const0_rtx) 9435 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]); 9436 else if (operands[5] == const0_rtx) 9437 emit_note (NOTE_INSN_DELETED); 9438 if (operands[5] == constm1_rtx) 9439 { 9440 if (<CODE> == IOR) 9441 { 9442 operands[4] = constm1_rtx; 9443 ix86_expand_move (SImode, &operands[3]); 9444 } 9445 else 9446 ix86_expand_unary_operator (NOT, SImode, &operands[3]); 9447 } 9448 else if (operands[5] != const0_rtx) 9449 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]); 9450 DONE; 9451}) 9452 9453(define_insn "*<code><mode>_1" 9454 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm") 9455 (any_or:SWI248 9456 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0") 9457 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>"))) 9458 (clobber (reg:CC FLAGS_REG))] 9459 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9460 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9461 [(set_attr "type" "alu") 9462 (set_attr "mode" "<MODE>")]) 9463 9464(define_insn_and_split "*iordi_1_bts" 9465 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9466 (ior:DI 9467 (match_operand:DI 1 "nonimmediate_operand" "%0") 9468 (match_operand:DI 2 "const_int_operand" "n"))) 9469 (clobber (reg:CC FLAGS_REG))] 9470 "TARGET_64BIT && TARGET_USE_BT 9471 && ix86_binary_operator_ok (IOR, DImode, operands) 9472 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)" 9473 "#" 9474 "&& reload_completed" 9475 [(parallel [(set (zero_extract:DI (match_dup 0) 9476 (const_int 1) 9477 (match_dup 3)) 9478 (const_int 1)) 9479 (clobber (reg:CC FLAGS_REG))])] 9480 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));" 9481 [(set_attr "type" "alu1") 9482 (set_attr "prefix_0f" "1") 9483 (set_attr "znver1_decode" "double") 9484 (set_attr "mode" "DI")]) 9485 9486(define_insn_and_split "*xordi_1_btc" 9487 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9488 (xor:DI 9489 (match_operand:DI 1 "nonimmediate_operand" "%0") 9490 (match_operand:DI 2 "const_int_operand" "n"))) 9491 (clobber (reg:CC FLAGS_REG))] 9492 "TARGET_64BIT && TARGET_USE_BT 9493 && ix86_binary_operator_ok (XOR, DImode, operands) 9494 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)" 9495 "#" 9496 "&& reload_completed" 9497 [(parallel [(set (zero_extract:DI (match_dup 0) 9498 (const_int 1) 9499 (match_dup 3)) 9500 (not:DI (zero_extract:DI (match_dup 0) 9501 (const_int 1) 9502 (match_dup 3)))) 9503 (clobber (reg:CC FLAGS_REG))])] 9504 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));" 9505 [(set_attr "type" "alu1") 9506 (set_attr "prefix_0f" "1") 9507 (set_attr "znver1_decode" "double") 9508 (set_attr "mode" "DI")]) 9509 9510;; See comment for addsi_1_zext why we do use nonimmediate_operand 9511(define_insn "*<code>si_1_zext" 9512 [(set (match_operand:DI 0 "register_operand" "=r") 9513 (zero_extend:DI 9514 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9515 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 9516 (clobber (reg:CC FLAGS_REG))] 9517 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9518 "<logic>{l}\t{%2, %k0|%k0, %2}" 9519 [(set_attr "type" "alu") 9520 (set_attr "mode" "SI")]) 9521 9522(define_insn "*<code>si_1_zext_imm" 9523 [(set (match_operand:DI 0 "register_operand" "=r") 9524 (any_or:DI 9525 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 9526 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 9527 (clobber (reg:CC FLAGS_REG))] 9528 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9529 "<logic>{l}\t{%2, %k0|%k0, %2}" 9530 [(set_attr "type" "alu") 9531 (set_attr "mode" "SI")]) 9532 9533(define_insn "*<code>qi_1" 9534 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r") 9535 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9536 (match_operand:QI 2 "general_operand" "qmn,qn,rn"))) 9537 (clobber (reg:CC FLAGS_REG))] 9538 "ix86_binary_operator_ok (<CODE>, QImode, operands)" 9539 "@ 9540 <logic>{b}\t{%2, %0|%0, %2} 9541 <logic>{b}\t{%2, %0|%0, %2} 9542 <logic>{l}\t{%k2, %k0|%k0, %k2}" 9543 [(set_attr "type" "alu") 9544 (set_attr "mode" "QI,QI,SI") 9545 ;; Potential partial reg stall on alternative 2. 9546 (set (attr "preferred_for_speed") 9547 (cond [(eq_attr "alternative" "2") 9548 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 9549 (symbol_ref "true")))]) 9550 9551(define_insn "*<code>qi_1_slp" 9552 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 9553 (any_or:QI (match_dup 0) 9554 (match_operand:QI 1 "general_operand" "qmn,qn"))) 9555 (clobber (reg:CC FLAGS_REG))] 9556 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9557 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9558 "<logic>{b}\t{%1, %0|%0, %1}" 9559 [(set_attr "type" "alu1") 9560 (set_attr "mode" "QI")]) 9561 9562(define_insn "*<code><mode>_2" 9563 [(set (reg FLAGS_REG) 9564 (compare (any_or:SWI 9565 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 9566 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")) 9567 (const_int 0))) 9568 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 9569 (any_or:SWI (match_dup 1) (match_dup 2)))] 9570 "ix86_match_ccmode (insn, CCNOmode) 9571 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9572 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9573 [(set_attr "type" "alu") 9574 (set_attr "mode" "<MODE>")]) 9575 9576;; See comment for addsi_1_zext why we do use nonimmediate_operand 9577;; ??? Special case for immediate operand is missing - it is tricky. 9578(define_insn "*<code>si_2_zext" 9579 [(set (reg FLAGS_REG) 9580 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9581 (match_operand:SI 2 "x86_64_general_operand" "rme")) 9582 (const_int 0))) 9583 (set (match_operand:DI 0 "register_operand" "=r") 9584 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] 9585 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9586 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9587 "<logic>{l}\t{%2, %k0|%k0, %2}" 9588 [(set_attr "type" "alu") 9589 (set_attr "mode" "SI")]) 9590 9591(define_insn "*<code>si_2_zext_imm" 9592 [(set (reg FLAGS_REG) 9593 (compare (any_or:SI 9594 (match_operand:SI 1 "nonimmediate_operand" "%0") 9595 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z")) 9596 (const_int 0))) 9597 (set (match_operand:DI 0 "register_operand" "=r") 9598 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 9599 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9600 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9601 "<logic>{l}\t{%2, %k0|%k0, %2}" 9602 [(set_attr "type" "alu") 9603 (set_attr "mode" "SI")]) 9604 9605(define_insn "*<code>qi_2_slp" 9606 [(set (reg FLAGS_REG) 9607 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 9608 (match_operand:QI 1 "general_operand" "qmn,qn")) 9609 (const_int 0))) 9610 (set (strict_low_part (match_dup 0)) 9611 (any_or:QI (match_dup 0) (match_dup 1)))] 9612 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9613 && ix86_match_ccmode (insn, CCNOmode) 9614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 9615 "<logic>{b}\t{%1, %0|%0, %1}" 9616 [(set_attr "type" "alu1") 9617 (set_attr "mode" "QI")]) 9618 9619(define_insn "*<code><mode>_3" 9620 [(set (reg FLAGS_REG) 9621 (compare (any_or:SWI 9622 (match_operand:SWI 1 "nonimmediate_operand" "%0") 9623 (match_operand:SWI 2 "<general_operand>" "<g>")) 9624 (const_int 0))) 9625 (clobber (match_scratch:SWI 0 "=<r>"))] 9626 "ix86_match_ccmode (insn, CCNOmode) 9627 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 9628 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9629 [(set_attr "type" "alu") 9630 (set_attr "mode" "<MODE>")]) 9631 9632(define_insn "*<code>qi_ext_1" 9633 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9634 (const_int 8) 9635 (const_int 8)) 9636 (subreg:SI 9637 (any_or:QI 9638 (subreg:QI 9639 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9640 (const_int 8) 9641 (const_int 8)) 0) 9642 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 9643 (clobber (reg:CC FLAGS_REG))] 9644 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9645 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9646 && rtx_equal_p (operands[0], operands[1])" 9647 "<logic>{b}\t{%2, %h0|%h0, %2}" 9648 [(set_attr "isa" "*,nox64") 9649 (set_attr "type" "alu") 9650 (set_attr "mode" "QI")]) 9651 9652(define_insn "*<code>qi_ext_2" 9653 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 9654 (const_int 8) 9655 (const_int 8)) 9656 (subreg:SI 9657 (any_or:QI 9658 (subreg:QI 9659 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 9660 (const_int 8) 9661 (const_int 8)) 0) 9662 (subreg:QI 9663 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9664 (const_int 8) 9665 (const_int 8)) 0)) 0)) 9666 (clobber (reg:CC FLAGS_REG))] 9667 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9668 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9669 && (rtx_equal_p (operands[0], operands[1]) 9670 || rtx_equal_p (operands[0], operands[2]))" 9671 "<logic>{b}\t{%h2, %h0|%h0, %h2}" 9672 [(set_attr "type" "alu") 9673 (set_attr "mode" "QI")]) 9674 9675;; Convert wide OR instructions with immediate operand to shorter QImode 9676;; equivalents when possible. 9677;; Don't do the splitting with memory operands, since it introduces risk 9678;; of memory mismatch stalls. We may want to do the splitting for optimizing 9679;; for size, but that can (should?) be handled by generic code instead. 9680(define_split 9681 [(set (match_operand:SWI248 0 "QIreg_operand") 9682 (any_or:SWI248 (match_operand:SWI248 1 "register_operand") 9683 (match_operand:SWI248 2 "const_int_operand"))) 9684 (clobber (reg:CC FLAGS_REG))] 9685 "reload_completed 9686 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9687 && !(INTVAL (operands[2]) & ~(255 << 8))" 9688 [(parallel 9689 [(set (zero_extract:SI (match_dup 0) 9690 (const_int 8) 9691 (const_int 8)) 9692 (subreg:SI 9693 (any_or:QI 9694 (subreg:QI 9695 (zero_extract:SI (match_dup 1) 9696 (const_int 8) 9697 (const_int 8)) 0) 9698 (match_dup 2)) 0)) 9699 (clobber (reg:CC FLAGS_REG))])] 9700{ 9701 operands[0] = gen_lowpart (SImode, operands[0]); 9702 operands[1] = gen_lowpart (SImode, operands[1]); 9703 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode); 9704}) 9705 9706;; Since OR can be encoded with sign extended immediate, this is only 9707;; profitable when 7th bit is set. 9708(define_split 9709 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9710 (any_or:SWI248 (match_operand:SWI248 1 "general_operand") 9711 (match_operand:SWI248 2 "const_int_operand"))) 9712 (clobber (reg:CC FLAGS_REG))] 9713 "reload_completed 9714 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9715 && !(INTVAL (operands[2]) & ~255) 9716 && (INTVAL (operands[2]) & 128)" 9717 [(parallel [(set (strict_low_part (match_dup 0)) 9718 (any_or:QI (match_dup 1) 9719 (match_dup 2))) 9720 (clobber (reg:CC FLAGS_REG))])] 9721{ 9722 operands[0] = gen_lowpart (QImode, operands[0]); 9723 operands[1] = gen_lowpart (QImode, operands[1]); 9724 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 9725}) 9726 9727(define_expand "xorqi_ext_1_cc" 9728 [(parallel [ 9729 (set (reg:CCNO FLAGS_REG) 9730 (compare:CCNO 9731 (xor:QI 9732 (subreg:QI 9733 (zero_extract:SI (match_operand 1 "ext_register_operand") 9734 (const_int 8) 9735 (const_int 8)) 0) 9736 (match_operand 2 "const_int_operand")) 9737 (const_int 0))) 9738 (set (zero_extract:SI (match_operand 0 "ext_register_operand") 9739 (const_int 8) 9740 (const_int 8)) 9741 (subreg:SI 9742 (xor:QI 9743 (subreg:QI 9744 (zero_extract:SI (match_dup 1) 9745 (const_int 8) 9746 (const_int 8)) 0) 9747 (match_dup 2)) 0))])]) 9748 9749(define_insn "*xorqi_ext_1_cc" 9750 [(set (reg FLAGS_REG) 9751 (compare 9752 (xor:QI 9753 (subreg:QI 9754 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9755 (const_int 8) 9756 (const_int 8)) 0) 9757 (match_operand:QI 2 "general_operand" "QnBc,m")) 9758 (const_int 0))) 9759 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9760 (const_int 8) 9761 (const_int 8)) 9762 (subreg:SI 9763 (xor:QI 9764 (subreg:QI 9765 (zero_extract:SI (match_dup 1) 9766 (const_int 8) 9767 (const_int 8)) 0) 9768 (match_dup 2)) 0))] 9769 "ix86_match_ccmode (insn, CCNOmode) 9770 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9771 && rtx_equal_p (operands[0], operands[1])" 9772 "xor{b}\t{%2, %h0|%h0, %2}" 9773 [(set_attr "isa" "*,nox64") 9774 (set_attr "type" "alu") 9775 (set_attr "mode" "QI")]) 9776 9777;; Negation instructions 9778 9779(define_expand "neg<mode>2" 9780 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 9781 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))] 9782 "" 9783 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;") 9784 9785(define_insn_and_split "*neg<dwi>2_doubleword" 9786 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 9787 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0"))) 9788 (clobber (reg:CC FLAGS_REG))] 9789 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)" 9790 "#" 9791 "reload_completed" 9792 [(parallel 9793 [(set (reg:CCZ FLAGS_REG) 9794 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0))) 9795 (set (match_dup 0) (neg:DWIH (match_dup 1)))]) 9796 (parallel 9797 [(set (match_dup 2) 9798 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 9799 (match_dup 3)) 9800 (const_int 0))) 9801 (clobber (reg:CC FLAGS_REG))]) 9802 (parallel 9803 [(set (match_dup 2) 9804 (neg:DWIH (match_dup 2))) 9805 (clobber (reg:CC FLAGS_REG))])] 9806 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);") 9807 9808(define_insn "*neg<mode>2_1" 9809 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9810 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) 9811 (clobber (reg:CC FLAGS_REG))] 9812 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 9813 "neg{<imodesuffix>}\t%0" 9814 [(set_attr "type" "negnot") 9815 (set_attr "mode" "<MODE>")]) 9816 9817;; Combine is quite creative about this pattern. 9818(define_insn "*negsi2_1_zext" 9819 [(set (match_operand:DI 0 "register_operand" "=r") 9820 (lshiftrt:DI 9821 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 9822 (const_int 32))) 9823 (const_int 32))) 9824 (clobber (reg:CC FLAGS_REG))] 9825 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9826 "neg{l}\t%k0" 9827 [(set_attr "type" "negnot") 9828 (set_attr "mode" "SI")]) 9829 9830;; The problem with neg is that it does not perform (compare x 0), 9831;; it really performs (compare 0 x), which leaves us with the zero 9832;; flag being the only useful item. 9833 9834(define_insn "*neg<mode>2_cmpz" 9835 [(set (reg:CCZ FLAGS_REG) 9836 (compare:CCZ 9837 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 9838 (const_int 0))) 9839 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9840 (neg:SWI (match_dup 1)))] 9841 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 9842 "neg{<imodesuffix>}\t%0" 9843 [(set_attr "type" "negnot") 9844 (set_attr "mode" "<MODE>")]) 9845 9846(define_insn "*negsi2_cmpz_zext" 9847 [(set (reg:CCZ FLAGS_REG) 9848 (compare:CCZ 9849 (lshiftrt:DI 9850 (neg:DI (ashift:DI 9851 (match_operand:DI 1 "register_operand" "0") 9852 (const_int 32))) 9853 (const_int 32)) 9854 (const_int 0))) 9855 (set (match_operand:DI 0 "register_operand" "=r") 9856 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 9857 (const_int 32))) 9858 (const_int 32)))] 9859 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9860 "neg{l}\t%k0" 9861 [(set_attr "type" "negnot") 9862 (set_attr "mode" "SI")]) 9863 9864;; Negate with jump on overflow. 9865(define_expand "negv<mode>3" 9866 [(parallel [(set (reg:CCO FLAGS_REG) 9867 (ne:CCO (match_operand:SWI 1 "register_operand") 9868 (match_dup 3))) 9869 (set (match_operand:SWI 0 "register_operand") 9870 (neg:SWI (match_dup 1)))]) 9871 (set (pc) (if_then_else 9872 (eq (reg:CCO FLAGS_REG) (const_int 0)) 9873 (label_ref (match_operand 2)) 9874 (pc)))] 9875 "" 9876{ 9877 operands[3] 9878 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1), 9879 <MODE>mode); 9880}) 9881 9882(define_insn "*negv<mode>3" 9883 [(set (reg:CCO FLAGS_REG) 9884 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") 9885 (match_operand:SWI 2 "const_int_operand"))) 9886 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9887 (neg:SWI (match_dup 1)))] 9888 "ix86_unary_operator_ok (NEG, <MODE>mode, operands) 9889 && mode_signbit_p (<MODE>mode, operands[2])" 9890 "neg{<imodesuffix>}\t%0" 9891 [(set_attr "type" "negnot") 9892 (set_attr "mode" "<MODE>")]) 9893 9894;; Changing of sign for FP values is doable using integer unit too. 9895 9896(define_expand "<code><mode>2" 9897 [(set (match_operand:X87MODEF 0 "register_operand") 9898 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))] 9899 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 9900 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 9901 9902(define_insn "*absneg<mode>2" 9903 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r") 9904 (match_operator:MODEF 3 "absneg_operator" 9905 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")])) 9906 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X")) 9907 (clobber (reg:CC FLAGS_REG))] 9908 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 9909 "#" 9910 [(set (attr "enabled") 9911 (if_then_else 9912 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 9913 (if_then_else 9914 (eq_attr "alternative" "2") 9915 (symbol_ref "TARGET_MIX_SSE_I387") 9916 (symbol_ref "true")) 9917 (if_then_else 9918 (eq_attr "alternative" "2,3") 9919 (symbol_ref "true") 9920 (symbol_ref "false"))))]) 9921 9922(define_insn "*absnegxf2_i387" 9923 [(set (match_operand:XF 0 "register_operand" "=f,!r") 9924 (match_operator:XF 3 "absneg_operator" 9925 [(match_operand:XF 1 "register_operand" "0,0")])) 9926 (use (match_operand 2)) 9927 (clobber (reg:CC FLAGS_REG))] 9928 "TARGET_80387" 9929 "#") 9930 9931(define_expand "<code>tf2" 9932 [(set (match_operand:TF 0 "register_operand") 9933 (absneg:TF (match_operand:TF 1 "register_operand")))] 9934 "TARGET_SSE" 9935 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") 9936 9937(define_insn "*absnegtf2_sse" 9938 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv") 9939 (match_operator:TF 3 "absneg_operator" 9940 [(match_operand:TF 1 "register_operand" "0,Yv")])) 9941 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0")) 9942 (clobber (reg:CC FLAGS_REG))] 9943 "TARGET_SSE" 9944 "#") 9945 9946;; Splitters for fp abs and neg. 9947 9948(define_split 9949 [(set (match_operand 0 "fp_register_operand") 9950 (match_operator 1 "absneg_operator" [(match_dup 0)])) 9951 (use (match_operand 2)) 9952 (clobber (reg:CC FLAGS_REG))] 9953 "reload_completed" 9954 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 9955 9956(define_split 9957 [(set (match_operand 0 "sse_reg_operand") 9958 (match_operator 3 "absneg_operator" 9959 [(match_operand 1 "register_operand")])) 9960 (use (match_operand 2 "nonimmediate_operand")) 9961 (clobber (reg:CC FLAGS_REG))] 9962 "reload_completed" 9963 [(set (match_dup 0) (match_dup 3))] 9964{ 9965 machine_mode mode = GET_MODE (operands[0]); 9966 machine_mode vmode = GET_MODE (operands[2]); 9967 rtx tmp; 9968 9969 operands[0] = lowpart_subreg (vmode, operands[0], mode); 9970 operands[1] = lowpart_subreg (vmode, operands[1], mode); 9971 if (operands_match_p (operands[0], operands[2])) 9972 std::swap (operands[1], operands[2]); 9973 if (GET_CODE (operands[3]) == ABS) 9974 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 9975 else 9976 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 9977 operands[3] = tmp; 9978}) 9979 9980(define_split 9981 [(set (match_operand:SF 0 "general_reg_operand") 9982 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 9983 (use (match_operand:V4SF 2)) 9984 (clobber (reg:CC FLAGS_REG))] 9985 "reload_completed" 9986 [(parallel [(set (match_dup 0) (match_dup 1)) 9987 (clobber (reg:CC FLAGS_REG))])] 9988{ 9989 rtx tmp; 9990 operands[0] = gen_lowpart (SImode, operands[0]); 9991 if (GET_CODE (operands[1]) == ABS) 9992 { 9993 tmp = gen_int_mode (0x7fffffff, SImode); 9994 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9995 } 9996 else 9997 { 9998 tmp = gen_int_mode (0x80000000, SImode); 9999 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10000 } 10001 operands[1] = tmp; 10002}) 10003 10004(define_split 10005 [(set (match_operand:DF 0 "general_reg_operand") 10006 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 10007 (use (match_operand 2)) 10008 (clobber (reg:CC FLAGS_REG))] 10009 "reload_completed" 10010 [(parallel [(set (match_dup 0) (match_dup 1)) 10011 (clobber (reg:CC FLAGS_REG))])] 10012{ 10013 rtx tmp; 10014 if (TARGET_64BIT) 10015 { 10016 tmp = gen_lowpart (DImode, operands[0]); 10017 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 10018 operands[0] = tmp; 10019 10020 if (GET_CODE (operands[1]) == ABS) 10021 tmp = const0_rtx; 10022 else 10023 tmp = gen_rtx_NOT (DImode, tmp); 10024 } 10025 else 10026 { 10027 operands[0] = gen_highpart (SImode, operands[0]); 10028 if (GET_CODE (operands[1]) == ABS) 10029 { 10030 tmp = gen_int_mode (0x7fffffff, SImode); 10031 tmp = gen_rtx_AND (SImode, operands[0], tmp); 10032 } 10033 else 10034 { 10035 tmp = gen_int_mode (0x80000000, SImode); 10036 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10037 } 10038 } 10039 operands[1] = tmp; 10040}) 10041 10042(define_split 10043 [(set (match_operand:XF 0 "general_reg_operand") 10044 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 10045 (use (match_operand 2)) 10046 (clobber (reg:CC FLAGS_REG))] 10047 "reload_completed" 10048 [(parallel [(set (match_dup 0) (match_dup 1)) 10049 (clobber (reg:CC FLAGS_REG))])] 10050{ 10051 rtx tmp; 10052 operands[0] = gen_rtx_REG (SImode, 10053 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2)); 10054 if (GET_CODE (operands[1]) == ABS) 10055 { 10056 tmp = GEN_INT (0x7fff); 10057 tmp = gen_rtx_AND (SImode, operands[0], tmp); 10058 } 10059 else 10060 { 10061 tmp = GEN_INT (0x8000); 10062 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 10063 } 10064 operands[1] = tmp; 10065}) 10066 10067;; Conditionalize these after reload. If they match before reload, we 10068;; lose the clobber and ability to use integer instructions. 10069 10070(define_insn "*<code><mode>2_1" 10071 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 10072 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] 10073 "TARGET_80387 10074 && (reload_completed 10075 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 10076 "f<absneg_mnemonic>" 10077 [(set_attr "type" "fsgn") 10078 (set_attr "mode" "<MODE>")]) 10079 10080(define_insn "*<code>extendsfdf2" 10081 [(set (match_operand:DF 0 "register_operand" "=f") 10082 (absneg:DF (float_extend:DF 10083 (match_operand:SF 1 "register_operand" "0"))))] 10084 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 10085 "f<absneg_mnemonic>" 10086 [(set_attr "type" "fsgn") 10087 (set_attr "mode" "DF")]) 10088 10089(define_insn "*<code>extendsfxf2" 10090 [(set (match_operand:XF 0 "register_operand" "=f") 10091 (absneg:XF (float_extend:XF 10092 (match_operand:SF 1 "register_operand" "0"))))] 10093 "TARGET_80387" 10094 "f<absneg_mnemonic>" 10095 [(set_attr "type" "fsgn") 10096 (set_attr "mode" "XF")]) 10097 10098(define_insn "*<code>extenddfxf2" 10099 [(set (match_operand:XF 0 "register_operand" "=f") 10100 (absneg:XF (float_extend:XF 10101 (match_operand:DF 1 "register_operand" "0"))))] 10102 "TARGET_80387" 10103 "f<absneg_mnemonic>" 10104 [(set_attr "type" "fsgn") 10105 (set_attr "mode" "XF")]) 10106 10107;; Copysign instructions 10108 10109(define_mode_iterator CSGNMODE [SF DF TF]) 10110(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) 10111 10112(define_expand "copysign<mode>3" 10113 [(match_operand:CSGNMODE 0 "register_operand") 10114 (match_operand:CSGNMODE 1 "nonmemory_operand") 10115 (match_operand:CSGNMODE 2 "register_operand")] 10116 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10117 || (TARGET_SSE && (<MODE>mode == TFmode))" 10118 "ix86_expand_copysign (operands); DONE;") 10119 10120(define_insn_and_split "copysign<mode>3_const" 10121 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv") 10122 (unspec:CSGNMODE 10123 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC") 10124 (match_operand:CSGNMODE 2 "register_operand" "0") 10125 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")] 10126 UNSPEC_COPYSIGN))] 10127 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10128 || (TARGET_SSE && (<MODE>mode == TFmode))" 10129 "#" 10130 "&& reload_completed" 10131 [(const_int 0)] 10132 "ix86_split_copysign_const (operands); DONE;") 10133 10134(define_insn "copysign<mode>3_var" 10135 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv") 10136 (unspec:CSGNMODE 10137 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv") 10138 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv") 10139 (match_operand:<CSGNVMODE> 4 10140 "nonimmediate_operand" "X,Yvm,Yvm,0,0") 10141 (match_operand:<CSGNVMODE> 5 10142 "nonimmediate_operand" "0,Yvm,1,Yvm,1")] 10143 UNSPEC_COPYSIGN)) 10144 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))] 10145 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10146 || (TARGET_SSE && (<MODE>mode == TFmode))" 10147 "#") 10148 10149(define_split 10150 [(set (match_operand:CSGNMODE 0 "register_operand") 10151 (unspec:CSGNMODE 10152 [(match_operand:CSGNMODE 2 "register_operand") 10153 (match_operand:CSGNMODE 3 "register_operand") 10154 (match_operand:<CSGNVMODE> 4) 10155 (match_operand:<CSGNVMODE> 5)] 10156 UNSPEC_COPYSIGN)) 10157 (clobber (match_scratch:<CSGNVMODE> 1))] 10158 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10159 || (TARGET_SSE && (<MODE>mode == TFmode))) 10160 && reload_completed" 10161 [(const_int 0)] 10162 "ix86_split_copysign_var (operands); DONE;") 10163 10164;; One complement instructions 10165 10166(define_expand "one_cmpl<mode>2" 10167 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand") 10168 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))] 10169 "" 10170 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") 10171 10172(define_insn_and_split "*one_cmpldi2_doubleword" 10173 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 10174 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))] 10175 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 10176 && ix86_unary_operator_ok (NOT, DImode, operands)" 10177 "#" 10178 "&& reload_completed" 10179 [(set (match_dup 0) 10180 (not:SI (match_dup 1))) 10181 (set (match_dup 2) 10182 (not:SI (match_dup 3)))] 10183 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);") 10184 10185(define_insn "*one_cmpl<mode>2_1" 10186 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") 10187 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))] 10188 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 10189 "not{<imodesuffix>}\t%0" 10190 [(set_attr "type" "negnot") 10191 (set_attr "mode" "<MODE>")]) 10192 10193;; ??? Currently never generated - xor is used instead. 10194(define_insn "*one_cmplsi2_1_zext" 10195 [(set (match_operand:DI 0 "register_operand" "=r") 10196 (zero_extend:DI 10197 (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10198 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10199 "not{l}\t%k0" 10200 [(set_attr "type" "negnot") 10201 (set_attr "mode" "SI")]) 10202 10203(define_insn "*one_cmplqi2_1" 10204 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10205 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10206 "ix86_unary_operator_ok (NOT, QImode, operands)" 10207 "@ 10208 not{b}\t%0 10209 not{l}\t%k0" 10210 [(set_attr "type" "negnot") 10211 (set_attr "mode" "QI,SI") 10212 ;; Potential partial reg stall on alternative 1. 10213 (set (attr "preferred_for_speed") 10214 (cond [(eq_attr "alternative" "1") 10215 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 10216 (symbol_ref "true")))]) 10217 10218(define_insn "*one_cmpl<mode>2_2" 10219 [(set (reg FLAGS_REG) 10220 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 10221 (const_int 0))) 10222 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10223 (not:SWI (match_dup 1)))] 10224 "ix86_match_ccmode (insn, CCNOmode) 10225 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 10226 "#" 10227 [(set_attr "type" "alu1") 10228 (set_attr "mode" "<MODE>")]) 10229 10230(define_split 10231 [(set (match_operand 0 "flags_reg_operand") 10232 (match_operator 2 "compare_operator" 10233 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand")) 10234 (const_int 0)])) 10235 (set (match_operand:SWI 1 "nonimmediate_operand") 10236 (not:SWI (match_dup 3)))] 10237 "ix86_match_ccmode (insn, CCNOmode)" 10238 [(parallel [(set (match_dup 0) 10239 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1)) 10240 (const_int 0)])) 10241 (set (match_dup 1) 10242 (xor:SWI (match_dup 3) (const_int -1)))])]) 10243 10244;; ??? Currently never generated - xor is used instead. 10245(define_insn "*one_cmplsi2_2_zext" 10246 [(set (reg FLAGS_REG) 10247 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10248 (const_int 0))) 10249 (set (match_operand:DI 0 "register_operand" "=r") 10250 (zero_extend:DI (not:SI (match_dup 1))))] 10251 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10252 && ix86_unary_operator_ok (NOT, SImode, operands)" 10253 "#" 10254 [(set_attr "type" "alu1") 10255 (set_attr "mode" "SI")]) 10256 10257(define_split 10258 [(set (match_operand 0 "flags_reg_operand") 10259 (match_operator 2 "compare_operator" 10260 [(not:SI (match_operand:SI 3 "register_operand")) 10261 (const_int 0)])) 10262 (set (match_operand:DI 1 "register_operand") 10263 (zero_extend:DI (not:SI (match_dup 3))))] 10264 "ix86_match_ccmode (insn, CCNOmode)" 10265 [(parallel [(set (match_dup 0) 10266 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10267 (const_int 0)])) 10268 (set (match_dup 1) 10269 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]) 10270 10271;; Shift instructions 10272 10273;; DImode shifts are implemented using the i386 "shift double" opcode, 10274;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10275;; is variable, then the count is in %cl and the "imm" operand is dropped 10276;; from the assembler input. 10277;; 10278;; This instruction shifts the target reg/mem as usual, but instead of 10279;; shifting in zeros, bits are shifted in from reg operand. If the insn 10280;; is a left shift double, bits are taken from the high order bits of 10281;; reg, else if the insn is a shift right double, bits are taken from the 10282;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10283;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10284;; 10285;; Since sh[lr]d does not change the `reg' operand, that is done 10286;; separately, making all shifts emit pairs of shift double and normal 10287;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10288;; support a 63 bit shift, each shift where the count is in a reg expands 10289;; to a pair of shifts, a branch, a shift by 32 and a label. 10290;; 10291;; If the shift count is a constant, we need never emit more than one 10292;; shift pair, instead using moves and sign extension for counts greater 10293;; than 31. 10294 10295(define_expand "ashl<mode>3" 10296 [(set (match_operand:SDWIM 0 "<shift_operand>") 10297 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>") 10298 (match_operand:QI 2 "nonmemory_operand")))] 10299 "" 10300 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") 10301 10302(define_insn "*ashl<mode>3_doubleword" 10303 [(set (match_operand:DWI 0 "register_operand" "=&r") 10304 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n") 10305 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 10306 (clobber (reg:CC FLAGS_REG))] 10307 "" 10308 "#" 10309 [(set_attr "type" "multi")]) 10310 10311(define_split 10312 [(set (match_operand:DWI 0 "register_operand") 10313 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand") 10314 (match_operand:QI 2 "nonmemory_operand"))) 10315 (clobber (reg:CC FLAGS_REG))] 10316 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 10317 [(const_int 0)] 10318 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;") 10319 10320;; By default we don't ask for a scratch register, because when DWImode 10321;; values are manipulated, registers are already at a premium. But if 10322;; we have one handy, we won't turn it away. 10323 10324(define_peephole2 10325 [(match_scratch:DWIH 3 "r") 10326 (parallel [(set (match_operand:<DWI> 0 "register_operand") 10327 (ashift:<DWI> 10328 (match_operand:<DWI> 1 "nonmemory_operand") 10329 (match_operand:QI 2 "nonmemory_operand"))) 10330 (clobber (reg:CC FLAGS_REG))]) 10331 (match_dup 3)] 10332 "TARGET_CMOVE" 10333 [(const_int 0)] 10334 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;") 10335 10336(define_insn "x86_64_shld" 10337 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 10338 (ior:DI (ashift:DI (match_dup 0) 10339 (match_operand:QI 2 "nonmemory_operand" "Jc")) 10340 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 10341 (minus:QI (const_int 64) (match_dup 2))))) 10342 (clobber (reg:CC FLAGS_REG))] 10343 "TARGET_64BIT" 10344 "shld{q}\t{%s2%1, %0|%0, %1, %2}" 10345 [(set_attr "type" "ishift") 10346 (set_attr "prefix_0f" "1") 10347 (set_attr "mode" "DI") 10348 (set_attr "athlon_decode" "vector") 10349 (set_attr "amdfam10_decode" "vector") 10350 (set_attr "bdver1_decode" "vector")]) 10351 10352(define_insn "x86_shld" 10353 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 10354 (ior:SI (ashift:SI (match_dup 0) 10355 (match_operand:QI 2 "nonmemory_operand" "Ic")) 10356 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 10357 (minus:QI (const_int 32) (match_dup 2))))) 10358 (clobber (reg:CC FLAGS_REG))] 10359 "" 10360 "shld{l}\t{%s2%1, %0|%0, %1, %2}" 10361 [(set_attr "type" "ishift") 10362 (set_attr "prefix_0f" "1") 10363 (set_attr "mode" "SI") 10364 (set_attr "pent_pair" "np") 10365 (set_attr "athlon_decode" "vector") 10366 (set_attr "amdfam10_decode" "vector") 10367 (set_attr "bdver1_decode" "vector")]) 10368 10369(define_expand "x86_shift<mode>_adj_1" 10370 [(set (reg:CCZ FLAGS_REG) 10371 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand") 10372 (match_dup 4)) 10373 (const_int 0))) 10374 (set (match_operand:SWI48 0 "register_operand") 10375 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10376 (match_operand:SWI48 1 "register_operand") 10377 (match_dup 0))) 10378 (set (match_dup 1) 10379 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10380 (match_operand:SWI48 3 "register_operand") 10381 (match_dup 1)))] 10382 "TARGET_CMOVE" 10383 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 10384 10385(define_expand "x86_shift<mode>_adj_2" 10386 [(use (match_operand:SWI48 0 "register_operand")) 10387 (use (match_operand:SWI48 1 "register_operand")) 10388 (use (match_operand:QI 2 "register_operand"))] 10389 "" 10390{ 10391 rtx_code_label *label = gen_label_rtx (); 10392 rtx tmp; 10393 10394 emit_insn (gen_testqi_ccz_1 (operands[2], 10395 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 10396 10397 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10398 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10399 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10400 gen_rtx_LABEL_REF (VOIDmode, label), 10401 pc_rtx); 10402 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 10403 JUMP_LABEL (tmp) = label; 10404 10405 emit_move_insn (operands[0], operands[1]); 10406 ix86_expand_clear (operands[1]); 10407 10408 emit_label (label); 10409 LABEL_NUSES (label) = 1; 10410 10411 DONE; 10412}) 10413 10414;; Avoid useless masking of count operand. 10415(define_insn_and_split "*ashl<mode>3_mask" 10416 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10417 (ashift:SWI48 10418 (match_operand:SWI48 1 "nonimmediate_operand") 10419 (subreg:QI 10420 (and:SI 10421 (match_operand:SI 2 "register_operand" "c,r") 10422 (match_operand:SI 3 "const_int_operand")) 0))) 10423 (clobber (reg:CC FLAGS_REG))] 10424 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 10425 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10426 == GET_MODE_BITSIZE (<MODE>mode)-1 10427 && can_create_pseudo_p ()" 10428 "#" 10429 "&& 1" 10430 [(parallel 10431 [(set (match_dup 0) 10432 (ashift:SWI48 (match_dup 1) 10433 (match_dup 2))) 10434 (clobber (reg:CC FLAGS_REG))])] 10435 "operands[2] = gen_lowpart (QImode, operands[2]);" 10436 [(set_attr "isa" "*,bmi2")]) 10437 10438(define_insn_and_split "*ashl<mode>3_mask_1" 10439 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10440 (ashift:SWI48 10441 (match_operand:SWI48 1 "nonimmediate_operand") 10442 (and:QI 10443 (match_operand:QI 2 "register_operand" "c,r") 10444 (match_operand:QI 3 "const_int_operand")))) 10445 (clobber (reg:CC FLAGS_REG))] 10446 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 10447 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10448 == GET_MODE_BITSIZE (<MODE>mode)-1 10449 && can_create_pseudo_p ()" 10450 "#" 10451 "&& 1" 10452 [(parallel 10453 [(set (match_dup 0) 10454 (ashift:SWI48 (match_dup 1) 10455 (match_dup 2))) 10456 (clobber (reg:CC FLAGS_REG))])] 10457 "" 10458 [(set_attr "isa" "*,bmi2")]) 10459 10460(define_insn "*bmi2_ashl<mode>3_1" 10461 [(set (match_operand:SWI48 0 "register_operand" "=r") 10462 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10463 (match_operand:SWI48 2 "register_operand" "r")))] 10464 "TARGET_BMI2" 10465 "shlx\t{%2, %1, %0|%0, %1, %2}" 10466 [(set_attr "type" "ishiftx") 10467 (set_attr "mode" "<MODE>")]) 10468 10469(define_insn "*ashl<mode>3_1" 10470 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") 10471 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm") 10472 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r"))) 10473 (clobber (reg:CC FLAGS_REG))] 10474 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 10475{ 10476 switch (get_attr_type (insn)) 10477 { 10478 case TYPE_LEA: 10479 case TYPE_ISHIFTX: 10480 return "#"; 10481 10482 case TYPE_ALU: 10483 gcc_assert (operands[2] == const1_rtx); 10484 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10485 return "add{<imodesuffix>}\t%0, %0"; 10486 10487 default: 10488 if (operands[2] == const1_rtx 10489 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10490 return "sal{<imodesuffix>}\t%0"; 10491 else 10492 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10493 } 10494} 10495 [(set_attr "isa" "*,*,bmi2") 10496 (set (attr "type") 10497 (cond [(eq_attr "alternative" "1") 10498 (const_string "lea") 10499 (eq_attr "alternative" "2") 10500 (const_string "ishiftx") 10501 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10502 (match_operand 0 "register_operand")) 10503 (match_operand 2 "const1_operand")) 10504 (const_string "alu") 10505 ] 10506 (const_string "ishift"))) 10507 (set (attr "length_immediate") 10508 (if_then_else 10509 (ior (eq_attr "type" "alu") 10510 (and (eq_attr "type" "ishift") 10511 (and (match_operand 2 "const1_operand") 10512 (ior (match_test "TARGET_SHIFT1") 10513 (match_test "optimize_function_for_size_p (cfun)"))))) 10514 (const_string "0") 10515 (const_string "*"))) 10516 (set_attr "mode" "<MODE>")]) 10517 10518;; Convert shift to the shiftx pattern to avoid flags dependency. 10519(define_split 10520 [(set (match_operand:SWI48 0 "register_operand") 10521 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 10522 (match_operand:QI 2 "register_operand"))) 10523 (clobber (reg:CC FLAGS_REG))] 10524 "TARGET_BMI2 && reload_completed" 10525 [(set (match_dup 0) 10526 (ashift:SWI48 (match_dup 1) (match_dup 2)))] 10527 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 10528 10529(define_insn "*bmi2_ashlsi3_1_zext" 10530 [(set (match_operand:DI 0 "register_operand" "=r") 10531 (zero_extend:DI 10532 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10533 (match_operand:SI 2 "register_operand" "r"))))] 10534 "TARGET_64BIT && TARGET_BMI2" 10535 "shlx\t{%2, %1, %k0|%k0, %1, %2}" 10536 [(set_attr "type" "ishiftx") 10537 (set_attr "mode" "SI")]) 10538 10539(define_insn "*ashlsi3_1_zext" 10540 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 10541 (zero_extend:DI 10542 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm") 10543 (match_operand:QI 2 "nonmemory_operand" "cI,M,r")))) 10544 (clobber (reg:CC FLAGS_REG))] 10545 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10546{ 10547 switch (get_attr_type (insn)) 10548 { 10549 case TYPE_LEA: 10550 case TYPE_ISHIFTX: 10551 return "#"; 10552 10553 case TYPE_ALU: 10554 gcc_assert (operands[2] == const1_rtx); 10555 return "add{l}\t%k0, %k0"; 10556 10557 default: 10558 if (operands[2] == const1_rtx 10559 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10560 return "sal{l}\t%k0"; 10561 else 10562 return "sal{l}\t{%2, %k0|%k0, %2}"; 10563 } 10564} 10565 [(set_attr "isa" "*,*,bmi2") 10566 (set (attr "type") 10567 (cond [(eq_attr "alternative" "1") 10568 (const_string "lea") 10569 (eq_attr "alternative" "2") 10570 (const_string "ishiftx") 10571 (and (match_test "TARGET_DOUBLE_WITH_ADD") 10572 (match_operand 2 "const1_operand")) 10573 (const_string "alu") 10574 ] 10575 (const_string "ishift"))) 10576 (set (attr "length_immediate") 10577 (if_then_else 10578 (ior (eq_attr "type" "alu") 10579 (and (eq_attr "type" "ishift") 10580 (and (match_operand 2 "const1_operand") 10581 (ior (match_test "TARGET_SHIFT1") 10582 (match_test "optimize_function_for_size_p (cfun)"))))) 10583 (const_string "0") 10584 (const_string "*"))) 10585 (set_attr "mode" "SI")]) 10586 10587;; Convert shift to the shiftx pattern to avoid flags dependency. 10588(define_split 10589 [(set (match_operand:DI 0 "register_operand") 10590 (zero_extend:DI 10591 (ashift:SI (match_operand:SI 1 "nonimmediate_operand") 10592 (match_operand:QI 2 "register_operand")))) 10593 (clobber (reg:CC FLAGS_REG))] 10594 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10595 [(set (match_dup 0) 10596 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10597 "operands[2] = gen_lowpart (SImode, operands[2]);") 10598 10599(define_insn "*ashlhi3_1" 10600 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") 10601 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10602 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10603 (clobber (reg:CC FLAGS_REG))] 10604 "ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10605{ 10606 switch (get_attr_type (insn)) 10607 { 10608 case TYPE_LEA: 10609 return "#"; 10610 10611 case TYPE_ALU: 10612 gcc_assert (operands[2] == const1_rtx); 10613 return "add{w}\t%0, %0"; 10614 10615 default: 10616 if (operands[2] == const1_rtx 10617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10618 return "sal{w}\t%0"; 10619 else 10620 return "sal{w}\t{%2, %0|%0, %2}"; 10621 } 10622} 10623 [(set (attr "type") 10624 (cond [(eq_attr "alternative" "1") 10625 (const_string "lea") 10626 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10627 (match_operand 0 "register_operand")) 10628 (match_operand 2 "const1_operand")) 10629 (const_string "alu") 10630 ] 10631 (const_string "ishift"))) 10632 (set (attr "length_immediate") 10633 (if_then_else 10634 (ior (eq_attr "type" "alu") 10635 (and (eq_attr "type" "ishift") 10636 (and (match_operand 2 "const1_operand") 10637 (ior (match_test "TARGET_SHIFT1") 10638 (match_test "optimize_function_for_size_p (cfun)"))))) 10639 (const_string "0") 10640 (const_string "*"))) 10641 (set_attr "mode" "HI,SI")]) 10642 10643(define_insn "*ashlqi3_1" 10644 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") 10645 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 10646 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 10647 (clobber (reg:CC FLAGS_REG))] 10648 "ix86_binary_operator_ok (ASHIFT, QImode, operands)" 10649{ 10650 switch (get_attr_type (insn)) 10651 { 10652 case TYPE_LEA: 10653 return "#"; 10654 10655 case TYPE_ALU: 10656 gcc_assert (operands[2] == const1_rtx); 10657 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1]))) 10658 return "add{l}\t%k0, %k0"; 10659 else 10660 return "add{b}\t%0, %0"; 10661 10662 default: 10663 if (operands[2] == const1_rtx 10664 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10665 { 10666 if (get_attr_mode (insn) == MODE_SI) 10667 return "sal{l}\t%k0"; 10668 else 10669 return "sal{b}\t%0"; 10670 } 10671 else 10672 { 10673 if (get_attr_mode (insn) == MODE_SI) 10674 return "sal{l}\t{%2, %k0|%k0, %2}"; 10675 else 10676 return "sal{b}\t{%2, %0|%0, %2}"; 10677 } 10678 } 10679} 10680 [(set (attr "type") 10681 (cond [(eq_attr "alternative" "2") 10682 (const_string "lea") 10683 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10684 (match_operand 0 "register_operand")) 10685 (match_operand 2 "const1_operand")) 10686 (const_string "alu") 10687 ] 10688 (const_string "ishift"))) 10689 (set (attr "length_immediate") 10690 (if_then_else 10691 (ior (eq_attr "type" "alu") 10692 (and (eq_attr "type" "ishift") 10693 (and (match_operand 2 "const1_operand") 10694 (ior (match_test "TARGET_SHIFT1") 10695 (match_test "optimize_function_for_size_p (cfun)"))))) 10696 (const_string "0") 10697 (const_string "*"))) 10698 (set_attr "mode" "QI,SI,SI") 10699 ;; Potential partial reg stall on alternative 1. 10700 (set (attr "preferred_for_speed") 10701 (cond [(eq_attr "alternative" "1") 10702 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 10703 (symbol_ref "true")))]) 10704 10705(define_insn "*ashlqi3_1_slp" 10706 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10707 (ashift:QI (match_dup 0) 10708 (match_operand:QI 1 "nonmemory_operand" "cI"))) 10709 (clobber (reg:CC FLAGS_REG))] 10710 "(optimize_function_for_size_p (cfun) 10711 || !TARGET_PARTIAL_FLAG_REG_STALL 10712 || (operands[1] == const1_rtx 10713 && (TARGET_SHIFT1 10714 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 10715{ 10716 switch (get_attr_type (insn)) 10717 { 10718 case TYPE_ALU1: 10719 gcc_assert (operands[1] == const1_rtx); 10720 return "add{b}\t%0, %0"; 10721 10722 default: 10723 if (operands[1] == const1_rtx 10724 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10725 return "sal{b}\t%0"; 10726 else 10727 return "sal{b}\t{%1, %0|%0, %1}"; 10728 } 10729} 10730 [(set (attr "type") 10731 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10732 (match_operand 0 "register_operand")) 10733 (match_operand 1 "const1_operand")) 10734 (const_string "alu1") 10735 ] 10736 (const_string "ishift1"))) 10737 (set (attr "length_immediate") 10738 (if_then_else 10739 (ior (eq_attr "type" "alu1") 10740 (and (eq_attr "type" "ishift1") 10741 (and (match_operand 1 "const1_operand") 10742 (ior (match_test "TARGET_SHIFT1") 10743 (match_test "optimize_function_for_size_p (cfun)"))))) 10744 (const_string "0") 10745 (const_string "*"))) 10746 (set_attr "mode" "QI")]) 10747 10748;; Convert ashift to the lea pattern to avoid flags dependency. 10749(define_split 10750 [(set (match_operand:SWI 0 "register_operand") 10751 (ashift:SWI (match_operand:SWI 1 "index_register_operand") 10752 (match_operand 2 "const_0_to_3_operand"))) 10753 (clobber (reg:CC FLAGS_REG))] 10754 "reload_completed 10755 && REGNO (operands[0]) != REGNO (operands[1])" 10756 [(set (match_dup 0) 10757 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))] 10758{ 10759 if (<MODE>mode != <LEAMODE>mode) 10760 { 10761 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]); 10762 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]); 10763 } 10764 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10765}) 10766 10767;; Convert ashift to the lea pattern to avoid flags dependency. 10768(define_split 10769 [(set (match_operand:DI 0 "register_operand") 10770 (zero_extend:DI 10771 (ashift:SI (match_operand:SI 1 "index_register_operand") 10772 (match_operand 2 "const_0_to_3_operand")))) 10773 (clobber (reg:CC FLAGS_REG))] 10774 "TARGET_64BIT && reload_completed 10775 && REGNO (operands[0]) != REGNO (operands[1])" 10776 [(set (match_dup 0) 10777 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))] 10778{ 10779 operands[1] = gen_lowpart (SImode, operands[1]); 10780 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10781}) 10782 10783;; This pattern can't accept a variable shift count, since shifts by 10784;; zero don't affect the flags. We assume that shifts by constant 10785;; zero are optimized away. 10786(define_insn "*ashl<mode>3_cmp" 10787 [(set (reg FLAGS_REG) 10788 (compare 10789 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") 10790 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10791 (const_int 0))) 10792 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10793 (ashift:SWI (match_dup 1) (match_dup 2)))] 10794 "(optimize_function_for_size_p (cfun) 10795 || !TARGET_PARTIAL_FLAG_REG_STALL 10796 || (operands[2] == const1_rtx 10797 && (TARGET_SHIFT1 10798 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) 10799 && ix86_match_ccmode (insn, CCGOCmode) 10800 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 10801{ 10802 switch (get_attr_type (insn)) 10803 { 10804 case TYPE_ALU: 10805 gcc_assert (operands[2] == const1_rtx); 10806 return "add{<imodesuffix>}\t%0, %0"; 10807 10808 default: 10809 if (operands[2] == const1_rtx 10810 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10811 return "sal{<imodesuffix>}\t%0"; 10812 else 10813 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10814 } 10815} 10816 [(set (attr "type") 10817 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10818 (match_operand 0 "register_operand")) 10819 (match_operand 2 "const1_operand")) 10820 (const_string "alu") 10821 ] 10822 (const_string "ishift"))) 10823 (set (attr "length_immediate") 10824 (if_then_else 10825 (ior (eq_attr "type" "alu") 10826 (and (eq_attr "type" "ishift") 10827 (and (match_operand 2 "const1_operand") 10828 (ior (match_test "TARGET_SHIFT1") 10829 (match_test "optimize_function_for_size_p (cfun)"))))) 10830 (const_string "0") 10831 (const_string "*"))) 10832 (set_attr "mode" "<MODE>")]) 10833 10834(define_insn "*ashlsi3_cmp_zext" 10835 [(set (reg FLAGS_REG) 10836 (compare 10837 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10838 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10839 (const_int 0))) 10840 (set (match_operand:DI 0 "register_operand" "=r") 10841 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10842 "TARGET_64BIT 10843 && (optimize_function_for_size_p (cfun) 10844 || !TARGET_PARTIAL_FLAG_REG_STALL 10845 || (operands[2] == const1_rtx 10846 && (TARGET_SHIFT1 10847 || TARGET_DOUBLE_WITH_ADD))) 10848 && ix86_match_ccmode (insn, CCGOCmode) 10849 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10850{ 10851 switch (get_attr_type (insn)) 10852 { 10853 case TYPE_ALU: 10854 gcc_assert (operands[2] == const1_rtx); 10855 return "add{l}\t%k0, %k0"; 10856 10857 default: 10858 if (operands[2] == const1_rtx 10859 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10860 return "sal{l}\t%k0"; 10861 else 10862 return "sal{l}\t{%2, %k0|%k0, %2}"; 10863 } 10864} 10865 [(set (attr "type") 10866 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 10867 (match_operand 2 "const1_operand")) 10868 (const_string "alu") 10869 ] 10870 (const_string "ishift"))) 10871 (set (attr "length_immediate") 10872 (if_then_else 10873 (ior (eq_attr "type" "alu") 10874 (and (eq_attr "type" "ishift") 10875 (and (match_operand 2 "const1_operand") 10876 (ior (match_test "TARGET_SHIFT1") 10877 (match_test "optimize_function_for_size_p (cfun)"))))) 10878 (const_string "0") 10879 (const_string "*"))) 10880 (set_attr "mode" "SI")]) 10881 10882(define_insn "*ashl<mode>3_cconly" 10883 [(set (reg FLAGS_REG) 10884 (compare 10885 (ashift:SWI (match_operand:SWI 1 "register_operand" "0") 10886 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10887 (const_int 0))) 10888 (clobber (match_scratch:SWI 0 "=<r>"))] 10889 "(optimize_function_for_size_p (cfun) 10890 || !TARGET_PARTIAL_FLAG_REG_STALL 10891 || (operands[2] == const1_rtx 10892 && (TARGET_SHIFT1 10893 || TARGET_DOUBLE_WITH_ADD))) 10894 && ix86_match_ccmode (insn, CCGOCmode)" 10895{ 10896 switch (get_attr_type (insn)) 10897 { 10898 case TYPE_ALU: 10899 gcc_assert (operands[2] == const1_rtx); 10900 return "add{<imodesuffix>}\t%0, %0"; 10901 10902 default: 10903 if (operands[2] == const1_rtx 10904 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10905 return "sal{<imodesuffix>}\t%0"; 10906 else 10907 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10908 } 10909} 10910 [(set (attr "type") 10911 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10912 (match_operand 0 "register_operand")) 10913 (match_operand 2 "const1_operand")) 10914 (const_string "alu") 10915 ] 10916 (const_string "ishift"))) 10917 (set (attr "length_immediate") 10918 (if_then_else 10919 (ior (eq_attr "type" "alu") 10920 (and (eq_attr "type" "ishift") 10921 (and (match_operand 2 "const1_operand") 10922 (ior (match_test "TARGET_SHIFT1") 10923 (match_test "optimize_function_for_size_p (cfun)"))))) 10924 (const_string "0") 10925 (const_string "*"))) 10926 (set_attr "mode" "<MODE>")]) 10927 10928;; See comment above `ashl<mode>3' about how this works. 10929 10930(define_expand "<shift_insn><mode>3" 10931 [(set (match_operand:SDWIM 0 "<shift_operand>") 10932 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>") 10933 (match_operand:QI 2 "nonmemory_operand")))] 10934 "" 10935 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 10936 10937;; Avoid useless masking of count operand. 10938(define_insn_and_split "*<shift_insn><mode>3_mask" 10939 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10940 (any_shiftrt:SWI48 10941 (match_operand:SWI48 1 "nonimmediate_operand") 10942 (subreg:QI 10943 (and:SI 10944 (match_operand:SI 2 "register_operand" "c,r") 10945 (match_operand:SI 3 "const_int_operand")) 0))) 10946 (clobber (reg:CC FLAGS_REG))] 10947 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10948 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10949 == GET_MODE_BITSIZE (<MODE>mode)-1 10950 && can_create_pseudo_p ()" 10951 "#" 10952 "&& 1" 10953 [(parallel 10954 [(set (match_dup 0) 10955 (any_shiftrt:SWI48 (match_dup 1) 10956 (match_dup 2))) 10957 (clobber (reg:CC FLAGS_REG))])] 10958 "operands[2] = gen_lowpart (QImode, operands[2]);" 10959 [(set_attr "isa" "*,bmi2")]) 10960 10961(define_insn_and_split "*<shift_insn><mode>3_mask_1" 10962 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10963 (any_shiftrt:SWI48 10964 (match_operand:SWI48 1 "nonimmediate_operand") 10965 (and:QI 10966 (match_operand:QI 2 "register_operand" "c,r") 10967 (match_operand:QI 3 "const_int_operand")))) 10968 (clobber (reg:CC FLAGS_REG))] 10969 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10970 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10971 == GET_MODE_BITSIZE (<MODE>mode)-1 10972 && can_create_pseudo_p ()" 10973 "#" 10974 "&& 1" 10975 [(parallel 10976 [(set (match_dup 0) 10977 (any_shiftrt:SWI48 (match_dup 1) 10978 (match_dup 2))) 10979 (clobber (reg:CC FLAGS_REG))])] 10980 "" 10981 [(set_attr "isa" "*,bmi2")]) 10982 10983(define_insn_and_split "*<shift_insn><mode>3_doubleword" 10984 [(set (match_operand:DWI 0 "register_operand" "=&r") 10985 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") 10986 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 10987 (clobber (reg:CC FLAGS_REG))] 10988 "" 10989 "#" 10990 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 10991 [(const_int 0)] 10992 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;" 10993 [(set_attr "type" "multi")]) 10994 10995;; By default we don't ask for a scratch register, because when DWImode 10996;; values are manipulated, registers are already at a premium. But if 10997;; we have one handy, we won't turn it away. 10998 10999(define_peephole2 11000 [(match_scratch:DWIH 3 "r") 11001 (parallel [(set (match_operand:<DWI> 0 "register_operand") 11002 (any_shiftrt:<DWI> 11003 (match_operand:<DWI> 1 "register_operand") 11004 (match_operand:QI 2 "nonmemory_operand"))) 11005 (clobber (reg:CC FLAGS_REG))]) 11006 (match_dup 3)] 11007 "TARGET_CMOVE" 11008 [(const_int 0)] 11009 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;") 11010 11011(define_insn "x86_64_shrd" 11012 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 11013 (ior:DI (lshiftrt:DI (match_dup 0) 11014 (match_operand:QI 2 "nonmemory_operand" "Jc")) 11015 (ashift:DI (match_operand:DI 1 "register_operand" "r") 11016 (minus:QI (const_int 64) (match_dup 2))))) 11017 (clobber (reg:CC FLAGS_REG))] 11018 "TARGET_64BIT" 11019 "shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11020 [(set_attr "type" "ishift") 11021 (set_attr "prefix_0f" "1") 11022 (set_attr "mode" "DI") 11023 (set_attr "athlon_decode" "vector") 11024 (set_attr "amdfam10_decode" "vector") 11025 (set_attr "bdver1_decode" "vector")]) 11026 11027(define_insn "x86_shrd" 11028 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 11029 (ior:SI (lshiftrt:SI (match_dup 0) 11030 (match_operand:QI 2 "nonmemory_operand" "Ic")) 11031 (ashift:SI (match_operand:SI 1 "register_operand" "r") 11032 (minus:QI (const_int 32) (match_dup 2))))) 11033 (clobber (reg:CC FLAGS_REG))] 11034 "" 11035 "shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11036 [(set_attr "type" "ishift") 11037 (set_attr "prefix_0f" "1") 11038 (set_attr "mode" "SI") 11039 (set_attr "pent_pair" "np") 11040 (set_attr "athlon_decode" "vector") 11041 (set_attr "amdfam10_decode" "vector") 11042 (set_attr "bdver1_decode" "vector")]) 11043 11044(define_insn "ashrdi3_cvt" 11045 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 11046 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 11047 (match_operand:QI 2 "const_int_operand"))) 11048 (clobber (reg:CC FLAGS_REG))] 11049 "TARGET_64BIT && INTVAL (operands[2]) == 63 11050 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11051 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 11052 "@ 11053 {cqto|cqo} 11054 sar{q}\t{%2, %0|%0, %2}" 11055 [(set_attr "type" "imovx,ishift") 11056 (set_attr "prefix_0f" "0,*") 11057 (set_attr "length_immediate" "0,*") 11058 (set_attr "modrm" "0,1") 11059 (set_attr "mode" "DI")]) 11060 11061(define_insn "*ashrsi3_cvt_zext" 11062 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11063 (zero_extend:DI 11064 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11065 (match_operand:QI 2 "const_int_operand")))) 11066 (clobber (reg:CC FLAGS_REG))] 11067 "TARGET_64BIT && INTVAL (operands[2]) == 31 11068 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11069 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11070 "@ 11071 {cltd|cdq} 11072 sar{l}\t{%2, %k0|%k0, %2}" 11073 [(set_attr "type" "imovx,ishift") 11074 (set_attr "prefix_0f" "0,*") 11075 (set_attr "length_immediate" "0,*") 11076 (set_attr "modrm" "0,1") 11077 (set_attr "mode" "SI")]) 11078 11079(define_insn "ashrsi3_cvt" 11080 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 11081 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 11082 (match_operand:QI 2 "const_int_operand"))) 11083 (clobber (reg:CC FLAGS_REG))] 11084 "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, %0|%0, %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_expand "x86_shift<mode>_adj_3" 11097 [(use (match_operand:SWI48 0 "register_operand")) 11098 (use (match_operand:SWI48 1 "register_operand")) 11099 (use (match_operand:QI 2 "register_operand"))] 11100 "" 11101{ 11102 rtx_code_label *label = gen_label_rtx (); 11103 rtx tmp; 11104 11105 emit_insn (gen_testqi_ccz_1 (operands[2], 11106 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 11107 11108 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11109 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11110 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11111 gen_rtx_LABEL_REF (VOIDmode, label), 11112 pc_rtx); 11113 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 11114 JUMP_LABEL (tmp) = label; 11115 11116 emit_move_insn (operands[0], operands[1]); 11117 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1], 11118 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1))); 11119 emit_label (label); 11120 LABEL_NUSES (label) = 1; 11121 11122 DONE; 11123}) 11124 11125(define_insn "*bmi2_<shift_insn><mode>3_1" 11126 [(set (match_operand:SWI48 0 "register_operand" "=r") 11127 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 11128 (match_operand:SWI48 2 "register_operand" "r")))] 11129 "TARGET_BMI2" 11130 "<shift>x\t{%2, %1, %0|%0, %1, %2}" 11131 [(set_attr "type" "ishiftx") 11132 (set_attr "mode" "<MODE>")]) 11133 11134(define_insn "*<shift_insn><mode>3_1" 11135 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 11136 (any_shiftrt:SWI48 11137 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 11138 (match_operand:QI 2 "nonmemory_operand" "c<S>,r"))) 11139 (clobber (reg:CC FLAGS_REG))] 11140 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11141{ 11142 switch (get_attr_type (insn)) 11143 { 11144 case TYPE_ISHIFTX: 11145 return "#"; 11146 11147 default: 11148 if (operands[2] == const1_rtx 11149 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11150 return "<shift>{<imodesuffix>}\t%0"; 11151 else 11152 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11153 } 11154} 11155 [(set_attr "isa" "*,bmi2") 11156 (set_attr "type" "ishift,ishiftx") 11157 (set (attr "length_immediate") 11158 (if_then_else 11159 (and (match_operand 2 "const1_operand") 11160 (ior (match_test "TARGET_SHIFT1") 11161 (match_test "optimize_function_for_size_p (cfun)"))) 11162 (const_string "0") 11163 (const_string "*"))) 11164 (set_attr "mode" "<MODE>")]) 11165 11166;; Convert shift to the shiftx pattern to avoid flags dependency. 11167(define_split 11168 [(set (match_operand:SWI48 0 "register_operand") 11169 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11170 (match_operand:QI 2 "register_operand"))) 11171 (clobber (reg:CC FLAGS_REG))] 11172 "TARGET_BMI2 && reload_completed" 11173 [(set (match_dup 0) 11174 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))] 11175 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 11176 11177(define_insn "*bmi2_<shift_insn>si3_1_zext" 11178 [(set (match_operand:DI 0 "register_operand" "=r") 11179 (zero_extend:DI 11180 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 11181 (match_operand:SI 2 "register_operand" "r"))))] 11182 "TARGET_64BIT && TARGET_BMI2" 11183 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}" 11184 [(set_attr "type" "ishiftx") 11185 (set_attr "mode" "SI")]) 11186 11187(define_insn "*<shift_insn>si3_1_zext" 11188 [(set (match_operand:DI 0 "register_operand" "=r,r") 11189 (zero_extend:DI 11190 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 11191 (match_operand:QI 2 "nonmemory_operand" "cI,r")))) 11192 (clobber (reg:CC FLAGS_REG))] 11193 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11194{ 11195 switch (get_attr_type (insn)) 11196 { 11197 case TYPE_ISHIFTX: 11198 return "#"; 11199 11200 default: 11201 if (operands[2] == const1_rtx 11202 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11203 return "<shift>{l}\t%k0"; 11204 else 11205 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 11206 } 11207} 11208 [(set_attr "isa" "*,bmi2") 11209 (set_attr "type" "ishift,ishiftx") 11210 (set (attr "length_immediate") 11211 (if_then_else 11212 (and (match_operand 2 "const1_operand") 11213 (ior (match_test "TARGET_SHIFT1") 11214 (match_test "optimize_function_for_size_p (cfun)"))) 11215 (const_string "0") 11216 (const_string "*"))) 11217 (set_attr "mode" "SI")]) 11218 11219;; Convert shift to the shiftx pattern to avoid flags dependency. 11220(define_split 11221 [(set (match_operand:DI 0 "register_operand") 11222 (zero_extend:DI 11223 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand") 11224 (match_operand:QI 2 "register_operand")))) 11225 (clobber (reg:CC FLAGS_REG))] 11226 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11227 [(set (match_dup 0) 11228 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 11229 "operands[2] = gen_lowpart (SImode, operands[2]);") 11230 11231(define_insn "*<shift_insn><mode>3_1" 11232 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 11233 (any_shiftrt:SWI12 11234 (match_operand:SWI12 1 "nonimmediate_operand" "0") 11235 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 11236 (clobber (reg:CC FLAGS_REG))] 11237 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11238{ 11239 if (operands[2] == const1_rtx 11240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11241 return "<shift>{<imodesuffix>}\t%0"; 11242 else 11243 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11244} 11245 [(set_attr "type" "ishift") 11246 (set (attr "length_immediate") 11247 (if_then_else 11248 (and (match_operand 2 "const1_operand") 11249 (ior (match_test "TARGET_SHIFT1") 11250 (match_test "optimize_function_for_size_p (cfun)"))) 11251 (const_string "0") 11252 (const_string "*"))) 11253 (set_attr "mode" "<MODE>")]) 11254 11255(define_insn "*<shift_insn>qi3_1_slp" 11256 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11257 (any_shiftrt:QI (match_dup 0) 11258 (match_operand:QI 1 "nonmemory_operand" "cI"))) 11259 (clobber (reg:CC FLAGS_REG))] 11260 "(optimize_function_for_size_p (cfun) 11261 || !TARGET_PARTIAL_REG_STALL 11262 || (operands[1] == const1_rtx 11263 && TARGET_SHIFT1))" 11264{ 11265 if (operands[1] == const1_rtx 11266 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11267 return "<shift>{b}\t%0"; 11268 else 11269 return "<shift>{b}\t{%1, %0|%0, %1}"; 11270} 11271 [(set_attr "type" "ishift1") 11272 (set (attr "length_immediate") 11273 (if_then_else 11274 (and (match_operand 1 "const1_operand") 11275 (ior (match_test "TARGET_SHIFT1") 11276 (match_test "optimize_function_for_size_p (cfun)"))) 11277 (const_string "0") 11278 (const_string "*"))) 11279 (set_attr "mode" "QI")]) 11280 11281;; This pattern can't accept a variable shift count, since shifts by 11282;; zero don't affect the flags. We assume that shifts by constant 11283;; zero are optimized away. 11284(define_insn "*<shift_insn><mode>3_cmp" 11285 [(set (reg FLAGS_REG) 11286 (compare 11287 (any_shiftrt:SWI 11288 (match_operand:SWI 1 "nonimmediate_operand" "0") 11289 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11290 (const_int 0))) 11291 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 11292 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] 11293 "(optimize_function_for_size_p (cfun) 11294 || !TARGET_PARTIAL_FLAG_REG_STALL 11295 || (operands[2] == const1_rtx 11296 && TARGET_SHIFT1)) 11297 && ix86_match_ccmode (insn, CCGOCmode) 11298 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11299{ 11300 if (operands[2] == const1_rtx 11301 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11302 return "<shift>{<imodesuffix>}\t%0"; 11303 else 11304 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11305} 11306 [(set_attr "type" "ishift") 11307 (set (attr "length_immediate") 11308 (if_then_else 11309 (and (match_operand 2 "const1_operand") 11310 (ior (match_test "TARGET_SHIFT1") 11311 (match_test "optimize_function_for_size_p (cfun)"))) 11312 (const_string "0") 11313 (const_string "*"))) 11314 (set_attr "mode" "<MODE>")]) 11315 11316(define_insn "*<shift_insn>si3_cmp_zext" 11317 [(set (reg FLAGS_REG) 11318 (compare 11319 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") 11320 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11321 (const_int 0))) 11322 (set (match_operand:DI 0 "register_operand" "=r") 11323 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 11324 "TARGET_64BIT 11325 && (optimize_function_for_size_p (cfun) 11326 || !TARGET_PARTIAL_FLAG_REG_STALL 11327 || (operands[2] == const1_rtx 11328 && TARGET_SHIFT1)) 11329 && ix86_match_ccmode (insn, CCGOCmode) 11330 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11331{ 11332 if (operands[2] == const1_rtx 11333 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11334 return "<shift>{l}\t%k0"; 11335 else 11336 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 11337} 11338 [(set_attr "type" "ishift") 11339 (set (attr "length_immediate") 11340 (if_then_else 11341 (and (match_operand 2 "const1_operand") 11342 (ior (match_test "TARGET_SHIFT1") 11343 (match_test "optimize_function_for_size_p (cfun)"))) 11344 (const_string "0") 11345 (const_string "*"))) 11346 (set_attr "mode" "SI")]) 11347 11348(define_insn "*<shift_insn><mode>3_cconly" 11349 [(set (reg FLAGS_REG) 11350 (compare 11351 (any_shiftrt:SWI 11352 (match_operand:SWI 1 "register_operand" "0") 11353 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11354 (const_int 0))) 11355 (clobber (match_scratch:SWI 0 "=<r>"))] 11356 "(optimize_function_for_size_p (cfun) 11357 || !TARGET_PARTIAL_FLAG_REG_STALL 11358 || (operands[2] == const1_rtx 11359 && TARGET_SHIFT1)) 11360 && ix86_match_ccmode (insn, CCGOCmode)" 11361{ 11362 if (operands[2] == const1_rtx 11363 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11364 return "<shift>{<imodesuffix>}\t%0"; 11365 else 11366 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11367} 11368 [(set_attr "type" "ishift") 11369 (set (attr "length_immediate") 11370 (if_then_else 11371 (and (match_operand 2 "const1_operand") 11372 (ior (match_test "TARGET_SHIFT1") 11373 (match_test "optimize_function_for_size_p (cfun)"))) 11374 (const_string "0") 11375 (const_string "*"))) 11376 (set_attr "mode" "<MODE>")]) 11377 11378;; Rotate instructions 11379 11380(define_expand "<rotate_insn>ti3" 11381 [(set (match_operand:TI 0 "register_operand") 11382 (any_rotate:TI (match_operand:TI 1 "register_operand") 11383 (match_operand:QI 2 "nonmemory_operand")))] 11384 "TARGET_64BIT" 11385{ 11386 if (const_1_to_63_operand (operands[2], VOIDmode)) 11387 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword 11388 (operands[0], operands[1], operands[2])); 11389 else 11390 FAIL; 11391 11392 DONE; 11393}) 11394 11395(define_expand "<rotate_insn>di3" 11396 [(set (match_operand:DI 0 "shiftdi_operand") 11397 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand") 11398 (match_operand:QI 2 "nonmemory_operand")))] 11399 "" 11400{ 11401 if (TARGET_64BIT) 11402 ix86_expand_binary_operator (<CODE>, DImode, operands); 11403 else if (const_1_to_31_operand (operands[2], VOIDmode)) 11404 emit_insn (gen_ix86_<rotate_insn>di3_doubleword 11405 (operands[0], operands[1], operands[2])); 11406 else 11407 FAIL; 11408 11409 DONE; 11410}) 11411 11412(define_expand "<rotate_insn><mode>3" 11413 [(set (match_operand:SWIM124 0 "nonimmediate_operand") 11414 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand") 11415 (match_operand:QI 2 "nonmemory_operand")))] 11416 "" 11417 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 11418 11419;; Avoid useless masking of count operand. 11420(define_insn_and_split "*<rotate_insn><mode>3_mask" 11421 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11422 (any_rotate:SWI48 11423 (match_operand:SWI48 1 "nonimmediate_operand") 11424 (subreg:QI 11425 (and:SI 11426 (match_operand:SI 2 "register_operand" "c") 11427 (match_operand:SI 3 "const_int_operand")) 0))) 11428 (clobber (reg:CC FLAGS_REG))] 11429 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11430 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11431 == GET_MODE_BITSIZE (<MODE>mode)-1 11432 && can_create_pseudo_p ()" 11433 "#" 11434 "&& 1" 11435 [(parallel 11436 [(set (match_dup 0) 11437 (any_rotate:SWI48 (match_dup 1) 11438 (match_dup 2))) 11439 (clobber (reg:CC FLAGS_REG))])] 11440 "operands[2] = gen_lowpart (QImode, operands[2]);") 11441 11442(define_insn_and_split "*<rotate_insn><mode>3_mask_1" 11443 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11444 (any_rotate:SWI48 11445 (match_operand:SWI48 1 "nonimmediate_operand") 11446 (and:QI 11447 (match_operand:QI 2 "register_operand" "c") 11448 (match_operand:QI 3 "const_int_operand")))) 11449 (clobber (reg:CC FLAGS_REG))] 11450 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11451 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11452 == GET_MODE_BITSIZE (<MODE>mode)-1 11453 && can_create_pseudo_p ()" 11454 "#" 11455 "&& 1" 11456 [(parallel 11457 [(set (match_dup 0) 11458 (any_rotate:SWI48 (match_dup 1) 11459 (match_dup 2))) 11460 (clobber (reg:CC FLAGS_REG))])]) 11461 11462;; Implement rotation using two double-precision 11463;; shift instructions and a scratch register. 11464 11465(define_insn_and_split "ix86_rotl<dwi>3_doubleword" 11466 [(set (match_operand:<DWI> 0 "register_operand" "=r") 11467 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 11468 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 11469 (clobber (reg:CC FLAGS_REG)) 11470 (clobber (match_scratch:DWIH 3 "=&r"))] 11471 "" 11472 "#" 11473 "reload_completed" 11474 [(set (match_dup 3) (match_dup 4)) 11475 (parallel 11476 [(set (match_dup 4) 11477 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) 11478 (lshiftrt:DWIH (match_dup 5) 11479 (minus:QI (match_dup 6) (match_dup 2))))) 11480 (clobber (reg:CC FLAGS_REG))]) 11481 (parallel 11482 [(set (match_dup 5) 11483 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) 11484 (lshiftrt:DWIH (match_dup 3) 11485 (minus:QI (match_dup 6) (match_dup 2))))) 11486 (clobber (reg:CC FLAGS_REG))])] 11487{ 11488 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 11489 11490 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 11491}) 11492 11493(define_insn_and_split "ix86_rotr<dwi>3_doubleword" 11494 [(set (match_operand:<DWI> 0 "register_operand" "=r") 11495 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 11496 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 11497 (clobber (reg:CC FLAGS_REG)) 11498 (clobber (match_scratch:DWIH 3 "=&r"))] 11499 "" 11500 "#" 11501 "reload_completed" 11502 [(set (match_dup 3) (match_dup 4)) 11503 (parallel 11504 [(set (match_dup 4) 11505 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) 11506 (ashift:DWIH (match_dup 5) 11507 (minus:QI (match_dup 6) (match_dup 2))))) 11508 (clobber (reg:CC FLAGS_REG))]) 11509 (parallel 11510 [(set (match_dup 5) 11511 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2)) 11512 (ashift:DWIH (match_dup 3) 11513 (minus:QI (match_dup 6) (match_dup 2))))) 11514 (clobber (reg:CC FLAGS_REG))])] 11515{ 11516 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 11517 11518 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 11519}) 11520 11521(define_mode_attr rorx_immediate_operand 11522 [(SI "const_0_to_31_operand") 11523 (DI "const_0_to_63_operand")]) 11524 11525(define_insn "*bmi2_rorx<mode>3_1" 11526 [(set (match_operand:SWI48 0 "register_operand" "=r") 11527 (rotatert:SWI48 11528 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 11529 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))] 11530 "TARGET_BMI2" 11531 "rorx\t{%2, %1, %0|%0, %1, %2}" 11532 [(set_attr "type" "rotatex") 11533 (set_attr "mode" "<MODE>")]) 11534 11535(define_insn "*<rotate_insn><mode>3_1" 11536 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 11537 (any_rotate:SWI48 11538 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 11539 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>"))) 11540 (clobber (reg:CC FLAGS_REG))] 11541 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11542{ 11543 switch (get_attr_type (insn)) 11544 { 11545 case TYPE_ROTATEX: 11546 return "#"; 11547 11548 default: 11549 if (operands[2] == const1_rtx 11550 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11551 return "<rotate>{<imodesuffix>}\t%0"; 11552 else 11553 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11554 } 11555} 11556 [(set_attr "isa" "*,bmi2") 11557 (set_attr "type" "rotate,rotatex") 11558 (set (attr "length_immediate") 11559 (if_then_else 11560 (and (eq_attr "type" "rotate") 11561 (and (match_operand 2 "const1_operand") 11562 (ior (match_test "TARGET_SHIFT1") 11563 (match_test "optimize_function_for_size_p (cfun)")))) 11564 (const_string "0") 11565 (const_string "*"))) 11566 (set_attr "mode" "<MODE>")]) 11567 11568;; Convert rotate to the rotatex pattern to avoid flags dependency. 11569(define_split 11570 [(set (match_operand:SWI48 0 "register_operand") 11571 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11572 (match_operand:QI 2 "const_int_operand"))) 11573 (clobber (reg:CC FLAGS_REG))] 11574 "TARGET_BMI2 && reload_completed" 11575 [(set (match_dup 0) 11576 (rotatert:SWI48 (match_dup 1) (match_dup 2)))] 11577{ 11578 int bitsize = GET_MODE_BITSIZE (<MODE>mode); 11579 11580 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize); 11581}) 11582 11583(define_split 11584 [(set (match_operand:SWI48 0 "register_operand") 11585 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11586 (match_operand:QI 2 "const_int_operand"))) 11587 (clobber (reg:CC FLAGS_REG))] 11588 "TARGET_BMI2 && reload_completed" 11589 [(set (match_dup 0) 11590 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]) 11591 11592(define_insn "*bmi2_rorxsi3_1_zext" 11593 [(set (match_operand:DI 0 "register_operand" "=r") 11594 (zero_extend:DI 11595 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 11596 (match_operand:QI 2 "const_0_to_31_operand" "I"))))] 11597 "TARGET_64BIT && TARGET_BMI2" 11598 "rorx\t{%2, %1, %k0|%k0, %1, %2}" 11599 [(set_attr "type" "rotatex") 11600 (set_attr "mode" "SI")]) 11601 11602(define_insn "*<rotate_insn>si3_1_zext" 11603 [(set (match_operand:DI 0 "register_operand" "=r,r") 11604 (zero_extend:DI 11605 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 11606 (match_operand:QI 2 "nonmemory_operand" "cI,I")))) 11607 (clobber (reg:CC FLAGS_REG))] 11608 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11609{ 11610 switch (get_attr_type (insn)) 11611 { 11612 case TYPE_ROTATEX: 11613 return "#"; 11614 11615 default: 11616 if (operands[2] == const1_rtx 11617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11618 return "<rotate>{l}\t%k0"; 11619 else 11620 return "<rotate>{l}\t{%2, %k0|%k0, %2}"; 11621 } 11622} 11623 [(set_attr "isa" "*,bmi2") 11624 (set_attr "type" "rotate,rotatex") 11625 (set (attr "length_immediate") 11626 (if_then_else 11627 (and (eq_attr "type" "rotate") 11628 (and (match_operand 2 "const1_operand") 11629 (ior (match_test "TARGET_SHIFT1") 11630 (match_test "optimize_function_for_size_p (cfun)")))) 11631 (const_string "0") 11632 (const_string "*"))) 11633 (set_attr "mode" "SI")]) 11634 11635;; Convert rotate to the rotatex pattern to avoid flags dependency. 11636(define_split 11637 [(set (match_operand:DI 0 "register_operand") 11638 (zero_extend:DI 11639 (rotate:SI (match_operand:SI 1 "nonimmediate_operand") 11640 (match_operand:QI 2 "const_int_operand")))) 11641 (clobber (reg:CC FLAGS_REG))] 11642 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11643 [(set (match_dup 0) 11644 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))] 11645{ 11646 int bitsize = GET_MODE_BITSIZE (SImode); 11647 11648 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize); 11649}) 11650 11651(define_split 11652 [(set (match_operand:DI 0 "register_operand") 11653 (zero_extend:DI 11654 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand") 11655 (match_operand:QI 2 "const_int_operand")))) 11656 (clobber (reg:CC FLAGS_REG))] 11657 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11658 [(set (match_dup 0) 11659 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) 11660 11661(define_insn "*<rotate_insn><mode>3_1" 11662 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 11663 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0") 11664 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 11665 (clobber (reg:CC FLAGS_REG))] 11666 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11667{ 11668 if (operands[2] == const1_rtx 11669 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11670 return "<rotate>{<imodesuffix>}\t%0"; 11671 else 11672 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11673} 11674 [(set_attr "type" "rotate") 11675 (set (attr "length_immediate") 11676 (if_then_else 11677 (and (match_operand 2 "const1_operand") 11678 (ior (match_test "TARGET_SHIFT1") 11679 (match_test "optimize_function_for_size_p (cfun)"))) 11680 (const_string "0") 11681 (const_string "*"))) 11682 (set_attr "mode" "<MODE>")]) 11683 11684(define_insn "*<rotate_insn>qi3_1_slp" 11685 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 11686 (any_rotate:QI (match_dup 0) 11687 (match_operand:QI 1 "nonmemory_operand" "cI"))) 11688 (clobber (reg:CC FLAGS_REG))] 11689 "(optimize_function_for_size_p (cfun) 11690 || !TARGET_PARTIAL_REG_STALL 11691 || (operands[1] == const1_rtx 11692 && TARGET_SHIFT1))" 11693{ 11694 if (operands[1] == const1_rtx 11695 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11696 return "<rotate>{b}\t%0"; 11697 else 11698 return "<rotate>{b}\t{%1, %0|%0, %1}"; 11699} 11700 [(set_attr "type" "rotate1") 11701 (set (attr "length_immediate") 11702 (if_then_else 11703 (and (match_operand 1 "const1_operand") 11704 (ior (match_test "TARGET_SHIFT1") 11705 (match_test "optimize_function_for_size_p (cfun)"))) 11706 (const_string "0") 11707 (const_string "*"))) 11708 (set_attr "mode" "QI")]) 11709 11710(define_split 11711 [(set (match_operand:HI 0 "QIreg_operand") 11712 (any_rotate:HI (match_dup 0) (const_int 8))) 11713 (clobber (reg:CC FLAGS_REG))] 11714 "reload_completed 11715 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" 11716 [(parallel [(set (strict_low_part (match_dup 0)) 11717 (bswap:HI (match_dup 0))) 11718 (clobber (reg:CC FLAGS_REG))])]) 11719 11720;; Bit set / bit test instructions 11721 11722;; %%% bts, btr, btc 11723 11724;; These instructions are *slow* when applied to memory. 11725 11726(define_code_attr btsc [(ior "bts") (xor "btc")]) 11727 11728(define_insn "*<btsc><mode>" 11729 [(set (match_operand:SWI48 0 "register_operand" "=r") 11730 (any_or:SWI48 11731 (ashift:SWI48 (const_int 1) 11732 (match_operand:QI 2 "register_operand" "r")) 11733 (match_operand:SWI48 1 "register_operand" "0"))) 11734 (clobber (reg:CC FLAGS_REG))] 11735 "TARGET_USE_BT" 11736 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}" 11737 [(set_attr "type" "alu1") 11738 (set_attr "prefix_0f" "1") 11739 (set_attr "znver1_decode" "double") 11740 (set_attr "mode" "<MODE>")]) 11741 11742;; Avoid useless masking of count operand. 11743(define_insn_and_split "*<btsc><mode>_mask" 11744 [(set (match_operand:SWI48 0 "register_operand") 11745 (any_or:SWI48 11746 (ashift:SWI48 11747 (const_int 1) 11748 (subreg:QI 11749 (and:SI 11750 (match_operand:SI 1 "register_operand") 11751 (match_operand:SI 2 "const_int_operand")) 0)) 11752 (match_operand:SWI48 3 "register_operand"))) 11753 (clobber (reg:CC FLAGS_REG))] 11754 "TARGET_USE_BT 11755 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11756 == GET_MODE_BITSIZE (<MODE>mode)-1 11757 && can_create_pseudo_p ()" 11758 "#" 11759 "&& 1" 11760 [(parallel 11761 [(set (match_dup 0) 11762 (any_or:SWI48 11763 (ashift:SWI48 (const_int 1) 11764 (match_dup 1)) 11765 (match_dup 3))) 11766 (clobber (reg:CC FLAGS_REG))])] 11767 "operands[1] = gen_lowpart (QImode, operands[1]);") 11768 11769(define_insn_and_split "*<btsc><mode>_mask_1" 11770 [(set (match_operand:SWI48 0 "register_operand") 11771 (any_or:SWI48 11772 (ashift:SWI48 11773 (const_int 1) 11774 (and:QI 11775 (match_operand:QI 1 "register_operand") 11776 (match_operand:QI 2 "const_int_operand"))) 11777 (match_operand:SWI48 3 "register_operand"))) 11778 (clobber (reg:CC FLAGS_REG))] 11779 "TARGET_USE_BT 11780 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11781 == GET_MODE_BITSIZE (<MODE>mode)-1 11782 && can_create_pseudo_p ()" 11783 "#" 11784 "&& 1" 11785 [(parallel 11786 [(set (match_dup 0) 11787 (any_or:SWI48 11788 (ashift:SWI48 (const_int 1) 11789 (match_dup 1)) 11790 (match_dup 3))) 11791 (clobber (reg:CC FLAGS_REG))])]) 11792 11793(define_insn "*btr<mode>" 11794 [(set (match_operand:SWI48 0 "register_operand" "=r") 11795 (and:SWI48 11796 (rotate:SWI48 (const_int -2) 11797 (match_operand:QI 2 "register_operand" "r")) 11798 (match_operand:SWI48 1 "register_operand" "0"))) 11799 (clobber (reg:CC FLAGS_REG))] 11800 "TARGET_USE_BT" 11801 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}" 11802 [(set_attr "type" "alu1") 11803 (set_attr "prefix_0f" "1") 11804 (set_attr "znver1_decode" "double") 11805 (set_attr "mode" "<MODE>")]) 11806 11807;; Avoid useless masking of count operand. 11808(define_insn_and_split "*btr<mode>_mask" 11809 [(set (match_operand:SWI48 0 "register_operand") 11810 (and:SWI48 11811 (rotate:SWI48 11812 (const_int -2) 11813 (subreg:QI 11814 (and:SI 11815 (match_operand:SI 1 "register_operand") 11816 (match_operand:SI 2 "const_int_operand")) 0)) 11817 (match_operand:SWI48 3 "register_operand"))) 11818 (clobber (reg:CC FLAGS_REG))] 11819 "TARGET_USE_BT 11820 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11821 == GET_MODE_BITSIZE (<MODE>mode)-1 11822 && can_create_pseudo_p ()" 11823 "#" 11824 "&& 1" 11825 [(parallel 11826 [(set (match_dup 0) 11827 (and:SWI48 11828 (rotate:SWI48 (const_int -2) 11829 (match_dup 1)) 11830 (match_dup 3))) 11831 (clobber (reg:CC FLAGS_REG))])] 11832 "operands[1] = gen_lowpart (QImode, operands[1]);") 11833 11834(define_insn_and_split "*btr<mode>_mask_1" 11835 [(set (match_operand:SWI48 0 "register_operand") 11836 (and:SWI48 11837 (rotate:SWI48 11838 (const_int -2) 11839 (and:QI 11840 (match_operand:QI 1 "register_operand") 11841 (match_operand:QI 2 "const_int_operand"))) 11842 (match_operand:SWI48 3 "register_operand"))) 11843 (clobber (reg:CC FLAGS_REG))] 11844 "TARGET_USE_BT 11845 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11846 == GET_MODE_BITSIZE (<MODE>mode)-1 11847 && can_create_pseudo_p ()" 11848 "#" 11849 "&& 1" 11850 [(parallel 11851 [(set (match_dup 0) 11852 (and:SWI48 11853 (rotate:SWI48 (const_int -2) 11854 (match_dup 1)) 11855 (match_dup 3))) 11856 (clobber (reg:CC FLAGS_REG))])]) 11857 11858;; These instructions are never faster than the corresponding 11859;; and/ior/xor operations when using immediate operand, so with 11860;; 32-bit there's no point. But in 64-bit, we can't hold the 11861;; relevant immediates within the instruction itself, so operating 11862;; on bits in the high 32-bits of a register becomes easier. 11863;; 11864;; These are slow on Nocona, but fast on Athlon64. We do require the use 11865;; of btrq and btcq for corner cases of post-reload expansion of absdf and 11866;; negdf respectively, so they can never be disabled entirely. 11867 11868(define_insn "*btsq_imm" 11869 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11870 (const_int 1) 11871 (match_operand 1 "const_0_to_63_operand" "J")) 11872 (const_int 1)) 11873 (clobber (reg:CC FLAGS_REG))] 11874 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11875 "bts{q}\t{%1, %0|%0, %1}" 11876 [(set_attr "type" "alu1") 11877 (set_attr "prefix_0f" "1") 11878 (set_attr "znver1_decode" "double") 11879 (set_attr "mode" "DI")]) 11880 11881(define_insn "*btrq_imm" 11882 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11883 (const_int 1) 11884 (match_operand 1 "const_0_to_63_operand" "J")) 11885 (const_int 0)) 11886 (clobber (reg:CC FLAGS_REG))] 11887 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11888 "btr{q}\t{%1, %0|%0, %1}" 11889 [(set_attr "type" "alu1") 11890 (set_attr "prefix_0f" "1") 11891 (set_attr "znver1_decode" "double") 11892 (set_attr "mode" "DI")]) 11893 11894(define_insn "*btcq_imm" 11895 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 11896 (const_int 1) 11897 (match_operand 1 "const_0_to_63_operand" "J")) 11898 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 11899 (clobber (reg:CC FLAGS_REG))] 11900 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 11901 "btc{q}\t{%1, %0|%0, %1}" 11902 [(set_attr "type" "alu1") 11903 (set_attr "prefix_0f" "1") 11904 (set_attr "znver1_decode" "double") 11905 (set_attr "mode" "DI")]) 11906 11907;; Allow Nocona to avoid these instructions if a register is available. 11908 11909(define_peephole2 11910 [(match_scratch:DI 2 "r") 11911 (parallel [(set (zero_extract:DI 11912 (match_operand:DI 0 "nonimmediate_operand") 11913 (const_int 1) 11914 (match_operand 1 "const_0_to_63_operand")) 11915 (const_int 1)) 11916 (clobber (reg:CC FLAGS_REG))])] 11917 "TARGET_64BIT && !TARGET_USE_BT" 11918 [(parallel [(set (match_dup 0) 11919 (ior:DI (match_dup 0) (match_dup 3))) 11920 (clobber (reg:CC FLAGS_REG))])] 11921{ 11922 int i = INTVAL (operands[1]); 11923 11924 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); 11925 11926 if (!x86_64_immediate_operand (operands[3], DImode)) 11927 { 11928 emit_move_insn (operands[2], operands[3]); 11929 operands[3] = operands[2]; 11930 } 11931}) 11932 11933(define_peephole2 11934 [(match_scratch:DI 2 "r") 11935 (parallel [(set (zero_extract:DI 11936 (match_operand:DI 0 "nonimmediate_operand") 11937 (const_int 1) 11938 (match_operand 1 "const_0_to_63_operand")) 11939 (const_int 0)) 11940 (clobber (reg:CC FLAGS_REG))])] 11941 "TARGET_64BIT && !TARGET_USE_BT" 11942 [(parallel [(set (match_dup 0) 11943 (and:DI (match_dup 0) (match_dup 3))) 11944 (clobber (reg:CC FLAGS_REG))])] 11945{ 11946 int i = INTVAL (operands[1]); 11947 11948 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode); 11949 11950 if (!x86_64_immediate_operand (operands[3], DImode)) 11951 { 11952 emit_move_insn (operands[2], operands[3]); 11953 operands[3] = operands[2]; 11954 } 11955}) 11956 11957(define_peephole2 11958 [(match_scratch:DI 2 "r") 11959 (parallel [(set (zero_extract:DI 11960 (match_operand:DI 0 "nonimmediate_operand") 11961 (const_int 1) 11962 (match_operand 1 "const_0_to_63_operand")) 11963 (not:DI (zero_extract:DI 11964 (match_dup 0) (const_int 1) (match_dup 1)))) 11965 (clobber (reg:CC FLAGS_REG))])] 11966 "TARGET_64BIT && !TARGET_USE_BT" 11967 [(parallel [(set (match_dup 0) 11968 (xor:DI (match_dup 0) (match_dup 3))) 11969 (clobber (reg:CC FLAGS_REG))])] 11970{ 11971 int i = INTVAL (operands[1]); 11972 11973 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); 11974 11975 if (!x86_64_immediate_operand (operands[3], DImode)) 11976 { 11977 emit_move_insn (operands[2], operands[3]); 11978 operands[3] = operands[2]; 11979 } 11980}) 11981 11982;; %%% bt 11983 11984(define_insn "*bt<mode>" 11985 [(set (reg:CCC FLAGS_REG) 11986 (compare:CCC 11987 (zero_extract:SWI48 11988 (match_operand:SWI48 0 "nonimmediate_operand" "r,m") 11989 (const_int 1) 11990 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>")) 11991 (const_int 0)))] 11992 "" 11993{ 11994 switch (get_attr_mode (insn)) 11995 { 11996 case MODE_SI: 11997 return "bt{l}\t{%1, %k0|%k0, %1}"; 11998 11999 case MODE_DI: 12000 return "bt{q}\t{%q1, %0|%0, %q1}"; 12001 12002 default: 12003 gcc_unreachable (); 12004 } 12005} 12006 [(set_attr "type" "alu1") 12007 (set_attr "prefix_0f" "1") 12008 (set (attr "mode") 12009 (if_then_else 12010 (and (match_test "CONST_INT_P (operands[1])") 12011 (match_test "INTVAL (operands[1]) < 32")) 12012 (const_string "SI") 12013 (const_string "<MODE>")))]) 12014 12015(define_insn_and_split "*jcc_bt<mode>" 12016 [(set (pc) 12017 (if_then_else (match_operator 0 "bt_comparison_operator" 12018 [(zero_extract:SWI48 12019 (match_operand:SWI48 1 "nonimmediate_operand") 12020 (const_int 1) 12021 (match_operand:SI 2 "nonmemory_operand")) 12022 (const_int 0)]) 12023 (label_ref (match_operand 3)) 12024 (pc))) 12025 (clobber (reg:CC FLAGS_REG))] 12026 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12027 && (CONST_INT_P (operands[2]) 12028 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode) 12029 && INTVAL (operands[2]) 12030 >= (optimize_function_for_size_p (cfun) ? 8 : 32)) 12031 : !memory_operand (operands[1], <MODE>mode)) 12032 && can_create_pseudo_p ()" 12033 "#" 12034 "&& 1" 12035 [(set (reg:CCC FLAGS_REG) 12036 (compare:CCC 12037 (zero_extract:SWI48 12038 (match_dup 1) 12039 (const_int 1) 12040 (match_dup 2)) 12041 (const_int 0))) 12042 (set (pc) 12043 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12044 (label_ref (match_dup 3)) 12045 (pc)))] 12046{ 12047 operands[0] = shallow_copy_rtx (operands[0]); 12048 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12049}) 12050 12051(define_insn_and_split "*jcc_bt<mode>_1" 12052 [(set (pc) 12053 (if_then_else (match_operator 0 "bt_comparison_operator" 12054 [(zero_extract:SWI48 12055 (match_operand:SWI48 1 "register_operand") 12056 (const_int 1) 12057 (zero_extend:SI 12058 (match_operand:QI 2 "register_operand"))) 12059 (const_int 0)]) 12060 (label_ref (match_operand 3)) 12061 (pc))) 12062 (clobber (reg:CC FLAGS_REG))] 12063 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12064 && can_create_pseudo_p ()" 12065 "#" 12066 "&& 1" 12067 [(set (reg:CCC FLAGS_REG) 12068 (compare:CCC 12069 (zero_extract:SWI48 12070 (match_dup 1) 12071 (const_int 1) 12072 (match_dup 2)) 12073 (const_int 0))) 12074 (set (pc) 12075 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12076 (label_ref (match_dup 3)) 12077 (pc)))] 12078{ 12079 operands[2] = lowpart_subreg (SImode, operands[2], QImode); 12080 operands[0] = shallow_copy_rtx (operands[0]); 12081 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12082}) 12083 12084;; Avoid useless masking of bit offset operand. 12085(define_insn_and_split "*jcc_bt<mode>_mask" 12086 [(set (pc) 12087 (if_then_else (match_operator 0 "bt_comparison_operator" 12088 [(zero_extract:SWI48 12089 (match_operand:SWI48 1 "register_operand") 12090 (const_int 1) 12091 (and:SI 12092 (match_operand:SI 2 "register_operand") 12093 (match_operand 3 "const_int_operand")))]) 12094 (label_ref (match_operand 4)) 12095 (pc))) 12096 (clobber (reg:CC FLAGS_REG))] 12097 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12098 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 12099 == GET_MODE_BITSIZE (<MODE>mode)-1 12100 && can_create_pseudo_p ()" 12101 "#" 12102 "&& 1" 12103 [(set (reg:CCC FLAGS_REG) 12104 (compare:CCC 12105 (zero_extract:SWI48 12106 (match_dup 1) 12107 (const_int 1) 12108 (match_dup 2)) 12109 (const_int 0))) 12110 (set (pc) 12111 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12112 (label_ref (match_dup 4)) 12113 (pc)))] 12114{ 12115 operands[0] = shallow_copy_rtx (operands[0]); 12116 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12117}) 12118 12119;; Store-flag instructions. 12120 12121;; For all sCOND expanders, also expand the compare or test insn that 12122;; generates cc0. Generate an equality comparison if `seq' or `sne'. 12123 12124(define_insn_and_split "*setcc_di_1" 12125 [(set (match_operand:DI 0 "register_operand" "=q") 12126 (match_operator:DI 1 "ix86_comparison_operator" 12127 [(reg FLAGS_REG) (const_int 0)]))] 12128 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL" 12129 "#" 12130 "&& reload_completed" 12131 [(set (match_dup 2) (match_dup 1)) 12132 (set (match_dup 0) (zero_extend:DI (match_dup 2)))] 12133{ 12134 operands[1] = shallow_copy_rtx (operands[1]); 12135 PUT_MODE (operands[1], QImode); 12136 operands[2] = gen_lowpart (QImode, operands[0]); 12137}) 12138 12139(define_insn_and_split "*setcc_si_1_and" 12140 [(set (match_operand:SI 0 "register_operand" "=q") 12141 (match_operator:SI 1 "ix86_comparison_operator" 12142 [(reg FLAGS_REG) (const_int 0)])) 12143 (clobber (reg:CC FLAGS_REG))] 12144 "!TARGET_PARTIAL_REG_STALL 12145 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 12146 "#" 12147 "&& reload_completed" 12148 [(set (match_dup 2) (match_dup 1)) 12149 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) 12150 (clobber (reg:CC FLAGS_REG))])] 12151{ 12152 operands[1] = shallow_copy_rtx (operands[1]); 12153 PUT_MODE (operands[1], QImode); 12154 operands[2] = gen_lowpart (QImode, operands[0]); 12155}) 12156 12157(define_insn_and_split "*setcc_si_1_movzbl" 12158 [(set (match_operand:SI 0 "register_operand" "=q") 12159 (match_operator:SI 1 "ix86_comparison_operator" 12160 [(reg FLAGS_REG) (const_int 0)]))] 12161 "!TARGET_PARTIAL_REG_STALL 12162 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 12163 "#" 12164 "&& reload_completed" 12165 [(set (match_dup 2) (match_dup 1)) 12166 (set (match_dup 0) (zero_extend:SI (match_dup 2)))] 12167{ 12168 operands[1] = shallow_copy_rtx (operands[1]); 12169 PUT_MODE (operands[1], QImode); 12170 operands[2] = gen_lowpart (QImode, operands[0]); 12171}) 12172 12173(define_insn "*setcc_qi" 12174 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12175 (match_operator:QI 1 "ix86_comparison_operator" 12176 [(reg FLAGS_REG) (const_int 0)]))] 12177 "" 12178 "set%C1\t%0" 12179 [(set_attr "type" "setcc") 12180 (set_attr "mode" "QI")]) 12181 12182(define_insn "*setcc_qi_slp" 12183 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 12184 (match_operator:QI 1 "ix86_comparison_operator" 12185 [(reg FLAGS_REG) (const_int 0)]))] 12186 "" 12187 "set%C1\t%0" 12188 [(set_attr "type" "setcc") 12189 (set_attr "mode" "QI")]) 12190 12191;; In general it is not safe to assume too much about CCmode registers, 12192;; so simplify-rtx stops when it sees a second one. Under certain 12193;; conditions this is safe on x86, so help combine not create 12194;; 12195;; seta %al 12196;; testb %al, %al 12197;; sete %al 12198 12199(define_split 12200 [(set (match_operand:QI 0 "nonimmediate_operand") 12201 (ne:QI (match_operator 1 "ix86_comparison_operator" 12202 [(reg FLAGS_REG) (const_int 0)]) 12203 (const_int 0)))] 12204 "" 12205 [(set (match_dup 0) (match_dup 1))] 12206{ 12207 operands[1] = shallow_copy_rtx (operands[1]); 12208 PUT_MODE (operands[1], QImode); 12209}) 12210 12211(define_split 12212 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) 12213 (ne:QI (match_operator 1 "ix86_comparison_operator" 12214 [(reg FLAGS_REG) (const_int 0)]) 12215 (const_int 0)))] 12216 "" 12217 [(set (match_dup 0) (match_dup 1))] 12218{ 12219 operands[1] = shallow_copy_rtx (operands[1]); 12220 PUT_MODE (operands[1], QImode); 12221}) 12222 12223(define_split 12224 [(set (match_operand:QI 0 "nonimmediate_operand") 12225 (eq:QI (match_operator 1 "ix86_comparison_operator" 12226 [(reg FLAGS_REG) (const_int 0)]) 12227 (const_int 0)))] 12228 "" 12229 [(set (match_dup 0) (match_dup 1))] 12230{ 12231 operands[1] = shallow_copy_rtx (operands[1]); 12232 PUT_MODE (operands[1], QImode); 12233 PUT_CODE (operands[1], 12234 ix86_reverse_condition (GET_CODE (operands[1]), 12235 GET_MODE (XEXP (operands[1], 0)))); 12236 12237 /* Make sure that (a) the CCmode we have for the flags is strong 12238 enough for the reversed compare or (b) we have a valid FP compare. */ 12239 if (! ix86_comparison_operator (operands[1], VOIDmode)) 12240 FAIL; 12241}) 12242 12243(define_split 12244 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) 12245 (eq:QI (match_operator 1 "ix86_comparison_operator" 12246 [(reg FLAGS_REG) (const_int 0)]) 12247 (const_int 0)))] 12248 "" 12249 [(set (match_dup 0) (match_dup 1))] 12250{ 12251 operands[1] = shallow_copy_rtx (operands[1]); 12252 PUT_MODE (operands[1], QImode); 12253 PUT_CODE (operands[1], 12254 ix86_reverse_condition (GET_CODE (operands[1]), 12255 GET_MODE (XEXP (operands[1], 0)))); 12256 12257 /* Make sure that (a) the CCmode we have for the flags is strong 12258 enough for the reversed compare or (b) we have a valid FP compare. */ 12259 if (! ix86_comparison_operator (operands[1], VOIDmode)) 12260 FAIL; 12261}) 12262 12263;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 12264;; subsequent logical operations are used to imitate conditional moves. 12265;; 0xffffffff is NaN, but not in normalized form, so we can't represent 12266;; it directly. 12267 12268(define_insn "setcc_<mode>_sse" 12269 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 12270 (match_operator:MODEF 3 "sse_comparison_operator" 12271 [(match_operand:MODEF 1 "register_operand" "0,x") 12272 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 12273 "SSE_FLOAT_MODE_P (<MODE>mode)" 12274 "@ 12275 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2} 12276 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 12277 [(set_attr "isa" "noavx,avx") 12278 (set_attr "type" "ssecmp") 12279 (set_attr "length_immediate" "1") 12280 (set_attr "prefix" "orig,vex") 12281 (set_attr "mode" "<MODE>")]) 12282 12283;; Basic conditional jump instructions. 12284;; We ignore the overflow flag for signed branch instructions. 12285 12286(define_insn "*jcc" 12287 [(set (pc) 12288 (if_then_else (match_operator 1 "ix86_comparison_operator" 12289 [(reg FLAGS_REG) (const_int 0)]) 12290 (label_ref (match_operand 0)) 12291 (pc)))] 12292 "" 12293 "%!%+j%C1\t%l0" 12294 [(set_attr "type" "ibr") 12295 (set_attr "modrm" "0") 12296 (set (attr "length") 12297 (if_then_else 12298 (and (ge (minus (match_dup 0) (pc)) 12299 (const_int -126)) 12300 (lt (minus (match_dup 0) (pc)) 12301 (const_int 128))) 12302 (const_int 2) 12303 (const_int 6))) 12304 (set_attr "maybe_prefix_bnd" "1")]) 12305 12306;; In general it is not safe to assume too much about CCmode registers, 12307;; so simplify-rtx stops when it sees a second one. Under certain 12308;; conditions this is safe on x86, so help combine not create 12309;; 12310;; seta %al 12311;; testb %al, %al 12312;; je Lfoo 12313 12314(define_split 12315 [(set (pc) 12316 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 12317 [(reg FLAGS_REG) (const_int 0)]) 12318 (const_int 0)) 12319 (label_ref (match_operand 1)) 12320 (pc)))] 12321 "" 12322 [(set (pc) 12323 (if_then_else (match_dup 0) 12324 (label_ref (match_dup 1)) 12325 (pc)))] 12326{ 12327 operands[0] = shallow_copy_rtx (operands[0]); 12328 PUT_MODE (operands[0], VOIDmode); 12329}) 12330 12331(define_split 12332 [(set (pc) 12333 (if_then_else (eq (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 PUT_CODE (operands[0], 12347 ix86_reverse_condition (GET_CODE (operands[0]), 12348 GET_MODE (XEXP (operands[0], 0)))); 12349 12350 /* Make sure that (a) the CCmode we have for the flags is strong 12351 enough for the reversed compare or (b) we have a valid FP compare. */ 12352 if (! ix86_comparison_operator (operands[0], VOIDmode)) 12353 FAIL; 12354}) 12355 12356;; Unconditional and other jump instructions 12357 12358(define_insn "jump" 12359 [(set (pc) 12360 (label_ref (match_operand 0)))] 12361 "" 12362 "%!jmp\t%l0" 12363 [(set_attr "type" "ibr") 12364 (set_attr "modrm" "0") 12365 (set (attr "length") 12366 (if_then_else 12367 (and (ge (minus (match_dup 0) (pc)) 12368 (const_int -126)) 12369 (lt (minus (match_dup 0) (pc)) 12370 (const_int 128))) 12371 (const_int 2) 12372 (const_int 5))) 12373 (set_attr "maybe_prefix_bnd" "1")]) 12374 12375(define_expand "indirect_jump" 12376 [(set (pc) (match_operand 0 "indirect_branch_operand"))] 12377 "" 12378{ 12379 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) 12380 operands[0] = convert_memory_address (word_mode, operands[0]); 12381 cfun->machine->has_local_indirect_jump = true; 12382}) 12383 12384(define_insn "*indirect_jump" 12385 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] 12386 "" 12387 "* return ix86_output_indirect_jmp (operands[0]);" 12388 [(set (attr "type") 12389 (if_then_else (match_test "(cfun->machine->indirect_branch_type 12390 != indirect_branch_keep)") 12391 (const_string "multi") 12392 (const_string "ibr"))) 12393 (set_attr "length_immediate" "0") 12394 (set_attr "maybe_prefix_bnd" "1")]) 12395 12396(define_expand "tablejump" 12397 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand")) 12398 (use (label_ref (match_operand 1)))])] 12399 "" 12400{ 12401 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 12402 relative. Convert the relative address to an absolute address. */ 12403 if (flag_pic) 12404 { 12405 rtx op0, op1; 12406 enum rtx_code code; 12407 12408 /* We can't use @GOTOFF for text labels on VxWorks; 12409 see gotoff_operand. */ 12410 if (TARGET_64BIT || TARGET_VXWORKS_RTP) 12411 { 12412 code = PLUS; 12413 op0 = operands[0]; 12414 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 12415 } 12416 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 12417 { 12418 code = PLUS; 12419 op0 = operands[0]; 12420 op1 = pic_offset_table_rtx; 12421 } 12422 else 12423 { 12424 code = MINUS; 12425 op0 = pic_offset_table_rtx; 12426 op1 = operands[0]; 12427 } 12428 12429 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 12430 OPTAB_DIRECT); 12431 } 12432 12433 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) 12434 operands[0] = convert_memory_address (word_mode, operands[0]); 12435 cfun->machine->has_local_indirect_jump = true; 12436}) 12437 12438(define_insn "*tablejump_1" 12439 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) 12440 (use (label_ref (match_operand 1)))] 12441 "" 12442 "* return ix86_output_indirect_jmp (operands[0]);" 12443 [(set (attr "type") 12444 (if_then_else (match_test "(cfun->machine->indirect_branch_type 12445 != indirect_branch_keep)") 12446 (const_string "multi") 12447 (const_string "ibr"))) 12448 (set_attr "length_immediate" "0") 12449 (set_attr "maybe_prefix_bnd" "1")]) 12450 12451;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 12452 12453(define_peephole2 12454 [(set (reg FLAGS_REG) (match_operand 0)) 12455 (set (match_operand:QI 1 "register_operand") 12456 (match_operator:QI 2 "ix86_comparison_operator" 12457 [(reg FLAGS_REG) (const_int 0)])) 12458 (set (match_operand 3 "any_QIreg_operand") 12459 (zero_extend (match_dup 1)))] 12460 "(peep2_reg_dead_p (3, operands[1]) 12461 || operands_match_p (operands[1], operands[3])) 12462 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12463 && peep2_regno_dead_p (0, FLAGS_REG)" 12464 [(set (match_dup 4) (match_dup 0)) 12465 (set (strict_low_part (match_dup 5)) 12466 (match_dup 2))] 12467{ 12468 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12469 operands[5] = gen_lowpart (QImode, operands[3]); 12470 ix86_expand_clear (operands[3]); 12471}) 12472 12473(define_peephole2 12474 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 12475 (match_operand 4)]) 12476 (set (match_operand:QI 1 "register_operand") 12477 (match_operator:QI 2 "ix86_comparison_operator" 12478 [(reg FLAGS_REG) (const_int 0)])) 12479 (set (match_operand 3 "any_QIreg_operand") 12480 (zero_extend (match_dup 1)))] 12481 "(peep2_reg_dead_p (3, operands[1]) 12482 || operands_match_p (operands[1], operands[3])) 12483 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12484 && ! reg_set_p (operands[3], operands[4]) 12485 && peep2_regno_dead_p (0, FLAGS_REG)" 12486 [(parallel [(set (match_dup 5) (match_dup 0)) 12487 (match_dup 4)]) 12488 (set (strict_low_part (match_dup 6)) 12489 (match_dup 2))] 12490{ 12491 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12492 operands[6] = gen_lowpart (QImode, operands[3]); 12493 ix86_expand_clear (operands[3]); 12494}) 12495 12496(define_peephole2 12497 [(set (reg FLAGS_REG) (match_operand 0)) 12498 (parallel [(set (reg FLAGS_REG) (match_operand 1)) 12499 (match_operand 5)]) 12500 (set (match_operand:QI 2 "register_operand") 12501 (match_operator:QI 3 "ix86_comparison_operator" 12502 [(reg FLAGS_REG) (const_int 0)])) 12503 (set (match_operand 4 "any_QIreg_operand") 12504 (zero_extend (match_dup 2)))] 12505 "(peep2_reg_dead_p (4, operands[2]) 12506 || operands_match_p (operands[2], operands[4])) 12507 && ! reg_overlap_mentioned_p (operands[4], operands[0]) 12508 && ! reg_overlap_mentioned_p (operands[4], operands[1]) 12509 && ! reg_set_p (operands[4], operands[5]) 12510 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) 12511 && peep2_regno_dead_p (0, FLAGS_REG)" 12512 [(set (match_dup 6) (match_dup 0)) 12513 (parallel [(set (match_dup 7) (match_dup 1)) 12514 (match_dup 5)]) 12515 (set (strict_low_part (match_dup 8)) 12516 (match_dup 3))] 12517{ 12518 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12519 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); 12520 operands[8] = gen_lowpart (QImode, operands[4]); 12521 ix86_expand_clear (operands[4]); 12522}) 12523 12524;; Similar, but match zero extend with andsi3. 12525 12526(define_peephole2 12527 [(set (reg FLAGS_REG) (match_operand 0)) 12528 (set (match_operand:QI 1 "register_operand") 12529 (match_operator:QI 2 "ix86_comparison_operator" 12530 [(reg FLAGS_REG) (const_int 0)])) 12531 (parallel [(set (match_operand:SI 3 "any_QIreg_operand") 12532 (and:SI (match_dup 3) (const_int 255))) 12533 (clobber (reg:CC FLAGS_REG))])] 12534 "REGNO (operands[1]) == REGNO (operands[3]) 12535 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12536 && peep2_regno_dead_p (0, FLAGS_REG)" 12537 [(set (match_dup 4) (match_dup 0)) 12538 (set (strict_low_part (match_dup 5)) 12539 (match_dup 2))] 12540{ 12541 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12542 operands[5] = gen_lowpart (QImode, operands[3]); 12543 ix86_expand_clear (operands[3]); 12544}) 12545 12546(define_peephole2 12547 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 12548 (match_operand 4)]) 12549 (set (match_operand:QI 1 "register_operand") 12550 (match_operator:QI 2 "ix86_comparison_operator" 12551 [(reg FLAGS_REG) (const_int 0)])) 12552 (parallel [(set (match_operand 3 "any_QIreg_operand") 12553 (zero_extend (match_dup 1))) 12554 (clobber (reg:CC FLAGS_REG))])] 12555 "(peep2_reg_dead_p (3, operands[1]) 12556 || operands_match_p (operands[1], operands[3])) 12557 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12558 && ! reg_set_p (operands[3], operands[4]) 12559 && peep2_regno_dead_p (0, FLAGS_REG)" 12560 [(parallel [(set (match_dup 5) (match_dup 0)) 12561 (match_dup 4)]) 12562 (set (strict_low_part (match_dup 6)) 12563 (match_dup 2))] 12564{ 12565 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12566 operands[6] = gen_lowpart (QImode, operands[3]); 12567 ix86_expand_clear (operands[3]); 12568}) 12569 12570(define_peephole2 12571 [(set (reg FLAGS_REG) (match_operand 0)) 12572 (parallel [(set (reg FLAGS_REG) (match_operand 1)) 12573 (match_operand 5)]) 12574 (set (match_operand:QI 2 "register_operand") 12575 (match_operator:QI 3 "ix86_comparison_operator" 12576 [(reg FLAGS_REG) (const_int 0)])) 12577 (parallel [(set (match_operand 4 "any_QIreg_operand") 12578 (zero_extend (match_dup 2))) 12579 (clobber (reg:CC FLAGS_REG))])] 12580 "(peep2_reg_dead_p (4, operands[2]) 12581 || operands_match_p (operands[2], operands[4])) 12582 && ! reg_overlap_mentioned_p (operands[4], operands[0]) 12583 && ! reg_overlap_mentioned_p (operands[4], operands[1]) 12584 && ! reg_set_p (operands[4], operands[5]) 12585 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) 12586 && peep2_regno_dead_p (0, FLAGS_REG)" 12587 [(set (match_dup 6) (match_dup 0)) 12588 (parallel [(set (match_dup 7) (match_dup 1)) 12589 (match_dup 5)]) 12590 (set (strict_low_part (match_dup 8)) 12591 (match_dup 3))] 12592{ 12593 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12594 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); 12595 operands[8] = gen_lowpart (QImode, operands[4]); 12596 ix86_expand_clear (operands[4]); 12597}) 12598 12599;; Call instructions. 12600 12601;; The predicates normally associated with named expanders are not properly 12602;; checked for calls. This is a bug in the generic code, but it isn't that 12603;; easy to fix. Ignore it for now and be prepared to fix things up. 12604 12605;; P6 processors will jump to the address after the decrement when %esp 12606;; is used as a call operand, so they will execute return address as a code. 12607;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 12608 12609;; Register constraint for call instruction. 12610(define_mode_attr c [(SI "l") (DI "r")]) 12611 12612;; Call subroutine returning no value. 12613 12614(define_expand "call" 12615 [(call (match_operand:QI 0) 12616 (match_operand 1)) 12617 (use (match_operand 2))] 12618 "" 12619{ 12620 ix86_expand_call (NULL, operands[0], operands[1], 12621 operands[2], NULL, false); 12622 DONE; 12623}) 12624 12625(define_expand "sibcall" 12626 [(call (match_operand:QI 0) 12627 (match_operand 1)) 12628 (use (match_operand 2))] 12629 "" 12630{ 12631 ix86_expand_call (NULL, operands[0], operands[1], 12632 operands[2], NULL, true); 12633 DONE; 12634}) 12635 12636(define_insn "*call" 12637 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz")) 12638 (match_operand 1))] 12639 "!SIBLING_CALL_P (insn)" 12640 "* return ix86_output_call_insn (insn, operands[0]);" 12641 [(set_attr "type" "call")]) 12642 12643;; This covers both call and sibcall since only GOT slot is allowed. 12644(define_insn "*call_got_x32" 12645 [(call (mem:QI (zero_extend:DI 12646 (match_operand:SI 0 "GOT_memory_operand" "Bg"))) 12647 (match_operand 1))] 12648 "TARGET_X32" 12649{ 12650 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0)); 12651 return ix86_output_call_insn (insn, fnaddr); 12652} 12653 [(set_attr "type" "call")]) 12654 12655;; Since sibcall never returns, we can only use call-clobbered register 12656;; as GOT base. 12657(define_insn "*sibcall_GOT_32" 12658 [(call (mem:QI 12659 (mem:SI (plus:SI 12660 (match_operand:SI 0 "register_no_elim_operand" "U") 12661 (match_operand:SI 1 "GOT32_symbol_operand")))) 12662 (match_operand 2))] 12663 "!TARGET_MACHO 12664 && !TARGET_64BIT 12665 && !TARGET_INDIRECT_BRANCH_REGISTER 12666 && SIBLING_CALL_P (insn)" 12667{ 12668 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]); 12669 fnaddr = gen_const_mem (SImode, fnaddr); 12670 return ix86_output_call_insn (insn, fnaddr); 12671} 12672 [(set_attr "type" "call")]) 12673 12674(define_insn "*sibcall" 12675 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz")) 12676 (match_operand 1))] 12677 "SIBLING_CALL_P (insn)" 12678 "* return ix86_output_call_insn (insn, operands[0]);" 12679 [(set_attr "type" "call")]) 12680 12681(define_insn "*sibcall_memory" 12682 [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) 12683 (match_operand 1)) 12684 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12685 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" 12686 "* return ix86_output_call_insn (insn, operands[0]);" 12687 [(set_attr "type" "call")]) 12688 12689(define_peephole2 12690 [(set (match_operand:W 0 "register_operand") 12691 (match_operand:W 1 "memory_operand")) 12692 (call (mem:QI (match_dup 0)) 12693 (match_operand 3))] 12694 "!TARGET_X32 12695 && !TARGET_INDIRECT_BRANCH_REGISTER 12696 && SIBLING_CALL_P (peep2_next_insn (1)) 12697 && !reg_mentioned_p (operands[0], 12698 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12699 [(parallel [(call (mem:QI (match_dup 1)) 12700 (match_dup 3)) 12701 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12702 12703(define_peephole2 12704 [(set (match_operand:W 0 "register_operand") 12705 (match_operand:W 1 "memory_operand")) 12706 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12707 (call (mem:QI (match_dup 0)) 12708 (match_operand 3))] 12709 "!TARGET_X32 12710 && !TARGET_INDIRECT_BRANCH_REGISTER 12711 && SIBLING_CALL_P (peep2_next_insn (2)) 12712 && !reg_mentioned_p (operands[0], 12713 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12714 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12715 (parallel [(call (mem:QI (match_dup 1)) 12716 (match_dup 3)) 12717 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12718 12719(define_expand "call_pop" 12720 [(parallel [(call (match_operand:QI 0) 12721 (match_operand:SI 1)) 12722 (set (reg:SI SP_REG) 12723 (plus:SI (reg:SI SP_REG) 12724 (match_operand:SI 3)))])] 12725 "!TARGET_64BIT" 12726{ 12727 ix86_expand_call (NULL, operands[0], operands[1], 12728 operands[2], operands[3], false); 12729 DONE; 12730}) 12731 12732(define_insn "*call_pop" 12733 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) 12734 (match_operand 1)) 12735 (set (reg:SI SP_REG) 12736 (plus:SI (reg:SI SP_REG) 12737 (match_operand:SI 2 "immediate_operand" "i")))] 12738 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 12739 "* return ix86_output_call_insn (insn, operands[0]);" 12740 [(set_attr "type" "call")]) 12741 12742(define_insn "*sibcall_pop" 12743 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz")) 12744 (match_operand 1)) 12745 (set (reg:SI SP_REG) 12746 (plus:SI (reg:SI SP_REG) 12747 (match_operand:SI 2 "immediate_operand" "i")))] 12748 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 12749 "* return ix86_output_call_insn (insn, operands[0]);" 12750 [(set_attr "type" "call")]) 12751 12752(define_insn "*sibcall_pop_memory" 12753 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) 12754 (match_operand 1)) 12755 (set (reg:SI SP_REG) 12756 (plus:SI (reg:SI SP_REG) 12757 (match_operand:SI 2 "immediate_operand" "i"))) 12758 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12759 "!TARGET_64BIT" 12760 "* return ix86_output_call_insn (insn, operands[0]);" 12761 [(set_attr "type" "call")]) 12762 12763(define_peephole2 12764 [(set (match_operand:SI 0 "register_operand") 12765 (match_operand:SI 1 "memory_operand")) 12766 (parallel [(call (mem:QI (match_dup 0)) 12767 (match_operand 3)) 12768 (set (reg:SI SP_REG) 12769 (plus:SI (reg:SI SP_REG) 12770 (match_operand:SI 4 "immediate_operand")))])] 12771 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 12772 && !reg_mentioned_p (operands[0], 12773 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12774 [(parallel [(call (mem:QI (match_dup 1)) 12775 (match_dup 3)) 12776 (set (reg:SI SP_REG) 12777 (plus:SI (reg:SI SP_REG) 12778 (match_dup 4))) 12779 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12780 12781(define_peephole2 12782 [(set (match_operand:SI 0 "register_operand") 12783 (match_operand:SI 1 "memory_operand")) 12784 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12785 (parallel [(call (mem:QI (match_dup 0)) 12786 (match_operand 3)) 12787 (set (reg:SI SP_REG) 12788 (plus:SI (reg:SI SP_REG) 12789 (match_operand:SI 4 "immediate_operand")))])] 12790 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 12791 && !reg_mentioned_p (operands[0], 12792 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12793 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12794 (parallel [(call (mem:QI (match_dup 1)) 12795 (match_dup 3)) 12796 (set (reg:SI SP_REG) 12797 (plus:SI (reg:SI SP_REG) 12798 (match_dup 4))) 12799 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12800 12801;; Combining simple memory jump instruction 12802 12803(define_peephole2 12804 [(set (match_operand:W 0 "register_operand") 12805 (match_operand:W 1 "memory_operand")) 12806 (set (pc) (match_dup 0))] 12807 "!TARGET_X32 12808 && !TARGET_INDIRECT_BRANCH_REGISTER 12809 && peep2_reg_dead_p (2, operands[0])" 12810 [(set (pc) (match_dup 1))]) 12811 12812;; Call subroutine, returning value in operand 0 12813 12814(define_expand "call_value" 12815 [(set (match_operand 0) 12816 (call (match_operand:QI 1) 12817 (match_operand 2))) 12818 (use (match_operand 3))] 12819 "" 12820{ 12821 ix86_expand_call (operands[0], operands[1], operands[2], 12822 operands[3], NULL, false); 12823 DONE; 12824}) 12825 12826(define_expand "sibcall_value" 12827 [(set (match_operand 0) 12828 (call (match_operand:QI 1) 12829 (match_operand 2))) 12830 (use (match_operand 3))] 12831 "" 12832{ 12833 ix86_expand_call (operands[0], operands[1], operands[2], 12834 operands[3], NULL, true); 12835 DONE; 12836}) 12837 12838(define_insn "*call_value" 12839 [(set (match_operand 0) 12840 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz")) 12841 (match_operand 2)))] 12842 "!SIBLING_CALL_P (insn)" 12843 "* return ix86_output_call_insn (insn, operands[1]);" 12844 [(set_attr "type" "callv")]) 12845 12846;; This covers both call and sibcall since only GOT slot is allowed. 12847(define_insn "*call_value_got_x32" 12848 [(set (match_operand 0) 12849 (call (mem:QI 12850 (zero_extend:DI 12851 (match_operand:SI 1 "GOT_memory_operand" "Bg"))) 12852 (match_operand 2)))] 12853 "TARGET_X32" 12854{ 12855 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0)); 12856 return ix86_output_call_insn (insn, fnaddr); 12857} 12858 [(set_attr "type" "callv")]) 12859 12860;; Since sibcall never returns, we can only use call-clobbered register 12861;; as GOT base. 12862(define_insn "*sibcall_value_GOT_32" 12863 [(set (match_operand 0) 12864 (call (mem:QI 12865 (mem:SI (plus:SI 12866 (match_operand:SI 1 "register_no_elim_operand" "U") 12867 (match_operand:SI 2 "GOT32_symbol_operand")))) 12868 (match_operand 3)))] 12869 "!TARGET_MACHO 12870 && !TARGET_64BIT 12871 && !TARGET_INDIRECT_BRANCH_REGISTER 12872 && SIBLING_CALL_P (insn)" 12873{ 12874 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]); 12875 fnaddr = gen_const_mem (SImode, fnaddr); 12876 return ix86_output_call_insn (insn, fnaddr); 12877} 12878 [(set_attr "type" "callv")]) 12879 12880(define_insn "*sibcall_value" 12881 [(set (match_operand 0) 12882 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz")) 12883 (match_operand 2)))] 12884 "SIBLING_CALL_P (insn)" 12885 "* return ix86_output_call_insn (insn, operands[1]);" 12886 [(set_attr "type" "callv")]) 12887 12888(define_insn "*sibcall_value_memory" 12889 [(set (match_operand 0) 12890 (call (mem:QI (match_operand:W 1 "memory_operand" "m")) 12891 (match_operand 2))) 12892 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12893 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" 12894 "* return ix86_output_call_insn (insn, operands[1]);" 12895 [(set_attr "type" "callv")]) 12896 12897(define_peephole2 12898 [(set (match_operand:W 0 "register_operand") 12899 (match_operand:W 1 "memory_operand")) 12900 (set (match_operand 2) 12901 (call (mem:QI (match_dup 0)) 12902 (match_operand 3)))] 12903 "!TARGET_X32 12904 && !TARGET_INDIRECT_BRANCH_REGISTER 12905 && SIBLING_CALL_P (peep2_next_insn (1)) 12906 && !reg_mentioned_p (operands[0], 12907 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12908 [(parallel [(set (match_dup 2) 12909 (call (mem:QI (match_dup 1)) 12910 (match_dup 3))) 12911 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12912 12913(define_peephole2 12914 [(set (match_operand:W 0 "register_operand") 12915 (match_operand:W 1 "memory_operand")) 12916 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12917 (set (match_operand 2) 12918 (call (mem:QI (match_dup 0)) 12919 (match_operand 3)))] 12920 "!TARGET_X32 12921 && !TARGET_INDIRECT_BRANCH_REGISTER 12922 && SIBLING_CALL_P (peep2_next_insn (2)) 12923 && !reg_mentioned_p (operands[0], 12924 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12925 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12926 (parallel [(set (match_dup 2) 12927 (call (mem:QI (match_dup 1)) 12928 (match_dup 3))) 12929 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12930 12931(define_expand "call_value_pop" 12932 [(parallel [(set (match_operand 0) 12933 (call (match_operand:QI 1) 12934 (match_operand:SI 2))) 12935 (set (reg:SI SP_REG) 12936 (plus:SI (reg:SI SP_REG) 12937 (match_operand:SI 4)))])] 12938 "!TARGET_64BIT" 12939{ 12940 ix86_expand_call (operands[0], operands[1], operands[2], 12941 operands[3], operands[4], false); 12942 DONE; 12943}) 12944 12945(define_insn "*call_value_pop" 12946 [(set (match_operand 0) 12947 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) 12948 (match_operand 2))) 12949 (set (reg:SI SP_REG) 12950 (plus:SI (reg:SI SP_REG) 12951 (match_operand:SI 3 "immediate_operand" "i")))] 12952 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 12953 "* return ix86_output_call_insn (insn, operands[1]);" 12954 [(set_attr "type" "callv")]) 12955 12956(define_insn "*sibcall_value_pop" 12957 [(set (match_operand 0) 12958 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz")) 12959 (match_operand 2))) 12960 (set (reg:SI SP_REG) 12961 (plus:SI (reg:SI SP_REG) 12962 (match_operand:SI 3 "immediate_operand" "i")))] 12963 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 12964 "* return ix86_output_call_insn (insn, operands[1]);" 12965 [(set_attr "type" "callv")]) 12966 12967(define_insn "*sibcall_value_pop_memory" 12968 [(set (match_operand 0) 12969 (call (mem:QI (match_operand:SI 1 "memory_operand" "m")) 12970 (match_operand 2))) 12971 (set (reg:SI SP_REG) 12972 (plus:SI (reg:SI SP_REG) 12973 (match_operand:SI 3 "immediate_operand" "i"))) 12974 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12975 "!TARGET_64BIT" 12976 "* return ix86_output_call_insn (insn, operands[1]);" 12977 [(set_attr "type" "callv")]) 12978 12979(define_peephole2 12980 [(set (match_operand:SI 0 "register_operand") 12981 (match_operand:SI 1 "memory_operand")) 12982 (parallel [(set (match_operand 2) 12983 (call (mem:QI (match_dup 0)) 12984 (match_operand 3))) 12985 (set (reg:SI SP_REG) 12986 (plus:SI (reg:SI SP_REG) 12987 (match_operand:SI 4 "immediate_operand")))])] 12988 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 12989 && !reg_mentioned_p (operands[0], 12990 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12991 [(parallel [(set (match_dup 2) 12992 (call (mem:QI (match_dup 1)) 12993 (match_dup 3))) 12994 (set (reg:SI SP_REG) 12995 (plus:SI (reg:SI SP_REG) 12996 (match_dup 4))) 12997 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12998 12999(define_peephole2 13000 [(set (match_operand:SI 0 "register_operand") 13001 (match_operand:SI 1 "memory_operand")) 13002 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 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 (2)) 13010 && !reg_mentioned_p (operands[0], 13011 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 13012 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13013 (parallel [(set (match_dup 2) 13014 (call (mem:QI (match_dup 1)) 13015 (match_dup 3))) 13016 (set (reg:SI SP_REG) 13017 (plus:SI (reg:SI SP_REG) 13018 (match_dup 4))) 13019 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13020 13021;; Call subroutine returning any type. 13022 13023(define_expand "untyped_call" 13024 [(parallel [(call (match_operand 0) 13025 (const_int 0)) 13026 (match_operand 1) 13027 (match_operand 2)])] 13028 "" 13029{ 13030 int i; 13031 13032 /* In order to give reg-stack an easier job in validating two 13033 coprocessor registers as containing a possible return value, 13034 simply pretend the untyped call returns a complex long double 13035 value. 13036 13037 We can't use SSE_REGPARM_MAX here since callee is unprototyped 13038 and should have the default ABI. */ 13039 13040 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 13041 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 13042 operands[0], const0_rtx, 13043 GEN_INT ((TARGET_64BIT 13044 ? (ix86_abi == SYSV_ABI 13045 ? X86_64_SSE_REGPARM_MAX 13046 : X86_64_MS_SSE_REGPARM_MAX) 13047 : X86_32_SSE_REGPARM_MAX) 13048 - 1), 13049 NULL, false); 13050 13051 for (i = 0; i < XVECLEN (operands[2], 0); i++) 13052 { 13053 rtx set = XVECEXP (operands[2], 0, i); 13054 emit_move_insn (SET_DEST (set), SET_SRC (set)); 13055 } 13056 13057 /* The optimizer does not know that the call sets the function value 13058 registers we stored in the result block. We avoid problems by 13059 claiming that all hard registers are used and clobbered at this 13060 point. */ 13061 emit_insn (gen_blockage ()); 13062 13063 DONE; 13064}) 13065 13066;; Prologue and epilogue instructions 13067 13068;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 13069;; all of memory. This blocks insns from being moved across this point. 13070 13071(define_insn "blockage" 13072 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 13073 "" 13074 "" 13075 [(set_attr "length" "0")]) 13076 13077;; Do not schedule instructions accessing memory across this point. 13078 13079(define_expand "memory_blockage" 13080 [(set (match_dup 0) 13081 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 13082 "" 13083{ 13084 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 13085 MEM_VOLATILE_P (operands[0]) = 1; 13086}) 13087 13088(define_insn "*memory_blockage" 13089 [(set (match_operand:BLK 0) 13090 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 13091 "" 13092 "" 13093 [(set_attr "length" "0")]) 13094 13095;; As USE insns aren't meaningful after reload, this is used instead 13096;; to prevent deleting instructions setting registers for PIC code 13097(define_insn "prologue_use" 13098 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)] 13099 "" 13100 "" 13101 [(set_attr "length" "0")]) 13102 13103;; Insn emitted into the body of a function to return from a function. 13104;; This is only done if the function's epilogue is known to be simple. 13105;; See comments for ix86_can_use_return_insn_p in i386.c. 13106 13107(define_expand "return" 13108 [(simple_return)] 13109 "ix86_can_use_return_insn_p ()" 13110{ 13111 if (crtl->args.pops_args) 13112 { 13113 rtx popc = GEN_INT (crtl->args.pops_args); 13114 emit_jump_insn (gen_simple_return_pop_internal (popc)); 13115 DONE; 13116 } 13117}) 13118 13119;; We need to disable this for TARGET_SEH, as otherwise 13120;; shrink-wrapped prologue gets enabled too. This might exceed 13121;; the maximum size of prologue in unwind information. 13122;; Also disallow shrink-wrapping if using stack slot to pass the 13123;; static chain pointer - the first instruction has to be pushl %esi 13124;; and it can't be moved around, as we use alternate entry points 13125;; in that case. 13126 13127(define_expand "simple_return" 13128 [(simple_return)] 13129 "!TARGET_SEH && !ix86_static_chain_on_stack" 13130{ 13131 if (crtl->args.pops_args) 13132 { 13133 rtx popc = GEN_INT (crtl->args.pops_args); 13134 emit_jump_insn (gen_simple_return_pop_internal (popc)); 13135 DONE; 13136 } 13137}) 13138 13139(define_insn "simple_return_internal" 13140 [(simple_return)] 13141 "reload_completed" 13142 "* return ix86_output_function_return (false);" 13143 [(set_attr "length" "1") 13144 (set_attr "atom_unit" "jeu") 13145 (set_attr "length_immediate" "0") 13146 (set_attr "modrm" "0") 13147 (set_attr "maybe_prefix_bnd" "1")]) 13148 13149(define_insn "interrupt_return" 13150 [(simple_return) 13151 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)] 13152 "reload_completed" 13153{ 13154 return TARGET_64BIT ? "iretq" : "iret"; 13155}) 13156 13157;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 13158;; instruction Athlon and K8 have. 13159 13160(define_insn "simple_return_internal_long" 13161 [(simple_return) 13162 (unspec [(const_int 0)] UNSPEC_REP)] 13163 "reload_completed" 13164 "* return ix86_output_function_return (true);" 13165 [(set_attr "length" "2") 13166 (set_attr "atom_unit" "jeu") 13167 (set_attr "length_immediate" "0") 13168 (set_attr "prefix_rep" "1") 13169 (set_attr "modrm" "0")]) 13170 13171(define_insn_and_split "simple_return_pop_internal" 13172 [(simple_return) 13173 (use (match_operand:SI 0 "const_int_operand"))] 13174 "reload_completed" 13175 "%!ret\t%0" 13176 "&& cfun->machine->function_return_type != indirect_branch_keep" 13177 [(const_int 0)] 13178 "ix86_split_simple_return_pop_internal (operands[0]); DONE;" 13179 [(set_attr "length" "3") 13180 (set_attr "atom_unit" "jeu") 13181 (set_attr "length_immediate" "2") 13182 (set_attr "modrm" "0") 13183 (set_attr "maybe_prefix_bnd" "1")]) 13184 13185(define_insn "simple_return_indirect_internal" 13186 [(simple_return) 13187 (use (match_operand 0 "register_operand" "r"))] 13188 "reload_completed" 13189 "* return ix86_output_indirect_function_return (operands[0]);" 13190 [(set (attr "type") 13191 (if_then_else (match_test "(cfun->machine->indirect_branch_type 13192 != indirect_branch_keep)") 13193 (const_string "multi") 13194 (const_string "ibr"))) 13195 (set_attr "length_immediate" "0") 13196 (set_attr "maybe_prefix_bnd" "1")]) 13197 13198(define_insn "nop" 13199 [(const_int 0)] 13200 "" 13201 "nop" 13202 [(set_attr "length" "1") 13203 (set_attr "length_immediate" "0") 13204 (set_attr "modrm" "0")]) 13205 13206;; Generate nops. Operand 0 is the number of nops, up to 8. 13207(define_insn "nops" 13208 [(unspec_volatile [(match_operand 0 "const_int_operand")] 13209 UNSPECV_NOPS)] 13210 "reload_completed" 13211{ 13212 int num = INTVAL (operands[0]); 13213 13214 gcc_assert (IN_RANGE (num, 1, 8)); 13215 13216 while (num--) 13217 fputs ("\tnop\n", asm_out_file); 13218 13219 return ""; 13220} 13221 [(set (attr "length") (symbol_ref "INTVAL (operands[0])")) 13222 (set_attr "length_immediate" "0") 13223 (set_attr "modrm" "0")]) 13224 13225;; Pad to 16-byte boundary, max skip in op0. Used to avoid 13226;; branch prediction penalty for the third jump in a 16-byte 13227;; block on K8. 13228 13229(define_insn "pad" 13230 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)] 13231 "" 13232{ 13233#ifdef ASM_OUTPUT_MAX_SKIP_PAD 13234 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); 13235#else 13236 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 13237 The align insn is used to avoid 3 jump instructions in the row to improve 13238 branch prediction and the benefits hardly outweigh the cost of extra 8 13239 nops on the average inserted by full alignment pseudo operation. */ 13240#endif 13241 return ""; 13242} 13243 [(set_attr "length" "16")]) 13244 13245(define_expand "prologue" 13246 [(const_int 0)] 13247 "" 13248 "ix86_expand_prologue (); DONE;") 13249 13250(define_expand "set_got" 13251 [(parallel 13252 [(set (match_operand:SI 0 "register_operand") 13253 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 13254 (clobber (reg:CC FLAGS_REG))])] 13255 "!TARGET_64BIT" 13256{ 13257 if (flag_pic && !TARGET_VXWORKS_RTP) 13258 ix86_pc_thunk_call_expanded = true; 13259}) 13260 13261(define_insn "*set_got" 13262 [(set (match_operand:SI 0 "register_operand" "=r") 13263 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 13264 (clobber (reg:CC FLAGS_REG))] 13265 "!TARGET_64BIT" 13266 "* return output_set_got (operands[0], NULL_RTX);" 13267 [(set_attr "type" "multi") 13268 (set_attr "length" "12")]) 13269 13270(define_expand "set_got_labelled" 13271 [(parallel 13272 [(set (match_operand:SI 0 "register_operand") 13273 (unspec:SI [(label_ref (match_operand 1))] 13274 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_labelled" 13283 [(set (match_operand:SI 0 "register_operand" "=r") 13284 (unspec:SI [(label_ref (match_operand 1))] 13285 UNSPEC_SET_GOT)) 13286 (clobber (reg:CC FLAGS_REG))] 13287 "!TARGET_64BIT" 13288 "* return output_set_got (operands[0], operands[1]);" 13289 [(set_attr "type" "multi") 13290 (set_attr "length" "12")]) 13291 13292(define_insn "set_got_rex64" 13293 [(set (match_operand:DI 0 "register_operand" "=r") 13294 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 13295 "TARGET_64BIT" 13296 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" 13297 [(set_attr "type" "lea") 13298 (set_attr "length_address" "4") 13299 (set_attr "modrm_class" "unknown") 13300 (set_attr "mode" "DI")]) 13301 13302(define_insn "set_rip_rex64" 13303 [(set (match_operand:DI 0 "register_operand" "=r") 13304 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))] 13305 "TARGET_64BIT" 13306 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" 13307 [(set_attr "type" "lea") 13308 (set_attr "length_address" "4") 13309 (set_attr "mode" "DI")]) 13310 13311(define_insn "set_got_offset_rex64" 13312 [(set (match_operand:DI 0 "register_operand" "=r") 13313 (unspec:DI 13314 [(label_ref (match_operand 1))] 13315 UNSPEC_SET_GOT_OFFSET))] 13316 "TARGET_LP64" 13317 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" 13318 [(set_attr "type" "imov") 13319 (set_attr "length_immediate" "0") 13320 (set_attr "length_address" "8") 13321 (set_attr "mode" "DI")]) 13322 13323(define_expand "epilogue" 13324 [(const_int 0)] 13325 "" 13326 "ix86_expand_epilogue (1); DONE;") 13327 13328(define_expand "sibcall_epilogue" 13329 [(const_int 0)] 13330 "" 13331 "ix86_expand_epilogue (0); DONE;") 13332 13333(define_expand "eh_return" 13334 [(use (match_operand 0 "register_operand"))] 13335 "" 13336{ 13337 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 13338 13339 /* Tricky bit: we write the address of the handler to which we will 13340 be returning into someone else's stack frame, one word below the 13341 stack address we wish to restore. */ 13342 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 13343 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD); 13344 tmp = gen_rtx_MEM (Pmode, tmp); 13345 emit_move_insn (tmp, ra); 13346 13347 emit_jump_insn (gen_eh_return_internal ()); 13348 emit_barrier (); 13349 DONE; 13350}) 13351 13352(define_insn_and_split "eh_return_internal" 13353 [(eh_return)] 13354 "" 13355 "#" 13356 "epilogue_completed" 13357 [(const_int 0)] 13358 "ix86_expand_epilogue (2); DONE;") 13359 13360(define_insn "leave" 13361 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 13362 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 13363 (clobber (mem:BLK (scratch)))] 13364 "!TARGET_64BIT" 13365 "leave" 13366 [(set_attr "type" "leave")]) 13367 13368(define_insn "leave_rex64" 13369 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 13370 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 13371 (clobber (mem:BLK (scratch)))] 13372 "TARGET_64BIT" 13373 "leave" 13374 [(set_attr "type" "leave")]) 13375 13376;; Handle -fsplit-stack. 13377 13378(define_expand "split_stack_prologue" 13379 [(const_int 0)] 13380 "" 13381{ 13382 ix86_expand_split_stack_prologue (); 13383 DONE; 13384}) 13385 13386;; In order to support the call/return predictor, we use a return 13387;; instruction which the middle-end doesn't see. 13388(define_insn "split_stack_return" 13389 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] 13390 UNSPECV_SPLIT_STACK_RETURN)] 13391 "" 13392{ 13393 if (operands[0] == const0_rtx) 13394 return "ret"; 13395 else 13396 return "ret\t%0"; 13397} 13398 [(set_attr "atom_unit" "jeu") 13399 (set_attr "modrm" "0") 13400 (set (attr "length") 13401 (if_then_else (match_operand:SI 0 "const0_operand") 13402 (const_int 1) 13403 (const_int 3))) 13404 (set (attr "length_immediate") 13405 (if_then_else (match_operand:SI 0 "const0_operand") 13406 (const_int 0) 13407 (const_int 2)))]) 13408 13409;; If there are operand 0 bytes available on the stack, jump to 13410;; operand 1. 13411 13412(define_expand "split_stack_space_check" 13413 [(set (pc) (if_then_else 13414 (ltu (minus (reg SP_REG) 13415 (match_operand 0 "register_operand")) 13416 (match_dup 2)) 13417 (label_ref (match_operand 1)) 13418 (pc)))] 13419 "" 13420{ 13421 rtx reg = gen_reg_rtx (Pmode); 13422 13423 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0])); 13424 13425 operands[2] = ix86_split_stack_guard (); 13426 ix86_expand_branch (GEU, reg, operands[2], operands[1]); 13427 13428 DONE; 13429}) 13430 13431;; Bit manipulation instructions. 13432 13433(define_expand "ffs<mode>2" 13434 [(set (match_dup 2) (const_int -1)) 13435 (parallel [(set (match_dup 3) (match_dup 4)) 13436 (set (match_operand:SWI48 0 "register_operand") 13437 (ctz:SWI48 13438 (match_operand:SWI48 1 "nonimmediate_operand")))]) 13439 (set (match_dup 0) (if_then_else:SWI48 13440 (eq (match_dup 3) (const_int 0)) 13441 (match_dup 2) 13442 (match_dup 0))) 13443 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) 13444 (clobber (reg:CC FLAGS_REG))])] 13445 "" 13446{ 13447 machine_mode flags_mode; 13448 13449 if (<MODE>mode == SImode && !TARGET_CMOVE) 13450 { 13451 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); 13452 DONE; 13453 } 13454 13455 flags_mode = TARGET_BMI ? CCCmode : CCZmode; 13456 13457 operands[2] = gen_reg_rtx (<MODE>mode); 13458 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG); 13459 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 13460}) 13461 13462(define_insn_and_split "ffssi2_no_cmove" 13463 [(set (match_operand:SI 0 "register_operand" "=r") 13464 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 13465 (clobber (match_scratch:SI 2 "=&q")) 13466 (clobber (reg:CC FLAGS_REG))] 13467 "!TARGET_CMOVE" 13468 "#" 13469 "&& reload_completed" 13470 [(parallel [(set (match_dup 4) (match_dup 5)) 13471 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 13472 (set (strict_low_part (match_dup 3)) 13473 (eq:QI (match_dup 4) (const_int 0))) 13474 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 13475 (clobber (reg:CC FLAGS_REG))]) 13476 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 13477 (clobber (reg:CC FLAGS_REG))]) 13478 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 13479 (clobber (reg:CC FLAGS_REG))])] 13480{ 13481 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode; 13482 13483 operands[3] = gen_lowpart (QImode, operands[2]); 13484 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG); 13485 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 13486 13487 ix86_expand_clear (operands[2]); 13488}) 13489 13490(define_insn_and_split "*tzcnt<mode>_1" 13491 [(set (reg:CCC FLAGS_REG) 13492 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13493 (const_int 0))) 13494 (set (match_operand:SWI48 0 "register_operand" "=r") 13495 (ctz:SWI48 (match_dup 1)))] 13496 "TARGET_BMI" 13497 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13498 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13499 && optimize_function_for_speed_p (cfun) 13500 && !reg_mentioned_p (operands[0], operands[1])" 13501 [(parallel 13502 [(set (reg:CCC FLAGS_REG) 13503 (compare:CCC (match_dup 1) (const_int 0))) 13504 (set (match_dup 0) 13505 (ctz:SWI48 (match_dup 1))) 13506 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] 13507 "ix86_expand_clear (operands[0]);" 13508 [(set_attr "type" "alu1") 13509 (set_attr "prefix_0f" "1") 13510 (set_attr "prefix_rep" "1") 13511 (set_attr "btver2_decode" "double") 13512 (set_attr "mode" "<MODE>")]) 13513 13514; False dependency happens when destination is only updated by tzcnt, 13515; lzcnt or popcnt. There is no false dependency when destination is 13516; also used in source. 13517(define_insn "*tzcnt<mode>_1_falsedep" 13518 [(set (reg:CCC FLAGS_REG) 13519 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13520 (const_int 0))) 13521 (set (match_operand:SWI48 0 "register_operand" "=r") 13522 (ctz:SWI48 (match_dup 1))) 13523 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13524 UNSPEC_INSN_FALSE_DEP)] 13525 "TARGET_BMI" 13526 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13527 [(set_attr "type" "alu1") 13528 (set_attr "prefix_0f" "1") 13529 (set_attr "prefix_rep" "1") 13530 (set_attr "btver2_decode" "double") 13531 (set_attr "mode" "<MODE>")]) 13532 13533(define_insn "*bsf<mode>_1" 13534 [(set (reg:CCZ FLAGS_REG) 13535 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13536 (const_int 0))) 13537 (set (match_operand:SWI48 0 "register_operand" "=r") 13538 (ctz:SWI48 (match_dup 1)))] 13539 "" 13540 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" 13541 [(set_attr "type" "alu1") 13542 (set_attr "prefix_0f" "1") 13543 (set_attr "btver2_decode" "double") 13544 (set_attr "znver1_decode" "vector") 13545 (set_attr "mode" "<MODE>")]) 13546 13547(define_insn_and_split "ctz<mode>2" 13548 [(set (match_operand:SWI48 0 "register_operand" "=r") 13549 (ctz:SWI48 13550 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13551 (clobber (reg:CC FLAGS_REG))] 13552 "" 13553{ 13554 if (TARGET_BMI) 13555 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13556 else if (optimize_function_for_size_p (cfun)) 13557 ; 13558 else if (TARGET_GENERIC) 13559 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 13560 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13561 13562 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13563} 13564 "(TARGET_BMI || TARGET_GENERIC) 13565 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13566 && optimize_function_for_speed_p (cfun) 13567 && !reg_mentioned_p (operands[0], operands[1])" 13568 [(parallel 13569 [(set (match_dup 0) 13570 (ctz:SWI48 (match_dup 1))) 13571 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13572 (clobber (reg:CC FLAGS_REG))])] 13573 "ix86_expand_clear (operands[0]);" 13574 [(set_attr "type" "alu1") 13575 (set_attr "prefix_0f" "1") 13576 (set (attr "prefix_rep") 13577 (if_then_else 13578 (ior (match_test "TARGET_BMI") 13579 (and (not (match_test "optimize_function_for_size_p (cfun)")) 13580 (match_test "TARGET_GENERIC"))) 13581 (const_string "1") 13582 (const_string "0"))) 13583 (set_attr "mode" "<MODE>")]) 13584 13585; False dependency happens when destination is only updated by tzcnt, 13586; lzcnt or popcnt. There is no false dependency when destination is 13587; also used in source. 13588(define_insn "*ctz<mode>2_falsedep" 13589 [(set (match_operand:SWI48 0 "register_operand" "=r") 13590 (ctz:SWI48 13591 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13592 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13593 UNSPEC_INSN_FALSE_DEP) 13594 (clobber (reg:CC FLAGS_REG))] 13595 "" 13596{ 13597 if (TARGET_BMI) 13598 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13599 else if (TARGET_GENERIC) 13600 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 13601 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13602 else 13603 gcc_unreachable (); 13604} 13605 [(set_attr "type" "alu1") 13606 (set_attr "prefix_0f" "1") 13607 (set_attr "prefix_rep" "1") 13608 (set_attr "mode" "<MODE>")]) 13609 13610(define_insn "bsr_rex64" 13611 [(set (match_operand:DI 0 "register_operand" "=r") 13612 (minus:DI (const_int 63) 13613 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 13614 (clobber (reg:CC FLAGS_REG))] 13615 "TARGET_64BIT" 13616 "bsr{q}\t{%1, %0|%0, %1}" 13617 [(set_attr "type" "alu1") 13618 (set_attr "prefix_0f" "1") 13619 (set_attr "znver1_decode" "vector") 13620 (set_attr "mode" "DI")]) 13621 13622(define_insn "bsr" 13623 [(set (match_operand:SI 0 "register_operand" "=r") 13624 (minus:SI (const_int 31) 13625 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 13626 (clobber (reg:CC FLAGS_REG))] 13627 "" 13628 "bsr{l}\t{%1, %0|%0, %1}" 13629 [(set_attr "type" "alu1") 13630 (set_attr "prefix_0f" "1") 13631 (set_attr "znver1_decode" "vector") 13632 (set_attr "mode" "SI")]) 13633 13634(define_insn "*bsrhi" 13635 [(set (match_operand:HI 0 "register_operand" "=r") 13636 (minus:HI (const_int 15) 13637 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 13638 (clobber (reg:CC FLAGS_REG))] 13639 "" 13640 "bsr{w}\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" "HI")]) 13645 13646(define_expand "clz<mode>2" 13647 [(parallel 13648 [(set (match_operand:SWI48 0 "register_operand") 13649 (minus:SWI48 13650 (match_dup 2) 13651 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")))) 13652 (clobber (reg:CC FLAGS_REG))]) 13653 (parallel 13654 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2))) 13655 (clobber (reg:CC FLAGS_REG))])] 13656 "" 13657{ 13658 if (TARGET_LZCNT) 13659 { 13660 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1])); 13661 DONE; 13662 } 13663 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 13664}) 13665 13666(define_insn_and_split "clz<mode>2_lzcnt" 13667 [(set (match_operand:SWI48 0 "register_operand" "=r") 13668 (clz:SWI48 13669 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13670 (clobber (reg:CC FLAGS_REG))] 13671 "TARGET_LZCNT" 13672 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 13673 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13674 && optimize_function_for_speed_p (cfun) 13675 && !reg_mentioned_p (operands[0], operands[1])" 13676 [(parallel 13677 [(set (match_dup 0) 13678 (clz:SWI48 (match_dup 1))) 13679 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13680 (clobber (reg:CC FLAGS_REG))])] 13681 "ix86_expand_clear (operands[0]);" 13682 [(set_attr "prefix_rep" "1") 13683 (set_attr "type" "bitmanip") 13684 (set_attr "mode" "<MODE>")]) 13685 13686; False dependency happens when destination is only updated by tzcnt, 13687; lzcnt or popcnt. There is no false dependency when destination is 13688; also used in source. 13689(define_insn "*clz<mode>2_lzcnt_falsedep" 13690 [(set (match_operand:SWI48 0 "register_operand" "=r") 13691 (clz:SWI48 13692 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13693 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13694 UNSPEC_INSN_FALSE_DEP) 13695 (clobber (reg:CC FLAGS_REG))] 13696 "TARGET_LZCNT" 13697 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 13698 [(set_attr "prefix_rep" "1") 13699 (set_attr "type" "bitmanip") 13700 (set_attr "mode" "<MODE>")]) 13701 13702(define_int_iterator LT_ZCNT 13703 [(UNSPEC_TZCNT "TARGET_BMI") 13704 (UNSPEC_LZCNT "TARGET_LZCNT")]) 13705 13706(define_int_attr lt_zcnt 13707 [(UNSPEC_TZCNT "tzcnt") 13708 (UNSPEC_LZCNT "lzcnt")]) 13709 13710(define_int_attr lt_zcnt_type 13711 [(UNSPEC_TZCNT "alu1") 13712 (UNSPEC_LZCNT "bitmanip")]) 13713 13714;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version 13715;; provides operand size as output when source operand is zero. 13716 13717(define_insn_and_split "<lt_zcnt>_<mode>" 13718 [(set (match_operand:SWI48 0 "register_operand" "=r") 13719 (unspec:SWI48 13720 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13721 (clobber (reg:CC FLAGS_REG))] 13722 "" 13723 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" 13724 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13725 && optimize_function_for_speed_p (cfun) 13726 && !reg_mentioned_p (operands[0], operands[1])" 13727 [(parallel 13728 [(set (match_dup 0) 13729 (unspec:SWI48 [(match_dup 1)] LT_ZCNT)) 13730 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13731 (clobber (reg:CC FLAGS_REG))])] 13732 "ix86_expand_clear (operands[0]);" 13733 [(set_attr "type" "<lt_zcnt_type>") 13734 (set_attr "prefix_0f" "1") 13735 (set_attr "prefix_rep" "1") 13736 (set_attr "mode" "<MODE>")]) 13737 13738; False dependency happens when destination is only updated by tzcnt, 13739; lzcnt or popcnt. There is no false dependency when destination is 13740; also used in source. 13741(define_insn "*<lt_zcnt>_<mode>_falsedep" 13742 [(set (match_operand:SWI48 0 "register_operand" "=r") 13743 (unspec:SWI48 13744 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13745 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13746 UNSPEC_INSN_FALSE_DEP) 13747 (clobber (reg:CC FLAGS_REG))] 13748 "" 13749 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" 13750 [(set_attr "type" "<lt_zcnt_type>") 13751 (set_attr "prefix_0f" "1") 13752 (set_attr "prefix_rep" "1") 13753 (set_attr "mode" "<MODE>")]) 13754 13755(define_insn "<lt_zcnt>_hi" 13756 [(set (match_operand:HI 0 "register_operand" "=r") 13757 (unspec:HI 13758 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13759 (clobber (reg:CC FLAGS_REG))] 13760 "" 13761 "<lt_zcnt>{w}\t{%1, %0|%0, %1}" 13762 [(set_attr "type" "<lt_zcnt_type>") 13763 (set_attr "prefix_0f" "1") 13764 (set_attr "prefix_rep" "1") 13765 (set_attr "mode" "HI")]) 13766 13767;; BMI instructions. 13768 13769(define_insn "bmi_bextr_<mode>" 13770 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 13771 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 13772 (match_operand:SWI48 2 "register_operand" "r,r")] 13773 UNSPEC_BEXTR)) 13774 (clobber (reg:CC FLAGS_REG))] 13775 "TARGET_BMI" 13776 "bextr\t{%2, %1, %0|%0, %1, %2}" 13777 [(set_attr "type" "bitmanip") 13778 (set_attr "btver2_decode" "direct, double") 13779 (set_attr "mode" "<MODE>")]) 13780 13781(define_insn "*bmi_bextr_<mode>_ccz" 13782 [(set (reg:CCZ FLAGS_REG) 13783 (compare:CCZ 13784 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 13785 (match_operand:SWI48 2 "register_operand" "r,r")] 13786 UNSPEC_BEXTR) 13787 (const_int 0))) 13788 (clobber (match_scratch:SWI48 0 "=r,r"))] 13789 "TARGET_BMI" 13790 "bextr\t{%2, %1, %0|%0, %1, %2}" 13791 [(set_attr "type" "bitmanip") 13792 (set_attr "btver2_decode" "direct, double") 13793 (set_attr "mode" "<MODE>")]) 13794 13795(define_insn "*bmi_blsi_<mode>" 13796 [(set (match_operand:SWI48 0 "register_operand" "=r") 13797 (and:SWI48 13798 (neg:SWI48 13799 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 13800 (match_dup 1))) 13801 (clobber (reg:CC FLAGS_REG))] 13802 "TARGET_BMI" 13803 "blsi\t{%1, %0|%0, %1}" 13804 [(set_attr "type" "bitmanip") 13805 (set_attr "btver2_decode" "double") 13806 (set_attr "mode" "<MODE>")]) 13807 13808(define_insn "*bmi_blsmsk_<mode>" 13809 [(set (match_operand:SWI48 0 "register_operand" "=r") 13810 (xor:SWI48 13811 (plus:SWI48 13812 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13813 (const_int -1)) 13814 (match_dup 1))) 13815 (clobber (reg:CC FLAGS_REG))] 13816 "TARGET_BMI" 13817 "blsmsk\t{%1, %0|%0, %1}" 13818 [(set_attr "type" "bitmanip") 13819 (set_attr "btver2_decode" "double") 13820 (set_attr "mode" "<MODE>")]) 13821 13822(define_insn "*bmi_blsr_<mode>" 13823 [(set (match_operand:SWI48 0 "register_operand" "=r") 13824 (and:SWI48 13825 (plus:SWI48 13826 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13827 (const_int -1)) 13828 (match_dup 1))) 13829 (clobber (reg:CC FLAGS_REG))] 13830 "TARGET_BMI" 13831 "blsr\t{%1, %0|%0, %1}" 13832 [(set_attr "type" "bitmanip") 13833 (set_attr "btver2_decode" "double") 13834 (set_attr "mode" "<MODE>")]) 13835 13836(define_insn "*bmi_blsr_<mode>_cmp" 13837 [(set (reg:CCZ FLAGS_REG) 13838 (compare:CCZ 13839 (and:SWI48 13840 (plus:SWI48 13841 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13842 (const_int -1)) 13843 (match_dup 1)) 13844 (const_int 0))) 13845 (set (match_operand:SWI48 0 "register_operand" "=r") 13846 (and:SWI48 13847 (plus:SWI48 13848 (match_dup 1) 13849 (const_int -1)) 13850 (match_dup 1)))] 13851 "TARGET_BMI" 13852 "blsr\t{%1, %0|%0, %1}" 13853 [(set_attr "type" "bitmanip") 13854 (set_attr "btver2_decode" "double") 13855 (set_attr "mode" "<MODE>")]) 13856 13857(define_insn "*bmi_blsr_<mode>_ccz" 13858 [(set (reg:CCZ FLAGS_REG) 13859 (compare:CCZ 13860 (and:SWI48 13861 (plus:SWI48 13862 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13863 (const_int -1)) 13864 (match_dup 1)) 13865 (const_int 0))) 13866 (clobber (match_scratch:SWI48 0 "=r"))] 13867 "TARGET_BMI" 13868 "blsr\t{%1, %0|%0, %1}" 13869 [(set_attr "type" "bitmanip") 13870 (set_attr "btver2_decode" "double") 13871 (set_attr "mode" "<MODE>")]) 13872 13873;; BMI2 instructions. 13874(define_expand "bmi2_bzhi_<mode>3" 13875 [(parallel 13876 [(set (match_operand:SWI48 0 "register_operand") 13877 (zero_extract:SWI48 13878 (match_operand:SWI48 1 "nonimmediate_operand") 13879 (umin:SWI48 13880 (and:SWI48 (match_operand:SWI48 2 "register_operand") 13881 (const_int 255)) 13882 (match_dup 3)) 13883 (const_int 0))) 13884 (clobber (reg:CC FLAGS_REG))])] 13885 "TARGET_BMI2" 13886 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);") 13887 13888(define_insn "*bmi2_bzhi_<mode>3" 13889 [(set (match_operand:SWI48 0 "register_operand" "=r") 13890 (zero_extract:SWI48 13891 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13892 (umin:SWI48 13893 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r") 13894 (const_int 255)) 13895 (match_operand:SWI48 3 "const_int_operand" "n")) 13896 (const_int 0))) 13897 (clobber (reg:CC FLAGS_REG))] 13898 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13899 "bzhi\t{%2, %1, %0|%0, %1, %2}" 13900 [(set_attr "type" "bitmanip") 13901 (set_attr "prefix" "vex") 13902 (set_attr "mode" "<MODE>")]) 13903 13904(define_insn "*bmi2_bzhi_<mode>3_1" 13905 [(set (match_operand:SWI48 0 "register_operand" "=r") 13906 (zero_extract:SWI48 13907 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13908 (umin:SWI48 13909 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r")) 13910 (match_operand:SWI48 3 "const_int_operand" "n")) 13911 (const_int 0))) 13912 (clobber (reg:CC FLAGS_REG))] 13913 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13914 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 13915 [(set_attr "type" "bitmanip") 13916 (set_attr "prefix" "vex") 13917 (set_attr "mode" "<MODE>")]) 13918 13919(define_insn "*bmi2_bzhi_<mode>3_1_ccz" 13920 [(set (reg:CCZ FLAGS_REG) 13921 (compare:CCZ 13922 (zero_extract:SWI48 13923 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13924 (umin:SWI48 13925 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r")) 13926 (match_operand:SWI48 3 "const_int_operand" "n")) 13927 (const_int 0)) 13928 (const_int 0))) 13929 (clobber (match_scratch:SWI48 0 "=r"))] 13930 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 13931 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 13932 [(set_attr "type" "bitmanip") 13933 (set_attr "prefix" "vex") 13934 (set_attr "mode" "<MODE>")]) 13935 13936(define_insn "bmi2_pdep_<mode>3" 13937 [(set (match_operand:SWI48 0 "register_operand" "=r") 13938 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 13939 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 13940 UNSPEC_PDEP))] 13941 "TARGET_BMI2" 13942 "pdep\t{%2, %1, %0|%0, %1, %2}" 13943 [(set_attr "type" "bitmanip") 13944 (set_attr "prefix" "vex") 13945 (set_attr "mode" "<MODE>")]) 13946 13947(define_insn "bmi2_pext_<mode>3" 13948 [(set (match_operand:SWI48 0 "register_operand" "=r") 13949 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 13950 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 13951 UNSPEC_PEXT))] 13952 "TARGET_BMI2" 13953 "pext\t{%2, %1, %0|%0, %1, %2}" 13954 [(set_attr "type" "bitmanip") 13955 (set_attr "prefix" "vex") 13956 (set_attr "mode" "<MODE>")]) 13957 13958;; TBM instructions. 13959(define_insn "tbm_bextri_<mode>" 13960 [(set (match_operand:SWI48 0 "register_operand" "=r") 13961 (zero_extract:SWI48 13962 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13963 (match_operand 2 "const_0_to_255_operand" "N") 13964 (match_operand 3 "const_0_to_255_operand" "N"))) 13965 (clobber (reg:CC FLAGS_REG))] 13966 "TARGET_TBM" 13967{ 13968 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); 13969 return "bextr\t{%2, %1, %0|%0, %1, %2}"; 13970} 13971 [(set_attr "type" "bitmanip") 13972 (set_attr "mode" "<MODE>")]) 13973 13974(define_insn "*tbm_blcfill_<mode>" 13975 [(set (match_operand:SWI48 0 "register_operand" "=r") 13976 (and:SWI48 13977 (plus:SWI48 13978 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13979 (const_int 1)) 13980 (match_dup 1))) 13981 (clobber (reg:CC FLAGS_REG))] 13982 "TARGET_TBM" 13983 "blcfill\t{%1, %0|%0, %1}" 13984 [(set_attr "type" "bitmanip") 13985 (set_attr "mode" "<MODE>")]) 13986 13987(define_insn "*tbm_blci_<mode>" 13988 [(set (match_operand:SWI48 0 "register_operand" "=r") 13989 (ior:SWI48 13990 (not:SWI48 13991 (plus:SWI48 13992 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13993 (const_int 1))) 13994 (match_dup 1))) 13995 (clobber (reg:CC FLAGS_REG))] 13996 "TARGET_TBM" 13997 "blci\t{%1, %0|%0, %1}" 13998 [(set_attr "type" "bitmanip") 13999 (set_attr "mode" "<MODE>")]) 14000 14001(define_insn "*tbm_blcic_<mode>" 14002 [(set (match_operand:SWI48 0 "register_operand" "=r") 14003 (and:SWI48 14004 (plus:SWI48 14005 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14006 (const_int 1)) 14007 (not:SWI48 14008 (match_dup 1)))) 14009 (clobber (reg:CC FLAGS_REG))] 14010 "TARGET_TBM" 14011 "blcic\t{%1, %0|%0, %1}" 14012 [(set_attr "type" "bitmanip") 14013 (set_attr "mode" "<MODE>")]) 14014 14015(define_insn "*tbm_blcmsk_<mode>" 14016 [(set (match_operand:SWI48 0 "register_operand" "=r") 14017 (xor:SWI48 14018 (plus:SWI48 14019 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14020 (const_int 1)) 14021 (match_dup 1))) 14022 (clobber (reg:CC FLAGS_REG))] 14023 "TARGET_TBM" 14024 "blcmsk\t{%1, %0|%0, %1}" 14025 [(set_attr "type" "bitmanip") 14026 (set_attr "mode" "<MODE>")]) 14027 14028(define_insn "*tbm_blcs_<mode>" 14029 [(set (match_operand:SWI48 0 "register_operand" "=r") 14030 (ior:SWI48 14031 (plus:SWI48 14032 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14033 (const_int 1)) 14034 (match_dup 1))) 14035 (clobber (reg:CC FLAGS_REG))] 14036 "TARGET_TBM" 14037 "blcs\t{%1, %0|%0, %1}" 14038 [(set_attr "type" "bitmanip") 14039 (set_attr "mode" "<MODE>")]) 14040 14041(define_insn "*tbm_blsfill_<mode>" 14042 [(set (match_operand:SWI48 0 "register_operand" "=r") 14043 (ior:SWI48 14044 (plus:SWI48 14045 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14046 (const_int -1)) 14047 (match_dup 1))) 14048 (clobber (reg:CC FLAGS_REG))] 14049 "TARGET_TBM" 14050 "blsfill\t{%1, %0|%0, %1}" 14051 [(set_attr "type" "bitmanip") 14052 (set_attr "mode" "<MODE>")]) 14053 14054(define_insn "*tbm_blsic_<mode>" 14055 [(set (match_operand:SWI48 0 "register_operand" "=r") 14056 (ior:SWI48 14057 (plus:SWI48 14058 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14059 (const_int -1)) 14060 (not:SWI48 14061 (match_dup 1)))) 14062 (clobber (reg:CC FLAGS_REG))] 14063 "TARGET_TBM" 14064 "blsic\t{%1, %0|%0, %1}" 14065 [(set_attr "type" "bitmanip") 14066 (set_attr "mode" "<MODE>")]) 14067 14068(define_insn "*tbm_t1mskc_<mode>" 14069 [(set (match_operand:SWI48 0 "register_operand" "=r") 14070 (ior:SWI48 14071 (plus:SWI48 14072 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14073 (const_int 1)) 14074 (not:SWI48 14075 (match_dup 1)))) 14076 (clobber (reg:CC FLAGS_REG))] 14077 "TARGET_TBM" 14078 "t1mskc\t{%1, %0|%0, %1}" 14079 [(set_attr "type" "bitmanip") 14080 (set_attr "mode" "<MODE>")]) 14081 14082(define_insn "*tbm_tzmsk_<mode>" 14083 [(set (match_operand:SWI48 0 "register_operand" "=r") 14084 (and:SWI48 14085 (plus:SWI48 14086 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14087 (const_int -1)) 14088 (not:SWI48 14089 (match_dup 1)))) 14090 (clobber (reg:CC FLAGS_REG))] 14091 "TARGET_TBM" 14092 "tzmsk\t{%1, %0|%0, %1}" 14093 [(set_attr "type" "bitmanip") 14094 (set_attr "mode" "<MODE>")]) 14095 14096(define_insn_and_split "popcount<mode>2" 14097 [(set (match_operand:SWI48 0 "register_operand" "=r") 14098 (popcount:SWI48 14099 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14100 (clobber (reg:CC FLAGS_REG))] 14101 "TARGET_POPCNT" 14102{ 14103#if TARGET_MACHO 14104 return "popcnt\t{%1, %0|%0, %1}"; 14105#else 14106 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 14107#endif 14108} 14109 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 14110 && optimize_function_for_speed_p (cfun) 14111 && !reg_mentioned_p (operands[0], operands[1])" 14112 [(parallel 14113 [(set (match_dup 0) 14114 (popcount:SWI48 (match_dup 1))) 14115 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 14116 (clobber (reg:CC FLAGS_REG))])] 14117 "ix86_expand_clear (operands[0]);" 14118 [(set_attr "prefix_rep" "1") 14119 (set_attr "type" "bitmanip") 14120 (set_attr "mode" "<MODE>")]) 14121 14122; False dependency happens when destination is only updated by tzcnt, 14123; lzcnt or popcnt. There is no false dependency when destination is 14124; also used in source. 14125(define_insn "*popcount<mode>2_falsedep" 14126 [(set (match_operand:SWI48 0 "register_operand" "=r") 14127 (popcount:SWI48 14128 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14129 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 14130 UNSPEC_INSN_FALSE_DEP) 14131 (clobber (reg:CC FLAGS_REG))] 14132 "TARGET_POPCNT" 14133{ 14134#if TARGET_MACHO 14135 return "popcnt\t{%1, %0|%0, %1}"; 14136#else 14137 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 14138#endif 14139} 14140 [(set_attr "prefix_rep" "1") 14141 (set_attr "type" "bitmanip") 14142 (set_attr "mode" "<MODE>")]) 14143 14144(define_insn_and_split "*popcounthi2_1" 14145 [(set (match_operand:SI 0 "register_operand") 14146 (popcount:SI 14147 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))) 14148 (clobber (reg:CC FLAGS_REG))] 14149 "TARGET_POPCNT 14150 && can_create_pseudo_p ()" 14151 "#" 14152 "&& 1" 14153 [(const_int 0)] 14154{ 14155 rtx tmp = gen_reg_rtx (HImode); 14156 14157 emit_insn (gen_popcounthi2 (tmp, operands[1])); 14158 emit_insn (gen_zero_extendhisi2 (operands[0], tmp)); 14159 DONE; 14160}) 14161 14162(define_insn "popcounthi2" 14163 [(set (match_operand:HI 0 "register_operand" "=r") 14164 (popcount:HI 14165 (match_operand:HI 1 "nonimmediate_operand" "rm"))) 14166 (clobber (reg:CC FLAGS_REG))] 14167 "TARGET_POPCNT" 14168{ 14169#if TARGET_MACHO 14170 return "popcnt\t{%1, %0|%0, %1}"; 14171#else 14172 return "popcnt{w}\t{%1, %0|%0, %1}"; 14173#endif 14174} 14175 [(set_attr "prefix_rep" "1") 14176 (set_attr "type" "bitmanip") 14177 (set_attr "mode" "HI")]) 14178 14179(define_expand "bswapdi2" 14180 [(set (match_operand:DI 0 "register_operand") 14181 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))] 14182 "TARGET_64BIT" 14183{ 14184 if (!TARGET_MOVBE) 14185 operands[1] = force_reg (DImode, operands[1]); 14186}) 14187 14188(define_expand "bswapsi2" 14189 [(set (match_operand:SI 0 "register_operand") 14190 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))] 14191 "" 14192{ 14193 if (TARGET_MOVBE) 14194 ; 14195 else if (TARGET_BSWAP) 14196 operands[1] = force_reg (SImode, operands[1]); 14197 else 14198 { 14199 rtx x = operands[0]; 14200 14201 emit_move_insn (x, operands[1]); 14202 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 14203 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 14204 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 14205 DONE; 14206 } 14207}) 14208 14209(define_insn "*bswap<mode>2_movbe" 14210 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") 14211 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] 14212 "TARGET_MOVBE 14213 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 14214 "@ 14215 bswap\t%0 14216 movbe{<imodesuffix>}\t{%1, %0|%0, %1} 14217 movbe{<imodesuffix>}\t{%1, %0|%0, %1}" 14218 [(set_attr "type" "bitmanip,imov,imov") 14219 (set_attr "modrm" "0,1,1") 14220 (set_attr "prefix_0f" "*,1,1") 14221 (set_attr "prefix_extra" "*,1,1") 14222 (set_attr "mode" "<MODE>")]) 14223 14224(define_insn "*bswap<mode>2" 14225 [(set (match_operand:SWI48 0 "register_operand" "=r") 14226 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] 14227 "TARGET_BSWAP" 14228 "bswap\t%0" 14229 [(set_attr "type" "bitmanip") 14230 (set_attr "modrm" "0") 14231 (set_attr "mode" "<MODE>")]) 14232 14233(define_expand "bswaphi2" 14234 [(set (match_operand:HI 0 "register_operand") 14235 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))] 14236 "TARGET_MOVBE") 14237 14238(define_insn "*bswaphi2_movbe" 14239 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m") 14240 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))] 14241 "TARGET_MOVBE 14242 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 14243 "@ 14244 xchg{b}\t{%h0, %b0|%b0, %h0} 14245 movbe{w}\t{%1, %0|%0, %1} 14246 movbe{w}\t{%1, %0|%0, %1}" 14247 [(set_attr "type" "imov") 14248 (set_attr "modrm" "*,1,1") 14249 (set_attr "prefix_0f" "*,1,1") 14250 (set_attr "prefix_extra" "*,1,1") 14251 (set_attr "pent_pair" "np,*,*") 14252 (set_attr "athlon_decode" "vector,*,*") 14253 (set_attr "amdfam10_decode" "double,*,*") 14254 (set_attr "bdver1_decode" "double,*,*") 14255 (set_attr "mode" "QI,HI,HI")]) 14256 14257(define_peephole2 14258 [(set (match_operand:HI 0 "general_reg_operand") 14259 (bswap:HI (match_dup 0)))] 14260 "TARGET_MOVBE 14261 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)) 14262 && peep2_regno_dead_p (0, FLAGS_REG)" 14263 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8))) 14264 (clobber (reg:CC FLAGS_REG))])]) 14265 14266(define_insn "bswaphi_lowpart" 14267 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) 14268 (bswap:HI (match_dup 0))) 14269 (clobber (reg:CC FLAGS_REG))] 14270 "" 14271 "@ 14272 xchg{b}\t{%h0, %b0|%b0, %h0} 14273 rol{w}\t{$8, %0|%0, 8}" 14274 [(set (attr "preferred_for_size") 14275 (cond [(eq_attr "alternative" "0") 14276 (symbol_ref "true")] 14277 (symbol_ref "false"))) 14278 (set (attr "preferred_for_speed") 14279 (cond [(eq_attr "alternative" "0") 14280 (symbol_ref "TARGET_USE_XCHGB")] 14281 (symbol_ref "!TARGET_USE_XCHGB"))) 14282 (set_attr "length" "2,4") 14283 (set_attr "mode" "QI,HI")]) 14284 14285(define_expand "paritydi2" 14286 [(set (match_operand:DI 0 "register_operand") 14287 (parity:DI (match_operand:DI 1 "register_operand")))] 14288 "! TARGET_POPCNT" 14289{ 14290 rtx scratch = gen_reg_rtx (QImode); 14291 14292 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, 14293 NULL_RTX, operands[1])); 14294 14295 ix86_expand_setcc (scratch, ORDERED, 14296 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 14297 14298 if (TARGET_64BIT) 14299 emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); 14300 else 14301 { 14302 rtx tmp = gen_reg_rtx (SImode); 14303 14304 emit_insn (gen_zero_extendqisi2 (tmp, scratch)); 14305 emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); 14306 } 14307 DONE; 14308}) 14309 14310(define_expand "paritysi2" 14311 [(set (match_operand:SI 0 "register_operand") 14312 (parity:SI (match_operand:SI 1 "register_operand")))] 14313 "! TARGET_POPCNT" 14314{ 14315 rtx scratch = gen_reg_rtx (QImode); 14316 14317 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); 14318 14319 ix86_expand_setcc (scratch, ORDERED, 14320 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 14321 14322 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 14323 DONE; 14324}) 14325 14326(define_insn_and_split "paritydi2_cmp" 14327 [(set (reg:CC FLAGS_REG) 14328 (unspec:CC [(match_operand:DI 3 "register_operand" "0")] 14329 UNSPEC_PARITY)) 14330 (clobber (match_scratch:DI 0 "=r")) 14331 (clobber (match_scratch:SI 1 "=&r")) 14332 (clobber (match_scratch:HI 2 "=Q"))] 14333 "! TARGET_POPCNT" 14334 "#" 14335 "&& reload_completed" 14336 [(parallel 14337 [(set (match_dup 1) 14338 (xor:SI (match_dup 1) (match_dup 4))) 14339 (clobber (reg:CC FLAGS_REG))]) 14340 (parallel 14341 [(set (reg:CC FLAGS_REG) 14342 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 14343 (clobber (match_dup 1)) 14344 (clobber (match_dup 2))])] 14345{ 14346 operands[4] = gen_lowpart (SImode, operands[3]); 14347 14348 if (TARGET_64BIT) 14349 { 14350 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); 14351 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); 14352 } 14353 else 14354 operands[1] = gen_highpart (SImode, operands[3]); 14355}) 14356 14357(define_insn_and_split "paritysi2_cmp" 14358 [(set (reg:CC FLAGS_REG) 14359 (unspec:CC [(match_operand:SI 2 "register_operand" "0")] 14360 UNSPEC_PARITY)) 14361 (clobber (match_scratch:SI 0 "=r")) 14362 (clobber (match_scratch:HI 1 "=&Q"))] 14363 "! TARGET_POPCNT" 14364 "#" 14365 "&& reload_completed" 14366 [(parallel 14367 [(set (match_dup 1) 14368 (xor:HI (match_dup 1) (match_dup 3))) 14369 (clobber (reg:CC FLAGS_REG))]) 14370 (parallel 14371 [(set (reg:CC FLAGS_REG) 14372 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 14373 (clobber (match_dup 1))])] 14374{ 14375 operands[3] = gen_lowpart (HImode, operands[2]); 14376 14377 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); 14378 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); 14379}) 14380 14381(define_insn "*parityhi2_cmp" 14382 [(set (reg:CC FLAGS_REG) 14383 (unspec:CC [(match_operand:HI 1 "register_operand" "0")] 14384 UNSPEC_PARITY)) 14385 (clobber (match_scratch:HI 0 "=Q"))] 14386 "! TARGET_POPCNT" 14387 "xor{b}\t{%h0, %b0|%b0, %h0}" 14388 [(set_attr "length" "2") 14389 (set_attr "mode" "HI")]) 14390 14391 14392;; Thread-local storage patterns for ELF. 14393;; 14394;; Note that these code sequences must appear exactly as shown 14395;; in order to allow linker relaxation. 14396 14397(define_insn "*tls_global_dynamic_32_gnu" 14398 [(set (match_operand:SI 0 "register_operand" "=a") 14399 (unspec:SI 14400 [(match_operand:SI 1 "register_operand" "Yb") 14401 (match_operand 2 "tls_symbolic_operand") 14402 (match_operand 3 "constant_call_address_operand" "Bz") 14403 (reg:SI SP_REG)] 14404 UNSPEC_TLS_GD)) 14405 (clobber (match_scratch:SI 4 "=d")) 14406 (clobber (match_scratch:SI 5 "=c")) 14407 (clobber (reg:CC FLAGS_REG))] 14408 "!TARGET_64BIT && TARGET_GNU_TLS" 14409{ 14410 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14411 output_asm_insn 14412 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); 14413 else 14414 output_asm_insn 14415 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands); 14416 if (TARGET_SUN_TLS) 14417#ifdef HAVE_AS_IX86_TLSGDPLT 14418 return "call\t%a2@tlsgdplt"; 14419#else 14420 return "call\t%p3@plt"; 14421#endif 14422 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14423 return "call\t%P3"; 14424 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}"; 14425} 14426 [(set_attr "type" "multi") 14427 (set_attr "length" "12")]) 14428 14429(define_expand "tls_global_dynamic_32" 14430 [(parallel 14431 [(set (match_operand:SI 0 "register_operand") 14432 (unspec:SI [(match_operand:SI 2 "register_operand") 14433 (match_operand 1 "tls_symbolic_operand") 14434 (match_operand 3 "constant_call_address_operand") 14435 (reg:SI SP_REG)] 14436 UNSPEC_TLS_GD)) 14437 (clobber (match_scratch:SI 4)) 14438 (clobber (match_scratch:SI 5)) 14439 (clobber (reg:CC FLAGS_REG))])] 14440 "" 14441 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14442 14443(define_insn "*tls_global_dynamic_64_<mode>" 14444 [(set (match_operand:P 0 "register_operand" "=a") 14445 (call:P 14446 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz")) 14447 (match_operand 3))) 14448 (unspec:P [(match_operand 1 "tls_symbolic_operand") 14449 (reg:P SP_REG)] 14450 UNSPEC_TLS_GD)] 14451 "TARGET_64BIT" 14452{ 14453 if (!TARGET_X32) 14454 fputs (ASM_BYTE "0x66\n", asm_out_file); 14455 output_asm_insn 14456 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 14457 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14458 fputs (ASM_SHORT "0x6666\n", asm_out_file); 14459 else 14460 fputs (ASM_BYTE "0x66\n", asm_out_file); 14461 fputs ("\trex64\n", asm_out_file); 14462 if (TARGET_SUN_TLS) 14463 return "call\t%p2@plt"; 14464 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14465 return "call\t%P2"; 14466 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}"; 14467} 14468 [(set_attr "type" "multi") 14469 (set (attr "length") 14470 (symbol_ref "TARGET_X32 ? 15 : 16"))]) 14471 14472(define_insn "*tls_global_dynamic_64_largepic" 14473 [(set (match_operand:DI 0 "register_operand" "=a") 14474 (call:DI 14475 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b") 14476 (match_operand:DI 3 "immediate_operand" "i"))) 14477 (match_operand 4))) 14478 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 14479 (reg:DI SP_REG)] 14480 UNSPEC_TLS_GD)] 14481 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 14482 && GET_CODE (operands[3]) == CONST 14483 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC 14484 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF" 14485{ 14486 output_asm_insn 14487 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 14488 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands); 14489 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands); 14490 return "call\t{*%%rax|rax}"; 14491} 14492 [(set_attr "type" "multi") 14493 (set_attr "length" "22")]) 14494 14495(define_expand "tls_global_dynamic_64_<mode>" 14496 [(parallel 14497 [(set (match_operand:P 0 "register_operand") 14498 (call:P 14499 (mem:QI (match_operand 2)) 14500 (const_int 0))) 14501 (unspec:P [(match_operand 1 "tls_symbolic_operand") 14502 (reg:P SP_REG)] 14503 UNSPEC_TLS_GD)])] 14504 "TARGET_64BIT" 14505 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14506 14507(define_insn "*tls_local_dynamic_base_32_gnu" 14508 [(set (match_operand:SI 0 "register_operand" "=a") 14509 (unspec:SI 14510 [(match_operand:SI 1 "register_operand" "Yb") 14511 (match_operand 2 "constant_call_address_operand" "Bz") 14512 (reg:SI SP_REG)] 14513 UNSPEC_TLS_LD_BASE)) 14514 (clobber (match_scratch:SI 3 "=d")) 14515 (clobber (match_scratch:SI 4 "=c")) 14516 (clobber (reg:CC FLAGS_REG))] 14517 "!TARGET_64BIT && TARGET_GNU_TLS" 14518{ 14519 output_asm_insn 14520 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); 14521 if (TARGET_SUN_TLS) 14522 { 14523 if (HAVE_AS_IX86_TLSLDMPLT) 14524 return "call\t%&@tlsldmplt"; 14525 else 14526 return "call\t%p2@plt"; 14527 } 14528 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14529 return "call\t%P2"; 14530 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}"; 14531} 14532 [(set_attr "type" "multi") 14533 (set_attr "length" "11")]) 14534 14535(define_expand "tls_local_dynamic_base_32" 14536 [(parallel 14537 [(set (match_operand:SI 0 "register_operand") 14538 (unspec:SI 14539 [(match_operand:SI 1 "register_operand") 14540 (match_operand 2 "constant_call_address_operand") 14541 (reg:SI SP_REG)] 14542 UNSPEC_TLS_LD_BASE)) 14543 (clobber (match_scratch:SI 3)) 14544 (clobber (match_scratch:SI 4)) 14545 (clobber (reg:CC FLAGS_REG))])] 14546 "" 14547 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14548 14549(define_insn "*tls_local_dynamic_base_64_<mode>" 14550 [(set (match_operand:P 0 "register_operand" "=a") 14551 (call:P 14552 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz")) 14553 (match_operand 2))) 14554 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)] 14555 "TARGET_64BIT" 14556{ 14557 output_asm_insn 14558 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 14559 if (TARGET_SUN_TLS) 14560 return "call\t%p1@plt"; 14561 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14562 return "call\t%P1"; 14563 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}"; 14564} 14565 [(set_attr "type" "multi") 14566 (set_attr "length" "12")]) 14567 14568(define_insn "*tls_local_dynamic_base_64_largepic" 14569 [(set (match_operand:DI 0 "register_operand" "=a") 14570 (call:DI 14571 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b") 14572 (match_operand:DI 2 "immediate_operand" "i"))) 14573 (match_operand 3))) 14574 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)] 14575 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 14576 && GET_CODE (operands[2]) == CONST 14577 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC 14578 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF" 14579{ 14580 output_asm_insn 14581 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 14582 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands); 14583 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands); 14584 return "call\t{*%%rax|rax}"; 14585} 14586 [(set_attr "type" "multi") 14587 (set_attr "length" "22")]) 14588 14589(define_expand "tls_local_dynamic_base_64_<mode>" 14590 [(parallel 14591 [(set (match_operand:P 0 "register_operand") 14592 (call:P 14593 (mem:QI (match_operand 1)) 14594 (const_int 0))) 14595 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])] 14596 "TARGET_64BIT" 14597 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14598 14599;; Local dynamic of a single variable is a lose. Show combine how 14600;; to convert that back to global dynamic. 14601 14602(define_insn_and_split "*tls_local_dynamic_32_once" 14603 [(set (match_operand:SI 0 "register_operand" "=a") 14604 (plus:SI 14605 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14606 (match_operand 2 "constant_call_address_operand" "Bz") 14607 (reg:SI SP_REG)] 14608 UNSPEC_TLS_LD_BASE) 14609 (const:SI (unspec:SI 14610 [(match_operand 3 "tls_symbolic_operand")] 14611 UNSPEC_DTPOFF)))) 14612 (clobber (match_scratch:SI 4 "=d")) 14613 (clobber (match_scratch:SI 5 "=c")) 14614 (clobber (reg:CC FLAGS_REG))] 14615 "" 14616 "#" 14617 "" 14618 [(parallel 14619 [(set (match_dup 0) 14620 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2) 14621 (reg:SI SP_REG)] 14622 UNSPEC_TLS_GD)) 14623 (clobber (match_dup 4)) 14624 (clobber (match_dup 5)) 14625 (clobber (reg:CC FLAGS_REG))])]) 14626 14627;; Load and add the thread base pointer from %<tp_seg>:0. 14628(define_insn_and_split "*load_tp_<mode>" 14629 [(set (match_operand:PTR 0 "register_operand" "=r") 14630 (unspec:PTR [(const_int 0)] UNSPEC_TP))] 14631 "" 14632 "#" 14633 "" 14634 [(set (match_dup 0) 14635 (match_dup 1))] 14636{ 14637 addr_space_t as = DEFAULT_TLS_SEG_REG; 14638 14639 operands[1] = gen_const_mem (<MODE>mode, const0_rtx); 14640 set_mem_addr_space (operands[1], as); 14641}) 14642 14643(define_insn_and_split "*load_tp_x32_zext" 14644 [(set (match_operand:DI 0 "register_operand" "=r") 14645 (zero_extend:DI 14646 (unspec:SI [(const_int 0)] UNSPEC_TP)))] 14647 "TARGET_X32" 14648 "#" 14649 "" 14650 [(set (match_dup 0) 14651 (zero_extend:DI (match_dup 1)))] 14652{ 14653 addr_space_t as = DEFAULT_TLS_SEG_REG; 14654 14655 operands[1] = gen_const_mem (SImode, const0_rtx); 14656 set_mem_addr_space (operands[1], as); 14657}) 14658 14659(define_insn_and_split "*add_tp_<mode>" 14660 [(set (match_operand:PTR 0 "register_operand" "=r") 14661 (plus:PTR 14662 (unspec:PTR [(const_int 0)] UNSPEC_TP) 14663 (match_operand:PTR 1 "register_operand" "0"))) 14664 (clobber (reg:CC FLAGS_REG))] 14665 "" 14666 "#" 14667 "" 14668 [(parallel 14669 [(set (match_dup 0) 14670 (plus:PTR (match_dup 1) (match_dup 2))) 14671 (clobber (reg:CC FLAGS_REG))])] 14672{ 14673 addr_space_t as = DEFAULT_TLS_SEG_REG; 14674 14675 operands[2] = gen_const_mem (<MODE>mode, const0_rtx); 14676 set_mem_addr_space (operands[2], as); 14677}) 14678 14679(define_insn_and_split "*add_tp_x32_zext" 14680 [(set (match_operand:DI 0 "register_operand" "=r") 14681 (zero_extend:DI 14682 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 14683 (match_operand:SI 1 "register_operand" "0")))) 14684 (clobber (reg:CC FLAGS_REG))] 14685 "TARGET_X32" 14686 "#" 14687 "" 14688 [(parallel 14689 [(set (match_dup 0) 14690 (zero_extend:DI 14691 (plus:SI (match_dup 1) (match_dup 2)))) 14692 (clobber (reg:CC FLAGS_REG))])] 14693{ 14694 addr_space_t as = DEFAULT_TLS_SEG_REG; 14695 14696 operands[2] = gen_const_mem (SImode, const0_rtx); 14697 set_mem_addr_space (operands[2], as); 14698}) 14699 14700;; The Sun linker took the AMD64 TLS spec literally and can only handle 14701;; %rax as destination of the initial executable code sequence. 14702(define_insn "tls_initial_exec_64_sun" 14703 [(set (match_operand:DI 0 "register_operand" "=a") 14704 (unspec:DI 14705 [(match_operand 1 "tls_symbolic_operand")] 14706 UNSPEC_TLS_IE_SUN)) 14707 (clobber (reg:CC FLAGS_REG))] 14708 "TARGET_64BIT && TARGET_SUN_TLS" 14709{ 14710 output_asm_insn 14711 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); 14712 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; 14713} 14714 [(set_attr "type" "multi")]) 14715 14716;; GNU2 TLS patterns can be split. 14717 14718(define_expand "tls_dynamic_gnu2_32" 14719 [(set (match_dup 3) 14720 (plus:SI (match_operand:SI 2 "register_operand") 14721 (const:SI 14722 (unspec:SI [(match_operand 1 "tls_symbolic_operand")] 14723 UNSPEC_TLSDESC)))) 14724 (parallel 14725 [(set (match_operand:SI 0 "register_operand") 14726 (unspec:SI [(match_dup 1) (match_dup 3) 14727 (match_dup 2) (reg:SI SP_REG)] 14728 UNSPEC_TLSDESC)) 14729 (clobber (reg:CC FLAGS_REG))])] 14730 "!TARGET_64BIT && TARGET_GNU2_TLS" 14731{ 14732 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14733 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14734}) 14735 14736(define_insn "*tls_dynamic_gnu2_lea_32" 14737 [(set (match_operand:SI 0 "register_operand" "=r") 14738 (plus:SI (match_operand:SI 1 "register_operand" "b") 14739 (const:SI 14740 (unspec:SI [(match_operand 2 "tls_symbolic_operand")] 14741 UNSPEC_TLSDESC))))] 14742 "!TARGET_64BIT && TARGET_GNU2_TLS" 14743 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" 14744 [(set_attr "type" "lea") 14745 (set_attr "mode" "SI") 14746 (set_attr "length" "6") 14747 (set_attr "length_address" "4")]) 14748 14749(define_insn "*tls_dynamic_gnu2_call_32" 14750 [(set (match_operand:SI 0 "register_operand" "=a") 14751 (unspec:SI [(match_operand 1 "tls_symbolic_operand") 14752 (match_operand:SI 2 "register_operand" "0") 14753 ;; we have to make sure %ebx still points to the GOT 14754 (match_operand:SI 3 "register_operand" "b") 14755 (reg:SI SP_REG)] 14756 UNSPEC_TLSDESC)) 14757 (clobber (reg:CC FLAGS_REG))] 14758 "!TARGET_64BIT && TARGET_GNU2_TLS" 14759 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 14760 [(set_attr "type" "call") 14761 (set_attr "length" "2") 14762 (set_attr "length_address" "0")]) 14763 14764(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 14765 [(set (match_operand:SI 0 "register_operand" "=&a") 14766 (plus:SI 14767 (unspec:SI [(match_operand 3 "tls_modbase_operand") 14768 (match_operand:SI 4) 14769 (match_operand:SI 2 "register_operand" "b") 14770 (reg:SI SP_REG)] 14771 UNSPEC_TLSDESC) 14772 (const:SI (unspec:SI 14773 [(match_operand 1 "tls_symbolic_operand")] 14774 UNSPEC_DTPOFF)))) 14775 (clobber (reg:CC FLAGS_REG))] 14776 "!TARGET_64BIT && TARGET_GNU2_TLS" 14777 "#" 14778 "" 14779 [(set (match_dup 0) (match_dup 5))] 14780{ 14781 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14782 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 14783}) 14784 14785(define_expand "tls_dynamic_gnu2_64" 14786 [(set (match_dup 2) 14787 (unspec:DI [(match_operand 1 "tls_symbolic_operand")] 14788 UNSPEC_TLSDESC)) 14789 (parallel 14790 [(set (match_operand:DI 0 "register_operand") 14791 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 14792 UNSPEC_TLSDESC)) 14793 (clobber (reg:CC FLAGS_REG))])] 14794 "TARGET_64BIT && TARGET_GNU2_TLS" 14795{ 14796 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14797 ix86_tls_descriptor_calls_expanded_in_cfun = true; 14798}) 14799 14800(define_insn "*tls_dynamic_gnu2_lea_64" 14801 [(set (match_operand:DI 0 "register_operand" "=r") 14802 (unspec:DI [(match_operand 1 "tls_symbolic_operand")] 14803 UNSPEC_TLSDESC))] 14804 "TARGET_64BIT && TARGET_GNU2_TLS" 14805 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" 14806 [(set_attr "type" "lea") 14807 (set_attr "mode" "DI") 14808 (set_attr "length" "7") 14809 (set_attr "length_address" "4")]) 14810 14811(define_insn "*tls_dynamic_gnu2_call_64" 14812 [(set (match_operand:DI 0 "register_operand" "=a") 14813 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 14814 (match_operand:DI 2 "register_operand" "0") 14815 (reg:DI SP_REG)] 14816 UNSPEC_TLSDESC)) 14817 (clobber (reg:CC FLAGS_REG))] 14818 "TARGET_64BIT && TARGET_GNU2_TLS" 14819 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 14820 [(set_attr "type" "call") 14821 (set_attr "length" "2") 14822 (set_attr "length_address" "0")]) 14823 14824(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 14825 [(set (match_operand:DI 0 "register_operand" "=&a") 14826 (plus:DI 14827 (unspec:DI [(match_operand 2 "tls_modbase_operand") 14828 (match_operand:DI 3) 14829 (reg:DI SP_REG)] 14830 UNSPEC_TLSDESC) 14831 (const:DI (unspec:DI 14832 [(match_operand 1 "tls_symbolic_operand")] 14833 UNSPEC_DTPOFF)))) 14834 (clobber (reg:CC FLAGS_REG))] 14835 "TARGET_64BIT && TARGET_GNU2_TLS" 14836 "#" 14837 "" 14838 [(set (match_dup 0) (match_dup 4))] 14839{ 14840 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 14841 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 14842}) 14843 14844(define_split 14845 [(match_operand 0 "tls_address_pattern")] 14846 "TARGET_TLS_DIRECT_SEG_REFS" 14847 [(match_dup 0)] 14848 "operands[0] = ix86_rewrite_tls_address (operands[0]);") 14849 14850 14851;; These patterns match the binary 387 instructions for addM3, subM3, 14852;; mulM3 and divM3. There are three patterns for each of DFmode and 14853;; SFmode. The first is the normal insn, the second the same insn but 14854;; with one operand a conversion, and the third the same insn but with 14855;; the other operand a conversion. The conversion may be SFmode or 14856;; SImode if the target mode DFmode, but only SImode if the target mode 14857;; is SFmode. 14858 14859;; Gcc is slightly more smart about handling normal two address instructions 14860;; so use special patterns for add and mull. 14861 14862(define_insn "*fop_<mode>_comm" 14863 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v") 14864 (match_operator:MODEF 3 "binary_fp_operator" 14865 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v") 14866 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))] 14867 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14868 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))) 14869 && COMMUTATIVE_ARITH_P (operands[3]) 14870 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 14871 "* return output_387_binary_op (insn, operands);" 14872 [(set (attr "type") 14873 (if_then_else (eq_attr "alternative" "1,2") 14874 (if_then_else (match_operand:MODEF 3 "mult_operator") 14875 (const_string "ssemul") 14876 (const_string "sseadd")) 14877 (if_then_else (match_operand:MODEF 3 "mult_operator") 14878 (const_string "fmul") 14879 (const_string "fop")))) 14880 (set_attr "isa" "*,noavx,avx") 14881 (set_attr "prefix" "orig,orig,vex") 14882 (set_attr "mode" "<MODE>") 14883 (set (attr "enabled") 14884 (if_then_else 14885 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 14886 (if_then_else 14887 (eq_attr "alternative" "0") 14888 (symbol_ref "TARGET_MIX_SSE_I387 14889 && X87_ENABLE_ARITH (<MODE>mode)") 14890 (const_string "*")) 14891 (if_then_else 14892 (eq_attr "alternative" "0") 14893 (symbol_ref "true") 14894 (symbol_ref "false"))))]) 14895 14896(define_insn "*rcpsf2_sse" 14897 [(set (match_operand:SF 0 "register_operand" "=x") 14898 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 14899 UNSPEC_RCP))] 14900 "TARGET_SSE && TARGET_SSE_MATH" 14901 "%vrcpss\t{%1, %d0|%d0, %1}" 14902 [(set_attr "type" "sse") 14903 (set_attr "atom_sse_attr" "rcp") 14904 (set_attr "btver2_sse_attr" "rcp") 14905 (set_attr "prefix" "maybe_vex") 14906 (set_attr "mode" "SF")]) 14907 14908(define_insn "*fop_<mode>_1" 14909 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v") 14910 (match_operator:MODEF 3 "binary_fp_operator" 14911 [(match_operand:MODEF 1 14912 "x87nonimm_ssenomem_operand" "0,fm,0,v") 14913 (match_operand:MODEF 2 14914 "nonimmediate_operand" "fm,0,xm,vm")]))] 14915 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14916 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))) 14917 && !COMMUTATIVE_ARITH_P (operands[3]) 14918 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 14919 "* return output_387_binary_op (insn, operands);" 14920 [(set (attr "type") 14921 (if_then_else (eq_attr "alternative" "2,3") 14922 (if_then_else (match_operand:MODEF 3 "div_operator") 14923 (const_string "ssediv") 14924 (const_string "sseadd")) 14925 (if_then_else (match_operand:MODEF 3 "div_operator") 14926 (const_string "fdiv") 14927 (const_string "fop")))) 14928 (set_attr "isa" "*,*,noavx,avx") 14929 (set_attr "prefix" "orig,orig,orig,vex") 14930 (set_attr "mode" "<MODE>") 14931 (set (attr "enabled") 14932 (if_then_else 14933 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 14934 (if_then_else 14935 (eq_attr "alternative" "0,1") 14936 (symbol_ref "TARGET_MIX_SSE_I387 14937 && X87_ENABLE_ARITH (<MODE>mode)") 14938 (const_string "*")) 14939 (if_then_else 14940 (eq_attr "alternative" "0,1") 14941 (symbol_ref "true") 14942 (symbol_ref "false"))))]) 14943 14944;; ??? Add SSE splitters for these! 14945(define_insn "*fop_<MODEF:mode>_2_i387" 14946 [(set (match_operand:MODEF 0 "register_operand" "=f") 14947 (match_operator:MODEF 3 "binary_fp_operator" 14948 [(float:MODEF 14949 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 14950 (match_operand:MODEF 2 "register_operand" "0")]))] 14951 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 14952 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 14953 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 14954 || optimize_function_for_size_p (cfun))" 14955 "* return output_387_binary_op (insn, operands);" 14956 [(set (attr "type") 14957 (cond [(match_operand:MODEF 3 "mult_operator") 14958 (const_string "fmul") 14959 (match_operand:MODEF 3 "div_operator") 14960 (const_string "fdiv") 14961 ] 14962 (const_string "fop"))) 14963 (set_attr "fp_int_src" "true") 14964 (set_attr "mode" "<SWI24:MODE>")]) 14965 14966(define_insn "*fop_<MODEF:mode>_3_i387" 14967 [(set (match_operand:MODEF 0 "register_operand" "=f") 14968 (match_operator:MODEF 3 "binary_fp_operator" 14969 [(match_operand:MODEF 1 "register_operand" "0") 14970 (float:MODEF 14971 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 14972 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 14973 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 14974 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 14975 || optimize_function_for_size_p (cfun))" 14976 "* return output_387_binary_op (insn, operands);" 14977 [(set (attr "type") 14978 (cond [(match_operand:MODEF 3 "mult_operator") 14979 (const_string "fmul") 14980 (match_operand:MODEF 3 "div_operator") 14981 (const_string "fdiv") 14982 ] 14983 (const_string "fop"))) 14984 (set_attr "fp_int_src" "true") 14985 (set_attr "mode" "<MODE>")]) 14986 14987(define_insn "*fop_df_4_i387" 14988 [(set (match_operand:DF 0 "register_operand" "=f,f") 14989 (match_operator:DF 3 "binary_fp_operator" 14990 [(float_extend:DF 14991 (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 14992 (match_operand:DF 2 "register_operand" "0,f")]))] 14993 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 14994 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 14995 "* return output_387_binary_op (insn, operands);" 14996 [(set (attr "type") 14997 (cond [(match_operand:DF 3 "mult_operator") 14998 (const_string "fmul") 14999 (match_operand:DF 3 "div_operator") 15000 (const_string "fdiv") 15001 ] 15002 (const_string "fop"))) 15003 (set_attr "mode" "SF")]) 15004 15005(define_insn "*fop_df_5_i387" 15006 [(set (match_operand:DF 0 "register_operand" "=f,f") 15007 (match_operator:DF 3 "binary_fp_operator" 15008 [(match_operand:DF 1 "register_operand" "0,f") 15009 (float_extend:DF 15010 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15011 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15012 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15013 "* return output_387_binary_op (insn, operands);" 15014 [(set (attr "type") 15015 (cond [(match_operand:DF 3 "mult_operator") 15016 (const_string "fmul") 15017 (match_operand:DF 3 "div_operator") 15018 (const_string "fdiv") 15019 ] 15020 (const_string "fop"))) 15021 (set_attr "mode" "SF")]) 15022 15023(define_insn "*fop_df_6_i387" 15024 [(set (match_operand:DF 0 "register_operand" "=f,f") 15025 (match_operator:DF 3 "binary_fp_operator" 15026 [(float_extend:DF 15027 (match_operand:SF 1 "register_operand" "0,f")) 15028 (float_extend:DF 15029 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15030 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15031 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15032 "* return output_387_binary_op (insn, operands);" 15033 [(set (attr "type") 15034 (cond [(match_operand:DF 3 "mult_operator") 15035 (const_string "fmul") 15036 (match_operand:DF 3 "div_operator") 15037 (const_string "fdiv") 15038 ] 15039 (const_string "fop"))) 15040 (set_attr "mode" "SF")]) 15041 15042(define_insn "*fop_xf_comm_i387" 15043 [(set (match_operand:XF 0 "register_operand" "=f") 15044 (match_operator:XF 3 "binary_fp_operator" 15045 [(match_operand:XF 1 "register_operand" "%0") 15046 (match_operand:XF 2 "register_operand" "f")]))] 15047 "TARGET_80387 15048 && COMMUTATIVE_ARITH_P (operands[3])" 15049 "* return output_387_binary_op (insn, operands);" 15050 [(set (attr "type") 15051 (if_then_else (match_operand:XF 3 "mult_operator") 15052 (const_string "fmul") 15053 (const_string "fop"))) 15054 (set_attr "mode" "XF")]) 15055 15056(define_insn "*fop_xf_1_i387" 15057 [(set (match_operand:XF 0 "register_operand" "=f,f") 15058 (match_operator:XF 3 "binary_fp_operator" 15059 [(match_operand:XF 1 "register_operand" "0,f") 15060 (match_operand:XF 2 "register_operand" "f,0")]))] 15061 "TARGET_80387 15062 && !COMMUTATIVE_ARITH_P (operands[3])" 15063 "* return output_387_binary_op (insn, operands);" 15064 [(set (attr "type") 15065 (if_then_else (match_operand:XF 3 "div_operator") 15066 (const_string "fdiv") 15067 (const_string "fop"))) 15068 (set_attr "mode" "XF")]) 15069 15070(define_insn "*fop_xf_2_i387" 15071 [(set (match_operand:XF 0 "register_operand" "=f") 15072 (match_operator:XF 3 "binary_fp_operator" 15073 [(float:XF 15074 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 15075 (match_operand:XF 2 "register_operand" "0")]))] 15076 "TARGET_80387 15077 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 15078 "* return output_387_binary_op (insn, operands);" 15079 [(set (attr "type") 15080 (cond [(match_operand:XF 3 "mult_operator") 15081 (const_string "fmul") 15082 (match_operand:XF 3 "div_operator") 15083 (const_string "fdiv") 15084 ] 15085 (const_string "fop"))) 15086 (set_attr "fp_int_src" "true") 15087 (set_attr "mode" "<MODE>")]) 15088 15089(define_insn "*fop_xf_3_i387" 15090 [(set (match_operand:XF 0 "register_operand" "=f") 15091 (match_operator:XF 3 "binary_fp_operator" 15092 [(match_operand:XF 1 "register_operand" "0") 15093 (float:XF 15094 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 15095 "TARGET_80387 15096 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 15097 "* return output_387_binary_op (insn, operands);" 15098 [(set (attr "type") 15099 (cond [(match_operand:XF 3 "mult_operator") 15100 (const_string "fmul") 15101 (match_operand:XF 3 "div_operator") 15102 (const_string "fdiv") 15103 ] 15104 (const_string "fop"))) 15105 (set_attr "fp_int_src" "true") 15106 (set_attr "mode" "<MODE>")]) 15107 15108(define_insn "*fop_xf_4_i387" 15109 [(set (match_operand:XF 0 "register_operand" "=f,f") 15110 (match_operator:XF 3 "binary_fp_operator" 15111 [(float_extend:XF 15112 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) 15113 (match_operand:XF 2 "register_operand" "0,f")]))] 15114 "TARGET_80387" 15115 "* return output_387_binary_op (insn, operands);" 15116 [(set (attr "type") 15117 (cond [(match_operand:XF 3 "mult_operator") 15118 (const_string "fmul") 15119 (match_operand:XF 3 "div_operator") 15120 (const_string "fdiv") 15121 ] 15122 (const_string "fop"))) 15123 (set_attr "mode" "<MODE>")]) 15124 15125(define_insn "*fop_xf_5_i387" 15126 [(set (match_operand:XF 0 "register_operand" "=f,f") 15127 (match_operator:XF 3 "binary_fp_operator" 15128 [(match_operand:XF 1 "register_operand" "0,f") 15129 (float_extend:XF 15130 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 15131 "TARGET_80387" 15132 "* return output_387_binary_op (insn, operands);" 15133 [(set (attr "type") 15134 (cond [(match_operand:XF 3 "mult_operator") 15135 (const_string "fmul") 15136 (match_operand:XF 3 "div_operator") 15137 (const_string "fdiv") 15138 ] 15139 (const_string "fop"))) 15140 (set_attr "mode" "<MODE>")]) 15141 15142(define_insn "*fop_xf_6_i387" 15143 [(set (match_operand:XF 0 "register_operand" "=f,f") 15144 (match_operator:XF 3 "binary_fp_operator" 15145 [(float_extend:XF 15146 (match_operand:MODEF 1 "register_operand" "0,f")) 15147 (float_extend:XF 15148 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 15149 "TARGET_80387" 15150 "* return output_387_binary_op (insn, operands);" 15151 [(set (attr "type") 15152 (cond [(match_operand:XF 3 "mult_operator") 15153 (const_string "fmul") 15154 (match_operand:XF 3 "div_operator") 15155 (const_string "fdiv") 15156 ] 15157 (const_string "fop"))) 15158 (set_attr "mode" "<MODE>")]) 15159 15160;; FPU special functions. 15161 15162;; This pattern implements a no-op XFmode truncation for 15163;; all fancy i386 XFmode math functions. 15164 15165(define_insn "truncxf<mode>2_i387_noop_unspec" 15166 [(set (match_operand:MODEF 0 "register_operand" "=f") 15167 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] 15168 UNSPEC_TRUNC_NOOP))] 15169 "TARGET_USE_FANCY_MATH_387" 15170 "* return output_387_reg_move (insn, operands);" 15171 [(set_attr "type" "fmov") 15172 (set_attr "mode" "<MODE>")]) 15173 15174(define_insn "sqrtxf2" 15175 [(set (match_operand:XF 0 "register_operand" "=f") 15176 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15177 "TARGET_USE_FANCY_MATH_387" 15178 "fsqrt" 15179 [(set_attr "type" "fpspc") 15180 (set_attr "mode" "XF") 15181 (set_attr "athlon_decode" "direct") 15182 (set_attr "amdfam10_decode" "direct") 15183 (set_attr "bdver1_decode" "direct")]) 15184 15185(define_insn "sqrt_extend<mode>xf2_i387" 15186 [(set (match_operand:XF 0 "register_operand" "=f") 15187 (sqrt:XF 15188 (float_extend:XF 15189 (match_operand:MODEF 1 "register_operand" "0"))))] 15190 "TARGET_USE_FANCY_MATH_387" 15191 "fsqrt" 15192 [(set_attr "type" "fpspc") 15193 (set_attr "mode" "XF") 15194 (set_attr "athlon_decode" "direct") 15195 (set_attr "amdfam10_decode" "direct") 15196 (set_attr "bdver1_decode" "direct")]) 15197 15198(define_insn "*rsqrtsf2_sse" 15199 [(set (match_operand:SF 0 "register_operand" "=x") 15200 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 15201 UNSPEC_RSQRT))] 15202 "TARGET_SSE && TARGET_SSE_MATH" 15203 "%vrsqrtss\t{%1, %d0|%d0, %1}" 15204 [(set_attr "type" "sse") 15205 (set_attr "atom_sse_attr" "rcp") 15206 (set_attr "btver2_sse_attr" "rcp") 15207 (set_attr "prefix" "maybe_vex") 15208 (set_attr "mode" "SF")]) 15209 15210(define_expand "rsqrtsf2" 15211 [(set (match_operand:SF 0 "register_operand") 15212 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")] 15213 UNSPEC_RSQRT))] 15214 "TARGET_SSE && TARGET_SSE_MATH" 15215{ 15216 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); 15217 DONE; 15218}) 15219 15220(define_insn "*sqrt<mode>2_sse" 15221 [(set (match_operand:MODEF 0 "register_operand" "=v") 15222 (sqrt:MODEF 15223 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))] 15224 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 15225 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}" 15226 [(set_attr "type" "sse") 15227 (set_attr "atom_sse_attr" "sqrt") 15228 (set_attr "btver2_sse_attr" "sqrt") 15229 (set_attr "prefix" "maybe_vex") 15230 (set_attr "mode" "<MODE>") 15231 (set_attr "athlon_decode" "*") 15232 (set_attr "amdfam10_decode" "*") 15233 (set_attr "bdver1_decode" "*")]) 15234 15235(define_expand "sqrt<mode>2" 15236 [(set (match_operand:MODEF 0 "register_operand") 15237 (sqrt:MODEF 15238 (match_operand:MODEF 1 "nonimmediate_operand")))] 15239 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) 15240 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 15241{ 15242 if (<MODE>mode == SFmode 15243 && TARGET_SSE && TARGET_SSE_MATH 15244 && TARGET_RECIP_SQRT 15245 && !optimize_function_for_size_p (cfun) 15246 && flag_finite_math_only && !flag_trapping_math 15247 && flag_unsafe_math_optimizations) 15248 { 15249 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); 15250 DONE; 15251 } 15252 15253 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 15254 { 15255 rtx op0 = gen_reg_rtx (XFmode); 15256 rtx op1 = force_reg (<MODE>mode, operands[1]); 15257 15258 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1)); 15259 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 15260 DONE; 15261 } 15262}) 15263 15264(define_insn "fpremxf4_i387" 15265 [(set (match_operand:XF 0 "register_operand" "=f") 15266 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15267 (match_operand:XF 3 "register_operand" "1")] 15268 UNSPEC_FPREM_F)) 15269 (set (match_operand:XF 1 "register_operand" "=u") 15270 (unspec:XF [(match_dup 2) (match_dup 3)] 15271 UNSPEC_FPREM_U)) 15272 (set (reg:CCFP FPSR_REG) 15273 (unspec:CCFP [(match_dup 2) (match_dup 3)] 15274 UNSPEC_C2_FLAG))] 15275 "TARGET_USE_FANCY_MATH_387 15276 && flag_finite_math_only" 15277 "fprem" 15278 [(set_attr "type" "fpspc") 15279 (set_attr "znver1_decode" "vector") 15280 (set_attr "mode" "XF")]) 15281 15282(define_expand "fmodxf3" 15283 [(use (match_operand:XF 0 "register_operand")) 15284 (use (match_operand:XF 1 "general_operand")) 15285 (use (match_operand:XF 2 "general_operand"))] 15286 "TARGET_USE_FANCY_MATH_387 15287 && flag_finite_math_only" 15288{ 15289 rtx_code_label *label = gen_label_rtx (); 15290 15291 rtx op1 = gen_reg_rtx (XFmode); 15292 rtx op2 = gen_reg_rtx (XFmode); 15293 15294 emit_move_insn (op2, operands[2]); 15295 emit_move_insn (op1, operands[1]); 15296 15297 emit_label (label); 15298 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 15299 ix86_emit_fp_unordered_jump (label); 15300 LABEL_NUSES (label) = 1; 15301 15302 emit_move_insn (operands[0], op1); 15303 DONE; 15304}) 15305 15306(define_expand "fmod<mode>3" 15307 [(use (match_operand:MODEF 0 "register_operand")) 15308 (use (match_operand:MODEF 1 "general_operand")) 15309 (use (match_operand:MODEF 2 "general_operand"))] 15310 "TARGET_USE_FANCY_MATH_387 15311 && flag_finite_math_only" 15312{ 15313 rtx (*gen_truncxf) (rtx, rtx); 15314 15315 rtx_code_label *label = gen_label_rtx (); 15316 15317 rtx op1 = gen_reg_rtx (XFmode); 15318 rtx op2 = gen_reg_rtx (XFmode); 15319 15320 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15321 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15322 15323 emit_label (label); 15324 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 15325 ix86_emit_fp_unordered_jump (label); 15326 LABEL_NUSES (label) = 1; 15327 15328 /* Truncate the result properly for strict SSE math. */ 15329 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15330 && !TARGET_MIX_SSE_I387) 15331 gen_truncxf = gen_truncxf<mode>2; 15332 else 15333 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 15334 15335 emit_insn (gen_truncxf (operands[0], op1)); 15336 DONE; 15337}) 15338 15339(define_insn "fprem1xf4_i387" 15340 [(set (match_operand:XF 0 "register_operand" "=f") 15341 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15342 (match_operand:XF 3 "register_operand" "1")] 15343 UNSPEC_FPREM1_F)) 15344 (set (match_operand:XF 1 "register_operand" "=u") 15345 (unspec:XF [(match_dup 2) (match_dup 3)] 15346 UNSPEC_FPREM1_U)) 15347 (set (reg:CCFP FPSR_REG) 15348 (unspec:CCFP [(match_dup 2) (match_dup 3)] 15349 UNSPEC_C2_FLAG))] 15350 "TARGET_USE_FANCY_MATH_387 15351 && flag_finite_math_only" 15352 "fprem1" 15353 [(set_attr "type" "fpspc") 15354 (set_attr "znver1_decode" "vector") 15355 (set_attr "mode" "XF")]) 15356 15357(define_expand "remainderxf3" 15358 [(use (match_operand:XF 0 "register_operand")) 15359 (use (match_operand:XF 1 "general_operand")) 15360 (use (match_operand:XF 2 "general_operand"))] 15361 "TARGET_USE_FANCY_MATH_387 15362 && flag_finite_math_only" 15363{ 15364 rtx_code_label *label = gen_label_rtx (); 15365 15366 rtx op1 = gen_reg_rtx (XFmode); 15367 rtx op2 = gen_reg_rtx (XFmode); 15368 15369 emit_move_insn (op2, operands[2]); 15370 emit_move_insn (op1, operands[1]); 15371 15372 emit_label (label); 15373 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 15374 ix86_emit_fp_unordered_jump (label); 15375 LABEL_NUSES (label) = 1; 15376 15377 emit_move_insn (operands[0], op1); 15378 DONE; 15379}) 15380 15381(define_expand "remainder<mode>3" 15382 [(use (match_operand:MODEF 0 "register_operand")) 15383 (use (match_operand:MODEF 1 "general_operand")) 15384 (use (match_operand:MODEF 2 "general_operand"))] 15385 "TARGET_USE_FANCY_MATH_387 15386 && flag_finite_math_only" 15387{ 15388 rtx (*gen_truncxf) (rtx, rtx); 15389 15390 rtx_code_label *label = gen_label_rtx (); 15391 15392 rtx op1 = gen_reg_rtx (XFmode); 15393 rtx op2 = gen_reg_rtx (XFmode); 15394 15395 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15396 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15397 15398 emit_label (label); 15399 15400 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 15401 ix86_emit_fp_unordered_jump (label); 15402 LABEL_NUSES (label) = 1; 15403 15404 /* Truncate the result properly for strict SSE math. */ 15405 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15406 && !TARGET_MIX_SSE_I387) 15407 gen_truncxf = gen_truncxf<mode>2; 15408 else 15409 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 15410 15411 emit_insn (gen_truncxf (operands[0], op1)); 15412 DONE; 15413}) 15414 15415(define_int_iterator SINCOS 15416 [UNSPEC_SIN 15417 UNSPEC_COS]) 15418 15419(define_int_attr sincos 15420 [(UNSPEC_SIN "sin") 15421 (UNSPEC_COS "cos")]) 15422 15423(define_insn "*<sincos>xf2_i387" 15424 [(set (match_operand:XF 0 "register_operand" "=f") 15425 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15426 SINCOS))] 15427 "TARGET_USE_FANCY_MATH_387 15428 && flag_unsafe_math_optimizations" 15429 "f<sincos>" 15430 [(set_attr "type" "fpspc") 15431 (set_attr "znver1_decode" "vector") 15432 (set_attr "mode" "XF")]) 15433 15434(define_insn "*<sincos>_extend<mode>xf2_i387" 15435 [(set (match_operand:XF 0 "register_operand" "=f") 15436 (unspec:XF [(float_extend:XF 15437 (match_operand:MODEF 1 "register_operand" "0"))] 15438 SINCOS))] 15439 "TARGET_USE_FANCY_MATH_387 15440 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15441 || TARGET_MIX_SSE_I387) 15442 && flag_unsafe_math_optimizations" 15443 "f<sincos>" 15444 [(set_attr "type" "fpspc") 15445 (set_attr "znver1_decode" "vector") 15446 (set_attr "mode" "XF")]) 15447 15448;; When sincos pattern is defined, sin and cos builtin functions will be 15449;; expanded to sincos pattern with one of its outputs left unused. 15450;; CSE pass will figure out if two sincos patterns can be combined, 15451;; otherwise sincos pattern will be split back to sin or cos pattern, 15452;; depending on the unused output. 15453 15454(define_insn "sincosxf3" 15455 [(set (match_operand:XF 0 "register_operand" "=f") 15456 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15457 UNSPEC_SINCOS_COS)) 15458 (set (match_operand:XF 1 "register_operand" "=u") 15459 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15460 "TARGET_USE_FANCY_MATH_387 15461 && flag_unsafe_math_optimizations" 15462 "fsincos" 15463 [(set_attr "type" "fpspc") 15464 (set_attr "znver1_decode" "vector") 15465 (set_attr "mode" "XF")]) 15466 15467(define_split 15468 [(set (match_operand:XF 0 "register_operand") 15469 (unspec:XF [(match_operand:XF 2 "register_operand")] 15470 UNSPEC_SINCOS_COS)) 15471 (set (match_operand:XF 1 "register_operand") 15472 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15473 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15474 && can_create_pseudo_p ()" 15475 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]) 15476 15477(define_split 15478 [(set (match_operand:XF 0 "register_operand") 15479 (unspec:XF [(match_operand:XF 2 "register_operand")] 15480 UNSPEC_SINCOS_COS)) 15481 (set (match_operand:XF 1 "register_operand") 15482 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15483 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15484 && can_create_pseudo_p ()" 15485 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]) 15486 15487(define_insn "sincos_extend<mode>xf3_i387" 15488 [(set (match_operand:XF 0 "register_operand" "=f") 15489 (unspec:XF [(float_extend:XF 15490 (match_operand:MODEF 2 "register_operand" "0"))] 15491 UNSPEC_SINCOS_COS)) 15492 (set (match_operand:XF 1 "register_operand" "=u") 15493 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15494 "TARGET_USE_FANCY_MATH_387 15495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15496 || TARGET_MIX_SSE_I387) 15497 && flag_unsafe_math_optimizations" 15498 "fsincos" 15499 [(set_attr "type" "fpspc") 15500 (set_attr "znver1_decode" "vector") 15501 (set_attr "mode" "XF")]) 15502 15503(define_split 15504 [(set (match_operand:XF 0 "register_operand") 15505 (unspec:XF [(float_extend:XF 15506 (match_operand:MODEF 2 "register_operand"))] 15507 UNSPEC_SINCOS_COS)) 15508 (set (match_operand:XF 1 "register_operand") 15509 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15510 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 15511 && can_create_pseudo_p ()" 15512 [(set (match_dup 1) 15513 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]) 15514 15515(define_split 15516 [(set (match_operand:XF 0 "register_operand") 15517 (unspec:XF [(float_extend:XF 15518 (match_operand:MODEF 2 "register_operand"))] 15519 UNSPEC_SINCOS_COS)) 15520 (set (match_operand:XF 1 "register_operand") 15521 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 15522 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 15523 && can_create_pseudo_p ()" 15524 [(set (match_dup 0) 15525 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]) 15526 15527(define_expand "sincos<mode>3" 15528 [(use (match_operand:MODEF 0 "register_operand")) 15529 (use (match_operand:MODEF 1 "register_operand")) 15530 (use (match_operand:MODEF 2 "register_operand"))] 15531 "TARGET_USE_FANCY_MATH_387 15532 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15533 || TARGET_MIX_SSE_I387) 15534 && flag_unsafe_math_optimizations" 15535{ 15536 rtx op0 = gen_reg_rtx (XFmode); 15537 rtx op1 = gen_reg_rtx (XFmode); 15538 15539 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2])); 15540 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1)); 15542 DONE; 15543}) 15544 15545(define_insn "fptanxf4_i387" 15546 [(set (match_operand:XF 0 "register_operand" "=f") 15547 (match_operand:XF 3 "const_double_operand" "F")) 15548 (set (match_operand:XF 1 "register_operand" "=u") 15549 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15550 UNSPEC_TAN))] 15551 "TARGET_USE_FANCY_MATH_387 15552 && flag_unsafe_math_optimizations 15553 && standard_80387_constant_p (operands[3]) == 2" 15554 "fptan" 15555 [(set_attr "type" "fpspc") 15556 (set_attr "znver1_decode" "vector") 15557 (set_attr "mode" "XF")]) 15558 15559(define_insn "fptan_extend<mode>xf4_i387" 15560 [(set (match_operand:MODEF 0 "register_operand" "=f") 15561 (match_operand:MODEF 3 "const_double_operand" "F")) 15562 (set (match_operand:XF 1 "register_operand" "=u") 15563 (unspec:XF [(float_extend:XF 15564 (match_operand:MODEF 2 "register_operand" "0"))] 15565 UNSPEC_TAN))] 15566 "TARGET_USE_FANCY_MATH_387 15567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15568 || TARGET_MIX_SSE_I387) 15569 && flag_unsafe_math_optimizations 15570 && standard_80387_constant_p (operands[3]) == 2" 15571 "fptan" 15572 [(set_attr "type" "fpspc") 15573 (set_attr "znver1_decode" "vector") 15574 (set_attr "mode" "XF")]) 15575 15576(define_expand "tanxf2" 15577 [(use (match_operand:XF 0 "register_operand")) 15578 (use (match_operand:XF 1 "register_operand"))] 15579 "TARGET_USE_FANCY_MATH_387 15580 && flag_unsafe_math_optimizations" 15581{ 15582 rtx one = gen_reg_rtx (XFmode); 15583 rtx op2 = CONST1_RTX (XFmode); /* fld1 */ 15584 15585 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2)); 15586 DONE; 15587}) 15588 15589(define_expand "tan<mode>2" 15590 [(use (match_operand:MODEF 0 "register_operand")) 15591 (use (match_operand:MODEF 1 "register_operand"))] 15592 "TARGET_USE_FANCY_MATH_387 15593 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15594 || TARGET_MIX_SSE_I387) 15595 && flag_unsafe_math_optimizations" 15596{ 15597 rtx op0 = gen_reg_rtx (XFmode); 15598 15599 rtx one = gen_reg_rtx (<MODE>mode); 15600 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */ 15601 15602 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0, 15603 operands[1], op2)); 15604 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15605 DONE; 15606}) 15607 15608(define_insn "*fpatanxf3_i387" 15609 [(set (match_operand:XF 0 "register_operand" "=f") 15610 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15611 (match_operand:XF 2 "register_operand" "u")] 15612 UNSPEC_FPATAN)) 15613 (clobber (match_scratch:XF 3 "=2"))] 15614 "TARGET_USE_FANCY_MATH_387 15615 && flag_unsafe_math_optimizations" 15616 "fpatan" 15617 [(set_attr "type" "fpspc") 15618 (set_attr "znver1_decode" "vector") 15619 (set_attr "mode" "XF")]) 15620 15621(define_insn "fpatan_extend<mode>xf3_i387" 15622 [(set (match_operand:XF 0 "register_operand" "=f") 15623 (unspec:XF [(float_extend:XF 15624 (match_operand:MODEF 1 "register_operand" "0")) 15625 (float_extend:XF 15626 (match_operand:MODEF 2 "register_operand" "u"))] 15627 UNSPEC_FPATAN)) 15628 (clobber (match_scratch:XF 3 "=2"))] 15629 "TARGET_USE_FANCY_MATH_387 15630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15631 || TARGET_MIX_SSE_I387) 15632 && flag_unsafe_math_optimizations" 15633 "fpatan" 15634 [(set_attr "type" "fpspc") 15635 (set_attr "znver1_decode" "vector") 15636 (set_attr "mode" "XF")]) 15637 15638(define_expand "atan2xf3" 15639 [(parallel [(set (match_operand:XF 0 "register_operand") 15640 (unspec:XF [(match_operand:XF 2 "register_operand") 15641 (match_operand:XF 1 "register_operand")] 15642 UNSPEC_FPATAN)) 15643 (clobber (match_scratch:XF 3))])] 15644 "TARGET_USE_FANCY_MATH_387 15645 && flag_unsafe_math_optimizations") 15646 15647(define_expand "atan2<mode>3" 15648 [(use (match_operand:MODEF 0 "register_operand")) 15649 (use (match_operand:MODEF 1 "register_operand")) 15650 (use (match_operand:MODEF 2 "register_operand"))] 15651 "TARGET_USE_FANCY_MATH_387 15652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15653 || TARGET_MIX_SSE_I387) 15654 && flag_unsafe_math_optimizations" 15655{ 15656 rtx op0 = gen_reg_rtx (XFmode); 15657 15658 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1])); 15659 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15660 DONE; 15661}) 15662 15663(define_expand "atanxf2" 15664 [(parallel [(set (match_operand:XF 0 "register_operand") 15665 (unspec:XF [(match_dup 2) 15666 (match_operand:XF 1 "register_operand")] 15667 UNSPEC_FPATAN)) 15668 (clobber (match_scratch:XF 3))])] 15669 "TARGET_USE_FANCY_MATH_387 15670 && flag_unsafe_math_optimizations" 15671{ 15672 operands[2] = gen_reg_rtx (XFmode); 15673 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 15674}) 15675 15676(define_expand "atan<mode>2" 15677 [(use (match_operand:MODEF 0 "register_operand")) 15678 (use (match_operand:MODEF 1 "register_operand"))] 15679 "TARGET_USE_FANCY_MATH_387 15680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15681 || TARGET_MIX_SSE_I387) 15682 && flag_unsafe_math_optimizations" 15683{ 15684 rtx op0 = gen_reg_rtx (XFmode); 15685 15686 rtx op2 = gen_reg_rtx (<MODE>mode); 15687 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */ 15688 15689 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1])); 15690 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15691 DONE; 15692}) 15693 15694(define_expand "asinxf2" 15695 [(set (match_dup 2) 15696 (mult:XF (match_operand:XF 1 "register_operand") 15697 (match_dup 1))) 15698 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 15699 (set (match_dup 5) (sqrt:XF (match_dup 4))) 15700 (parallel [(set (match_operand:XF 0 "register_operand") 15701 (unspec:XF [(match_dup 5) (match_dup 1)] 15702 UNSPEC_FPATAN)) 15703 (clobber (match_scratch:XF 6))])] 15704 "TARGET_USE_FANCY_MATH_387 15705 && flag_unsafe_math_optimizations" 15706{ 15707 int i; 15708 15709 for (i = 2; i < 6; i++) 15710 operands[i] = gen_reg_rtx (XFmode); 15711 15712 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 15713}) 15714 15715(define_expand "asin<mode>2" 15716 [(use (match_operand:MODEF 0 "register_operand")) 15717 (use (match_operand:MODEF 1 "general_operand"))] 15718 "TARGET_USE_FANCY_MATH_387 15719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15720 || TARGET_MIX_SSE_I387) 15721 && flag_unsafe_math_optimizations" 15722{ 15723 rtx op0 = gen_reg_rtx (XFmode); 15724 rtx op1 = gen_reg_rtx (XFmode); 15725 15726 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15727 emit_insn (gen_asinxf2 (op0, op1)); 15728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15729 DONE; 15730}) 15731 15732(define_expand "acosxf2" 15733 [(set (match_dup 2) 15734 (mult:XF (match_operand:XF 1 "register_operand") 15735 (match_dup 1))) 15736 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 15737 (set (match_dup 5) (sqrt:XF (match_dup 4))) 15738 (parallel [(set (match_operand:XF 0 "register_operand") 15739 (unspec:XF [(match_dup 1) (match_dup 5)] 15740 UNSPEC_FPATAN)) 15741 (clobber (match_scratch:XF 6))])] 15742 "TARGET_USE_FANCY_MATH_387 15743 && flag_unsafe_math_optimizations" 15744{ 15745 int i; 15746 15747 for (i = 2; i < 6; i++) 15748 operands[i] = gen_reg_rtx (XFmode); 15749 15750 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 15751}) 15752 15753(define_expand "acos<mode>2" 15754 [(use (match_operand:MODEF 0 "register_operand")) 15755 (use (match_operand:MODEF 1 "general_operand"))] 15756 "TARGET_USE_FANCY_MATH_387 15757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15758 || TARGET_MIX_SSE_I387) 15759 && flag_unsafe_math_optimizations" 15760{ 15761 rtx op0 = gen_reg_rtx (XFmode); 15762 rtx op1 = gen_reg_rtx (XFmode); 15763 15764 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15765 emit_insn (gen_acosxf2 (op0, op1)); 15766 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15767 DONE; 15768}) 15769 15770(define_insn "fyl2xxf3_i387" 15771 [(set (match_operand:XF 0 "register_operand" "=f") 15772 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15773 (match_operand:XF 2 "register_operand" "u")] 15774 UNSPEC_FYL2X)) 15775 (clobber (match_scratch:XF 3 "=2"))] 15776 "TARGET_USE_FANCY_MATH_387 15777 && flag_unsafe_math_optimizations" 15778 "fyl2x" 15779 [(set_attr "type" "fpspc") 15780 (set_attr "znver1_decode" "vector") 15781 (set_attr "mode" "XF")]) 15782 15783(define_insn "fyl2x_extend<mode>xf3_i387" 15784 [(set (match_operand:XF 0 "register_operand" "=f") 15785 (unspec:XF [(float_extend:XF 15786 (match_operand:MODEF 1 "register_operand" "0")) 15787 (match_operand:XF 2 "register_operand" "u")] 15788 UNSPEC_FYL2X)) 15789 (clobber (match_scratch:XF 3 "=2"))] 15790 "TARGET_USE_FANCY_MATH_387 15791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15792 || TARGET_MIX_SSE_I387) 15793 && flag_unsafe_math_optimizations" 15794 "fyl2x" 15795 [(set_attr "type" "fpspc") 15796 (set_attr "znver1_decode" "vector") 15797 (set_attr "mode" "XF")]) 15798 15799(define_expand "logxf2" 15800 [(parallel [(set (match_operand:XF 0 "register_operand") 15801 (unspec:XF [(match_operand:XF 1 "register_operand") 15802 (match_dup 2)] UNSPEC_FYL2X)) 15803 (clobber (match_scratch:XF 3))])] 15804 "TARGET_USE_FANCY_MATH_387 15805 && flag_unsafe_math_optimizations" 15806{ 15807 operands[2] = gen_reg_rtx (XFmode); 15808 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */ 15809}) 15810 15811(define_expand "log<mode>2" 15812 [(use (match_operand:MODEF 0 "register_operand")) 15813 (use (match_operand:MODEF 1 "register_operand"))] 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{ 15819 rtx op0 = gen_reg_rtx (XFmode); 15820 15821 rtx op2 = gen_reg_rtx (XFmode); 15822 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */ 15823 15824 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15825 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15826 DONE; 15827}) 15828 15829(define_expand "log10xf2" 15830 [(parallel [(set (match_operand:XF 0 "register_operand") 15831 (unspec:XF [(match_operand:XF 1 "register_operand") 15832 (match_dup 2)] UNSPEC_FYL2X)) 15833 (clobber (match_scratch:XF 3))])] 15834 "TARGET_USE_FANCY_MATH_387 15835 && flag_unsafe_math_optimizations" 15836{ 15837 operands[2] = gen_reg_rtx (XFmode); 15838 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */ 15839}) 15840 15841(define_expand "log10<mode>2" 15842 [(use (match_operand:MODEF 0 "register_operand")) 15843 (use (match_operand:MODEF 1 "register_operand"))] 15844 "TARGET_USE_FANCY_MATH_387 15845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15846 || TARGET_MIX_SSE_I387) 15847 && flag_unsafe_math_optimizations" 15848{ 15849 rtx op0 = gen_reg_rtx (XFmode); 15850 15851 rtx op2 = gen_reg_rtx (XFmode); 15852 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */ 15853 15854 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15855 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15856 DONE; 15857}) 15858 15859(define_expand "log2xf2" 15860 [(parallel [(set (match_operand:XF 0 "register_operand") 15861 (unspec:XF [(match_operand:XF 1 "register_operand") 15862 (match_dup 2)] UNSPEC_FYL2X)) 15863 (clobber (match_scratch:XF 3))])] 15864 "TARGET_USE_FANCY_MATH_387 15865 && flag_unsafe_math_optimizations" 15866{ 15867 operands[2] = gen_reg_rtx (XFmode); 15868 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 15869}) 15870 15871(define_expand "log2<mode>2" 15872 [(use (match_operand:MODEF 0 "register_operand")) 15873 (use (match_operand:MODEF 1 "register_operand"))] 15874 "TARGET_USE_FANCY_MATH_387 15875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15876 || TARGET_MIX_SSE_I387) 15877 && flag_unsafe_math_optimizations" 15878{ 15879 rtx op0 = gen_reg_rtx (XFmode); 15880 15881 rtx op2 = gen_reg_rtx (XFmode); 15882 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 15883 15884 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 15885 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15886 DONE; 15887}) 15888 15889(define_insn "fyl2xp1xf3_i387" 15890 [(set (match_operand:XF 0 "register_operand" "=f") 15891 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 15892 (match_operand:XF 2 "register_operand" "u")] 15893 UNSPEC_FYL2XP1)) 15894 (clobber (match_scratch:XF 3 "=2"))] 15895 "TARGET_USE_FANCY_MATH_387 15896 && flag_unsafe_math_optimizations" 15897 "fyl2xp1" 15898 [(set_attr "type" "fpspc") 15899 (set_attr "znver1_decode" "vector") 15900 (set_attr "mode" "XF")]) 15901 15902(define_insn "fyl2xp1_extend<mode>xf3_i387" 15903 [(set (match_operand:XF 0 "register_operand" "=f") 15904 (unspec:XF [(float_extend:XF 15905 (match_operand:MODEF 1 "register_operand" "0")) 15906 (match_operand:XF 2 "register_operand" "u")] 15907 UNSPEC_FYL2XP1)) 15908 (clobber (match_scratch:XF 3 "=2"))] 15909 "TARGET_USE_FANCY_MATH_387 15910 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15911 || TARGET_MIX_SSE_I387) 15912 && flag_unsafe_math_optimizations" 15913 "fyl2xp1" 15914 [(set_attr "type" "fpspc") 15915 (set_attr "znver1_decode" "vector") 15916 (set_attr "mode" "XF")]) 15917 15918(define_expand "log1pxf2" 15919 [(use (match_operand:XF 0 "register_operand")) 15920 (use (match_operand:XF 1 "register_operand"))] 15921 "TARGET_USE_FANCY_MATH_387 15922 && flag_unsafe_math_optimizations" 15923{ 15924 ix86_emit_i387_log1p (operands[0], operands[1]); 15925 DONE; 15926}) 15927 15928(define_expand "log1p<mode>2" 15929 [(use (match_operand:MODEF 0 "register_operand")) 15930 (use (match_operand:MODEF 1 "register_operand"))] 15931 "TARGET_USE_FANCY_MATH_387 15932 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15933 || TARGET_MIX_SSE_I387) 15934 && flag_unsafe_math_optimizations" 15935{ 15936 rtx op0; 15937 15938 op0 = gen_reg_rtx (XFmode); 15939 15940 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]); 15941 15942 ix86_emit_i387_log1p (op0, operands[1]); 15943 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15944 DONE; 15945}) 15946 15947(define_insn "fxtractxf3_i387" 15948 [(set (match_operand:XF 0 "register_operand" "=f") 15949 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15950 UNSPEC_XTRACT_FRACT)) 15951 (set (match_operand:XF 1 "register_operand" "=u") 15952 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 15953 "TARGET_USE_FANCY_MATH_387 15954 && flag_unsafe_math_optimizations" 15955 "fxtract" 15956 [(set_attr "type" "fpspc") 15957 (set_attr "znver1_decode" "vector") 15958 (set_attr "mode" "XF")]) 15959 15960(define_insn "fxtract_extend<mode>xf3_i387" 15961 [(set (match_operand:XF 0 "register_operand" "=f") 15962 (unspec:XF [(float_extend:XF 15963 (match_operand:MODEF 2 "register_operand" "0"))] 15964 UNSPEC_XTRACT_FRACT)) 15965 (set (match_operand:XF 1 "register_operand" "=u") 15966 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))] 15967 "TARGET_USE_FANCY_MATH_387 15968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15969 || TARGET_MIX_SSE_I387) 15970 && flag_unsafe_math_optimizations" 15971 "fxtract" 15972 [(set_attr "type" "fpspc") 15973 (set_attr "znver1_decode" "vector") 15974 (set_attr "mode" "XF")]) 15975 15976(define_expand "logbxf2" 15977 [(parallel [(set (match_dup 2) 15978 (unspec:XF [(match_operand:XF 1 "register_operand")] 15979 UNSPEC_XTRACT_FRACT)) 15980 (set (match_operand:XF 0 "register_operand") 15981 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 15982 "TARGET_USE_FANCY_MATH_387 15983 && flag_unsafe_math_optimizations" 15984 "operands[2] = gen_reg_rtx (XFmode);") 15985 15986(define_expand "logb<mode>2" 15987 [(use (match_operand:MODEF 0 "register_operand")) 15988 (use (match_operand:MODEF 1 "register_operand"))] 15989 "TARGET_USE_FANCY_MATH_387 15990 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15991 || TARGET_MIX_SSE_I387) 15992 && flag_unsafe_math_optimizations" 15993{ 15994 rtx op0 = gen_reg_rtx (XFmode); 15995 rtx op1 = gen_reg_rtx (XFmode); 15996 15997 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 15998 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1)); 15999 DONE; 16000}) 16001 16002(define_expand "ilogbxf2" 16003 [(use (match_operand:SI 0 "register_operand")) 16004 (use (match_operand:XF 1 "register_operand"))] 16005 "TARGET_USE_FANCY_MATH_387 16006 && flag_unsafe_math_optimizations" 16007{ 16008 rtx op0, op1; 16009 16010 if (optimize_insn_for_size_p ()) 16011 FAIL; 16012 16013 op0 = gen_reg_rtx (XFmode); 16014 op1 = gen_reg_rtx (XFmode); 16015 16016 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); 16017 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 16018 DONE; 16019}) 16020 16021(define_expand "ilogb<mode>2" 16022 [(use (match_operand:SI 0 "register_operand")) 16023 (use (match_operand:MODEF 1 "register_operand"))] 16024 "TARGET_USE_FANCY_MATH_387 16025 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16026 || TARGET_MIX_SSE_I387) 16027 && flag_unsafe_math_optimizations" 16028{ 16029 rtx op0, op1; 16030 16031 if (optimize_insn_for_size_p ()) 16032 FAIL; 16033 16034 op0 = gen_reg_rtx (XFmode); 16035 op1 = gen_reg_rtx (XFmode); 16036 16037 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 16038 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 16039 DONE; 16040}) 16041 16042(define_insn "*f2xm1xf2_i387" 16043 [(set (match_operand:XF 0 "register_operand" "=f") 16044 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16045 UNSPEC_F2XM1))] 16046 "TARGET_USE_FANCY_MATH_387 16047 && flag_unsafe_math_optimizations" 16048 "f2xm1" 16049 [(set_attr "type" "fpspc") 16050 (set_attr "znver1_decode" "vector") 16051 (set_attr "mode" "XF")]) 16052 16053(define_insn "fscalexf4_i387" 16054 [(set (match_operand:XF 0 "register_operand" "=f") 16055 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16056 (match_operand:XF 3 "register_operand" "1")] 16057 UNSPEC_FSCALE_FRACT)) 16058 (set (match_operand:XF 1 "register_operand" "=u") 16059 (unspec:XF [(match_dup 2) (match_dup 3)] 16060 UNSPEC_FSCALE_EXP))] 16061 "TARGET_USE_FANCY_MATH_387 16062 && flag_unsafe_math_optimizations" 16063 "fscale" 16064 [(set_attr "type" "fpspc") 16065 (set_attr "znver1_decode" "vector") 16066 (set_attr "mode" "XF")]) 16067 16068(define_expand "expNcorexf3" 16069 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 16070 (match_operand:XF 2 "register_operand"))) 16071 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16072 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16073 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16074 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16075 (parallel [(set (match_operand:XF 0 "register_operand") 16076 (unspec:XF [(match_dup 8) (match_dup 4)] 16077 UNSPEC_FSCALE_FRACT)) 16078 (set (match_dup 9) 16079 (unspec:XF [(match_dup 8) (match_dup 4)] 16080 UNSPEC_FSCALE_EXP))])] 16081 "TARGET_USE_FANCY_MATH_387 16082 && flag_unsafe_math_optimizations" 16083{ 16084 int i; 16085 16086 for (i = 3; i < 10; i++) 16087 operands[i] = gen_reg_rtx (XFmode); 16088 16089 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 16090}) 16091 16092(define_expand "expxf2" 16093 [(use (match_operand:XF 0 "register_operand")) 16094 (use (match_operand:XF 1 "register_operand"))] 16095 "TARGET_USE_FANCY_MATH_387 16096 && flag_unsafe_math_optimizations" 16097{ 16098 rtx op2; 16099 16100 op2 = gen_reg_rtx (XFmode); 16101 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */ 16102 16103 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16104 DONE; 16105}) 16106 16107(define_expand "exp<mode>2" 16108 [(use (match_operand:MODEF 0 "register_operand")) 16109 (use (match_operand:MODEF 1 "general_operand"))] 16110 "TARGET_USE_FANCY_MATH_387 16111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16112 || TARGET_MIX_SSE_I387) 16113 && flag_unsafe_math_optimizations" 16114{ 16115 rtx op0, op1; 16116 16117 op0 = gen_reg_rtx (XFmode); 16118 op1 = gen_reg_rtx (XFmode); 16119 16120 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16121 emit_insn (gen_expxf2 (op0, op1)); 16122 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16123 DONE; 16124}) 16125 16126(define_expand "exp10xf2" 16127 [(use (match_operand:XF 0 "register_operand")) 16128 (use (match_operand:XF 1 "register_operand"))] 16129 "TARGET_USE_FANCY_MATH_387 16130 && flag_unsafe_math_optimizations" 16131{ 16132 rtx op2; 16133 16134 op2 = gen_reg_rtx (XFmode); 16135 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */ 16136 16137 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16138 DONE; 16139}) 16140 16141(define_expand "exp10<mode>2" 16142 [(use (match_operand:MODEF 0 "register_operand")) 16143 (use (match_operand:MODEF 1 "general_operand"))] 16144 "TARGET_USE_FANCY_MATH_387 16145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16146 || TARGET_MIX_SSE_I387) 16147 && flag_unsafe_math_optimizations" 16148{ 16149 rtx op0, op1; 16150 16151 op0 = gen_reg_rtx (XFmode); 16152 op1 = gen_reg_rtx (XFmode); 16153 16154 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16155 emit_insn (gen_exp10xf2 (op0, op1)); 16156 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16157 DONE; 16158}) 16159 16160(define_expand "exp2xf2" 16161 [(use (match_operand:XF 0 "register_operand")) 16162 (use (match_operand:XF 1 "register_operand"))] 16163 "TARGET_USE_FANCY_MATH_387 16164 && flag_unsafe_math_optimizations" 16165{ 16166 rtx op2; 16167 16168 op2 = gen_reg_rtx (XFmode); 16169 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 16170 16171 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16172 DONE; 16173}) 16174 16175(define_expand "exp2<mode>2" 16176 [(use (match_operand:MODEF 0 "register_operand")) 16177 (use (match_operand:MODEF 1 "general_operand"))] 16178 "TARGET_USE_FANCY_MATH_387 16179 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16180 || TARGET_MIX_SSE_I387) 16181 && flag_unsafe_math_optimizations" 16182{ 16183 rtx op0, op1; 16184 16185 op0 = gen_reg_rtx (XFmode); 16186 op1 = gen_reg_rtx (XFmode); 16187 16188 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16189 emit_insn (gen_exp2xf2 (op0, op1)); 16190 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16191 DONE; 16192}) 16193 16194(define_expand "expm1xf2" 16195 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 16196 (match_dup 2))) 16197 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16198 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16199 (set (match_dup 9) (float_extend:XF (match_dup 13))) 16200 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16201 (parallel [(set (match_dup 7) 16202 (unspec:XF [(match_dup 6) (match_dup 4)] 16203 UNSPEC_FSCALE_FRACT)) 16204 (set (match_dup 8) 16205 (unspec:XF [(match_dup 6) (match_dup 4)] 16206 UNSPEC_FSCALE_EXP))]) 16207 (parallel [(set (match_dup 10) 16208 (unspec:XF [(match_dup 9) (match_dup 8)] 16209 UNSPEC_FSCALE_FRACT)) 16210 (set (match_dup 11) 16211 (unspec:XF [(match_dup 9) (match_dup 8)] 16212 UNSPEC_FSCALE_EXP))]) 16213 (set (match_dup 12) (minus:XF (match_dup 10) 16214 (float_extend:XF (match_dup 13)))) 16215 (set (match_operand:XF 0 "register_operand") 16216 (plus:XF (match_dup 12) (match_dup 7)))] 16217 "TARGET_USE_FANCY_MATH_387 16218 && flag_unsafe_math_optimizations" 16219{ 16220 int i; 16221 16222 for (i = 2; i < 13; i++) 16223 operands[i] = gen_reg_rtx (XFmode); 16224 16225 operands[13] 16226 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */ 16227 16228 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ 16229}) 16230 16231(define_expand "expm1<mode>2" 16232 [(use (match_operand:MODEF 0 "register_operand")) 16233 (use (match_operand:MODEF 1 "general_operand"))] 16234 "TARGET_USE_FANCY_MATH_387 16235 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16236 || TARGET_MIX_SSE_I387) 16237 && flag_unsafe_math_optimizations" 16238{ 16239 rtx op0, op1; 16240 16241 op0 = gen_reg_rtx (XFmode); 16242 op1 = gen_reg_rtx (XFmode); 16243 16244 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16245 emit_insn (gen_expm1xf2 (op0, op1)); 16246 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16247 DONE; 16248}) 16249 16250(define_expand "ldexpxf3" 16251 [(match_operand:XF 0 "register_operand") 16252 (match_operand:XF 1 "register_operand") 16253 (match_operand:SI 2 "register_operand")] 16254 "TARGET_USE_FANCY_MATH_387 16255 && flag_unsafe_math_optimizations" 16256{ 16257 rtx tmp1, tmp2; 16258 16259 tmp1 = gen_reg_rtx (XFmode); 16260 tmp2 = gen_reg_rtx (XFmode); 16261 16262 emit_insn (gen_floatsixf2 (tmp1, operands[2])); 16263 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2, 16264 operands[1], tmp1)); 16265 DONE; 16266}) 16267 16268(define_expand "ldexp<mode>3" 16269 [(use (match_operand:MODEF 0 "register_operand")) 16270 (use (match_operand:MODEF 1 "general_operand")) 16271 (use (match_operand:SI 2 "register_operand"))] 16272 "TARGET_USE_FANCY_MATH_387 16273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16274 || TARGET_MIX_SSE_I387) 16275 && flag_unsafe_math_optimizations" 16276{ 16277 rtx op0, op1; 16278 16279 op0 = gen_reg_rtx (XFmode); 16280 op1 = gen_reg_rtx (XFmode); 16281 16282 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16283 emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); 16284 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16285 DONE; 16286}) 16287 16288(define_expand "scalbxf3" 16289 [(parallel [(set (match_operand:XF 0 " register_operand") 16290 (unspec:XF [(match_operand:XF 1 "register_operand") 16291 (match_operand:XF 2 "register_operand")] 16292 UNSPEC_FSCALE_FRACT)) 16293 (set (match_dup 3) 16294 (unspec:XF [(match_dup 1) (match_dup 2)] 16295 UNSPEC_FSCALE_EXP))])] 16296 "TARGET_USE_FANCY_MATH_387 16297 && flag_unsafe_math_optimizations" 16298{ 16299 operands[3] = gen_reg_rtx (XFmode); 16300}) 16301 16302(define_expand "scalb<mode>3" 16303 [(use (match_operand:MODEF 0 "register_operand")) 16304 (use (match_operand:MODEF 1 "general_operand")) 16305 (use (match_operand:MODEF 2 "general_operand"))] 16306 "TARGET_USE_FANCY_MATH_387 16307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16308 || TARGET_MIX_SSE_I387) 16309 && flag_unsafe_math_optimizations" 16310{ 16311 rtx op0, op1, op2; 16312 16313 op0 = gen_reg_rtx (XFmode); 16314 op1 = gen_reg_rtx (XFmode); 16315 op2 = gen_reg_rtx (XFmode); 16316 16317 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16318 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 16319 emit_insn (gen_scalbxf3 (op0, op1, op2)); 16320 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16321 DONE; 16322}) 16323 16324(define_expand "significandxf2" 16325 [(parallel [(set (match_operand:XF 0 "register_operand") 16326 (unspec:XF [(match_operand:XF 1 "register_operand")] 16327 UNSPEC_XTRACT_FRACT)) 16328 (set (match_dup 2) 16329 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16330 "TARGET_USE_FANCY_MATH_387 16331 && flag_unsafe_math_optimizations" 16332 "operands[2] = gen_reg_rtx (XFmode);") 16333 16334(define_expand "significand<mode>2" 16335 [(use (match_operand:MODEF 0 "register_operand")) 16336 (use (match_operand:MODEF 1 "register_operand"))] 16337 "TARGET_USE_FANCY_MATH_387 16338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16339 || TARGET_MIX_SSE_I387) 16340 && flag_unsafe_math_optimizations" 16341{ 16342 rtx op0 = gen_reg_rtx (XFmode); 16343 rtx op1 = gen_reg_rtx (XFmode); 16344 16345 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 16346 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16347 DONE; 16348}) 16349 16350 16351(define_insn "sse4_1_round<mode>2" 16352 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 16353 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v") 16354 (match_operand:SI 2 "const_0_to_15_operand" "n,n")] 16355 UNSPEC_ROUND))] 16356 "TARGET_SSE4_1" 16357 "@ 16358 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2} 16359 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}" 16360 [(set_attr "type" "ssecvt") 16361 (set_attr "prefix_extra" "1,*") 16362 (set_attr "length_immediate" "*,1") 16363 (set_attr "prefix" "maybe_vex,evex") 16364 (set_attr "isa" "noavx512f,avx512f") 16365 (set_attr "mode" "<MODE>")]) 16366 16367(define_insn "rintxf2" 16368 [(set (match_operand:XF 0 "register_operand" "=f") 16369 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16370 UNSPEC_FRNDINT))] 16371 "TARGET_USE_FANCY_MATH_387" 16372 "frndint" 16373 [(set_attr "type" "fpspc") 16374 (set_attr "znver1_decode" "vector") 16375 (set_attr "mode" "XF")]) 16376 16377(define_insn "rint<mode>2_frndint" 16378 [(set (match_operand:MODEF 0 "register_operand" "=f") 16379 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")] 16380 UNSPEC_FRNDINT))] 16381 "TARGET_USE_FANCY_MATH_387" 16382 "frndint" 16383 [(set_attr "type" "fpspc") 16384 (set_attr "znver1_decode" "vector") 16385 (set_attr "mode" "<MODE>")]) 16386 16387(define_expand "rint<mode>2" 16388 [(use (match_operand:MODEF 0 "register_operand")) 16389 (use (match_operand:MODEF 1 "register_operand"))] 16390 "(TARGET_USE_FANCY_MATH_387 16391 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16392 || TARGET_MIX_SSE_I387)) 16393 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 16394{ 16395 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16396 { 16397 if (TARGET_SSE4_1) 16398 emit_insn (gen_sse4_1_round<mode>2 16399 (operands[0], operands[1], GEN_INT (ROUND_MXCSR))); 16400 else 16401 ix86_expand_rint (operands[0], operands[1]); 16402 } 16403 else 16404 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1])); 16405 DONE; 16406}) 16407 16408(define_expand "round<mode>2" 16409 [(match_operand:X87MODEF 0 "register_operand") 16410 (match_operand:X87MODEF 1 "nonimmediate_operand")] 16411 "(TARGET_USE_FANCY_MATH_387 16412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16413 || TARGET_MIX_SSE_I387) 16414 && flag_unsafe_math_optimizations 16415 && (flag_fp_int_builtin_inexact || !flag_trapping_math)) 16416 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16417 && !flag_trapping_math && !flag_rounding_math)" 16418{ 16419 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16420 && !flag_trapping_math && !flag_rounding_math) 16421 { 16422 if (TARGET_SSE4_1) 16423 { 16424 operands[1] = force_reg (<MODE>mode, operands[1]); 16425 ix86_expand_round_sse4 (operands[0], operands[1]); 16426 } 16427 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 16428 ix86_expand_round (operands[0], operands[1]); 16429 else 16430 ix86_expand_rounddf_32 (operands[0], operands[1]); 16431 } 16432 else 16433 { 16434 operands[1] = force_reg (<MODE>mode, operands[1]); 16435 ix86_emit_i387_round (operands[0], operands[1]); 16436 } 16437 DONE; 16438}) 16439 16440(define_insn_and_split "*fistdi2_1" 16441 [(set (match_operand:DI 0 "nonimmediate_operand") 16442 (unspec:DI [(match_operand:XF 1 "register_operand")] 16443 UNSPEC_FIST))] 16444 "TARGET_USE_FANCY_MATH_387 16445 && can_create_pseudo_p ()" 16446 "#" 16447 "&& 1" 16448 [(const_int 0)] 16449{ 16450 if (memory_operand (operands[0], VOIDmode)) 16451 emit_insn (gen_fistdi2 (operands[0], operands[1])); 16452 else 16453 { 16454 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 16455 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 16456 operands[2])); 16457 } 16458 DONE; 16459} 16460 [(set_attr "type" "fpspc") 16461 (set_attr "mode" "DI")]) 16462 16463(define_insn "fistdi2" 16464 [(set (match_operand:DI 0 "memory_operand" "=m") 16465 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 16466 UNSPEC_FIST)) 16467 (clobber (match_scratch:XF 2 "=&1f"))] 16468 "TARGET_USE_FANCY_MATH_387" 16469 "* return output_fix_trunc (insn, operands, false);" 16470 [(set_attr "type" "fpspc") 16471 (set_attr "mode" "DI")]) 16472 16473(define_insn "fistdi2_with_temp" 16474 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 16475 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 16476 UNSPEC_FIST)) 16477 (clobber (match_operand:DI 2 "memory_operand" "=X,m")) 16478 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 16479 "TARGET_USE_FANCY_MATH_387" 16480 "#" 16481 [(set_attr "type" "fpspc") 16482 (set_attr "mode" "DI")]) 16483 16484(define_split 16485 [(set (match_operand:DI 0 "register_operand") 16486 (unspec:DI [(match_operand:XF 1 "register_operand")] 16487 UNSPEC_FIST)) 16488 (clobber (match_operand:DI 2 "memory_operand")) 16489 (clobber (match_scratch 3))] 16490 "reload_completed" 16491 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 16492 (clobber (match_dup 3))]) 16493 (set (match_dup 0) (match_dup 2))]) 16494 16495(define_split 16496 [(set (match_operand:DI 0 "memory_operand") 16497 (unspec:DI [(match_operand:XF 1 "register_operand")] 16498 UNSPEC_FIST)) 16499 (clobber (match_operand:DI 2 "memory_operand")) 16500 (clobber (match_scratch 3))] 16501 "reload_completed" 16502 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 16503 (clobber (match_dup 3))])]) 16504 16505(define_insn_and_split "*fist<mode>2_1" 16506 [(set (match_operand:SWI24 0 "register_operand") 16507 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16508 UNSPEC_FIST))] 16509 "TARGET_USE_FANCY_MATH_387 16510 && can_create_pseudo_p ()" 16511 "#" 16512 "&& 1" 16513 [(const_int 0)] 16514{ 16515 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 16516 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 16517 operands[2])); 16518 DONE; 16519} 16520 [(set_attr "type" "fpspc") 16521 (set_attr "mode" "<MODE>")]) 16522 16523(define_insn "fist<mode>2" 16524 [(set (match_operand:SWI24 0 "memory_operand" "=m") 16525 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16526 UNSPEC_FIST))] 16527 "TARGET_USE_FANCY_MATH_387" 16528 "* return output_fix_trunc (insn, operands, false);" 16529 [(set_attr "type" "fpspc") 16530 (set_attr "mode" "<MODE>")]) 16531 16532(define_insn "fist<mode>2_with_temp" 16533 [(set (match_operand:SWI24 0 "register_operand" "=r") 16534 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16535 UNSPEC_FIST)) 16536 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))] 16537 "TARGET_USE_FANCY_MATH_387" 16538 "#" 16539 [(set_attr "type" "fpspc") 16540 (set_attr "mode" "<MODE>")]) 16541 16542(define_split 16543 [(set (match_operand:SWI24 0 "register_operand") 16544 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16545 UNSPEC_FIST)) 16546 (clobber (match_operand:SWI24 2 "memory_operand"))] 16547 "reload_completed" 16548 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST)) 16549 (set (match_dup 0) (match_dup 2))]) 16550 16551(define_split 16552 [(set (match_operand:SWI24 0 "memory_operand") 16553 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16554 UNSPEC_FIST)) 16555 (clobber (match_operand:SWI24 2 "memory_operand"))] 16556 "reload_completed" 16557 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))]) 16558 16559(define_expand "lrintxf<mode>2" 16560 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16561 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16562 UNSPEC_FIST))] 16563 "TARGET_USE_FANCY_MATH_387") 16564 16565(define_expand "lrint<MODEF:mode><SWI48:mode>2" 16566 [(set (match_operand:SWI48 0 "nonimmediate_operand") 16567 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 16568 UNSPEC_FIX_NOTRUNC))] 16569 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH") 16570 16571(define_expand "lround<X87MODEF:mode><SWI248x:mode>2" 16572 [(match_operand:SWI248x 0 "nonimmediate_operand") 16573 (match_operand:X87MODEF 1 "register_operand")] 16574 "(TARGET_USE_FANCY_MATH_387 16575 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 16576 || TARGET_MIX_SSE_I387) 16577 && flag_unsafe_math_optimizations) 16578 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 16579 && <SWI248x:MODE>mode != HImode 16580 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 16581 && !flag_trapping_math && !flag_rounding_math)" 16582{ 16583 if (optimize_insn_for_size_p ()) 16584 FAIL; 16585 16586 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 16587 && <SWI248x:MODE>mode != HImode 16588 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 16589 && !flag_trapping_math && !flag_rounding_math) 16590 ix86_expand_lround (operands[0], operands[1]); 16591 else 16592 ix86_emit_i387_round (operands[0], operands[1]); 16593 DONE; 16594}) 16595 16596(define_int_iterator FRNDINT_ROUNDING 16597 [UNSPEC_FRNDINT_FLOOR 16598 UNSPEC_FRNDINT_CEIL 16599 UNSPEC_FRNDINT_TRUNC]) 16600 16601(define_int_iterator FIST_ROUNDING 16602 [UNSPEC_FIST_FLOOR 16603 UNSPEC_FIST_CEIL]) 16604 16605;; Base name for define_insn 16606(define_int_attr rounding_insn 16607 [(UNSPEC_FRNDINT_FLOOR "floor") 16608 (UNSPEC_FRNDINT_CEIL "ceil") 16609 (UNSPEC_FRNDINT_TRUNC "btrunc") 16610 (UNSPEC_FIST_FLOOR "floor") 16611 (UNSPEC_FIST_CEIL "ceil")]) 16612 16613(define_int_attr rounding 16614 [(UNSPEC_FRNDINT_FLOOR "floor") 16615 (UNSPEC_FRNDINT_CEIL "ceil") 16616 (UNSPEC_FRNDINT_TRUNC "trunc") 16617 (UNSPEC_FIST_FLOOR "floor") 16618 (UNSPEC_FIST_CEIL "ceil")]) 16619 16620(define_int_attr ROUNDING 16621 [(UNSPEC_FRNDINT_FLOOR "FLOOR") 16622 (UNSPEC_FRNDINT_CEIL "CEIL") 16623 (UNSPEC_FRNDINT_TRUNC "TRUNC") 16624 (UNSPEC_FIST_FLOOR "FLOOR") 16625 (UNSPEC_FIST_CEIL "CEIL")]) 16626 16627;; Rounding mode control word calculation could clobber FLAGS_REG. 16628(define_insn_and_split "frndint<mode>2_<rounding>" 16629 [(set (match_operand:X87MODEF 0 "register_operand") 16630 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")] 16631 FRNDINT_ROUNDING)) 16632 (clobber (reg:CC FLAGS_REG))] 16633 "TARGET_USE_FANCY_MATH_387 16634 && (flag_fp_int_builtin_inexact || !flag_trapping_math) 16635 && can_create_pseudo_p ()" 16636 "#" 16637 "&& 1" 16638 [(const_int 0)] 16639{ 16640 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 16641 16642 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16643 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 16644 16645 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1], 16646 operands[2], operands[3])); 16647 DONE; 16648} 16649 [(set_attr "type" "frndint") 16650 (set_attr "i387_cw" "<rounding>") 16651 (set_attr "mode" "<MODE>")]) 16652 16653(define_insn "frndint<mode>2_<rounding>_i387" 16654 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 16655 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")] 16656 FRNDINT_ROUNDING)) 16657 (use (match_operand:HI 2 "memory_operand" "m")) 16658 (use (match_operand:HI 3 "memory_operand" "m"))] 16659 "TARGET_USE_FANCY_MATH_387 16660 && (flag_fp_int_builtin_inexact || !flag_trapping_math)" 16661 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 16662 [(set_attr "type" "frndint") 16663 (set_attr "i387_cw" "<rounding>") 16664 (set_attr "mode" "<MODE>")]) 16665 16666(define_expand "<rounding_insn>xf2" 16667 [(parallel [(set (match_operand:XF 0 "register_operand") 16668 (unspec:XF [(match_operand:XF 1 "register_operand")] 16669 FRNDINT_ROUNDING)) 16670 (clobber (reg:CC FLAGS_REG))])] 16671 "TARGET_USE_FANCY_MATH_387 16672 && (flag_fp_int_builtin_inexact || !flag_trapping_math)") 16673 16674(define_expand "<rounding_insn><mode>2" 16675 [(parallel [(set (match_operand:MODEF 0 "register_operand") 16676 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")] 16677 FRNDINT_ROUNDING)) 16678 (clobber (reg:CC FLAGS_REG))])] 16679 "(TARGET_USE_FANCY_MATH_387 16680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16681 || TARGET_MIX_SSE_I387) 16682 && (flag_fp_int_builtin_inexact || !flag_trapping_math)) 16683 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16684 && (TARGET_SSE4_1 || !flag_trapping_math 16685 || flag_fp_int_builtin_inexact))" 16686{ 16687 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16688 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact)) 16689 { 16690 if (TARGET_SSE4_1) 16691 emit_insn (gen_sse4_1_round<mode>2 16692 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING> 16693 | ROUND_NO_EXC))); 16694 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 16695 { 16696 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16697 ix86_expand_floorceil (operands[0], operands[1], true); 16698 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16699 ix86_expand_floorceil (operands[0], operands[1], false); 16700 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 16701 ix86_expand_trunc (operands[0], operands[1]); 16702 else 16703 gcc_unreachable (); 16704 } 16705 else 16706 { 16707 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16708 ix86_expand_floorceildf_32 (operands[0], operands[1], true); 16709 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16710 ix86_expand_floorceildf_32 (operands[0], operands[1], false); 16711 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 16712 ix86_expand_truncdf_32 (operands[0], operands[1]); 16713 else 16714 gcc_unreachable (); 16715 } 16716 } 16717 else 16718 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1])); 16719 DONE; 16720}) 16721 16722;; Rounding mode control word calculation could clobber FLAGS_REG. 16723(define_insn_and_split "frndintxf2_mask_pm" 16724 [(set (match_operand:XF 0 "register_operand") 16725 (unspec:XF [(match_operand:XF 1 "register_operand")] 16726 UNSPEC_FRNDINT_MASK_PM)) 16727 (clobber (reg:CC FLAGS_REG))] 16728 "TARGET_USE_FANCY_MATH_387 16729 && flag_unsafe_math_optimizations 16730 && can_create_pseudo_p ()" 16731 "#" 16732 "&& 1" 16733 [(const_int 0)] 16734{ 16735 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 16736 16737 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16738 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 16739 16740 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 16741 operands[2], operands[3])); 16742 DONE; 16743} 16744 [(set_attr "type" "frndint") 16745 (set_attr "i387_cw" "mask_pm") 16746 (set_attr "mode" "XF")]) 16747 16748(define_insn "frndintxf2_mask_pm_i387" 16749 [(set (match_operand:XF 0 "register_operand" "=f") 16750 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16751 UNSPEC_FRNDINT_MASK_PM)) 16752 (use (match_operand:HI 2 "memory_operand" "m")) 16753 (use (match_operand:HI 3 "memory_operand" "m"))] 16754 "TARGET_USE_FANCY_MATH_387 16755 && flag_unsafe_math_optimizations" 16756 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 16757 [(set_attr "type" "frndint") 16758 (set_attr "i387_cw" "mask_pm") 16759 (set_attr "mode" "XF")]) 16760 16761(define_expand "nearbyintxf2" 16762 [(parallel [(set (match_operand:XF 0 "register_operand") 16763 (unspec:XF [(match_operand:XF 1 "register_operand")] 16764 UNSPEC_FRNDINT_MASK_PM)) 16765 (clobber (reg:CC FLAGS_REG))])] 16766 "TARGET_USE_FANCY_MATH_387 16767 && flag_unsafe_math_optimizations") 16768 16769(define_expand "nearbyint<mode>2" 16770 [(use (match_operand:MODEF 0 "register_operand")) 16771 (use (match_operand:MODEF 1 "register_operand"))] 16772 "TARGET_USE_FANCY_MATH_387 16773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16774 || TARGET_MIX_SSE_I387) 16775 && flag_unsafe_math_optimizations" 16776{ 16777 rtx op0 = gen_reg_rtx (XFmode); 16778 rtx op1 = gen_reg_rtx (XFmode); 16779 16780 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16781 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 16782 16783 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 16784 DONE; 16785}) 16786 16787;; Rounding mode control word calculation could clobber FLAGS_REG. 16788(define_insn_and_split "*fist<mode>2_<rounding>_1" 16789 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16790 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16791 FIST_ROUNDING)) 16792 (clobber (reg:CC FLAGS_REG))] 16793 "TARGET_USE_FANCY_MATH_387 16794 && flag_unsafe_math_optimizations 16795 && can_create_pseudo_p ()" 16796 "#" 16797 "&& 1" 16798 [(const_int 0)] 16799{ 16800 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 16801 16802 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16803 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 16804 if (memory_operand (operands[0], VOIDmode)) 16805 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1], 16806 operands[2], operands[3])); 16807 else 16808 { 16809 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 16810 emit_insn (gen_fist<mode>2_<rounding>_with_temp 16811 (operands[0], operands[1], operands[2], 16812 operands[3], operands[4])); 16813 } 16814 DONE; 16815} 16816 [(set_attr "type" "fistp") 16817 (set_attr "i387_cw" "<rounding>") 16818 (set_attr "mode" "<MODE>")]) 16819 16820(define_insn "fistdi2_<rounding>" 16821 [(set (match_operand:DI 0 "memory_operand" "=m") 16822 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 16823 FIST_ROUNDING)) 16824 (use (match_operand:HI 2 "memory_operand" "m")) 16825 (use (match_operand:HI 3 "memory_operand" "m")) 16826 (clobber (match_scratch:XF 4 "=&1f"))] 16827 "TARGET_USE_FANCY_MATH_387 16828 && flag_unsafe_math_optimizations" 16829 "* return output_fix_trunc (insn, operands, false);" 16830 [(set_attr "type" "fistp") 16831 (set_attr "i387_cw" "<rounding>") 16832 (set_attr "mode" "DI")]) 16833 16834(define_insn "fistdi2_<rounding>_with_temp" 16835 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 16836 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 16837 FIST_ROUNDING)) 16838 (use (match_operand:HI 2 "memory_operand" "m,m")) 16839 (use (match_operand:HI 3 "memory_operand" "m,m")) 16840 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 16841 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 16842 "TARGET_USE_FANCY_MATH_387 16843 && flag_unsafe_math_optimizations" 16844 "#" 16845 [(set_attr "type" "fistp") 16846 (set_attr "i387_cw" "<rounding>") 16847 (set_attr "mode" "DI")]) 16848 16849(define_split 16850 [(set (match_operand:DI 0 "register_operand") 16851 (unspec:DI [(match_operand:XF 1 "register_operand")] 16852 FIST_ROUNDING)) 16853 (use (match_operand:HI 2 "memory_operand")) 16854 (use (match_operand:HI 3 "memory_operand")) 16855 (clobber (match_operand:DI 4 "memory_operand")) 16856 (clobber (match_scratch 5))] 16857 "reload_completed" 16858 [(parallel [(set (match_dup 4) 16859 (unspec:DI [(match_dup 1)] FIST_ROUNDING)) 16860 (use (match_dup 2)) 16861 (use (match_dup 3)) 16862 (clobber (match_dup 5))]) 16863 (set (match_dup 0) (match_dup 4))]) 16864 16865(define_split 16866 [(set (match_operand:DI 0 "memory_operand") 16867 (unspec:DI [(match_operand:XF 1 "register_operand")] 16868 FIST_ROUNDING)) 16869 (use (match_operand:HI 2 "memory_operand")) 16870 (use (match_operand:HI 3 "memory_operand")) 16871 (clobber (match_operand:DI 4 "memory_operand")) 16872 (clobber (match_scratch 5))] 16873 "reload_completed" 16874 [(parallel [(set (match_dup 0) 16875 (unspec:DI [(match_dup 1)] FIST_ROUNDING)) 16876 (use (match_dup 2)) 16877 (use (match_dup 3)) 16878 (clobber (match_dup 5))])]) 16879 16880(define_insn "fist<mode>2_<rounding>" 16881 [(set (match_operand:SWI24 0 "memory_operand" "=m") 16882 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16883 FIST_ROUNDING)) 16884 (use (match_operand:HI 2 "memory_operand" "m")) 16885 (use (match_operand:HI 3 "memory_operand" "m"))] 16886 "TARGET_USE_FANCY_MATH_387 16887 && flag_unsafe_math_optimizations" 16888 "* return output_fix_trunc (insn, operands, false);" 16889 [(set_attr "type" "fistp") 16890 (set_attr "i387_cw" "<rounding>") 16891 (set_attr "mode" "<MODE>")]) 16892 16893(define_insn "fist<mode>2_<rounding>_with_temp" 16894 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 16895 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 16896 FIST_ROUNDING)) 16897 (use (match_operand:HI 2 "memory_operand" "m,m")) 16898 (use (match_operand:HI 3 "memory_operand" "m,m")) 16899 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 16900 "TARGET_USE_FANCY_MATH_387 16901 && flag_unsafe_math_optimizations" 16902 "#" 16903 [(set_attr "type" "fistp") 16904 (set_attr "i387_cw" "<rounding>") 16905 (set_attr "mode" "<MODE>")]) 16906 16907(define_split 16908 [(set (match_operand:SWI24 0 "register_operand") 16909 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16910 FIST_ROUNDING)) 16911 (use (match_operand:HI 2 "memory_operand")) 16912 (use (match_operand:HI 3 "memory_operand")) 16913 (clobber (match_operand:SWI24 4 "memory_operand"))] 16914 "reload_completed" 16915 [(parallel [(set (match_dup 4) 16916 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) 16917 (use (match_dup 2)) 16918 (use (match_dup 3))]) 16919 (set (match_dup 0) (match_dup 4))]) 16920 16921(define_split 16922 [(set (match_operand:SWI24 0 "memory_operand") 16923 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 16924 FIST_ROUNDING)) 16925 (use (match_operand:HI 2 "memory_operand")) 16926 (use (match_operand:HI 3 "memory_operand")) 16927 (clobber (match_operand:SWI24 4 "memory_operand"))] 16928 "reload_completed" 16929 [(parallel [(set (match_dup 0) 16930 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) 16931 (use (match_dup 2)) 16932 (use (match_dup 3))])]) 16933 16934(define_expand "l<rounding_insn>xf<mode>2" 16935 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16936 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16937 FIST_ROUNDING)) 16938 (clobber (reg:CC FLAGS_REG))])] 16939 "TARGET_USE_FANCY_MATH_387 16940 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 16941 && flag_unsafe_math_optimizations") 16942 16943(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2" 16944 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand") 16945 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 16946 FIST_ROUNDING)) 16947 (clobber (reg:CC FLAGS_REG))])] 16948 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 16949 && !flag_trapping_math" 16950{ 16951 if (TARGET_64BIT && optimize_insn_for_size_p ()) 16952 FAIL; 16953 16954 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16955 ix86_expand_lfloorceil (operands[0], operands[1], true); 16956 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16957 ix86_expand_lfloorceil (operands[0], operands[1], false); 16958 else 16959 gcc_unreachable (); 16960 16961 DONE; 16962}) 16963 16964(define_insn "fxam<mode>2_i387" 16965 [(set (match_operand:HI 0 "register_operand" "=a") 16966 (unspec:HI 16967 [(match_operand:X87MODEF 1 "register_operand" "f")] 16968 UNSPEC_FXAM))] 16969 "TARGET_USE_FANCY_MATH_387" 16970 "fxam\n\tfnstsw\t%0" 16971 [(set_attr "type" "multi") 16972 (set_attr "length" "4") 16973 (set_attr "unit" "i387") 16974 (set_attr "mode" "<MODE>")]) 16975 16976(define_insn_and_split "fxam<mode>2_i387_with_temp" 16977 [(set (match_operand:HI 0 "register_operand") 16978 (unspec:HI 16979 [(match_operand:MODEF 1 "memory_operand")] 16980 UNSPEC_FXAM_MEM))] 16981 "TARGET_USE_FANCY_MATH_387 16982 && can_create_pseudo_p ()" 16983 "#" 16984 "&& 1" 16985 [(set (match_dup 2)(match_dup 1)) 16986 (set (match_dup 0) 16987 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))] 16988{ 16989 operands[2] = gen_reg_rtx (<MODE>mode); 16990 16991 MEM_VOLATILE_P (operands[1]) = 1; 16992} 16993 [(set_attr "type" "multi") 16994 (set_attr "unit" "i387") 16995 (set_attr "mode" "<MODE>")]) 16996 16997(define_expand "isinfxf2" 16998 [(use (match_operand:SI 0 "register_operand")) 16999 (use (match_operand:XF 1 "register_operand"))] 17000 "TARGET_USE_FANCY_MATH_387 17001 && ix86_libc_has_function (function_c99_misc)" 17002{ 17003 rtx mask = GEN_INT (0x45); 17004 rtx val = GEN_INT (0x05); 17005 17006 rtx scratch = gen_reg_rtx (HImode); 17007 rtx res = gen_reg_rtx (QImode); 17008 17009 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 17010 17011 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask)); 17012 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 17013 ix86_expand_setcc (res, EQ, 17014 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 17015 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 17016 DONE; 17017}) 17018 17019(define_expand "isinf<mode>2" 17020 [(use (match_operand:SI 0 "register_operand")) 17021 (use (match_operand:MODEF 1 "nonimmediate_operand"))] 17022 "TARGET_USE_FANCY_MATH_387 17023 && ix86_libc_has_function (function_c99_misc) 17024 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 17025{ 17026 rtx mask = GEN_INT (0x45); 17027 rtx val = GEN_INT (0x05); 17028 17029 rtx scratch = gen_reg_rtx (HImode); 17030 rtx res = gen_reg_rtx (QImode); 17031 17032 /* Remove excess precision by forcing value through memory. */ 17033 if (memory_operand (operands[1], VOIDmode)) 17034 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1])); 17035 else 17036 { 17037 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 17038 17039 emit_move_insn (temp, operands[1]); 17040 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp)); 17041 } 17042 17043 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask)); 17044 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 17045 ix86_expand_setcc (res, EQ, 17046 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 17047 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 17048 DONE; 17049}) 17050 17051(define_expand "signbittf2" 17052 [(use (match_operand:SI 0 "register_operand")) 17053 (use (match_operand:TF 1 "register_operand"))] 17054 "TARGET_SSE" 17055{ 17056 if (TARGET_SSE4_1) 17057 { 17058 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0); 17059 rtx scratch = gen_reg_rtx (QImode); 17060 17061 emit_insn (gen_ptesttf2 (operands[1], mask)); 17062 ix86_expand_setcc (scratch, NE, 17063 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 17064 17065 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 17066 } 17067 else 17068 { 17069 emit_insn (gen_sse_movmskps (operands[0], 17070 gen_lowpart (V4SFmode, operands[1]))); 17071 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8))); 17072 } 17073 DONE; 17074}) 17075 17076(define_expand "signbitxf2" 17077 [(use (match_operand:SI 0 "register_operand")) 17078 (use (match_operand:XF 1 "register_operand"))] 17079 "TARGET_USE_FANCY_MATH_387" 17080{ 17081 rtx scratch = gen_reg_rtx (HImode); 17082 17083 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 17084 emit_insn (gen_andsi3 (operands[0], 17085 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17086 DONE; 17087}) 17088 17089(define_insn "movmsk_df" 17090 [(set (match_operand:SI 0 "register_operand" "=r") 17091 (unspec:SI 17092 [(match_operand:DF 1 "register_operand" "x")] 17093 UNSPEC_MOVMSK))] 17094 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH" 17095 "%vmovmskpd\t{%1, %0|%0, %1}" 17096 [(set_attr "type" "ssemov") 17097 (set_attr "prefix" "maybe_vex") 17098 (set_attr "mode" "DF")]) 17099 17100;; Use movmskpd in SSE mode to avoid store forwarding stall 17101;; for 32bit targets and movq+shrq sequence for 64bit targets. 17102(define_expand "signbitdf2" 17103 [(use (match_operand:SI 0 "register_operand")) 17104 (use (match_operand:DF 1 "register_operand"))] 17105 "TARGET_USE_FANCY_MATH_387 17106 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 17107{ 17108 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH) 17109 { 17110 emit_insn (gen_movmsk_df (operands[0], operands[1])); 17111 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx)); 17112 } 17113 else 17114 { 17115 rtx scratch = gen_reg_rtx (HImode); 17116 17117 emit_insn (gen_fxamdf2_i387 (scratch, operands[1])); 17118 emit_insn (gen_andsi3 (operands[0], 17119 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17120 } 17121 DONE; 17122}) 17123 17124(define_expand "signbitsf2" 17125 [(use (match_operand:SI 0 "register_operand")) 17126 (use (match_operand:SF 1 "register_operand"))] 17127 "TARGET_USE_FANCY_MATH_387 17128 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)" 17129{ 17130 rtx scratch = gen_reg_rtx (HImode); 17131 17132 emit_insn (gen_fxamsf2_i387 (scratch, operands[1])); 17133 emit_insn (gen_andsi3 (operands[0], 17134 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17135 DONE; 17136}) 17137 17138;; Block operation instructions 17139 17140(define_insn "cld" 17141 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] 17142 "" 17143 "cld" 17144 [(set_attr "length" "1") 17145 (set_attr "length_immediate" "0") 17146 (set_attr "modrm" "0")]) 17147 17148(define_expand "movmem<mode>" 17149 [(use (match_operand:BLK 0 "memory_operand")) 17150 (use (match_operand:BLK 1 "memory_operand")) 17151 (use (match_operand:SWI48 2 "nonmemory_operand")) 17152 (use (match_operand:SWI48 3 "const_int_operand")) 17153 (use (match_operand:SI 4 "const_int_operand")) 17154 (use (match_operand:SI 5 "const_int_operand")) 17155 (use (match_operand:SI 6 "")) 17156 (use (match_operand:SI 7 "")) 17157 (use (match_operand:SI 8 ""))] 17158 "" 17159{ 17160 if (ix86_expand_set_or_movmem (operands[0], operands[1], 17161 operands[2], NULL, operands[3], 17162 operands[4], operands[5], 17163 operands[6], operands[7], 17164 operands[8], false)) 17165 DONE; 17166 else 17167 FAIL; 17168}) 17169 17170;; Most CPUs don't like single string operations 17171;; Handle this case here to simplify previous expander. 17172 17173(define_expand "strmov" 17174 [(set (match_dup 4) (match_operand 3 "memory_operand")) 17175 (set (match_operand 1 "memory_operand") (match_dup 4)) 17176 (parallel [(set (match_operand 0 "register_operand") (match_dup 5)) 17177 (clobber (reg:CC FLAGS_REG))]) 17178 (parallel [(set (match_operand 2 "register_operand") (match_dup 6)) 17179 (clobber (reg:CC FLAGS_REG))])] 17180 "" 17181{ 17182 /* Can't use this for non-default address spaces. */ 17183 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3]))) 17184 FAIL; 17185 17186 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 17187 17188 /* If .md ever supports :P for Pmode, these can be directly 17189 in the pattern above. */ 17190 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 17191 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 17192 17193 /* Can't use this if the user has appropriated esi or edi. */ 17194 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 17195 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])) 17196 { 17197 emit_insn (gen_strmov_singleop (operands[0], operands[1], 17198 operands[2], operands[3], 17199 operands[5], operands[6])); 17200 DONE; 17201 } 17202 17203 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 17204}) 17205 17206(define_expand "strmov_singleop" 17207 [(parallel [(set (match_operand 1 "memory_operand") 17208 (match_operand 3 "memory_operand")) 17209 (set (match_operand 0 "register_operand") 17210 (match_operand 4)) 17211 (set (match_operand 2 "register_operand") 17212 (match_operand 5))])] 17213 "" 17214{ 17215 if (TARGET_CLD) 17216 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17217}) 17218 17219(define_insn "*strmovdi_rex_1" 17220 [(set (mem:DI (match_operand:P 2 "register_operand" "0")) 17221 (mem:DI (match_operand:P 3 "register_operand" "1"))) 17222 (set (match_operand:P 0 "register_operand" "=D") 17223 (plus:P (match_dup 2) 17224 (const_int 8))) 17225 (set (match_operand:P 1 "register_operand" "=S") 17226 (plus:P (match_dup 3) 17227 (const_int 8)))] 17228 "TARGET_64BIT 17229 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17230 && ix86_check_no_addr_space (insn)" 17231 "%^movsq" 17232 [(set_attr "type" "str") 17233 (set_attr "memory" "both") 17234 (set_attr "mode" "DI")]) 17235 17236(define_insn "*strmovsi_1" 17237 [(set (mem:SI (match_operand:P 2 "register_operand" "0")) 17238 (mem:SI (match_operand:P 3 "register_operand" "1"))) 17239 (set (match_operand:P 0 "register_operand" "=D") 17240 (plus:P (match_dup 2) 17241 (const_int 4))) 17242 (set (match_operand:P 1 "register_operand" "=S") 17243 (plus:P (match_dup 3) 17244 (const_int 4)))] 17245 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17246 && ix86_check_no_addr_space (insn)" 17247 "%^movs{l|d}" 17248 [(set_attr "type" "str") 17249 (set_attr "memory" "both") 17250 (set_attr "mode" "SI")]) 17251 17252(define_insn "*strmovhi_1" 17253 [(set (mem:HI (match_operand:P 2 "register_operand" "0")) 17254 (mem:HI (match_operand:P 3 "register_operand" "1"))) 17255 (set (match_operand:P 0 "register_operand" "=D") 17256 (plus:P (match_dup 2) 17257 (const_int 2))) 17258 (set (match_operand:P 1 "register_operand" "=S") 17259 (plus:P (match_dup 3) 17260 (const_int 2)))] 17261 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17262 && ix86_check_no_addr_space (insn)" 17263 "%^movsw" 17264 [(set_attr "type" "str") 17265 (set_attr "memory" "both") 17266 (set_attr "mode" "HI")]) 17267 17268(define_insn "*strmovqi_1" 17269 [(set (mem:QI (match_operand:P 2 "register_operand" "0")) 17270 (mem:QI (match_operand:P 3 "register_operand" "1"))) 17271 (set (match_operand:P 0 "register_operand" "=D") 17272 (plus:P (match_dup 2) 17273 (const_int 1))) 17274 (set (match_operand:P 1 "register_operand" "=S") 17275 (plus:P (match_dup 3) 17276 (const_int 1)))] 17277 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17278 && ix86_check_no_addr_space (insn)" 17279 "%^movsb" 17280 [(set_attr "type" "str") 17281 (set_attr "memory" "both") 17282 (set (attr "prefix_rex") 17283 (if_then_else 17284 (match_test "<P:MODE>mode == DImode") 17285 (const_string "0") 17286 (const_string "*"))) 17287 (set_attr "mode" "QI")]) 17288 17289(define_expand "rep_mov" 17290 [(parallel [(set (match_operand 4 "register_operand") (const_int 0)) 17291 (set (match_operand 0 "register_operand") 17292 (match_operand 5)) 17293 (set (match_operand 2 "register_operand") 17294 (match_operand 6)) 17295 (set (match_operand 1 "memory_operand") 17296 (match_operand 3 "memory_operand")) 17297 (use (match_dup 4))])] 17298 "" 17299{ 17300 if (TARGET_CLD) 17301 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17302}) 17303 17304(define_insn "*rep_movdi_rex64" 17305 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17306 (set (match_operand:P 0 "register_operand" "=D") 17307 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 17308 (const_int 3)) 17309 (match_operand:P 3 "register_operand" "0"))) 17310 (set (match_operand:P 1 "register_operand" "=S") 17311 (plus:P (ashift:P (match_dup 5) (const_int 3)) 17312 (match_operand:P 4 "register_operand" "1"))) 17313 (set (mem:BLK (match_dup 3)) 17314 (mem:BLK (match_dup 4))) 17315 (use (match_dup 5))] 17316 "TARGET_64BIT 17317 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17318 && ix86_check_no_addr_space (insn)" 17319 "%^rep{%;} movsq" 17320 [(set_attr "type" "str") 17321 (set_attr "prefix_rep" "1") 17322 (set_attr "memory" "both") 17323 (set_attr "mode" "DI")]) 17324 17325(define_insn "*rep_movsi" 17326 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17327 (set (match_operand:P 0 "register_operand" "=D") 17328 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 17329 (const_int 2)) 17330 (match_operand:P 3 "register_operand" "0"))) 17331 (set (match_operand:P 1 "register_operand" "=S") 17332 (plus:P (ashift:P (match_dup 5) (const_int 2)) 17333 (match_operand:P 4 "register_operand" "1"))) 17334 (set (mem:BLK (match_dup 3)) 17335 (mem:BLK (match_dup 4))) 17336 (use (match_dup 5))] 17337 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17338 && ix86_check_no_addr_space (insn)" 17339 "%^rep{%;} movs{l|d}" 17340 [(set_attr "type" "str") 17341 (set_attr "prefix_rep" "1") 17342 (set_attr "memory" "both") 17343 (set_attr "mode" "SI")]) 17344 17345(define_insn "*rep_movqi" 17346 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17347 (set (match_operand:P 0 "register_operand" "=D") 17348 (plus:P (match_operand:P 3 "register_operand" "0") 17349 (match_operand:P 5 "register_operand" "2"))) 17350 (set (match_operand:P 1 "register_operand" "=S") 17351 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5))) 17352 (set (mem:BLK (match_dup 3)) 17353 (mem:BLK (match_dup 4))) 17354 (use (match_dup 5))] 17355 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17356 && ix86_check_no_addr_space (insn)" 17357 "%^rep{%;} movsb" 17358 [(set_attr "type" "str") 17359 (set_attr "prefix_rep" "1") 17360 (set_attr "memory" "both") 17361 (set_attr "mode" "QI")]) 17362 17363(define_expand "setmem<mode>" 17364 [(use (match_operand:BLK 0 "memory_operand")) 17365 (use (match_operand:SWI48 1 "nonmemory_operand")) 17366 (use (match_operand:QI 2 "nonmemory_operand")) 17367 (use (match_operand 3 "const_int_operand")) 17368 (use (match_operand:SI 4 "const_int_operand")) 17369 (use (match_operand:SI 5 "const_int_operand")) 17370 (use (match_operand:SI 6 "")) 17371 (use (match_operand:SI 7 "")) 17372 (use (match_operand:SI 8 ""))] 17373 "" 17374{ 17375 if (ix86_expand_set_or_movmem (operands[0], NULL, 17376 operands[1], operands[2], 17377 operands[3], operands[4], 17378 operands[5], operands[6], 17379 operands[7], operands[8], true)) 17380 DONE; 17381 else 17382 FAIL; 17383}) 17384 17385;; Most CPUs don't like single string operations 17386;; Handle this case here to simplify previous expander. 17387 17388(define_expand "strset" 17389 [(set (match_operand 1 "memory_operand") 17390 (match_operand 2 "register_operand")) 17391 (parallel [(set (match_operand 0 "register_operand") 17392 (match_dup 3)) 17393 (clobber (reg:CC FLAGS_REG))])] 17394 "" 17395{ 17396 /* Can't use this for non-default address spaces. */ 17397 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1]))) 17398 FAIL; 17399 17400 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 17401 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 17402 17403 /* If .md ever supports :P for Pmode, this can be directly 17404 in the pattern above. */ 17405 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 17406 GEN_INT (GET_MODE_SIZE (GET_MODE 17407 (operands[2])))); 17408 /* Can't use this if the user has appropriated eax or edi. */ 17409 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 17410 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])) 17411 { 17412 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 17413 operands[3])); 17414 DONE; 17415 } 17416}) 17417 17418(define_expand "strset_singleop" 17419 [(parallel [(set (match_operand 1 "memory_operand") 17420 (match_operand 2 "register_operand")) 17421 (set (match_operand 0 "register_operand") 17422 (match_operand 3)) 17423 (unspec [(const_int 0)] UNSPEC_STOS)])] 17424 "" 17425{ 17426 if (TARGET_CLD) 17427 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17428}) 17429 17430(define_insn "*strsetdi_rex_1" 17431 [(set (mem:DI (match_operand:P 1 "register_operand" "0")) 17432 (match_operand:DI 2 "register_operand" "a")) 17433 (set (match_operand:P 0 "register_operand" "=D") 17434 (plus:P (match_dup 1) 17435 (const_int 8))) 17436 (unspec [(const_int 0)] UNSPEC_STOS)] 17437 "TARGET_64BIT 17438 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17439 && ix86_check_no_addr_space (insn)" 17440 "%^stosq" 17441 [(set_attr "type" "str") 17442 (set_attr "memory" "store") 17443 (set_attr "mode" "DI")]) 17444 17445(define_insn "*strsetsi_1" 17446 [(set (mem:SI (match_operand:P 1 "register_operand" "0")) 17447 (match_operand:SI 2 "register_operand" "a")) 17448 (set (match_operand:P 0 "register_operand" "=D") 17449 (plus:P (match_dup 1) 17450 (const_int 4))) 17451 (unspec [(const_int 0)] UNSPEC_STOS)] 17452 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17453 && ix86_check_no_addr_space (insn)" 17454 "%^stos{l|d}" 17455 [(set_attr "type" "str") 17456 (set_attr "memory" "store") 17457 (set_attr "mode" "SI")]) 17458 17459(define_insn "*strsethi_1" 17460 [(set (mem:HI (match_operand:P 1 "register_operand" "0")) 17461 (match_operand:HI 2 "register_operand" "a")) 17462 (set (match_operand:P 0 "register_operand" "=D") 17463 (plus:P (match_dup 1) 17464 (const_int 2))) 17465 (unspec [(const_int 0)] UNSPEC_STOS)] 17466 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17467 && ix86_check_no_addr_space (insn)" 17468 "%^stosw" 17469 [(set_attr "type" "str") 17470 (set_attr "memory" "store") 17471 (set_attr "mode" "HI")]) 17472 17473(define_insn "*strsetqi_1" 17474 [(set (mem:QI (match_operand:P 1 "register_operand" "0")) 17475 (match_operand:QI 2 "register_operand" "a")) 17476 (set (match_operand:P 0 "register_operand" "=D") 17477 (plus:P (match_dup 1) 17478 (const_int 1))) 17479 (unspec [(const_int 0)] UNSPEC_STOS)] 17480 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17481 && ix86_check_no_addr_space (insn)" 17482 "%^stosb" 17483 [(set_attr "type" "str") 17484 (set_attr "memory" "store") 17485 (set (attr "prefix_rex") 17486 (if_then_else 17487 (match_test "<P:MODE>mode == DImode") 17488 (const_string "0") 17489 (const_string "*"))) 17490 (set_attr "mode" "QI")]) 17491 17492(define_expand "rep_stos" 17493 [(parallel [(set (match_operand 1 "register_operand") (const_int 0)) 17494 (set (match_operand 0 "register_operand") 17495 (match_operand 4)) 17496 (set (match_operand 2 "memory_operand") (const_int 0)) 17497 (use (match_operand 3 "register_operand")) 17498 (use (match_dup 1))])] 17499 "" 17500{ 17501 if (TARGET_CLD) 17502 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17503}) 17504 17505(define_insn "*rep_stosdi_rex64" 17506 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17507 (set (match_operand:P 0 "register_operand" "=D") 17508 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 17509 (const_int 3)) 17510 (match_operand:P 3 "register_operand" "0"))) 17511 (set (mem:BLK (match_dup 3)) 17512 (const_int 0)) 17513 (use (match_operand:DI 2 "register_operand" "a")) 17514 (use (match_dup 4))] 17515 "TARGET_64BIT 17516 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17517 && ix86_check_no_addr_space (insn)" 17518 "%^rep{%;} stosq" 17519 [(set_attr "type" "str") 17520 (set_attr "prefix_rep" "1") 17521 (set_attr "memory" "store") 17522 (set_attr "mode" "DI")]) 17523 17524(define_insn "*rep_stossi" 17525 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17526 (set (match_operand:P 0 "register_operand" "=D") 17527 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 17528 (const_int 2)) 17529 (match_operand:P 3 "register_operand" "0"))) 17530 (set (mem:BLK (match_dup 3)) 17531 (const_int 0)) 17532 (use (match_operand:SI 2 "register_operand" "a")) 17533 (use (match_dup 4))] 17534 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17535 && ix86_check_no_addr_space (insn)" 17536 "%^rep{%;} stos{l|d}" 17537 [(set_attr "type" "str") 17538 (set_attr "prefix_rep" "1") 17539 (set_attr "memory" "store") 17540 (set_attr "mode" "SI")]) 17541 17542(define_insn "*rep_stosqi" 17543 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17544 (set (match_operand:P 0 "register_operand" "=D") 17545 (plus:P (match_operand:P 3 "register_operand" "0") 17546 (match_operand:P 4 "register_operand" "1"))) 17547 (set (mem:BLK (match_dup 3)) 17548 (const_int 0)) 17549 (use (match_operand:QI 2 "register_operand" "a")) 17550 (use (match_dup 4))] 17551 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17552 && ix86_check_no_addr_space (insn)" 17553 "%^rep{%;} stosb" 17554 [(set_attr "type" "str") 17555 (set_attr "prefix_rep" "1") 17556 (set_attr "memory" "store") 17557 (set (attr "prefix_rex") 17558 (if_then_else 17559 (match_test "<P:MODE>mode == DImode") 17560 (const_string "0") 17561 (const_string "*"))) 17562 (set_attr "mode" "QI")]) 17563 17564(define_expand "cmpstrnsi" 17565 [(set (match_operand:SI 0 "register_operand") 17566 (compare:SI (match_operand:BLK 1 "general_operand") 17567 (match_operand:BLK 2 "general_operand"))) 17568 (use (match_operand 3 "general_operand")) 17569 (use (match_operand 4 "immediate_operand"))] 17570 "" 17571{ 17572 rtx addr1, addr2, out, outlow, count, countreg, align; 17573 17574 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) 17575 FAIL; 17576 17577 /* Can't use this if the user has appropriated ecx, esi or edi. */ 17578 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17579 FAIL; 17580 17581 /* One of the strings must be a constant. If so, expand_builtin_strncmp() 17582 will have rewritten the length arg to be the minimum of the const string 17583 length and the actual length arg. If both strings are the same and 17584 shorter than the length arg, repz cmpsb will not stop at the 0 byte and 17585 will incorrectly base the results on chars past the 0 byte. */ 17586 tree t1 = MEM_EXPR (operands[1]); 17587 tree t2 = MEM_EXPR (operands[2]); 17588 if (!((t1 && TREE_CODE (t1) == MEM_REF 17589 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR 17590 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST) 17591 || (t2 && TREE_CODE (t2) == MEM_REF 17592 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR 17593 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST))) 17594 FAIL; 17595 17596 out = operands[0]; 17597 if (!REG_P (out)) 17598 out = gen_reg_rtx (SImode); 17599 17600 addr1 = copy_addr_to_reg (XEXP (operands[1], 0)); 17601 addr2 = copy_addr_to_reg (XEXP (operands[2], 0)); 17602 if (addr1 != XEXP (operands[1], 0)) 17603 operands[1] = replace_equiv_address_nv (operands[1], addr1); 17604 if (addr2 != XEXP (operands[2], 0)) 17605 operands[2] = replace_equiv_address_nv (operands[2], addr2); 17606 17607 count = operands[3]; 17608 countreg = ix86_zero_extend_to_Pmode (count); 17609 17610 /* %%% Iff we are testing strict equality, we can use known alignment 17611 to good advantage. This may be possible with combine, particularly 17612 once cc0 is dead. */ 17613 align = operands[4]; 17614 17615 if (CONST_INT_P (count)) 17616 { 17617 if (INTVAL (count) == 0) 17618 { 17619 emit_move_insn (operands[0], const0_rtx); 17620 DONE; 17621 } 17622 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 17623 operands[1], operands[2])); 17624 } 17625 else 17626 { 17627 rtx (*gen_cmp) (rtx, rtx); 17628 17629 gen_cmp = (TARGET_64BIT 17630 ? gen_cmpdi_1 : gen_cmpsi_1); 17631 17632 emit_insn (gen_cmp (countreg, countreg)); 17633 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 17634 operands[1], operands[2])); 17635 } 17636 17637 outlow = gen_lowpart (QImode, out); 17638 emit_insn (gen_cmpintqi (outlow)); 17639 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 17640 17641 if (operands[0] != out) 17642 emit_move_insn (operands[0], out); 17643 17644 DONE; 17645}) 17646 17647;; Produce a tri-state integer (-1, 0, 1) from condition codes. 17648 17649(define_expand "cmpintqi" 17650 [(set (match_dup 1) 17651 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17652 (set (match_dup 2) 17653 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17654 (parallel [(set (match_operand:QI 0 "register_operand") 17655 (minus:QI (match_dup 1) 17656 (match_dup 2))) 17657 (clobber (reg:CC FLAGS_REG))])] 17658 "" 17659{ 17660 operands[1] = gen_reg_rtx (QImode); 17661 operands[2] = gen_reg_rtx (QImode); 17662}) 17663 17664;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 17665;; zero. Emit extra code to make sure that a zero-length compare is EQ. 17666 17667(define_expand "cmpstrnqi_nz_1" 17668 [(parallel [(set (reg:CC FLAGS_REG) 17669 (compare:CC (match_operand 4 "memory_operand") 17670 (match_operand 5 "memory_operand"))) 17671 (use (match_operand 2 "register_operand")) 17672 (use (match_operand:SI 3 "immediate_operand")) 17673 (clobber (match_operand 0 "register_operand")) 17674 (clobber (match_operand 1 "register_operand")) 17675 (clobber (match_dup 2))])] 17676 "" 17677{ 17678 if (TARGET_CLD) 17679 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17680}) 17681 17682(define_insn "*cmpstrnqi_nz_1" 17683 [(set (reg:CC FLAGS_REG) 17684 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 17685 (mem:BLK (match_operand:P 5 "register_operand" "1")))) 17686 (use (match_operand:P 6 "register_operand" "2")) 17687 (use (match_operand:SI 3 "immediate_operand" "i")) 17688 (clobber (match_operand:P 0 "register_operand" "=S")) 17689 (clobber (match_operand:P 1 "register_operand" "=D")) 17690 (clobber (match_operand:P 2 "register_operand" "=c"))] 17691 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17692 && ix86_check_no_addr_space (insn)" 17693 "%^repz{%;} cmpsb" 17694 [(set_attr "type" "str") 17695 (set_attr "mode" "QI") 17696 (set (attr "prefix_rex") 17697 (if_then_else 17698 (match_test "<P:MODE>mode == DImode") 17699 (const_string "0") 17700 (const_string "*"))) 17701 (set_attr "prefix_rep" "1")]) 17702 17703;; The same, but the count is not known to not be zero. 17704 17705(define_expand "cmpstrnqi_1" 17706 [(parallel [(set (reg:CC FLAGS_REG) 17707 (if_then_else:CC (ne (match_operand 2 "register_operand") 17708 (const_int 0)) 17709 (compare:CC (match_operand 4 "memory_operand") 17710 (match_operand 5 "memory_operand")) 17711 (const_int 0))) 17712 (use (match_operand:SI 3 "immediate_operand")) 17713 (use (reg:CC FLAGS_REG)) 17714 (clobber (match_operand 0 "register_operand")) 17715 (clobber (match_operand 1 "register_operand")) 17716 (clobber (match_dup 2))])] 17717 "" 17718{ 17719 if (TARGET_CLD) 17720 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17721}) 17722 17723(define_insn "*cmpstrnqi_1" 17724 [(set (reg:CC FLAGS_REG) 17725 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2") 17726 (const_int 0)) 17727 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 17728 (mem:BLK (match_operand:P 5 "register_operand" "1"))) 17729 (const_int 0))) 17730 (use (match_operand:SI 3 "immediate_operand" "i")) 17731 (use (reg:CC FLAGS_REG)) 17732 (clobber (match_operand:P 0 "register_operand" "=S")) 17733 (clobber (match_operand:P 1 "register_operand" "=D")) 17734 (clobber (match_operand:P 2 "register_operand" "=c"))] 17735 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17736 && ix86_check_no_addr_space (insn)" 17737 "%^repz{%;} cmpsb" 17738 [(set_attr "type" "str") 17739 (set_attr "mode" "QI") 17740 (set (attr "prefix_rex") 17741 (if_then_else 17742 (match_test "<P:MODE>mode == DImode") 17743 (const_string "0") 17744 (const_string "*"))) 17745 (set_attr "prefix_rep" "1")]) 17746 17747(define_expand "strlen<mode>" 17748 [(set (match_operand:P 0 "register_operand") 17749 (unspec:P [(match_operand:BLK 1 "general_operand") 17750 (match_operand:QI 2 "immediate_operand") 17751 (match_operand 3 "immediate_operand")] 17752 UNSPEC_SCAS))] 17753 "" 17754{ 17755 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 17756 DONE; 17757 else 17758 FAIL; 17759}) 17760 17761(define_expand "strlenqi_1" 17762 [(parallel [(set (match_operand 0 "register_operand") 17763 (match_operand 2)) 17764 (clobber (match_operand 1 "register_operand")) 17765 (clobber (reg:CC FLAGS_REG))])] 17766 "" 17767{ 17768 if (TARGET_CLD) 17769 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17770}) 17771 17772(define_insn "*strlenqi_1" 17773 [(set (match_operand:P 0 "register_operand" "=&c") 17774 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1")) 17775 (match_operand:QI 2 "register_operand" "a") 17776 (match_operand:P 3 "immediate_operand" "i") 17777 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS)) 17778 (clobber (match_operand:P 1 "register_operand" "=D")) 17779 (clobber (reg:CC FLAGS_REG))] 17780 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17781 && ix86_check_no_addr_space (insn)" 17782 "%^repnz{%;} scasb" 17783 [(set_attr "type" "str") 17784 (set_attr "mode" "QI") 17785 (set (attr "prefix_rex") 17786 (if_then_else 17787 (match_test "<P:MODE>mode == DImode") 17788 (const_string "0") 17789 (const_string "*"))) 17790 (set_attr "prefix_rep" "1")]) 17791 17792;; Peephole optimizations to clean up after cmpstrn*. This should be 17793;; handled in combine, but it is not currently up to the task. 17794;; When used for their truth value, the cmpstrn* expanders generate 17795;; code like this: 17796;; 17797;; repz cmpsb 17798;; seta %al 17799;; setb %dl 17800;; cmpb %al, %dl 17801;; jcc label 17802;; 17803;; The intermediate three instructions are unnecessary. 17804 17805;; This one handles cmpstrn*_nz_1... 17806(define_peephole2 17807 [(parallel[ 17808 (set (reg:CC FLAGS_REG) 17809 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 17810 (mem:BLK (match_operand 5 "register_operand")))) 17811 (use (match_operand 6 "register_operand")) 17812 (use (match_operand:SI 3 "immediate_operand")) 17813 (clobber (match_operand 0 "register_operand")) 17814 (clobber (match_operand 1 "register_operand")) 17815 (clobber (match_operand 2 "register_operand"))]) 17816 (set (match_operand:QI 7 "register_operand") 17817 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17818 (set (match_operand:QI 8 "register_operand") 17819 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17820 (set (reg FLAGS_REG) 17821 (compare (match_dup 7) (match_dup 8))) 17822 ] 17823 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 17824 [(parallel[ 17825 (set (reg:CC FLAGS_REG) 17826 (compare:CC (mem:BLK (match_dup 4)) 17827 (mem:BLK (match_dup 5)))) 17828 (use (match_dup 6)) 17829 (use (match_dup 3)) 17830 (clobber (match_dup 0)) 17831 (clobber (match_dup 1)) 17832 (clobber (match_dup 2))])]) 17833 17834;; ...and this one handles cmpstrn*_1. 17835(define_peephole2 17836 [(parallel[ 17837 (set (reg:CC FLAGS_REG) 17838 (if_then_else:CC (ne (match_operand 6 "register_operand") 17839 (const_int 0)) 17840 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 17841 (mem:BLK (match_operand 5 "register_operand"))) 17842 (const_int 0))) 17843 (use (match_operand:SI 3 "immediate_operand")) 17844 (use (reg:CC FLAGS_REG)) 17845 (clobber (match_operand 0 "register_operand")) 17846 (clobber (match_operand 1 "register_operand")) 17847 (clobber (match_operand 2 "register_operand"))]) 17848 (set (match_operand:QI 7 "register_operand") 17849 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17850 (set (match_operand:QI 8 "register_operand") 17851 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17852 (set (reg FLAGS_REG) 17853 (compare (match_dup 7) (match_dup 8))) 17854 ] 17855 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 17856 [(parallel[ 17857 (set (reg:CC FLAGS_REG) 17858 (if_then_else:CC (ne (match_dup 6) 17859 (const_int 0)) 17860 (compare:CC (mem:BLK (match_dup 4)) 17861 (mem:BLK (match_dup 5))) 17862 (const_int 0))) 17863 (use (match_dup 3)) 17864 (use (reg:CC FLAGS_REG)) 17865 (clobber (match_dup 0)) 17866 (clobber (match_dup 1)) 17867 (clobber (match_dup 2))])]) 17868 17869;; Conditional move instructions. 17870 17871(define_expand "mov<mode>cc" 17872 [(set (match_operand:SWIM 0 "register_operand") 17873 (if_then_else:SWIM (match_operand 1 "comparison_operator") 17874 (match_operand:SWIM 2 "<general_operand>") 17875 (match_operand:SWIM 3 "<general_operand>")))] 17876 "" 17877 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") 17878 17879;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 17880;; the register first winds up with `sbbl $0,reg', which is also weird. 17881;; So just document what we're doing explicitly. 17882 17883(define_expand "x86_mov<mode>cc_0_m1" 17884 [(parallel 17885 [(set (match_operand:SWI48 0 "register_operand") 17886 (if_then_else:SWI48 17887 (match_operator:SWI48 2 "ix86_carry_flag_operator" 17888 [(match_operand 1 "flags_reg_operand") 17889 (const_int 0)]) 17890 (const_int -1) 17891 (const_int 0))) 17892 (clobber (reg:CC FLAGS_REG))])]) 17893 17894(define_insn "*x86_mov<mode>cc_0_m1" 17895 [(set (match_operand:SWI48 0 "register_operand" "=r") 17896 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17897 [(reg FLAGS_REG) (const_int 0)]) 17898 (const_int -1) 17899 (const_int 0))) 17900 (clobber (reg:CC FLAGS_REG))] 17901 "" 17902 "sbb{<imodesuffix>}\t%0, %0" 17903 ; Since we don't have the proper number of operands for an alu insn, 17904 ; fill in all the blanks. 17905 [(set_attr "type" "alu") 17906 (set_attr "modrm_class" "op0") 17907 (set_attr "use_carry" "1") 17908 (set_attr "pent_pair" "pu") 17909 (set_attr "memory" "none") 17910 (set_attr "imm_disp" "false") 17911 (set_attr "mode" "<MODE>") 17912 (set_attr "length_immediate" "0")]) 17913 17914(define_insn "*x86_mov<mode>cc_0_m1_se" 17915 [(set (match_operand:SWI48 0 "register_operand" "=r") 17916 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17917 [(reg FLAGS_REG) (const_int 0)]) 17918 (const_int 1) 17919 (const_int 0))) 17920 (clobber (reg:CC FLAGS_REG))] 17921 "" 17922 "sbb{<imodesuffix>}\t%0, %0" 17923 [(set_attr "type" "alu") 17924 (set_attr "modrm_class" "op0") 17925 (set_attr "use_carry" "1") 17926 (set_attr "pent_pair" "pu") 17927 (set_attr "memory" "none") 17928 (set_attr "imm_disp" "false") 17929 (set_attr "mode" "<MODE>") 17930 (set_attr "length_immediate" "0")]) 17931 17932(define_insn "*x86_mov<mode>cc_0_m1_neg" 17933 [(set (match_operand:SWI48 0 "register_operand" "=r") 17934 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17935 [(reg FLAGS_REG) (const_int 0)]))) 17936 (clobber (reg:CC FLAGS_REG))] 17937 "" 17938 "sbb{<imodesuffix>}\t%0, %0" 17939 [(set_attr "type" "alu") 17940 (set_attr "modrm_class" "op0") 17941 (set_attr "use_carry" "1") 17942 (set_attr "pent_pair" "pu") 17943 (set_attr "memory" "none") 17944 (set_attr "imm_disp" "false") 17945 (set_attr "mode" "<MODE>") 17946 (set_attr "length_immediate" "0")]) 17947 17948(define_insn "*mov<mode>cc_noc" 17949 [(set (match_operand:SWI248 0 "register_operand" "=r,r") 17950 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 17951 [(reg FLAGS_REG) (const_int 0)]) 17952 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0") 17953 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))] 17954 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 17955 "@ 17956 cmov%O2%C1\t{%2, %0|%0, %2} 17957 cmov%O2%c1\t{%3, %0|%0, %3}" 17958 [(set_attr "type" "icmov") 17959 (set_attr "mode" "<MODE>")]) 17960 17961(define_insn "*movsicc_noc_zext" 17962 [(set (match_operand:DI 0 "register_operand" "=r,r") 17963 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 17964 [(reg FLAGS_REG) (const_int 0)]) 17965 (zero_extend:DI 17966 (match_operand:SI 2 "nonimmediate_operand" "rm,0")) 17967 (zero_extend:DI 17968 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))] 17969 "TARGET_64BIT 17970 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 17971 "@ 17972 cmov%O2%C1\t{%2, %k0|%k0, %2} 17973 cmov%O2%c1\t{%3, %k0|%k0, %3}" 17974 [(set_attr "type" "icmov") 17975 (set_attr "mode" "SI")]) 17976 17977;; Don't do conditional moves with memory inputs. This splitter helps 17978;; register starved x86_32 by forcing inputs into registers before reload. 17979(define_split 17980 [(set (match_operand:SWI248 0 "register_operand") 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") 17984 (match_operand:SWI248 3 "nonimmediate_operand")))] 17985 "!TARGET_64BIT && TARGET_CMOVE 17986 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 17987 && (MEM_P (operands[2]) || MEM_P (operands[3])) 17988 && can_create_pseudo_p () 17989 && optimize_insn_for_speed_p ()" 17990 [(set (match_dup 0) 17991 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 17992{ 17993 if (MEM_P (operands[2])) 17994 operands[2] = force_reg (<MODE>mode, operands[2]); 17995 if (MEM_P (operands[3])) 17996 operands[3] = force_reg (<MODE>mode, operands[3]); 17997}) 17998 17999(define_insn "*movqicc_noc" 18000 [(set (match_operand:QI 0 "register_operand" "=r,r") 18001 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 18002 [(reg FLAGS_REG) (const_int 0)]) 18003 (match_operand:QI 2 "register_operand" "r,0") 18004 (match_operand:QI 3 "register_operand" "0,r")))] 18005 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 18006 "#" 18007 [(set_attr "type" "icmov") 18008 (set_attr "mode" "QI")]) 18009 18010(define_split 18011 [(set (match_operand:SWI12 0 "register_operand") 18012 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator" 18013 [(reg FLAGS_REG) (const_int 0)]) 18014 (match_operand:SWI12 2 "register_operand") 18015 (match_operand:SWI12 3 "register_operand")))] 18016 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL 18017 && reload_completed" 18018 [(set (match_dup 0) 18019 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 18020{ 18021 operands[0] = gen_lowpart (SImode, operands[0]); 18022 operands[2] = gen_lowpart (SImode, operands[2]); 18023 operands[3] = gen_lowpart (SImode, operands[3]); 18024}) 18025 18026;; Don't do conditional moves with memory inputs 18027(define_peephole2 18028 [(match_scratch:SWI248 4 "r") 18029 (set (match_operand:SWI248 0 "register_operand") 18030 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 18031 [(reg FLAGS_REG) (const_int 0)]) 18032 (match_operand:SWI248 2 "nonimmediate_operand") 18033 (match_operand:SWI248 3 "nonimmediate_operand")))] 18034 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18035 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18036 && optimize_insn_for_speed_p ()" 18037 [(set (match_dup 4) (match_dup 5)) 18038 (set (match_dup 0) 18039 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 18040{ 18041 if (MEM_P (operands[2])) 18042 { 18043 operands[5] = operands[2]; 18044 operands[2] = operands[4]; 18045 } 18046 else if (MEM_P (operands[3])) 18047 { 18048 operands[5] = operands[3]; 18049 operands[3] = operands[4]; 18050 } 18051 else 18052 gcc_unreachable (); 18053}) 18054 18055(define_peephole2 18056 [(match_scratch:SI 4 "r") 18057 (set (match_operand:DI 0 "register_operand") 18058 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 18059 [(reg FLAGS_REG) (const_int 0)]) 18060 (zero_extend:DI 18061 (match_operand:SI 2 "nonimmediate_operand")) 18062 (zero_extend:DI 18063 (match_operand:SI 3 "nonimmediate_operand"))))] 18064 "TARGET_64BIT 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:DI (match_dup 1) 18071 (zero_extend:DI (match_dup 2)) 18072 (zero_extend:DI (match_dup 3))))] 18073{ 18074 if (MEM_P (operands[2])) 18075 { 18076 operands[5] = operands[2]; 18077 operands[2] = operands[4]; 18078 } 18079 else if (MEM_P (operands[3])) 18080 { 18081 operands[5] = operands[3]; 18082 operands[3] = operands[4]; 18083 } 18084 else 18085 gcc_unreachable (); 18086}) 18087 18088(define_expand "mov<mode>cc" 18089 [(set (match_operand:X87MODEF 0 "register_operand") 18090 (if_then_else:X87MODEF 18091 (match_operand 1 "comparison_operator") 18092 (match_operand:X87MODEF 2 "register_operand") 18093 (match_operand:X87MODEF 3 "register_operand")))] 18094 "(TARGET_80387 && TARGET_CMOVE) 18095 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 18096 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;") 18097 18098(define_insn "*movxfcc_1" 18099 [(set (match_operand:XF 0 "register_operand" "=f,f") 18100 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 18101 [(reg FLAGS_REG) (const_int 0)]) 18102 (match_operand:XF 2 "register_operand" "f,0") 18103 (match_operand:XF 3 "register_operand" "0,f")))] 18104 "TARGET_80387 && TARGET_CMOVE" 18105 "@ 18106 fcmov%F1\t{%2, %0|%0, %2} 18107 fcmov%f1\t{%3, %0|%0, %3}" 18108 [(set_attr "type" "fcmov") 18109 (set_attr "mode" "XF")]) 18110 18111(define_insn "*movdfcc_1" 18112 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r") 18113 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18114 [(reg FLAGS_REG) (const_int 0)]) 18115 (match_operand:DF 2 "nonimmediate_operand" 18116 "f ,0,rm,0 ,rm,0") 18117 (match_operand:DF 3 "nonimmediate_operand" 18118 "0 ,f,0 ,rm,0, rm")))] 18119 "TARGET_80387 && TARGET_CMOVE 18120 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18121 "@ 18122 fcmov%F1\t{%2, %0|%0, %2} 18123 fcmov%f1\t{%3, %0|%0, %3} 18124 # 18125 # 18126 cmov%O2%C1\t{%2, %0|%0, %2} 18127 cmov%O2%c1\t{%3, %0|%0, %3}" 18128 [(set_attr "isa" "*,*,nox64,nox64,x64,x64") 18129 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov") 18130 (set_attr "mode" "DF,DF,DI,DI,DI,DI")]) 18131 18132(define_split 18133 [(set (match_operand:DF 0 "general_reg_operand") 18134 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18135 [(reg FLAGS_REG) (const_int 0)]) 18136 (match_operand:DF 2 "nonimmediate_operand") 18137 (match_operand:DF 3 "nonimmediate_operand")))] 18138 "!TARGET_64BIT && reload_completed" 18139 [(set (match_dup 2) 18140 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5))) 18141 (set (match_dup 3) 18142 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))] 18143{ 18144 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]); 18145 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]); 18146}) 18147 18148(define_insn "*movsfcc_1_387" 18149 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 18150 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 18151 [(reg FLAGS_REG) (const_int 0)]) 18152 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 18153 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 18154 "TARGET_80387 && TARGET_CMOVE 18155 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18156 "@ 18157 fcmov%F1\t{%2, %0|%0, %2} 18158 fcmov%f1\t{%3, %0|%0, %3} 18159 cmov%O2%C1\t{%2, %0|%0, %2} 18160 cmov%O2%c1\t{%3, %0|%0, %3}" 18161 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 18162 (set_attr "mode" "SF,SF,SI,SI")]) 18163 18164;; Don't do conditional moves with memory inputs. This splitter helps 18165;; register starved x86_32 by forcing inputs into registers before reload. 18166(define_split 18167 [(set (match_operand:MODEF 0 "register_operand") 18168 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator" 18169 [(reg FLAGS_REG) (const_int 0)]) 18170 (match_operand:MODEF 2 "nonimmediate_operand") 18171 (match_operand:MODEF 3 "nonimmediate_operand")))] 18172 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 18173 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18174 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18175 && can_create_pseudo_p () 18176 && optimize_insn_for_speed_p ()" 18177 [(set (match_dup 0) 18178 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 18179{ 18180 if (MEM_P (operands[2])) 18181 operands[2] = force_reg (<MODE>mode, operands[2]); 18182 if (MEM_P (operands[3])) 18183 operands[3] = force_reg (<MODE>mode, operands[3]); 18184}) 18185 18186;; Don't do conditional moves with memory inputs 18187(define_peephole2 18188 [(match_scratch:MODEF 4 "r") 18189 (set (match_operand:MODEF 0 "general_reg_operand") 18190 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator" 18191 [(reg FLAGS_REG) (const_int 0)]) 18192 (match_operand:MODEF 2 "nonimmediate_operand") 18193 (match_operand:MODEF 3 "nonimmediate_operand")))] 18194 "(<MODE>mode != DFmode || TARGET_64BIT) 18195 && TARGET_80387 && TARGET_CMOVE 18196 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18197 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18198 && optimize_insn_for_speed_p ()" 18199 [(set (match_dup 4) (match_dup 5)) 18200 (set (match_dup 0) 18201 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 18202{ 18203 if (MEM_P (operands[2])) 18204 { 18205 operands[5] = operands[2]; 18206 operands[2] = operands[4]; 18207 } 18208 else if (MEM_P (operands[3])) 18209 { 18210 operands[5] = operands[3]; 18211 operands[3] = operands[4]; 18212 } 18213 else 18214 gcc_unreachable (); 18215}) 18216 18217;; All moves in XOP pcmov instructions are 128 bits and hence we restrict 18218;; the scalar versions to have only XMM registers as operands. 18219 18220;; XOP conditional move 18221(define_insn "*xop_pcmov_<mode>" 18222 [(set (match_operand:MODEF 0 "register_operand" "=x") 18223 (if_then_else:MODEF 18224 (match_operand:MODEF 1 "register_operand" "x") 18225 (match_operand:MODEF 2 "register_operand" "x") 18226 (match_operand:MODEF 3 "register_operand" "x")))] 18227 "TARGET_XOP" 18228 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}" 18229 [(set_attr "type" "sse4arg")]) 18230 18231;; These versions of the min/max patterns are intentionally ignorant of 18232;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 18233;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 18234;; are undefined in this condition, we're certain this is correct. 18235 18236(define_insn "<code><mode>3" 18237 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 18238 (smaxmin:MODEF 18239 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v") 18240 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))] 18241 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 18242 "@ 18243 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2} 18244 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 18245 [(set_attr "isa" "noavx,avx") 18246 (set_attr "prefix" "orig,vex") 18247 (set_attr "type" "sseadd") 18248 (set_attr "mode" "<MODE>")]) 18249 18250;; These versions of the min/max patterns implement exactly the operations 18251;; min = (op1 < op2 ? op1 : op2) 18252;; max = (!(op1 < op2) ? op1 : op2) 18253;; Their operands are not commutative, and thus they may be used in the 18254;; presence of -0.0 and NaN. 18255 18256(define_insn "*ieee_s<ieee_maxmin><mode>3" 18257 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 18258 (unspec:MODEF 18259 [(match_operand:MODEF 1 "register_operand" "0,v") 18260 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")] 18261 IEEE_MAXMIN))] 18262 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 18263 "@ 18264 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2} 18265 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 18266 [(set_attr "isa" "noavx,avx") 18267 (set_attr "prefix" "orig,maybe_evex") 18268 (set_attr "type" "sseadd") 18269 (set_attr "mode" "<MODE>")]) 18270 18271;; Make two stack loads independent: 18272;; fld aa fld aa 18273;; fld %st(0) -> fld bb 18274;; fmul bb fmul %st(1), %st 18275;; 18276;; Actually we only match the last two instructions for simplicity. 18277 18278(define_peephole2 18279 [(set (match_operand 0 "fp_register_operand") 18280 (match_operand 1 "fp_register_operand")) 18281 (set (match_dup 0) 18282 (match_operator 2 "binary_fp_operator" 18283 [(match_dup 0) 18284 (match_operand 3 "memory_operand")]))] 18285 "REGNO (operands[0]) != REGNO (operands[1])" 18286 [(set (match_dup 0) (match_dup 3)) 18287 (set (match_dup 0) 18288 (match_op_dup 2 18289 [(match_dup 5) (match_dup 4)]))] 18290{ 18291 operands[4] = operands[0]; 18292 operands[5] = operands[1]; 18293 18294 /* The % modifier is not operational anymore in peephole2's, so we have to 18295 swap the operands manually in the case of addition and multiplication. */ 18296 if (COMMUTATIVE_ARITH_P (operands[2])) 18297 std::swap (operands[4], operands[5]); 18298}) 18299 18300(define_peephole2 18301 [(set (match_operand 0 "fp_register_operand") 18302 (match_operand 1 "fp_register_operand")) 18303 (set (match_dup 0) 18304 (match_operator 2 "binary_fp_operator" 18305 [(match_operand 3 "memory_operand") 18306 (match_dup 0)]))] 18307 "REGNO (operands[0]) != REGNO (operands[1])" 18308 [(set (match_dup 0) (match_dup 3)) 18309 (set (match_dup 0) 18310 (match_op_dup 2 18311 [(match_dup 4) (match_dup 5)]))] 18312{ 18313 operands[4] = operands[0]; 18314 operands[5] = operands[1]; 18315 18316 /* The % modifier is not operational anymore in peephole2's, so we have to 18317 swap the operands manually in the case of addition and multiplication. */ 18318 if (COMMUTATIVE_ARITH_P (operands[2])) 18319 std::swap (operands[4], operands[5]); 18320}) 18321 18322;; Conditional addition patterns 18323(define_expand "add<mode>cc" 18324 [(match_operand:SWI 0 "register_operand") 18325 (match_operand 1 "ordered_comparison_operator") 18326 (match_operand:SWI 2 "register_operand") 18327 (match_operand:SWI 3 "const_int_operand")] 18328 "" 18329 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;") 18330 18331;; Misc patterns (?) 18332 18333;; This pattern exists to put a dependency on all ebp-based memory accesses. 18334;; Otherwise there will be nothing to keep 18335;; 18336;; [(set (reg ebp) (reg esp))] 18337;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 18338;; (clobber (eflags)] 18339;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 18340;; 18341;; in proper program order. 18342 18343(define_insn "pro_epilogue_adjust_stack_<mode>_add" 18344 [(set (match_operand:P 0 "register_operand" "=r,r") 18345 (plus:P (match_operand:P 1 "register_operand" "0,r") 18346 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>"))) 18347 (clobber (reg:CC FLAGS_REG)) 18348 (clobber (mem:BLK (scratch)))] 18349 "" 18350{ 18351 switch (get_attr_type (insn)) 18352 { 18353 case TYPE_IMOV: 18354 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 18355 18356 case TYPE_ALU: 18357 gcc_assert (rtx_equal_p (operands[0], operands[1])); 18358 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 18359 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 18360 18361 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 18362 18363 default: 18364 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 18365 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}"; 18366 } 18367} 18368 [(set (attr "type") 18369 (cond [(and (eq_attr "alternative" "0") 18370 (not (match_test "TARGET_OPT_AGU"))) 18371 (const_string "alu") 18372 (match_operand:<MODE> 2 "const0_operand") 18373 (const_string "imov") 18374 ] 18375 (const_string "lea"))) 18376 (set (attr "length_immediate") 18377 (cond [(eq_attr "type" "imov") 18378 (const_string "0") 18379 (and (eq_attr "type" "alu") 18380 (match_operand 2 "const128_operand")) 18381 (const_string "1") 18382 ] 18383 (const_string "*"))) 18384 (set_attr "mode" "<MODE>")]) 18385 18386(define_insn "pro_epilogue_adjust_stack_<mode>_sub" 18387 [(set (match_operand:P 0 "register_operand" "=r") 18388 (minus:P (match_operand:P 1 "register_operand" "0") 18389 (match_operand:P 2 "register_operand" "r"))) 18390 (clobber (reg:CC FLAGS_REG)) 18391 (clobber (mem:BLK (scratch)))] 18392 "" 18393 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 18394 [(set_attr "type" "alu") 18395 (set_attr "mode" "<MODE>")]) 18396 18397(define_insn "allocate_stack_worker_probe_<mode>" 18398 [(set (match_operand:P 0 "register_operand" "=a") 18399 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 18400 UNSPECV_STACK_PROBE)) 18401 (clobber (reg:CC FLAGS_REG))] 18402 "ix86_target_stack_probe ()" 18403 "call\t___chkstk_ms" 18404 [(set_attr "type" "multi") 18405 (set_attr "length" "5")]) 18406 18407(define_expand "allocate_stack" 18408 [(match_operand 0 "register_operand") 18409 (match_operand 1 "general_operand")] 18410 "ix86_target_stack_probe ()" 18411{ 18412 rtx x; 18413 18414#ifndef CHECK_STACK_LIMIT 18415#define CHECK_STACK_LIMIT 0 18416#endif 18417 18418 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1]) 18419 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 18420 x = operands[1]; 18421 else 18422 { 18423 rtx (*insn) (rtx, rtx); 18424 18425 x = copy_to_mode_reg (Pmode, operands[1]); 18426 18427 insn = (TARGET_64BIT 18428 ? gen_allocate_stack_worker_probe_di 18429 : gen_allocate_stack_worker_probe_si); 18430 18431 emit_insn (insn (x, x)); 18432 } 18433 18434 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x, 18435 stack_pointer_rtx, 0, OPTAB_DIRECT); 18436 18437 if (x != stack_pointer_rtx) 18438 emit_move_insn (stack_pointer_rtx, x); 18439 18440 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 18441 DONE; 18442}) 18443 18444(define_expand "probe_stack" 18445 [(match_operand 0 "memory_operand")] 18446 "" 18447{ 18448 rtx (*insn) (rtx, rtx) 18449 = (GET_MODE (operands[0]) == DImode 18450 ? gen_probe_stack_di : gen_probe_stack_si); 18451 18452 emit_insn (insn (operands[0], const0_rtx)); 18453 DONE; 18454}) 18455 18456;; Use OR for stack probes, this is shorter. 18457(define_insn "probe_stack_<mode>" 18458 [(set (match_operand:W 0 "memory_operand" "=m") 18459 (unspec:W [(match_operand:W 1 "const0_operand")] 18460 UNSPEC_PROBE_STACK)) 18461 (clobber (reg:CC FLAGS_REG))] 18462 "" 18463 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 18464 [(set_attr "type" "alu1") 18465 (set_attr "mode" "<MODE>") 18466 (set_attr "length_immediate" "1")]) 18467 18468(define_insn "adjust_stack_and_probe<mode>" 18469 [(set (match_operand:P 0 "register_operand" "=r") 18470 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 18471 UNSPECV_PROBE_STACK_RANGE)) 18472 (set (reg:P SP_REG) 18473 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n"))) 18474 (clobber (reg:CC FLAGS_REG)) 18475 (clobber (mem:BLK (scratch)))] 18476 "" 18477 "* return output_adjust_stack_and_probe (operands[0]);" 18478 [(set_attr "type" "multi")]) 18479 18480(define_insn "probe_stack_range<mode>" 18481 [(set (match_operand:P 0 "register_operand" "=r") 18482 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 18483 (match_operand:P 2 "const_int_operand" "n")] 18484 UNSPECV_PROBE_STACK_RANGE)) 18485 (clobber (reg:CC FLAGS_REG))] 18486 "" 18487 "* return output_probe_stack_range (operands[0], operands[2]);" 18488 [(set_attr "type" "multi")]) 18489 18490(define_expand "builtin_setjmp_receiver" 18491 [(label_ref (match_operand 0))] 18492 "!TARGET_64BIT && flag_pic" 18493{ 18494#if TARGET_MACHO 18495 if (TARGET_MACHO) 18496 { 18497 rtx xops[3]; 18498 rtx_code_label *label_rtx = gen_label_rtx (); 18499 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 18500 xops[0] = xops[1] = pic_offset_table_rtx; 18501 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx)); 18502 ix86_expand_binary_operator (MINUS, SImode, xops); 18503 } 18504 else 18505#endif 18506 emit_insn (gen_set_got (pic_offset_table_rtx)); 18507 DONE; 18508}) 18509 18510(define_expand "save_stack_nonlocal" 18511 [(set (match_operand 0 "memory_operand") 18512 (match_operand 1 "register_operand"))] 18513 "" 18514{ 18515 rtx stack_slot; 18516 if ((flag_cf_protection & CF_RETURN)) 18517 { 18518 /* Copy shadow stack pointer to the first slot and stack ppointer 18519 to the second slot. */ 18520 rtx ssp_slot = adjust_address (operands[0], word_mode, 0); 18521 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD); 18522 rtx ssp = gen_reg_rtx (word_mode); 18523 emit_insn ((word_mode == SImode) 18524 ? gen_rdsspsi (ssp) 18525 : gen_rdsspdi (ssp)); 18526 emit_move_insn (ssp_slot, ssp); 18527 } 18528 else 18529 stack_slot = adjust_address (operands[0], Pmode, 0); 18530 emit_move_insn (stack_slot, operands[1]); 18531 DONE; 18532}) 18533 18534(define_expand "restore_stack_nonlocal" 18535 [(set (match_operand 0 "register_operand" "") 18536 (match_operand 1 "memory_operand" ""))] 18537 "" 18538{ 18539 rtx stack_slot; 18540 if ((flag_cf_protection & CF_RETURN)) 18541 { 18542 /* Restore shadow stack pointer from the first slot and stack 18543 pointer from the second slot. */ 18544 rtx ssp_slot = adjust_address (operands[1], word_mode, 0); 18545 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD); 18546 18547 rtx flags, jump, noadj_label, inc_label, loop_label; 18548 rtx reg_adj, reg_ssp, tmp, clob; 18549 18550 /* Get the current shadow stack pointer. The code below will check if 18551 SHSTK feature is enabled. If it is not enabled the RDSSP instruction 18552 is a NOP. */ 18553 reg_ssp = gen_reg_rtx (word_mode); 18554 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx)); 18555 emit_insn ((word_mode == SImode) 18556 ? gen_rdsspsi (reg_ssp) 18557 : gen_rdsspdi (reg_ssp)); 18558 18559 /* Compare through substraction the saved and the current ssp to decide 18560 if ssp has to be adjusted. */ 18561 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp, 18562 ssp_slot)); 18563 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18564 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18565 emit_insn (tmp); 18566 18567 /* Compare and jump over adjustment code. */ 18568 noadj_label = gen_label_rtx (); 18569 flags = gen_rtx_REG (CCZmode, FLAGS_REG); 18570 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx); 18571 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18572 gen_rtx_LABEL_REF (VOIDmode, noadj_label), 18573 pc_rtx); 18574 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18575 JUMP_LABEL (jump) = noadj_label; 18576 18577 /* Compute the numebr of frames to adjust. */ 18578 reg_adj = gen_lowpart (ptr_mode, reg_ssp); 18579 tmp = gen_rtx_SET (reg_adj, 18580 gen_rtx_LSHIFTRT (ptr_mode, 18581 negate_rtx (ptr_mode, reg_adj), 18582 GEN_INT ((word_mode == SImode) 18583 ? 2 18584 : 3))); 18585 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18586 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18587 emit_insn (tmp); 18588 18589 /* Check if number of frames <= 255 so no loop is needed. */ 18590 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255)); 18591 flags = gen_rtx_REG (CCmode, FLAGS_REG); 18592 emit_insn (gen_rtx_SET (flags, tmp)); 18593 18594 inc_label = gen_label_rtx (); 18595 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx); 18596 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18597 gen_rtx_LABEL_REF (VOIDmode, inc_label), 18598 pc_rtx); 18599 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18600 JUMP_LABEL (jump) = inc_label; 18601 18602 rtx reg_255 = gen_reg_rtx (word_mode); 18603 emit_move_insn (reg_255, GEN_INT (255)); 18604 18605 /* Adjust the ssp in a loop. */ 18606 loop_label = gen_label_rtx (); 18607 emit_label (loop_label); 18608 LABEL_NUSES (loop_label) = 1; 18609 18610 emit_insn ((word_mode == SImode) 18611 ? gen_incsspsi (reg_255) 18612 : gen_incsspdi (reg_255)); 18613 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode, 18614 reg_adj, 18615 GEN_INT (255))); 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 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255)); 18621 flags = gen_rtx_REG (CCmode, FLAGS_REG); 18622 emit_insn (gen_rtx_SET (flags, tmp)); 18623 18624 /* Jump to the loop label. */ 18625 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx); 18626 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18627 gen_rtx_LABEL_REF (VOIDmode, loop_label), 18628 pc_rtx); 18629 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18630 JUMP_LABEL (jump) = loop_label; 18631 18632 emit_label (inc_label); 18633 LABEL_NUSES (inc_label) = 1; 18634 emit_insn ((word_mode == SImode) 18635 ? gen_incsspsi (reg_ssp) 18636 : gen_incsspdi (reg_ssp)); 18637 18638 emit_label (noadj_label); 18639 LABEL_NUSES (noadj_label) = 1; 18640 } 18641 else 18642 stack_slot = adjust_address (operands[1], Pmode, 0); 18643 emit_move_insn (operands[0], stack_slot); 18644 DONE; 18645}) 18646 18647 18648;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 18649;; Do not split instructions with mask registers. 18650(define_split 18651 [(set (match_operand 0 "general_reg_operand") 18652 (match_operator 3 "promotable_binary_operator" 18653 [(match_operand 1 "general_reg_operand") 18654 (match_operand 2 "aligned_operand")])) 18655 (clobber (reg:CC FLAGS_REG))] 18656 "! TARGET_PARTIAL_REG_STALL && reload_completed 18657 && ((GET_MODE (operands[0]) == HImode 18658 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX) 18659 /* ??? next two lines just !satisfies_constraint_K (...) */ 18660 || !CONST_INT_P (operands[2]) 18661 || satisfies_constraint_K (operands[2]))) 18662 || (GET_MODE (operands[0]) == QImode 18663 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))" 18664 [(parallel [(set (match_dup 0) 18665 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 18666 (clobber (reg:CC FLAGS_REG))])] 18667{ 18668 operands[0] = gen_lowpart (SImode, operands[0]); 18669 operands[1] = gen_lowpart (SImode, operands[1]); 18670 if (GET_CODE (operands[3]) != ASHIFT) 18671 operands[2] = gen_lowpart (SImode, operands[2]); 18672 operands[3] = shallow_copy_rtx (operands[3]); 18673 PUT_MODE (operands[3], SImode); 18674}) 18675 18676; Promote the QImode tests, as i386 has encoding of the AND 18677; instruction with 32-bit sign-extended immediate and thus the 18678; instruction size is unchanged, except in the %eax case for 18679; which it is increased by one byte, hence the ! optimize_size. 18680(define_split 18681 [(set (match_operand 0 "flags_reg_operand") 18682 (match_operator 2 "compare_operator" 18683 [(and (match_operand 3 "aligned_operand") 18684 (match_operand 4 "const_int_operand")) 18685 (const_int 0)])) 18686 (set (match_operand 1 "register_operand") 18687 (and (match_dup 3) (match_dup 4)))] 18688 "! TARGET_PARTIAL_REG_STALL && reload_completed 18689 && optimize_insn_for_speed_p () 18690 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 18691 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode)) 18692 /* Ensure that the operand will remain sign-extended immediate. */ 18693 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)" 18694 [(parallel [(set (match_dup 0) 18695 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 18696 (const_int 0)])) 18697 (set (match_dup 1) 18698 (and:SI (match_dup 3) (match_dup 4)))])] 18699{ 18700 operands[4] 18701 = gen_int_mode (INTVAL (operands[4]) 18702 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 18703 operands[1] = gen_lowpart (SImode, operands[1]); 18704 operands[3] = gen_lowpart (SImode, operands[3]); 18705}) 18706 18707; Don't promote the QImode tests, as i386 doesn't have encoding of 18708; the TEST instruction with 32-bit sign-extended immediate and thus 18709; the instruction size would at least double, which is not what we 18710; want even with ! optimize_size. 18711(define_split 18712 [(set (match_operand 0 "flags_reg_operand") 18713 (match_operator 1 "compare_operator" 18714 [(and (match_operand:HI 2 "aligned_operand") 18715 (match_operand:HI 3 "const_int_operand")) 18716 (const_int 0)]))] 18717 "! TARGET_PARTIAL_REG_STALL && reload_completed 18718 && ! TARGET_FAST_PREFIX 18719 && optimize_insn_for_speed_p () 18720 /* Ensure that the operand will remain sign-extended immediate. */ 18721 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)" 18722 [(set (match_dup 0) 18723 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 18724 (const_int 0)]))] 18725{ 18726 operands[3] 18727 = gen_int_mode (INTVAL (operands[3]) 18728 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 18729 operands[2] = gen_lowpart (SImode, operands[2]); 18730}) 18731 18732(define_split 18733 [(set (match_operand 0 "register_operand") 18734 (neg (match_operand 1 "register_operand"))) 18735 (clobber (reg:CC FLAGS_REG))] 18736 "! TARGET_PARTIAL_REG_STALL && reload_completed 18737 && (GET_MODE (operands[0]) == HImode 18738 || (GET_MODE (operands[0]) == QImode 18739 && (TARGET_PROMOTE_QImode 18740 || optimize_insn_for_size_p ())))" 18741 [(parallel [(set (match_dup 0) 18742 (neg:SI (match_dup 1))) 18743 (clobber (reg:CC FLAGS_REG))])] 18744{ 18745 operands[0] = gen_lowpart (SImode, operands[0]); 18746 operands[1] = gen_lowpart (SImode, operands[1]); 18747}) 18748 18749;; Do not split instructions with mask regs. 18750(define_split 18751 [(set (match_operand 0 "general_reg_operand") 18752 (not (match_operand 1 "general_reg_operand")))] 18753 "! TARGET_PARTIAL_REG_STALL && reload_completed 18754 && (GET_MODE (operands[0]) == HImode 18755 || (GET_MODE (operands[0]) == QImode 18756 && (TARGET_PROMOTE_QImode 18757 || optimize_insn_for_size_p ())))" 18758 [(set (match_dup 0) 18759 (not:SI (match_dup 1)))] 18760{ 18761 operands[0] = gen_lowpart (SImode, operands[0]); 18762 operands[1] = gen_lowpart (SImode, operands[1]); 18763}) 18764 18765;; RTL Peephole optimizations, run before sched2. These primarily look to 18766;; transform a complex memory operation into two memory to register operations. 18767 18768;; Don't push memory operands 18769(define_peephole2 18770 [(set (match_operand:SWI 0 "push_operand") 18771 (match_operand:SWI 1 "memory_operand")) 18772 (match_scratch:SWI 2 "<r>")] 18773 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 18774 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 18775 [(set (match_dup 2) (match_dup 1)) 18776 (set (match_dup 0) (match_dup 2))]) 18777 18778;; We need to handle SFmode only, because DFmode and XFmode are split to 18779;; SImode pushes. 18780(define_peephole2 18781 [(set (match_operand:SF 0 "push_operand") 18782 (match_operand:SF 1 "memory_operand")) 18783 (match_scratch:SF 2 "r")] 18784 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 18785 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 18786 [(set (match_dup 2) (match_dup 1)) 18787 (set (match_dup 0) (match_dup 2))]) 18788 18789;; Don't move an immediate directly to memory when the instruction 18790;; gets too big, or if LCP stalls are a problem for 16-bit moves. 18791(define_peephole2 18792 [(match_scratch:SWI124 1 "<r>") 18793 (set (match_operand:SWI124 0 "memory_operand") 18794 (const_int 0))] 18795 "optimize_insn_for_speed_p () 18796 && ((<MODE>mode == HImode 18797 && TARGET_LCP_STALL) 18798 || (!TARGET_USE_MOV0 18799 && TARGET_SPLIT_LONG_MOVES 18800 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn)) 18801 && peep2_regno_dead_p (0, FLAGS_REG)" 18802 [(parallel [(set (match_dup 2) (const_int 0)) 18803 (clobber (reg:CC FLAGS_REG))]) 18804 (set (match_dup 0) (match_dup 1))] 18805 "operands[2] = gen_lowpart (SImode, operands[1]);") 18806 18807(define_peephole2 18808 [(match_scratch:SWI124 2 "<r>") 18809 (set (match_operand:SWI124 0 "memory_operand") 18810 (match_operand:SWI124 1 "immediate_operand"))] 18811 "optimize_insn_for_speed_p () 18812 && ((<MODE>mode == HImode 18813 && TARGET_LCP_STALL) 18814 || (TARGET_SPLIT_LONG_MOVES 18815 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))" 18816 [(set (match_dup 2) (match_dup 1)) 18817 (set (match_dup 0) (match_dup 2))]) 18818 18819;; Don't compare memory with zero, load and use a test instead. 18820(define_peephole2 18821 [(set (match_operand 0 "flags_reg_operand") 18822 (match_operator 1 "compare_operator" 18823 [(match_operand:SI 2 "memory_operand") 18824 (const_int 0)])) 18825 (match_scratch:SI 3 "r")] 18826 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)" 18827 [(set (match_dup 3) (match_dup 2)) 18828 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]) 18829 18830;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 18831;; Don't split NOTs with a displacement operand, because resulting XOR 18832;; will not be pairable anyway. 18833;; 18834;; On AMD K6, NOT is vector decoded with memory operand that cannot be 18835;; represented using a modRM byte. The XOR replacement is long decoded, 18836;; so this split helps here as well. 18837;; 18838;; Note: Can't do this as a regular split because we can't get proper 18839;; lifetime information then. 18840 18841(define_peephole2 18842 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand") 18843 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))] 18844 "optimize_insn_for_speed_p () 18845 && ((TARGET_NOT_UNPAIRABLE 18846 && (!MEM_P (operands[0]) 18847 || !memory_displacement_operand (operands[0], <MODE>mode))) 18848 || (TARGET_NOT_VECTORMODE 18849 && long_memory_operand (operands[0], <MODE>mode))) 18850 && peep2_regno_dead_p (0, FLAGS_REG)" 18851 [(parallel [(set (match_dup 0) 18852 (xor:SWI124 (match_dup 1) (const_int -1))) 18853 (clobber (reg:CC FLAGS_REG))])]) 18854 18855;; Non pairable "test imm, reg" instructions can be translated to 18856;; "and imm, reg" if reg dies. The "and" form is also shorter (one 18857;; byte opcode instead of two, have a short form for byte operands), 18858;; so do it for other CPUs as well. Given that the value was dead, 18859;; this should not create any new dependencies. Pass on the sub-word 18860;; versions if we're concerned about partial register stalls. 18861 18862(define_peephole2 18863 [(set (match_operand 0 "flags_reg_operand") 18864 (match_operator 1 "compare_operator" 18865 [(and:SI (match_operand:SI 2 "register_operand") 18866 (match_operand:SI 3 "immediate_operand")) 18867 (const_int 0)]))] 18868 "ix86_match_ccmode (insn, CCNOmode) 18869 && (REGNO (operands[2]) != AX_REG 18870 || satisfies_constraint_K (operands[3])) 18871 && peep2_reg_dead_p (1, operands[2])" 18872 [(parallel 18873 [(set (match_dup 0) 18874 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 18875 (const_int 0)])) 18876 (set (match_dup 2) 18877 (and:SI (match_dup 2) (match_dup 3)))])]) 18878 18879;; We don't need to handle HImode case, because it will be promoted to SImode 18880;; on ! TARGET_PARTIAL_REG_STALL 18881 18882(define_peephole2 18883 [(set (match_operand 0 "flags_reg_operand") 18884 (match_operator 1 "compare_operator" 18885 [(and:QI (match_operand:QI 2 "register_operand") 18886 (match_operand:QI 3 "immediate_operand")) 18887 (const_int 0)]))] 18888 "! TARGET_PARTIAL_REG_STALL 18889 && ix86_match_ccmode (insn, CCNOmode) 18890 && REGNO (operands[2]) != AX_REG 18891 && peep2_reg_dead_p (1, operands[2])" 18892 [(parallel 18893 [(set (match_dup 0) 18894 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 18895 (const_int 0)])) 18896 (set (match_dup 2) 18897 (and:QI (match_dup 2) (match_dup 3)))])]) 18898 18899(define_peephole2 18900 [(set (match_operand 0 "flags_reg_operand") 18901 (match_operator 1 "compare_operator" 18902 [(and:QI 18903 (subreg:QI 18904 (zero_extract:SI (match_operand 2 "QIreg_operand") 18905 (const_int 8) 18906 (const_int 8)) 0) 18907 (match_operand 3 "const_int_operand")) 18908 (const_int 0)]))] 18909 "! TARGET_PARTIAL_REG_STALL 18910 && ix86_match_ccmode (insn, CCNOmode) 18911 && REGNO (operands[2]) != AX_REG 18912 && peep2_reg_dead_p (1, operands[2])" 18913 [(parallel 18914 [(set (match_dup 0) 18915 (match_op_dup 1 18916 [(and:QI 18917 (subreg:QI 18918 (zero_extract:SI (match_dup 2) 18919 (const_int 8) 18920 (const_int 8)) 0) 18921 (match_dup 3)) 18922 (const_int 0)])) 18923 (set (zero_extract:SI (match_dup 2) 18924 (const_int 8) 18925 (const_int 8)) 18926 (subreg:SI 18927 (and:QI 18928 (subreg:QI 18929 (zero_extract:SI (match_dup 2) 18930 (const_int 8) 18931 (const_int 8)) 0) 18932 (match_dup 3)) 0))])]) 18933 18934;; Don't do logical operations with memory inputs. 18935(define_peephole2 18936 [(match_scratch:SWI 2 "<r>") 18937 (parallel [(set (match_operand:SWI 0 "register_operand") 18938 (match_operator:SWI 3 "arith_or_logical_operator" 18939 [(match_dup 0) 18940 (match_operand:SWI 1 "memory_operand")])) 18941 (clobber (reg:CC FLAGS_REG))])] 18942 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 18943 [(set (match_dup 2) (match_dup 1)) 18944 (parallel [(set (match_dup 0) 18945 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 18946 (clobber (reg:CC FLAGS_REG))])]) 18947 18948(define_peephole2 18949 [(match_scratch:SWI 2 "<r>") 18950 (parallel [(set (match_operand:SWI 0 "register_operand") 18951 (match_operator:SWI 3 "arith_or_logical_operator" 18952 [(match_operand:SWI 1 "memory_operand") 18953 (match_dup 0)])) 18954 (clobber (reg:CC FLAGS_REG))])] 18955 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 18956 [(set (match_dup 2) (match_dup 1)) 18957 (parallel [(set (match_dup 0) 18958 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 18959 (clobber (reg:CC FLAGS_REG))])]) 18960 18961;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when 18962;; the memory address refers to the destination of the load! 18963 18964(define_peephole2 18965 [(set (match_operand:SWI 0 "general_reg_operand") 18966 (match_operand:SWI 1 "general_reg_operand")) 18967 (parallel [(set (match_dup 0) 18968 (match_operator:SWI 3 "commutative_operator" 18969 [(match_dup 0) 18970 (match_operand:SWI 2 "memory_operand")])) 18971 (clobber (reg:CC FLAGS_REG))])] 18972 "REGNO (operands[0]) != REGNO (operands[1]) 18973 && (<MODE>mode != QImode 18974 || any_QIreg_operand (operands[1], QImode))" 18975 [(set (match_dup 0) (match_dup 4)) 18976 (parallel [(set (match_dup 0) 18977 (match_op_dup 3 [(match_dup 0) (match_dup 1)])) 18978 (clobber (reg:CC FLAGS_REG))])] 18979 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);") 18980 18981(define_peephole2 18982 [(set (match_operand 0 "mmx_reg_operand") 18983 (match_operand 1 "mmx_reg_operand")) 18984 (set (match_dup 0) 18985 (match_operator 3 "commutative_operator" 18986 [(match_dup 0) 18987 (match_operand 2 "memory_operand")]))] 18988 "REGNO (operands[0]) != REGNO (operands[1])" 18989 [(set (match_dup 0) (match_dup 2)) 18990 (set (match_dup 0) 18991 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 18992 18993(define_peephole2 18994 [(set (match_operand 0 "sse_reg_operand") 18995 (match_operand 1 "sse_reg_operand")) 18996 (set (match_dup 0) 18997 (match_operator 3 "commutative_operator" 18998 [(match_dup 0) 18999 (match_operand 2 "memory_operand")]))] 19000 "REGNO (operands[0]) != REGNO (operands[1])" 19001 [(set (match_dup 0) (match_dup 2)) 19002 (set (match_dup 0) 19003 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 19004 19005; Don't do logical operations with memory outputs 19006; 19007; These two don't make sense for PPro/PII -- we're expanding a 4-uop 19008; instruction into two 1-uop insns plus a 2-uop insn. That last has 19009; the same decoder scheduling characteristics as the original. 19010 19011(define_peephole2 19012 [(match_scratch:SWI 2 "<r>") 19013 (parallel [(set (match_operand:SWI 0 "memory_operand") 19014 (match_operator:SWI 3 "arith_or_logical_operator" 19015 [(match_dup 0) 19016 (match_operand:SWI 1 "<nonmemory_operand>")])) 19017 (clobber (reg:CC FLAGS_REG))])] 19018 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())" 19019 [(set (match_dup 2) (match_dup 0)) 19020 (parallel [(set (match_dup 2) 19021 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 19022 (clobber (reg:CC FLAGS_REG))]) 19023 (set (match_dup 0) (match_dup 2))]) 19024 19025(define_peephole2 19026 [(match_scratch:SWI 2 "<r>") 19027 (parallel [(set (match_operand:SWI 0 "memory_operand") 19028 (match_operator:SWI 3 "arith_or_logical_operator" 19029 [(match_operand:SWI 1 "<nonmemory_operand>") 19030 (match_dup 0)])) 19031 (clobber (reg:CC FLAGS_REG))])] 19032 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())" 19033 [(set (match_dup 2) (match_dup 0)) 19034 (parallel [(set (match_dup 2) 19035 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19036 (clobber (reg:CC FLAGS_REG))]) 19037 (set (match_dup 0) (match_dup 2))]) 19038 19039;; Attempt to use arith or logical operations with memory outputs with 19040;; setting of flags. 19041(define_peephole2 19042 [(set (match_operand:SWI 0 "register_operand") 19043 (match_operand:SWI 1 "memory_operand")) 19044 (parallel [(set (match_dup 0) 19045 (match_operator:SWI 3 "plusminuslogic_operator" 19046 [(match_dup 0) 19047 (match_operand:SWI 2 "<nonmemory_operand>")])) 19048 (clobber (reg:CC FLAGS_REG))]) 19049 (set (match_dup 1) (match_dup 0)) 19050 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19051 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19052 && peep2_reg_dead_p (4, operands[0]) 19053 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19054 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19055 && (<MODE>mode != QImode 19056 || immediate_operand (operands[2], QImode) 19057 || any_QIreg_operand (operands[2], QImode)) 19058 && ix86_match_ccmode (peep2_next_insn (3), 19059 (GET_CODE (operands[3]) == PLUS 19060 || GET_CODE (operands[3]) == MINUS) 19061 ? CCGOCmode : CCNOmode)" 19062 [(parallel [(set (match_dup 4) (match_dup 6)) 19063 (set (match_dup 1) (match_dup 5))])] 19064{ 19065 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19066 operands[5] 19067 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19068 copy_rtx (operands[1]), 19069 operands[2]); 19070 operands[6] 19071 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19072 copy_rtx (operands[5]), 19073 const0_rtx); 19074}) 19075 19076;; Likewise for instances where we have a lea pattern. 19077(define_peephole2 19078 [(set (match_operand:SWI 0 "register_operand") 19079 (match_operand:SWI 1 "memory_operand")) 19080 (set (match_operand:SWI 3 "register_operand") 19081 (plus:SWI (match_dup 0) 19082 (match_operand:SWI 2 "<nonmemory_operand>"))) 19083 (set (match_dup 1) (match_dup 3)) 19084 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))] 19085 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19086 && peep2_reg_dead_p (4, operands[3]) 19087 && (rtx_equal_p (operands[0], operands[3]) 19088 || peep2_reg_dead_p (2, operands[0])) 19089 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19090 && !reg_overlap_mentioned_p (operands[3], operands[1]) 19091 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19092 && (<MODE>mode != QImode 19093 || immediate_operand (operands[2], QImode) 19094 || any_QIreg_operand (operands[2], QImode)) 19095 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)" 19096 [(parallel [(set (match_dup 4) (match_dup 6)) 19097 (set (match_dup 1) (match_dup 5))])] 19098{ 19099 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19100 operands[5] 19101 = gen_rtx_PLUS (<MODE>mode, 19102 copy_rtx (operands[1]), 19103 operands[2]); 19104 operands[6] 19105 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19106 copy_rtx (operands[5]), 19107 const0_rtx); 19108}) 19109 19110(define_peephole2 19111 [(parallel [(set (match_operand:SWI 0 "register_operand") 19112 (match_operator:SWI 2 "plusminuslogic_operator" 19113 [(match_dup 0) 19114 (match_operand:SWI 1 "memory_operand")])) 19115 (clobber (reg:CC FLAGS_REG))]) 19116 (set (match_dup 1) (match_dup 0)) 19117 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19118 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19119 && GET_CODE (operands[2]) != MINUS 19120 && peep2_reg_dead_p (3, operands[0]) 19121 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19122 && ix86_match_ccmode (peep2_next_insn (2), 19123 GET_CODE (operands[2]) == PLUS 19124 ? CCGOCmode : CCNOmode)" 19125 [(parallel [(set (match_dup 3) (match_dup 5)) 19126 (set (match_dup 1) (match_dup 4))])] 19127{ 19128 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); 19129 operands[4] 19130 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19131 copy_rtx (operands[1]), 19132 operands[0]); 19133 operands[5] 19134 = gen_rtx_COMPARE (GET_MODE (operands[3]), 19135 copy_rtx (operands[4]), 19136 const0_rtx); 19137}) 19138 19139(define_peephole2 19140 [(set (match_operand:SWI12 0 "register_operand") 19141 (match_operand:SWI12 1 "memory_operand")) 19142 (parallel [(set (match_operand:SI 4 "register_operand") 19143 (match_operator:SI 3 "plusminuslogic_operator" 19144 [(match_dup 4) 19145 (match_operand:SI 2 "nonmemory_operand")])) 19146 (clobber (reg:CC FLAGS_REG))]) 19147 (set (match_dup 1) (match_dup 0)) 19148 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19149 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19150 && REGNO (operands[0]) == REGNO (operands[4]) 19151 && peep2_reg_dead_p (4, operands[0]) 19152 && (<MODE>mode != QImode 19153 || immediate_operand (operands[2], SImode) 19154 || any_QIreg_operand (operands[2], SImode)) 19155 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19156 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19157 && ix86_match_ccmode (peep2_next_insn (3), 19158 (GET_CODE (operands[3]) == PLUS 19159 || GET_CODE (operands[3]) == MINUS) 19160 ? CCGOCmode : CCNOmode)" 19161 [(parallel [(set (match_dup 4) (match_dup 6)) 19162 (set (match_dup 1) (match_dup 5))])] 19163{ 19164 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19165 operands[5] 19166 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 19167 copy_rtx (operands[1]), 19168 gen_lowpart (<MODE>mode, operands[2])); 19169 operands[6] 19170 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19171 copy_rtx (operands[5]), 19172 const0_rtx); 19173}) 19174 19175;; Attempt to always use XOR for zeroing registers (including FP modes). 19176(define_peephole2 19177 [(set (match_operand 0 "general_reg_operand") 19178 (match_operand 1 "const0_operand"))] 19179 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 19180 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 19181 && peep2_regno_dead_p (0, FLAGS_REG)" 19182 [(parallel [(set (match_dup 0) (const_int 0)) 19183 (clobber (reg:CC FLAGS_REG))])] 19184 "operands[0] = gen_lowpart (word_mode, operands[0]);") 19185 19186(define_peephole2 19187 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand")) 19188 (const_int 0))] 19189 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 19190 && peep2_regno_dead_p (0, FLAGS_REG)" 19191 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 19192 (clobber (reg:CC FLAGS_REG))])]) 19193 19194;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg. 19195(define_peephole2 19196 [(set (match_operand:SWI248 0 "general_reg_operand") 19197 (const_int -1))] 19198 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ()) 19199 && peep2_regno_dead_p (0, FLAGS_REG)" 19200 [(parallel [(set (match_dup 0) (const_int -1)) 19201 (clobber (reg:CC FLAGS_REG))])] 19202{ 19203 if (<MODE_SIZE> < GET_MODE_SIZE (SImode)) 19204 operands[0] = gen_lowpart (SImode, operands[0]); 19205}) 19206 19207;; Attempt to convert simple lea to add/shift. 19208;; These can be created by move expanders. 19209;; Disable PLUS peepholes on TARGET_OPT_AGU, since all 19210;; relevant lea instructions were already split. 19211 19212(define_peephole2 19213 [(set (match_operand:SWI48 0 "register_operand") 19214 (plus:SWI48 (match_dup 0) 19215 (match_operand:SWI48 1 "<nonmemory_operand>")))] 19216 "!TARGET_OPT_AGU 19217 && peep2_regno_dead_p (0, FLAGS_REG)" 19218 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 19219 (clobber (reg:CC FLAGS_REG))])]) 19220 19221(define_peephole2 19222 [(set (match_operand:SWI48 0 "register_operand") 19223 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>") 19224 (match_dup 0)))] 19225 "!TARGET_OPT_AGU 19226 && peep2_regno_dead_p (0, FLAGS_REG)" 19227 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 19228 (clobber (reg:CC FLAGS_REG))])]) 19229 19230(define_peephole2 19231 [(set (match_operand:DI 0 "register_operand") 19232 (zero_extend:DI 19233 (plus:SI (match_operand:SI 1 "register_operand") 19234 (match_operand:SI 2 "nonmemory_operand"))))] 19235 "TARGET_64BIT && !TARGET_OPT_AGU 19236 && REGNO (operands[0]) == REGNO (operands[1]) 19237 && peep2_regno_dead_p (0, FLAGS_REG)" 19238 [(parallel [(set (match_dup 0) 19239 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))) 19240 (clobber (reg:CC FLAGS_REG))])]) 19241 19242(define_peephole2 19243 [(set (match_operand:DI 0 "register_operand") 19244 (zero_extend:DI 19245 (plus:SI (match_operand:SI 1 "nonmemory_operand") 19246 (match_operand:SI 2 "register_operand"))))] 19247 "TARGET_64BIT && !TARGET_OPT_AGU 19248 && REGNO (operands[0]) == REGNO (operands[2]) 19249 && peep2_regno_dead_p (0, FLAGS_REG)" 19250 [(parallel [(set (match_dup 0) 19251 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1)))) 19252 (clobber (reg:CC FLAGS_REG))])]) 19253 19254(define_peephole2 19255 [(set (match_operand:SWI48 0 "register_operand") 19256 (mult:SWI48 (match_dup 0) 19257 (match_operand:SWI48 1 "const_int_operand")))] 19258 "pow2p_hwi (INTVAL (operands[1])) 19259 && peep2_regno_dead_p (0, FLAGS_REG)" 19260 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1))) 19261 (clobber (reg:CC FLAGS_REG))])] 19262 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 19263 19264(define_peephole2 19265 [(set (match_operand:DI 0 "register_operand") 19266 (zero_extend:DI 19267 (mult:SI (match_operand:SI 1 "register_operand") 19268 (match_operand:SI 2 "const_int_operand"))))] 19269 "TARGET_64BIT 19270 && pow2p_hwi (INTVAL (operands[2])) 19271 && REGNO (operands[0]) == REGNO (operands[1]) 19272 && peep2_regno_dead_p (0, FLAGS_REG)" 19273 [(parallel [(set (match_dup 0) 19274 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2)))) 19275 (clobber (reg:CC FLAGS_REG))])] 19276 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 19277 19278;; The ESP adjustments can be done by the push and pop instructions. Resulting 19279;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes. 19280;; On many CPUs it is also faster, since special hardware to avoid esp 19281;; dependencies is present. 19282 19283;; While some of these conversions may be done using splitters, we use 19284;; peepholes in order to allow combine_stack_adjustments pass to see 19285;; nonobfuscated RTL. 19286 19287;; Convert prologue esp subtractions to push. 19288;; We need register to push. In order to keep verify_flow_info happy we have 19289;; two choices 19290;; - use scratch and clobber it in order to avoid dependencies 19291;; - use already live register 19292;; We can't use the second way right now, since there is no reliable way how to 19293;; verify that given register is live. First choice will also most likely in 19294;; fewer dependencies. On the place of esp adjustments it is very likely that 19295;; call clobbered registers are dead. We may want to use base pointer as an 19296;; alternative when no register is available later. 19297 19298(define_peephole2 19299 [(match_scratch:W 1 "r") 19300 (parallel [(set (reg:P SP_REG) 19301 (plus:P (reg:P SP_REG) 19302 (match_operand:P 0 "const_int_operand"))) 19303 (clobber (reg:CC FLAGS_REG)) 19304 (clobber (mem:BLK (scratch)))])] 19305 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 19306 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) 19307 && ix86_red_zone_size == 0" 19308 [(clobber (match_dup 1)) 19309 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19310 (clobber (mem:BLK (scratch)))])]) 19311 19312(define_peephole2 19313 [(match_scratch:W 1 "r") 19314 (parallel [(set (reg:P SP_REG) 19315 (plus:P (reg:P SP_REG) 19316 (match_operand:P 0 "const_int_operand"))) 19317 (clobber (reg:CC FLAGS_REG)) 19318 (clobber (mem:BLK (scratch)))])] 19319 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 19320 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) 19321 && ix86_red_zone_size == 0" 19322 [(clobber (match_dup 1)) 19323 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19324 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19325 (clobber (mem:BLK (scratch)))])]) 19326 19327;; Convert esp subtractions to push. 19328(define_peephole2 19329 [(match_scratch:W 1 "r") 19330 (parallel [(set (reg:P SP_REG) 19331 (plus:P (reg:P SP_REG) 19332 (match_operand:P 0 "const_int_operand"))) 19333 (clobber (reg:CC FLAGS_REG))])] 19334 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 19335 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) 19336 && ix86_red_zone_size == 0" 19337 [(clobber (match_dup 1)) 19338 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 19339 19340(define_peephole2 19341 [(match_scratch:W 1 "r") 19342 (parallel [(set (reg:P SP_REG) 19343 (plus:P (reg:P SP_REG) 19344 (match_operand:P 0 "const_int_operand"))) 19345 (clobber (reg:CC FLAGS_REG))])] 19346 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 19347 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) 19348 && ix86_red_zone_size == 0" 19349 [(clobber (match_dup 1)) 19350 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19351 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 19352 19353;; Convert epilogue deallocator to pop. 19354(define_peephole2 19355 [(match_scratch:W 1 "r") 19356 (parallel [(set (reg:P SP_REG) 19357 (plus:P (reg:P SP_REG) 19358 (match_operand:P 0 "const_int_operand"))) 19359 (clobber (reg:CC FLAGS_REG)) 19360 (clobber (mem:BLK (scratch)))])] 19361 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ()) 19362 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 19363 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19364 (clobber (mem:BLK (scratch)))])]) 19365 19366;; Two pops case is tricky, since pop causes dependency 19367;; on destination register. We use two registers if available. 19368(define_peephole2 19369 [(match_scratch:W 1 "r") 19370 (match_scratch:W 2 "r") 19371 (parallel [(set (reg:P SP_REG) 19372 (plus:P (reg:P SP_REG) 19373 (match_operand:P 0 "const_int_operand"))) 19374 (clobber (reg:CC FLAGS_REG)) 19375 (clobber (mem:BLK (scratch)))])] 19376 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ()) 19377 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19378 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19379 (clobber (mem:BLK (scratch)))]) 19380 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 19381 19382(define_peephole2 19383 [(match_scratch:W 1 "r") 19384 (parallel [(set (reg:P SP_REG) 19385 (plus:P (reg:P SP_REG) 19386 (match_operand:P 0 "const_int_operand"))) 19387 (clobber (reg:CC FLAGS_REG)) 19388 (clobber (mem:BLK (scratch)))])] 19389 "optimize_insn_for_size_p () 19390 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19391 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19392 (clobber (mem:BLK (scratch)))]) 19393 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19394 19395;; Convert esp additions to pop. 19396(define_peephole2 19397 [(match_scratch:W 1 "r") 19398 (parallel [(set (reg:P SP_REG) 19399 (plus:P (reg:P SP_REG) 19400 (match_operand:P 0 "const_int_operand"))) 19401 (clobber (reg:CC FLAGS_REG))])] 19402 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 19403 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19404 19405;; Two pops case is tricky, since pop causes dependency 19406;; on destination register. We use two registers if available. 19407(define_peephole2 19408 [(match_scratch:W 1 "r") 19409 (match_scratch:W 2 "r") 19410 (parallel [(set (reg:P SP_REG) 19411 (plus:P (reg:P SP_REG) 19412 (match_operand:P 0 "const_int_operand"))) 19413 (clobber (reg:CC FLAGS_REG))])] 19414 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19415 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19416 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 19417 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 "optimize_insn_for_size_p () 19425 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19426 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19427 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19428 19429;; Convert compares with 1 to shorter inc/dec operations when CF is not 19430;; required and register dies. Similarly for 128 to -128. 19431(define_peephole2 19432 [(set (match_operand 0 "flags_reg_operand") 19433 (match_operator 1 "compare_operator" 19434 [(match_operand 2 "register_operand") 19435 (match_operand 3 "const_int_operand")]))] 19436 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ()) 19437 && incdec_operand (operands[3], GET_MODE (operands[3]))) 19438 || (!TARGET_FUSE_CMP_AND_BRANCH 19439 && INTVAL (operands[3]) == 128)) 19440 && ix86_match_ccmode (insn, CCGCmode) 19441 && peep2_reg_dead_p (1, operands[2])" 19442 [(parallel [(set (match_dup 0) 19443 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 19444 (clobber (match_dup 2))])]) 19445 19446;; Convert imul by three, five and nine into lea 19447(define_peephole2 19448 [(parallel 19449 [(set (match_operand:SWI48 0 "register_operand") 19450 (mult:SWI48 (match_operand:SWI48 1 "register_operand") 19451 (match_operand:SWI48 2 "const359_operand"))) 19452 (clobber (reg:CC FLAGS_REG))])] 19453 "!TARGET_PARTIAL_REG_STALL 19454 || <MODE>mode == SImode 19455 || optimize_function_for_size_p (cfun)" 19456 [(set (match_dup 0) 19457 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2)) 19458 (match_dup 1)))] 19459 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 19460 19461(define_peephole2 19462 [(parallel 19463 [(set (match_operand:SWI48 0 "register_operand") 19464 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 19465 (match_operand:SWI48 2 "const359_operand"))) 19466 (clobber (reg:CC FLAGS_REG))])] 19467 "optimize_insn_for_speed_p () 19468 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)" 19469 [(set (match_dup 0) (match_dup 1)) 19470 (set (match_dup 0) 19471 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2)) 19472 (match_dup 0)))] 19473 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 19474 19475;; imul $32bit_imm, mem, reg is vector decoded, while 19476;; imul $32bit_imm, reg, reg is direct decoded. 19477(define_peephole2 19478 [(match_scratch:SWI48 3 "r") 19479 (parallel [(set (match_operand:SWI48 0 "register_operand") 19480 (mult:SWI48 (match_operand:SWI48 1 "memory_operand") 19481 (match_operand:SWI48 2 "immediate_operand"))) 19482 (clobber (reg:CC FLAGS_REG))])] 19483 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 19484 && !satisfies_constraint_K (operands[2])" 19485 [(set (match_dup 3) (match_dup 1)) 19486 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2))) 19487 (clobber (reg:CC FLAGS_REG))])]) 19488 19489(define_peephole2 19490 [(match_scratch:SI 3 "r") 19491 (parallel [(set (match_operand:DI 0 "register_operand") 19492 (zero_extend:DI 19493 (mult:SI (match_operand:SI 1 "memory_operand") 19494 (match_operand:SI 2 "immediate_operand")))) 19495 (clobber (reg:CC FLAGS_REG))])] 19496 "TARGET_64BIT 19497 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 19498 && !satisfies_constraint_K (operands[2])" 19499 [(set (match_dup 3) (match_dup 1)) 19500 (parallel [(set (match_dup 0) 19501 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 19502 (clobber (reg:CC FLAGS_REG))])]) 19503 19504;; imul $8/16bit_imm, regmem, reg is vector decoded. 19505;; Convert it into imul reg, reg 19506;; It would be better to force assembler to encode instruction using long 19507;; immediate, but there is apparently no way to do so. 19508(define_peephole2 19509 [(parallel [(set (match_operand:SWI248 0 "register_operand") 19510 (mult:SWI248 19511 (match_operand:SWI248 1 "nonimmediate_operand") 19512 (match_operand:SWI248 2 "const_int_operand"))) 19513 (clobber (reg:CC FLAGS_REG))]) 19514 (match_scratch:SWI248 3 "r")] 19515 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () 19516 && satisfies_constraint_K (operands[2])" 19517 [(set (match_dup 3) (match_dup 2)) 19518 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3))) 19519 (clobber (reg:CC FLAGS_REG))])] 19520{ 19521 if (!rtx_equal_p (operands[0], operands[1])) 19522 emit_move_insn (operands[0], operands[1]); 19523}) 19524 19525;; After splitting up read-modify operations, array accesses with memory 19526;; operands might end up in form: 19527;; sall $2, %eax 19528;; movl 4(%esp), %edx 19529;; addl %edx, %eax 19530;; instead of pre-splitting: 19531;; sall $2, %eax 19532;; addl 4(%esp), %eax 19533;; Turn it into: 19534;; movl 4(%esp), %edx 19535;; leal (%edx,%eax,4), %eax 19536 19537(define_peephole2 19538 [(match_scratch:W 5 "r") 19539 (parallel [(set (match_operand 0 "register_operand") 19540 (ashift (match_operand 1 "register_operand") 19541 (match_operand 2 "const_int_operand"))) 19542 (clobber (reg:CC FLAGS_REG))]) 19543 (parallel [(set (match_operand 3 "register_operand") 19544 (plus (match_dup 0) 19545 (match_operand 4 "x86_64_general_operand"))) 19546 (clobber (reg:CC FLAGS_REG))])] 19547 "IN_RANGE (INTVAL (operands[2]), 1, 3) 19548 /* Validate MODE for lea. */ 19549 && ((!TARGET_PARTIAL_REG_STALL 19550 && (GET_MODE (operands[0]) == QImode 19551 || GET_MODE (operands[0]) == HImode)) 19552 || GET_MODE (operands[0]) == SImode 19553 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 19554 && (rtx_equal_p (operands[0], operands[3]) 19555 || peep2_reg_dead_p (2, operands[0])) 19556 /* We reorder load and the shift. */ 19557 && !reg_overlap_mentioned_p (operands[0], operands[4])" 19558 [(set (match_dup 5) (match_dup 4)) 19559 (set (match_dup 0) (match_dup 1))] 19560{ 19561 machine_mode op1mode = GET_MODE (operands[1]); 19562 machine_mode mode = op1mode == DImode ? DImode : SImode; 19563 int scale = 1 << INTVAL (operands[2]); 19564 rtx index = gen_lowpart (word_mode, operands[1]); 19565 rtx base = gen_lowpart (word_mode, operands[5]); 19566 rtx dest = gen_lowpart (mode, operands[3]); 19567 19568 operands[1] = gen_rtx_PLUS (word_mode, base, 19569 gen_rtx_MULT (word_mode, index, GEN_INT (scale))); 19570 if (mode != word_mode) 19571 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 19572 19573 operands[5] = base; 19574 if (op1mode != word_mode) 19575 operands[5] = gen_lowpart (op1mode, operands[5]); 19576 19577 operands[0] = dest; 19578}) 19579 19580;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 19581;; That, however, is usually mapped by the OS to SIGSEGV, which is often 19582;; caught for use by garbage collectors and the like. Using an insn that 19583;; maps to SIGILL makes it more likely the program will rightfully die. 19584;; Keeping with tradition, "6" is in honor of #UD. 19585(define_insn "trap" 19586 [(trap_if (const_int 1) (const_int 6))] 19587 "" 19588{ 19589#ifdef HAVE_AS_IX86_UD2 19590 return "ud2"; 19591#else 19592 return ASM_SHORT "0x0b0f"; 19593#endif 19594} 19595 [(set_attr "length" "2")]) 19596 19597(define_insn "ud2" 19598 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)] 19599 "" 19600{ 19601#ifdef HAVE_AS_IX86_UD2 19602 return "ud2"; 19603#else 19604 return ASM_SHORT "0x0b0f"; 19605#endif 19606} 19607 [(set_attr "length" "2")]) 19608 19609(define_expand "prefetch" 19610 [(prefetch (match_operand 0 "address_operand") 19611 (match_operand:SI 1 "const_int_operand") 19612 (match_operand:SI 2 "const_int_operand"))] 19613 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1" 19614{ 19615 bool write = INTVAL (operands[1]) != 0; 19616 int locality = INTVAL (operands[2]); 19617 19618 gcc_assert (IN_RANGE (locality, 0, 3)); 19619 19620 /* Use 3dNOW prefetch in case we are asking for write prefetch not 19621 supported by SSE counterpart (non-SSE2 athlon machines) or the 19622 SSE prefetch is not available (K6 machines). Otherwise use SSE 19623 prefetch as it allows specifying of locality. */ 19624 19625 if (write) 19626 { 19627 if (TARGET_PREFETCHWT1) 19628 operands[2] = GEN_INT (MAX (locality, 2)); 19629 else if (TARGET_PRFCHW) 19630 operands[2] = GEN_INT (3); 19631 else if (TARGET_3DNOW && !TARGET_SSE2) 19632 operands[2] = GEN_INT (3); 19633 else if (TARGET_PREFETCH_SSE) 19634 operands[1] = const0_rtx; 19635 else 19636 { 19637 gcc_assert (TARGET_3DNOW); 19638 operands[2] = GEN_INT (3); 19639 } 19640 } 19641 else 19642 { 19643 if (TARGET_PREFETCH_SSE) 19644 ; 19645 else 19646 { 19647 gcc_assert (TARGET_3DNOW); 19648 operands[2] = GEN_INT (3); 19649 } 19650 } 19651}) 19652 19653(define_insn "*prefetch_sse" 19654 [(prefetch (match_operand 0 "address_operand" "p") 19655 (const_int 0) 19656 (match_operand:SI 1 "const_int_operand"))] 19657 "TARGET_PREFETCH_SSE" 19658{ 19659 static const char * const patterns[4] = { 19660 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 19661 }; 19662 19663 int locality = INTVAL (operands[1]); 19664 gcc_assert (IN_RANGE (locality, 0, 3)); 19665 19666 return patterns[locality]; 19667} 19668 [(set_attr "type" "sse") 19669 (set_attr "atom_sse_attr" "prefetch") 19670 (set (attr "length_address") 19671 (symbol_ref "memory_address_length (operands[0], false)")) 19672 (set_attr "memory" "none")]) 19673 19674(define_insn "*prefetch_3dnow" 19675 [(prefetch (match_operand 0 "address_operand" "p") 19676 (match_operand:SI 1 "const_int_operand" "n") 19677 (const_int 3))] 19678 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1" 19679{ 19680 if (INTVAL (operands[1]) == 0) 19681 return "prefetch\t%a0"; 19682 else 19683 return "prefetchw\t%a0"; 19684} 19685 [(set_attr "type" "mmx") 19686 (set (attr "length_address") 19687 (symbol_ref "memory_address_length (operands[0], false)")) 19688 (set_attr "memory" "none")]) 19689 19690(define_insn "*prefetch_prefetchwt1" 19691 [(prefetch (match_operand 0 "address_operand" "p") 19692 (const_int 1) 19693 (const_int 2))] 19694 "TARGET_PREFETCHWT1" 19695 "prefetchwt1\t%a0"; 19696 [(set_attr "type" "sse") 19697 (set (attr "length_address") 19698 (symbol_ref "memory_address_length (operands[0], false)")) 19699 (set_attr "memory" "none")]) 19700 19701(define_expand "stack_protect_set" 19702 [(match_operand 0 "memory_operand") 19703 (match_operand 1 "memory_operand")] 19704 "TARGET_SSP_TLS_GUARD" 19705{ 19706 rtx (*insn)(rtx, rtx); 19707 19708 insn = (TARGET_LP64 19709 ? gen_stack_protect_set_di 19710 : gen_stack_protect_set_si); 19711 19712 emit_insn (insn (operands[0], operands[1])); 19713 DONE; 19714}) 19715 19716(define_insn "stack_protect_set_<mode>" 19717 [(set (match_operand:PTR 0 "memory_operand" "=m") 19718 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] 19719 UNSPEC_SP_SET)) 19720 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 19721 (clobber (reg:CC FLAGS_REG))] 19722 "TARGET_SSP_TLS_GUARD" 19723 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 19724 [(set_attr "type" "multi")]) 19725 19726(define_expand "stack_protect_test" 19727 [(match_operand 0 "memory_operand") 19728 (match_operand 1 "memory_operand") 19729 (match_operand 2)] 19730 "TARGET_SSP_TLS_GUARD" 19731{ 19732 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 19733 19734 rtx (*insn)(rtx, rtx, rtx); 19735 19736 insn = (TARGET_LP64 19737 ? gen_stack_protect_test_di 19738 : gen_stack_protect_test_si); 19739 19740 emit_insn (insn (flags, operands[0], operands[1])); 19741 19742 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx), 19743 flags, const0_rtx, operands[2])); 19744 DONE; 19745}) 19746 19747(define_insn "stack_protect_test_<mode>" 19748 [(set (match_operand:CCZ 0 "flags_reg_operand") 19749 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 19750 (match_operand:PTR 2 "memory_operand" "m")] 19751 UNSPEC_SP_TEST)) 19752 (clobber (match_scratch:PTR 3 "=&r"))] 19753 "TARGET_SSP_TLS_GUARD" 19754 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}" 19755 [(set_attr "type" "multi")]) 19756 19757(define_insn "sse4_2_crc32<mode>" 19758 [(set (match_operand:SI 0 "register_operand" "=r") 19759 (unspec:SI 19760 [(match_operand:SI 1 "register_operand" "0") 19761 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")] 19762 UNSPEC_CRC32))] 19763 "TARGET_SSE4_2 || TARGET_CRC32" 19764 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}" 19765 [(set_attr "type" "sselog1") 19766 (set_attr "prefix_rep" "1") 19767 (set_attr "prefix_extra" "1") 19768 (set (attr "prefix_data16") 19769 (if_then_else (match_operand:HI 2) 19770 (const_string "1") 19771 (const_string "*"))) 19772 (set (attr "prefix_rex") 19773 (if_then_else (match_operand:QI 2 "ext_QIreg_operand") 19774 (const_string "1") 19775 (const_string "*"))) 19776 (set_attr "mode" "SI")]) 19777 19778(define_insn "sse4_2_crc32di" 19779 [(set (match_operand:DI 0 "register_operand" "=r") 19780 (unspec:DI 19781 [(match_operand:DI 1 "register_operand" "0") 19782 (match_operand:DI 2 "nonimmediate_operand" "rm")] 19783 UNSPEC_CRC32))] 19784 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)" 19785 "crc32{q}\t{%2, %0|%0, %2}" 19786 [(set_attr "type" "sselog1") 19787 (set_attr "prefix_rep" "1") 19788 (set_attr "prefix_extra" "1") 19789 (set_attr "mode" "DI")]) 19790 19791(define_insn "rdpmc" 19792 [(set (match_operand:DI 0 "register_operand" "=A") 19793 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 19794 UNSPECV_RDPMC))] 19795 "!TARGET_64BIT" 19796 "rdpmc" 19797 [(set_attr "type" "other") 19798 (set_attr "length" "2")]) 19799 19800(define_insn "rdpmc_rex64" 19801 [(set (match_operand:DI 0 "register_operand" "=a") 19802 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 19803 UNSPECV_RDPMC)) 19804 (set (match_operand:DI 1 "register_operand" "=d") 19805 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))] 19806 "TARGET_64BIT" 19807 "rdpmc" 19808 [(set_attr "type" "other") 19809 (set_attr "length" "2")]) 19810 19811(define_insn "rdtsc" 19812 [(set (match_operand:DI 0 "register_operand" "=A") 19813 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 19814 "!TARGET_64BIT" 19815 "rdtsc" 19816 [(set_attr "type" "other") 19817 (set_attr "length" "2")]) 19818 19819(define_insn "rdtsc_rex64" 19820 [(set (match_operand:DI 0 "register_operand" "=a") 19821 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC)) 19822 (set (match_operand:DI 1 "register_operand" "=d") 19823 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 19824 "TARGET_64BIT" 19825 "rdtsc" 19826 [(set_attr "type" "other") 19827 (set_attr "length" "2")]) 19828 19829(define_insn "rdtscp" 19830 [(set (match_operand:DI 0 "register_operand" "=A") 19831 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19832 (set (match_operand:SI 1 "register_operand" "=c") 19833 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 19834 "!TARGET_64BIT" 19835 "rdtscp" 19836 [(set_attr "type" "other") 19837 (set_attr "length" "3")]) 19838 19839(define_insn "rdtscp_rex64" 19840 [(set (match_operand:DI 0 "register_operand" "=a") 19841 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19842 (set (match_operand:DI 1 "register_operand" "=d") 19843 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 19844 (set (match_operand:SI 2 "register_operand" "=c") 19845 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 19846 "TARGET_64BIT" 19847 "rdtscp" 19848 [(set_attr "type" "other") 19849 (set_attr "length" "3")]) 19850 19851;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19852;; 19853;; FXSR, XSAVE and XSAVEOPT instructions 19854;; 19855;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 19856 19857(define_insn "fxsave" 19858 [(set (match_operand:BLK 0 "memory_operand" "=m") 19859 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))] 19860 "TARGET_FXSR" 19861 "fxsave\t%0" 19862 [(set_attr "type" "other") 19863 (set_attr "memory" "store") 19864 (set (attr "length") 19865 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19866 19867(define_insn "fxsave64" 19868 [(set (match_operand:BLK 0 "memory_operand" "=m") 19869 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))] 19870 "TARGET_64BIT && TARGET_FXSR" 19871 "fxsave64\t%0" 19872 [(set_attr "type" "other") 19873 (set_attr "memory" "store") 19874 (set (attr "length") 19875 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 19876 19877(define_insn "fxrstor" 19878 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 19879 UNSPECV_FXRSTOR)] 19880 "TARGET_FXSR" 19881 "fxrstor\t%0" 19882 [(set_attr "type" "other") 19883 (set_attr "memory" "load") 19884 (set (attr "length") 19885 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19886 19887(define_insn "fxrstor64" 19888 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 19889 UNSPECV_FXRSTOR64)] 19890 "TARGET_64BIT && TARGET_FXSR" 19891 "fxrstor64\t%0" 19892 [(set_attr "type" "other") 19893 (set_attr "memory" "load") 19894 (set (attr "length") 19895 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 19896 19897(define_int_iterator ANY_XSAVE 19898 [UNSPECV_XSAVE 19899 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT") 19900 (UNSPECV_XSAVEC "TARGET_XSAVEC") 19901 (UNSPECV_XSAVES "TARGET_XSAVES")]) 19902 19903(define_int_iterator ANY_XSAVE64 19904 [UNSPECV_XSAVE64 19905 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT") 19906 (UNSPECV_XSAVEC64 "TARGET_XSAVEC") 19907 (UNSPECV_XSAVES64 "TARGET_XSAVES")]) 19908 19909(define_int_attr xsave 19910 [(UNSPECV_XSAVE "xsave") 19911 (UNSPECV_XSAVE64 "xsave64") 19912 (UNSPECV_XSAVEOPT "xsaveopt") 19913 (UNSPECV_XSAVEOPT64 "xsaveopt64") 19914 (UNSPECV_XSAVEC "xsavec") 19915 (UNSPECV_XSAVEC64 "xsavec64") 19916 (UNSPECV_XSAVES "xsaves") 19917 (UNSPECV_XSAVES64 "xsaves64")]) 19918 19919(define_int_iterator ANY_XRSTOR 19920 [UNSPECV_XRSTOR 19921 (UNSPECV_XRSTORS "TARGET_XSAVES")]) 19922 19923(define_int_iterator ANY_XRSTOR64 19924 [UNSPECV_XRSTOR64 19925 (UNSPECV_XRSTORS64 "TARGET_XSAVES")]) 19926 19927(define_int_attr xrstor 19928 [(UNSPECV_XRSTOR "xrstor") 19929 (UNSPECV_XRSTOR64 "xrstor") 19930 (UNSPECV_XRSTORS "xrstors") 19931 (UNSPECV_XRSTORS64 "xrstors")]) 19932 19933(define_insn "<xsave>" 19934 [(set (match_operand:BLK 0 "memory_operand" "=m") 19935 (unspec_volatile:BLK 19936 [(match_operand:DI 1 "register_operand" "A")] 19937 ANY_XSAVE))] 19938 "!TARGET_64BIT && TARGET_XSAVE" 19939 "<xsave>\t%0" 19940 [(set_attr "type" "other") 19941 (set_attr "memory" "store") 19942 (set (attr "length") 19943 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19944 19945(define_insn "<xsave>_rex64" 19946 [(set (match_operand:BLK 0 "memory_operand" "=m") 19947 (unspec_volatile:BLK 19948 [(match_operand:SI 1 "register_operand" "a") 19949 (match_operand:SI 2 "register_operand" "d")] 19950 ANY_XSAVE))] 19951 "TARGET_64BIT && TARGET_XSAVE" 19952 "<xsave>\t%0" 19953 [(set_attr "type" "other") 19954 (set_attr "memory" "store") 19955 (set (attr "length") 19956 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19957 19958(define_insn "<xsave>" 19959 [(set (match_operand:BLK 0 "memory_operand" "=m") 19960 (unspec_volatile:BLK 19961 [(match_operand:SI 1 "register_operand" "a") 19962 (match_operand:SI 2 "register_operand" "d")] 19963 ANY_XSAVE64))] 19964 "TARGET_64BIT && TARGET_XSAVE" 19965 "<xsave>\t%0" 19966 [(set_attr "type" "other") 19967 (set_attr "memory" "store") 19968 (set (attr "length") 19969 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 19970 19971(define_insn "<xrstor>" 19972 [(unspec_volatile:BLK 19973 [(match_operand:BLK 0 "memory_operand" "m") 19974 (match_operand:DI 1 "register_operand" "A")] 19975 ANY_XRSTOR)] 19976 "!TARGET_64BIT && TARGET_XSAVE" 19977 "<xrstor>\t%0" 19978 [(set_attr "type" "other") 19979 (set_attr "memory" "load") 19980 (set (attr "length") 19981 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19982 19983(define_insn "<xrstor>_rex64" 19984 [(unspec_volatile:BLK 19985 [(match_operand:BLK 0 "memory_operand" "m") 19986 (match_operand:SI 1 "register_operand" "a") 19987 (match_operand:SI 2 "register_operand" "d")] 19988 ANY_XRSTOR)] 19989 "TARGET_64BIT && TARGET_XSAVE" 19990 "<xrstor>\t%0" 19991 [(set_attr "type" "other") 19992 (set_attr "memory" "load") 19993 (set (attr "length") 19994 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 19995 19996(define_insn "<xrstor>64" 19997 [(unspec_volatile:BLK 19998 [(match_operand:BLK 0 "memory_operand" "m") 19999 (match_operand:SI 1 "register_operand" "a") 20000 (match_operand:SI 2 "register_operand" "d")] 20001 ANY_XRSTOR64)] 20002 "TARGET_64BIT && TARGET_XSAVE" 20003 "<xrstor>64\t%0" 20004 [(set_attr "type" "other") 20005 (set_attr "memory" "load") 20006 (set (attr "length") 20007 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20008 20009(define_insn "xsetbv" 20010 [(unspec_volatile:SI 20011 [(match_operand:SI 0 "register_operand" "c") 20012 (match_operand:DI 1 "register_operand" "A")] 20013 UNSPECV_XSETBV)] 20014 "!TARGET_64BIT && TARGET_XSAVE" 20015 "xsetbv" 20016 [(set_attr "type" "other")]) 20017 20018(define_insn "xsetbv_rex64" 20019 [(unspec_volatile:SI 20020 [(match_operand:SI 0 "register_operand" "c") 20021 (match_operand:SI 1 "register_operand" "a") 20022 (match_operand:SI 2 "register_operand" "d")] 20023 UNSPECV_XSETBV)] 20024 "TARGET_64BIT && TARGET_XSAVE" 20025 "xsetbv" 20026 [(set_attr "type" "other")]) 20027 20028(define_insn "xgetbv" 20029 [(set (match_operand:DI 0 "register_operand" "=A") 20030 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 20031 UNSPECV_XGETBV))] 20032 "!TARGET_64BIT && TARGET_XSAVE" 20033 "xgetbv" 20034 [(set_attr "type" "other")]) 20035 20036(define_insn "xgetbv_rex64" 20037 [(set (match_operand:DI 0 "register_operand" "=a") 20038 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 20039 UNSPECV_XGETBV)) 20040 (set (match_operand:DI 1 "register_operand" "=d") 20041 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))] 20042 "TARGET_64BIT && TARGET_XSAVE" 20043 "xgetbv" 20044 [(set_attr "type" "other")]) 20045 20046;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20047;; 20048;; Floating-point instructions for atomic compound assignments 20049;; 20050;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20051 20052; Clobber all floating-point registers on environment save and restore 20053; to ensure that the TOS value saved at fnstenv is valid after fldenv. 20054(define_insn "fnstenv" 20055 [(set (match_operand:BLK 0 "memory_operand" "=m") 20056 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV)) 20057 (clobber (reg:HI FPCR_REG)) 20058 (clobber (reg:XF ST0_REG)) 20059 (clobber (reg:XF ST1_REG)) 20060 (clobber (reg:XF ST2_REG)) 20061 (clobber (reg:XF ST3_REG)) 20062 (clobber (reg:XF ST4_REG)) 20063 (clobber (reg:XF ST5_REG)) 20064 (clobber (reg:XF ST6_REG)) 20065 (clobber (reg:XF ST7_REG))] 20066 "TARGET_80387" 20067 "fnstenv\t%0" 20068 [(set_attr "type" "other") 20069 (set_attr "memory" "store") 20070 (set (attr "length") 20071 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20072 20073(define_insn "fldenv" 20074 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 20075 UNSPECV_FLDENV) 20076 (clobber (reg:CCFP FPSR_REG)) 20077 (clobber (reg:HI FPCR_REG)) 20078 (clobber (reg:XF ST0_REG)) 20079 (clobber (reg:XF ST1_REG)) 20080 (clobber (reg:XF ST2_REG)) 20081 (clobber (reg:XF ST3_REG)) 20082 (clobber (reg:XF ST4_REG)) 20083 (clobber (reg:XF ST5_REG)) 20084 (clobber (reg:XF ST6_REG)) 20085 (clobber (reg:XF ST7_REG))] 20086 "TARGET_80387" 20087 "fldenv\t%0" 20088 [(set_attr "type" "other") 20089 (set_attr "memory" "load") 20090 (set (attr "length") 20091 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20092 20093(define_insn "fnstsw" 20094 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m") 20095 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))] 20096 "TARGET_80387" 20097 "fnstsw\t%0" 20098 [(set_attr "type" "other,other") 20099 (set_attr "memory" "none,store") 20100 (set (attr "length") 20101 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20102 20103(define_insn "fnclex" 20104 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)] 20105 "TARGET_80387" 20106 "fnclex" 20107 [(set_attr "type" "other") 20108 (set_attr "memory" "none") 20109 (set_attr "length" "2")]) 20110 20111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20112;; 20113;; LWP instructions 20114;; 20115;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20116 20117(define_expand "lwp_llwpcb" 20118 [(unspec_volatile [(match_operand 0 "register_operand")] 20119 UNSPECV_LLWP_INTRINSIC)] 20120 "TARGET_LWP") 20121 20122(define_insn "*lwp_llwpcb<mode>1" 20123 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 20124 UNSPECV_LLWP_INTRINSIC)] 20125 "TARGET_LWP" 20126 "llwpcb\t%0" 20127 [(set_attr "type" "lwp") 20128 (set_attr "mode" "<MODE>") 20129 (set_attr "length" "5")]) 20130 20131(define_expand "lwp_slwpcb" 20132 [(set (match_operand 0 "register_operand") 20133 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 20134 "TARGET_LWP" 20135{ 20136 rtx (*insn)(rtx); 20137 20138 insn = (Pmode == DImode 20139 ? gen_lwp_slwpcbdi 20140 : gen_lwp_slwpcbsi); 20141 20142 emit_insn (insn (operands[0])); 20143 DONE; 20144}) 20145 20146(define_insn "lwp_slwpcb<mode>" 20147 [(set (match_operand:P 0 "register_operand" "=r") 20148 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 20149 "TARGET_LWP" 20150 "slwpcb\t%0" 20151 [(set_attr "type" "lwp") 20152 (set_attr "mode" "<MODE>") 20153 (set_attr "length" "5")]) 20154 20155(define_expand "lwp_lwpval<mode>3" 20156 [(unspec_volatile [(match_operand:SWI48 1 "register_operand") 20157 (match_operand:SI 2 "nonimmediate_operand") 20158 (match_operand:SI 3 "const_int_operand")] 20159 UNSPECV_LWPVAL_INTRINSIC)] 20160 "TARGET_LWP" 20161 ;; Avoid unused variable warning. 20162 "(void) operands[0];") 20163 20164(define_insn "*lwp_lwpval<mode>3_1" 20165 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") 20166 (match_operand:SI 1 "nonimmediate_operand" "rm") 20167 (match_operand:SI 2 "const_int_operand" "i")] 20168 UNSPECV_LWPVAL_INTRINSIC)] 20169 "TARGET_LWP" 20170 "lwpval\t{%2, %1, %0|%0, %1, %2}" 20171 [(set_attr "type" "lwp") 20172 (set_attr "mode" "<MODE>") 20173 (set (attr "length") 20174 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 20175 20176(define_expand "lwp_lwpins<mode>3" 20177 [(set (reg:CCC FLAGS_REG) 20178 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand") 20179 (match_operand:SI 2 "nonimmediate_operand") 20180 (match_operand:SI 3 "const_int_operand")] 20181 UNSPECV_LWPINS_INTRINSIC)) 20182 (set (match_operand:QI 0 "nonimmediate_operand") 20183 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] 20184 "TARGET_LWP") 20185 20186(define_insn "*lwp_lwpins<mode>3_1" 20187 [(set (reg:CCC FLAGS_REG) 20188 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r") 20189 (match_operand:SI 1 "nonimmediate_operand" "rm") 20190 (match_operand:SI 2 "const_int_operand" "i")] 20191 UNSPECV_LWPINS_INTRINSIC))] 20192 "TARGET_LWP" 20193 "lwpins\t{%2, %1, %0|%0, %1, %2}" 20194 [(set_attr "type" "lwp") 20195 (set_attr "mode" "<MODE>") 20196 (set (attr "length") 20197 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 20198 20199(define_int_iterator RDFSGSBASE 20200 [UNSPECV_RDFSBASE 20201 UNSPECV_RDGSBASE]) 20202 20203(define_int_iterator WRFSGSBASE 20204 [UNSPECV_WRFSBASE 20205 UNSPECV_WRGSBASE]) 20206 20207(define_int_attr fsgs 20208 [(UNSPECV_RDFSBASE "fs") 20209 (UNSPECV_RDGSBASE "gs") 20210 (UNSPECV_WRFSBASE "fs") 20211 (UNSPECV_WRGSBASE "gs")]) 20212 20213(define_insn "rd<fsgs>base<mode>" 20214 [(set (match_operand:SWI48 0 "register_operand" "=r") 20215 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))] 20216 "TARGET_64BIT && TARGET_FSGSBASE" 20217 "rd<fsgs>base\t%0" 20218 [(set_attr "type" "other") 20219 (set_attr "prefix_extra" "2")]) 20220 20221(define_insn "wr<fsgs>base<mode>" 20222 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 20223 WRFSGSBASE)] 20224 "TARGET_64BIT && TARGET_FSGSBASE" 20225 "wr<fsgs>base\t%0" 20226 [(set_attr "type" "other") 20227 (set_attr "prefix_extra" "2")]) 20228 20229(define_insn "rdrand<mode>_1" 20230 [(set (match_operand:SWI248 0 "register_operand" "=r") 20231 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND)) 20232 (set (reg:CCC FLAGS_REG) 20233 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))] 20234 "TARGET_RDRND" 20235 "rdrand\t%0" 20236 [(set_attr "type" "other") 20237 (set_attr "prefix_extra" "1")]) 20238 20239(define_insn "rdseed<mode>_1" 20240 [(set (match_operand:SWI248 0 "register_operand" "=r") 20241 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED)) 20242 (set (reg:CCC FLAGS_REG) 20243 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))] 20244 "TARGET_RDSEED" 20245 "rdseed\t%0" 20246 [(set_attr "type" "other") 20247 (set_attr "prefix_extra" "1")]) 20248 20249(define_expand "pause" 20250 [(set (match_dup 0) 20251 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 20252 "" 20253{ 20254 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 20255 MEM_VOLATILE_P (operands[0]) = 1; 20256}) 20257 20258;; Use "rep; nop", instead of "pause", to support older assemblers. 20259;; They have the same encoding. 20260(define_insn "*pause" 20261 [(set (match_operand:BLK 0) 20262 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 20263 "" 20264 "rep%; nop" 20265 [(set_attr "length" "2") 20266 (set_attr "memory" "unknown")]) 20267 20268;; CET instructions 20269(define_insn "rdssp<mode>" 20270 [(set (match_operand:SWI48x 0 "register_operand" "=r") 20271 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))] 20272 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" 20273 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0" 20274 [(set_attr "length" "6") 20275 (set_attr "type" "other")]) 20276 20277(define_insn "incssp<mode>" 20278 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")] 20279 UNSPECV_INCSSP)] 20280 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" 20281 "incssp<mskmodesuffix>\t%0" 20282 [(set_attr "length" "4") 20283 (set_attr "type" "other")]) 20284 20285(define_insn "saveprevssp" 20286 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)] 20287 "TARGET_SHSTK" 20288 "saveprevssp" 20289 [(set_attr "length" "5") 20290 (set_attr "type" "other")]) 20291 20292(define_insn "rstorssp" 20293 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 20294 UNSPECV_RSTORSSP)] 20295 "TARGET_SHSTK" 20296 "rstorssp\t%0" 20297 [(set_attr "length" "5") 20298 (set_attr "type" "other")]) 20299 20300(define_insn "wrss<mode>" 20301 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") 20302 (match_operand:SWI48x 1 "memory_operand" "m")] 20303 UNSPECV_WRSS)] 20304 "TARGET_SHSTK" 20305 "wrss<mskmodesuffix>\t%0, %1" 20306 [(set_attr "length" "3") 20307 (set_attr "type" "other")]) 20308 20309(define_insn "wruss<mode>" 20310 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") 20311 (match_operand:SWI48x 1 "memory_operand" "m")] 20312 UNSPECV_WRUSS)] 20313 "TARGET_SHSTK" 20314 "wruss<mskmodesuffix>\t%0, %1" 20315 [(set_attr "length" "4") 20316 (set_attr "type" "other")]) 20317 20318(define_insn "setssbsy" 20319 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)] 20320 "TARGET_SHSTK" 20321 "setssbsy" 20322 [(set_attr "length" "4") 20323 (set_attr "type" "other")]) 20324 20325(define_insn "clrssbsy" 20326 [(unspec_volatile [(match_operand 0 "memory_operand" "m")] 20327 UNSPECV_CLRSSBSY)] 20328 "TARGET_SHSTK" 20329 "clrssbsy\t%0" 20330 [(set_attr "length" "4") 20331 (set_attr "type" "other")]) 20332 20333(define_insn "nop_endbr" 20334 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)] 20335 "(flag_cf_protection & CF_BRANCH)" 20336 "* 20337{ return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }" 20338 [(set_attr "length" "4") 20339 (set_attr "length_immediate" "0") 20340 (set_attr "modrm" "0")]) 20341 20342;; For RTM support 20343(define_expand "xbegin" 20344 [(set (match_operand:SI 0 "register_operand") 20345 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))] 20346 "TARGET_RTM" 20347{ 20348 rtx_code_label *label = gen_label_rtx (); 20349 20350 /* xbegin is emitted as jump_insn, so reload won't be able 20351 to reload its operand. Force the value into AX hard register. */ 20352 rtx ax_reg = gen_rtx_REG (SImode, AX_REG); 20353 emit_move_insn (ax_reg, constm1_rtx); 20354 20355 emit_jump_insn (gen_xbegin_1 (ax_reg, label)); 20356 20357 emit_label (label); 20358 LABEL_NUSES (label) = 1; 20359 20360 emit_move_insn (operands[0], ax_reg); 20361 20362 DONE; 20363}) 20364 20365(define_insn "xbegin_1" 20366 [(set (pc) 20367 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT) 20368 (const_int 0)) 20369 (label_ref (match_operand 1)) 20370 (pc))) 20371 (set (match_operand:SI 0 "register_operand" "+a") 20372 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))] 20373 "TARGET_RTM" 20374 "xbegin\t%l1" 20375 [(set_attr "type" "other") 20376 (set_attr "length" "6")]) 20377 20378(define_insn "xend" 20379 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)] 20380 "TARGET_RTM" 20381 "xend" 20382 [(set_attr "type" "other") 20383 (set_attr "length" "3")]) 20384 20385(define_insn "xabort" 20386 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")] 20387 UNSPECV_XABORT)] 20388 "TARGET_RTM" 20389 "xabort\t%0" 20390 [(set_attr "type" "other") 20391 (set_attr "length" "3")]) 20392 20393(define_expand "xtest" 20394 [(set (match_operand:QI 0 "register_operand") 20395 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))] 20396 "TARGET_RTM" 20397{ 20398 emit_insn (gen_xtest_1 ()); 20399 20400 ix86_expand_setcc (operands[0], NE, 20401 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 20402 DONE; 20403}) 20404 20405(define_insn "xtest_1" 20406 [(set (reg:CCZ FLAGS_REG) 20407 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))] 20408 "TARGET_RTM" 20409 "xtest" 20410 [(set_attr "type" "other") 20411 (set_attr "length" "3")]) 20412 20413(define_insn "clwb" 20414 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 20415 UNSPECV_CLWB)] 20416 "TARGET_CLWB" 20417 "clwb\t%a0" 20418 [(set_attr "type" "sse") 20419 (set_attr "atom_sse_attr" "fence") 20420 (set_attr "memory" "unknown")]) 20421 20422(define_insn "clflushopt" 20423 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 20424 UNSPECV_CLFLUSHOPT)] 20425 "TARGET_CLFLUSHOPT" 20426 "clflushopt\t%a0" 20427 [(set_attr "type" "sse") 20428 (set_attr "atom_sse_attr" "fence") 20429 (set_attr "memory" "unknown")]) 20430 20431;; MONITORX and MWAITX 20432(define_insn "mwaitx" 20433 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c") 20434 (match_operand:SI 1 "register_operand" "a") 20435 (match_operand:SI 2 "register_operand" "b")] 20436 UNSPECV_MWAITX)] 20437 "TARGET_MWAITX" 20438;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used. 20439;; Since 32bit register operands are implicitly zero extended to 64bit, 20440;; we only need to set up 32bit registers. 20441 "mwaitx" 20442 [(set_attr "length" "3")]) 20443 20444(define_insn "monitorx_<mode>" 20445 [(unspec_volatile [(match_operand:P 0 "register_operand" "a") 20446 (match_operand:SI 1 "register_operand" "c") 20447 (match_operand:SI 2 "register_operand" "d")] 20448 UNSPECV_MONITORX)] 20449 "TARGET_MWAITX" 20450;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in 20451;; RCX and RDX are used. Since 32bit register operands are implicitly 20452;; zero extended to 64bit, we only need to set up 32bit registers. 20453 "%^monitorx" 20454 [(set (attr "length") 20455 (symbol_ref ("(Pmode != word_mode) + 3")))]) 20456 20457;; CLZERO 20458(define_insn "clzero_<mode>" 20459 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")] 20460 UNSPECV_CLZERO)] 20461 "TARGET_CLZERO" 20462 "clzero" 20463 [(set_attr "length" "3") 20464 (set_attr "memory" "unknown")]) 20465 20466;; MPX instructions 20467 20468(define_expand "<mode>_mk" 20469 [(set (match_operand:BND 0 "register_operand") 20470 (unspec:BND 20471 [(mem:<bnd_ptr> 20472 (match_par_dup 3 20473 [(match_operand:<bnd_ptr> 1 "register_operand") 20474 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))] 20475 UNSPEC_BNDMK))] 20476 "TARGET_MPX" 20477{ 20478 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], 20479 operands[2]), 20480 UNSPEC_BNDMK_ADDR); 20481}) 20482 20483(define_insn "*<mode>_mk" 20484 [(set (match_operand:BND 0 "register_operand" "=w") 20485 (unspec:BND 20486 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20487 [(unspec:<bnd_ptr> 20488 [(match_operand:<bnd_ptr> 1 "register_operand" "r") 20489 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")] 20490 UNSPEC_BNDMK_ADDR)])] 20491 UNSPEC_BNDMK))] 20492 "TARGET_MPX" 20493 "bndmk\t{%3, %0|%0, %3}" 20494 [(set_attr "type" "mpxmk")]) 20495 20496(define_expand "mov<mode>" 20497 [(set (match_operand:BND 0 "general_operand") 20498 (match_operand:BND 1 "general_operand"))] 20499 "TARGET_MPX" 20500 "ix86_expand_move (<MODE>mode, operands); DONE;") 20501 20502(define_insn "*mov<mode>_internal_mpx" 20503 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m") 20504 (match_operand:BND 1 "general_operand" "wm,w"))] 20505 "TARGET_MPX" 20506 "bndmov\t{%1, %0|%0, %1}" 20507 [(set_attr "type" "mpxmov")]) 20508 20509(define_expand "<mode>_<bndcheck>" 20510 [(parallel 20511 [(unspec 20512 [(match_operand:BND 0 "register_operand") 20513 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK) 20514 (set (match_dup 2) 20515 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])] 20516 "TARGET_MPX" 20517{ 20518 operands[2] = gen_rtx_MEM (BLKmode, operands[1]); 20519 MEM_VOLATILE_P (operands[2]) = 1; 20520}) 20521 20522(define_insn "*<mode>_<bndcheck>" 20523 [(unspec 20524 [(match_operand:BND 0 "register_operand" "w") 20525 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK) 20526 (set (match_operand:BLK 2 "bnd_mem_operator") 20527 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))] 20528 "TARGET_MPX" 20529 "bnd<bndcheck>\t{%a1, %0|%0, %a1}" 20530 [(set_attr "type" "mpxchk")]) 20531 20532(define_expand "<mode>_ldx" 20533 [(parallel 20534 [(set (match_operand:BND 0 "register_operand") 20535 (unspec:BND 20536 [(mem:<bnd_ptr> 20537 (match_par_dup 3 20538 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand") 20539 (match_operand:<bnd_ptr> 2 "register_operand")]))] 20540 UNSPEC_BNDLDX)) 20541 (use (mem:BLK (match_dup 1)))])] 20542 "TARGET_MPX" 20543{ 20544 /* Avoid registers which cannot be used as index. */ 20545 if (!index_register_operand (operands[2], Pmode)) 20546 operands[2] = copy_addr_to_reg (operands[2]); 20547 20548 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], 20549 operands[2]), 20550 UNSPEC_BNDLDX_ADDR); 20551}) 20552 20553(define_insn "*<mode>_ldx" 20554 [(set (match_operand:BND 0 "register_operand" "=w") 20555 (unspec:BND 20556 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20557 [(unspec:<bnd_ptr> 20558 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti") 20559 (match_operand:<bnd_ptr> 2 "register_operand" "l")] 20560 UNSPEC_BNDLDX_ADDR)])] 20561 UNSPEC_BNDLDX)) 20562 (use (mem:BLK (match_dup 1)))] 20563 "TARGET_MPX" 20564 "bndldx\t{%3, %0|%0, %3}" 20565 [(set_attr "type" "mpxld")]) 20566 20567(define_expand "<mode>_stx" 20568 [(parallel 20569 [(unspec 20570 [(mem:<bnd_ptr> 20571 (match_par_dup 3 20572 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand") 20573 (match_operand:<bnd_ptr> 1 "register_operand")])) 20574 (match_operand:BND 2 "register_operand")] 20575 UNSPEC_BNDSTX) 20576 (set (match_dup 4) 20577 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])] 20578 "TARGET_MPX" 20579{ 20580 /* Avoid registers which cannot be used as index. */ 20581 if (!index_register_operand (operands[1], Pmode)) 20582 operands[1] = copy_addr_to_reg (operands[1]); 20583 20584 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0], 20585 operands[1]), 20586 UNSPEC_BNDLDX_ADDR); 20587 operands[4] = gen_rtx_MEM (BLKmode, operands[0]); 20588 MEM_VOLATILE_P (operands[4]) = 1; 20589}) 20590 20591(define_insn "*<mode>_stx" 20592 [(unspec 20593 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 20594 [(unspec:<bnd_ptr> 20595 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti") 20596 (match_operand:<bnd_ptr> 1 "register_operand" "l")] 20597 UNSPEC_BNDLDX_ADDR)]) 20598 (match_operand:BND 2 "register_operand" "w")] 20599 UNSPEC_BNDSTX) 20600 (set (match_operand:BLK 4 "bnd_mem_operator") 20601 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))] 20602 "TARGET_MPX" 20603 "bndstx\t{%2, %3|%3, %2}" 20604 [(set_attr "type" "mpxst")]) 20605 20606(define_insn "move_size_reloc_<mode>" 20607 [(set (match_operand:SWI48 0 "register_operand" "=r") 20608 (unspec:SWI48 20609 [(match_operand:SWI48 1 "symbol_operand")] 20610 UNSPEC_SIZEOF))] 20611 "TARGET_MPX" 20612{ 20613 if (x86_64_immediate_size_operand (operands[1], VOIDmode)) 20614 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}"; 20615 else 20616 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}"; 20617} 20618 [(set_attr "type" "imov") 20619 (set_attr "mode" "<MODE>")]) 20620 20621;; RDPKRU and WRPKRU 20622 20623(define_expand "rdpkru" 20624 [(parallel 20625 [(set (match_operand:SI 0 "register_operand") 20626 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU)) 20627 (set (match_dup 2) (const_int 0))])] 20628 "TARGET_PKU" 20629{ 20630 operands[1] = force_reg (SImode, const0_rtx); 20631 operands[2] = gen_reg_rtx (SImode); 20632}) 20633 20634(define_insn "*rdpkru" 20635 [(set (match_operand:SI 0 "register_operand" "=a") 20636 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")] 20637 UNSPECV_PKU)) 20638 (set (match_operand:SI 1 "register_operand" "=d") 20639 (const_int 0))] 20640 "TARGET_PKU" 20641 "rdpkru" 20642 [(set_attr "type" "other")]) 20643 20644(define_expand "wrpkru" 20645 [(unspec_volatile:SI 20646 [(match_operand:SI 0 "register_operand") 20647 (match_dup 1) (match_dup 2)] UNSPECV_PKU)] 20648 "TARGET_PKU" 20649{ 20650 operands[1] = force_reg (SImode, const0_rtx); 20651 operands[2] = force_reg (SImode, const0_rtx); 20652}) 20653 20654(define_insn "*wrpkru" 20655 [(unspec_volatile:SI 20656 [(match_operand:SI 0 "register_operand" "a") 20657 (match_operand:SI 1 "register_operand" "d") 20658 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)] 20659 "TARGET_PKU" 20660 "wrpkru" 20661 [(set_attr "type" "other")]) 20662 20663(define_insn "rdpid" 20664 [(set (match_operand:SI 0 "register_operand" "=r") 20665 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))] 20666 "!TARGET_64BIT && TARGET_RDPID" 20667 "rdpid\t%0" 20668 [(set_attr "type" "other")]) 20669 20670(define_insn "rdpid_rex64" 20671 [(set (match_operand:DI 0 "register_operand" "=r") 20672 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))] 20673 "TARGET_64BIT && TARGET_RDPID" 20674 "rdpid\t%0" 20675 [(set_attr "type" "other")]) 20676 20677;; Intirinsics for > i486 20678 20679(define_insn "wbinvd" 20680 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)] 20681 "" 20682 "wbinvd" 20683 [(set_attr "type" "other")]) 20684 20685(define_insn "wbnoinvd" 20686 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)] 20687 "TARGET_WBNOINVD" 20688 "wbnoinvd" 20689 [(set_attr "type" "other")]) 20690 20691(define_insn "movdiri<mode>" 20692 [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m") 20693 (match_operand:SWI48 1 "register_operand" "r")] 20694 UNSPECV_MOVDIRI)] 20695 "TARGET_MOVDIRI" 20696 "movdiri\t{%1, %0|%0, %1}" 20697 [(set_attr "type" "other")]) 20698 20699(define_insn "movdir64b_<mode>" 20700 [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r") 20701 (match_operand:XI 1 "memory_operand")] 20702 UNSPECV_MOVDIR64B)] 20703 "TARGET_MOVDIR64B" 20704 "movdir64b\t{%1, %0|%0, %1}" 20705 [(set_attr "type" "other")]) 20706 20707(include "mmx.md") 20708(include "sse.md") 20709(include "sync.md") 20710