1;; GCC machine description for IA-32 and x86-64. 2;; Copyright (C) 1988-2015 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 a segment register of thread base pointer load 65;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode 66;; ! -- print MPX prefix for jxx/call/ret instructions if required. 67 68(define_c_enum "unspec" [ 69 ;; Relocation specifiers 70 UNSPEC_GOT 71 UNSPEC_GOTOFF 72 UNSPEC_GOTPCREL 73 UNSPEC_GOTTPOFF 74 UNSPEC_TPOFF 75 UNSPEC_NTPOFF 76 UNSPEC_DTPOFF 77 UNSPEC_GOTNTPOFF 78 UNSPEC_INDNTPOFF 79 UNSPEC_PLTOFF 80 UNSPEC_MACHOPIC_OFFSET 81 UNSPEC_PCREL 82 UNSPEC_SIZEOF 83 84 ;; Prologue support 85 UNSPEC_STACK_ALLOC 86 UNSPEC_SET_GOT 87 UNSPEC_SET_RIP 88 UNSPEC_SET_GOT_OFFSET 89 UNSPEC_MEMORY_BLOCKAGE 90 UNSPEC_STACK_CHECK 91 92 ;; TLS support 93 UNSPEC_TP 94 UNSPEC_TLS_GD 95 UNSPEC_TLS_LD_BASE 96 UNSPEC_TLSDESC 97 UNSPEC_TLS_IE_SUN 98 99 ;; Other random patterns 100 UNSPEC_SCAS 101 UNSPEC_FNSTSW 102 UNSPEC_SAHF 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 117 ;; For SSE/MMX support: 118 UNSPEC_FIX_NOTRUNC 119 UNSPEC_MASKMOV 120 UNSPEC_MOVMSK 121 UNSPEC_RCP 122 UNSPEC_RSQRT 123 UNSPEC_PSADBW 124 125 ;; Generic math support 126 UNSPEC_COPYSIGN 127 UNSPEC_IEEE_MIN ; not commutative 128 UNSPEC_IEEE_MAX ; not commutative 129 130 ;; x87 Floating point 131 UNSPEC_SIN 132 UNSPEC_COS 133 UNSPEC_FPATAN 134 UNSPEC_FYL2X 135 UNSPEC_FYL2XP1 136 UNSPEC_FRNDINT 137 UNSPEC_FIST 138 UNSPEC_F2XM1 139 UNSPEC_TAN 140 UNSPEC_FXAM 141 142 ;; x87 Rounding 143 UNSPEC_FRNDINT_FLOOR 144 UNSPEC_FRNDINT_CEIL 145 UNSPEC_FRNDINT_TRUNC 146 UNSPEC_FRNDINT_MASK_PM 147 UNSPEC_FIST_FLOOR 148 UNSPEC_FIST_CEIL 149 150 ;; x87 Double output FP 151 UNSPEC_SINCOS_COS 152 UNSPEC_SINCOS_SIN 153 UNSPEC_XTRACT_FRACT 154 UNSPEC_XTRACT_EXP 155 UNSPEC_FSCALE_FRACT 156 UNSPEC_FSCALE_EXP 157 UNSPEC_FPREM_F 158 UNSPEC_FPREM_U 159 UNSPEC_FPREM1_F 160 UNSPEC_FPREM1_U 161 162 UNSPEC_C2_FLAG 163 UNSPEC_FXAM_MEM 164 165 ;; SSP patterns 166 UNSPEC_SP_SET 167 UNSPEC_SP_TEST 168 UNSPEC_SP_TLS_SET 169 UNSPEC_SP_TLS_TEST 170 171 ;; For ROUND support 172 UNSPEC_ROUND 173 174 ;; For CRC32 support 175 UNSPEC_CRC32 176 177 ;; For BMI support 178 UNSPEC_BEXTR 179 180 ;; For BMI2 support 181 UNSPEC_PDEP 182 UNSPEC_PEXT 183 184 ;; For AVX512F support 185 UNSPEC_KMOV 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 198(define_c_enum "unspecv" [ 199 UNSPECV_BLOCKAGE 200 UNSPECV_STACK_PROBE 201 UNSPECV_PROBE_STACK_RANGE 202 UNSPECV_ALIGN 203 UNSPECV_PROLOGUE_USE 204 UNSPECV_SPLIT_STACK_RETURN 205 UNSPECV_CLD 206 UNSPECV_NOPS 207 UNSPECV_RDTSC 208 UNSPECV_RDTSCP 209 UNSPECV_RDPMC 210 UNSPECV_LLWP_INTRINSIC 211 UNSPECV_SLWP_INTRINSIC 212 UNSPECV_LWPVAL_INTRINSIC 213 UNSPECV_LWPINS_INTRINSIC 214 UNSPECV_RDFSBASE 215 UNSPECV_RDGSBASE 216 UNSPECV_WRFSBASE 217 UNSPECV_WRGSBASE 218 UNSPECV_FXSAVE 219 UNSPECV_FXRSTOR 220 UNSPECV_FXSAVE64 221 UNSPECV_FXRSTOR64 222 UNSPECV_XSAVE 223 UNSPECV_XRSTOR 224 UNSPECV_XSAVE64 225 UNSPECV_XRSTOR64 226 UNSPECV_XSAVEOPT 227 UNSPECV_XSAVEOPT64 228 UNSPECV_XSAVES 229 UNSPECV_XRSTORS 230 UNSPECV_XSAVES64 231 UNSPECV_XRSTORS64 232 UNSPECV_XSAVEC 233 UNSPECV_XSAVEC64 234 235 ;; For atomic compound assignments. 236 UNSPECV_FNSTENV 237 UNSPECV_FLDENV 238 UNSPECV_FNSTSW 239 UNSPECV_FNCLEX 240 241 ;; For RDRAND support 242 UNSPECV_RDRAND 243 244 ;; For RDSEED support 245 UNSPECV_RDSEED 246 247 ;; For RTM support 248 UNSPECV_XBEGIN 249 UNSPECV_XEND 250 UNSPECV_XABORT 251 UNSPECV_XTEST 252 253 UNSPECV_NLGR 254 255 ;; For CLWB support 256 UNSPECV_CLWB 257 258 ;; For PCOMMIT support 259 UNSPECV_PCOMMIT 260 261 ;; For CLFLUSHOPT support 262 UNSPECV_CLFLUSHOPT 263 264 ;; For MONITORX and MWAITX support 265 UNSPECV_MONITORX 266 UNSPECV_MWAITX 267 268]) 269 270;; Constants to represent rounding modes in the ROUND instruction 271(define_constants 272 [(ROUND_FLOOR 0x1) 273 (ROUND_CEIL 0x2) 274 (ROUND_TRUNC 0x3) 275 (ROUND_MXCSR 0x4) 276 (ROUND_NO_EXC 0x8) 277 ]) 278 279;; Constants to represent AVX512F embeded rounding 280(define_constants 281 [(ROUND_NEAREST_INT 0) 282 (ROUND_NEG_INF 1) 283 (ROUND_POS_INF 2) 284 (ROUND_ZERO 3) 285 (NO_ROUND 4) 286 (ROUND_SAE 8) 287 ]) 288 289;; Constants to represent pcomtrue/pcomfalse variants 290(define_constants 291 [(PCOM_FALSE 0) 292 (PCOM_TRUE 1) 293 (COM_FALSE_S 2) 294 (COM_FALSE_P 3) 295 (COM_TRUE_S 4) 296 (COM_TRUE_P 5) 297 ]) 298 299;; Constants used in the XOP pperm instruction 300(define_constants 301 [(PPERM_SRC 0x00) /* copy source */ 302 (PPERM_INVERT 0x20) /* invert source */ 303 (PPERM_REVERSE 0x40) /* bit reverse source */ 304 (PPERM_REV_INV 0x60) /* bit reverse & invert src */ 305 (PPERM_ZERO 0x80) /* all 0's */ 306 (PPERM_ONES 0xa0) /* all 1's */ 307 (PPERM_SIGN 0xc0) /* propagate sign bit */ 308 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */ 309 (PPERM_SRC1 0x00) /* use first source byte */ 310 (PPERM_SRC2 0x10) /* use second source byte */ 311 ]) 312 313;; Registers by name. 314(define_constants 315 [(AX_REG 0) 316 (DX_REG 1) 317 (CX_REG 2) 318 (BX_REG 3) 319 (SI_REG 4) 320 (DI_REG 5) 321 (BP_REG 6) 322 (SP_REG 7) 323 (ST0_REG 8) 324 (ST1_REG 9) 325 (ST2_REG 10) 326 (ST3_REG 11) 327 (ST4_REG 12) 328 (ST5_REG 13) 329 (ST6_REG 14) 330 (ST7_REG 15) 331 (FLAGS_REG 17) 332 (FPSR_REG 18) 333 (FPCR_REG 19) 334 (XMM0_REG 21) 335 (XMM1_REG 22) 336 (XMM2_REG 23) 337 (XMM3_REG 24) 338 (XMM4_REG 25) 339 (XMM5_REG 26) 340 (XMM6_REG 27) 341 (XMM7_REG 28) 342 (MM0_REG 29) 343 (MM1_REG 30) 344 (MM2_REG 31) 345 (MM3_REG 32) 346 (MM4_REG 33) 347 (MM5_REG 34) 348 (MM6_REG 35) 349 (MM7_REG 36) 350 (R8_REG 37) 351 (R9_REG 38) 352 (R10_REG 39) 353 (R11_REG 40) 354 (R12_REG 41) 355 (R13_REG 42) 356 (R14_REG 43) 357 (R15_REG 44) 358 (XMM8_REG 45) 359 (XMM9_REG 46) 360 (XMM10_REG 47) 361 (XMM11_REG 48) 362 (XMM12_REG 49) 363 (XMM13_REG 50) 364 (XMM14_REG 51) 365 (XMM15_REG 52) 366 (XMM16_REG 53) 367 (XMM17_REG 54) 368 (XMM18_REG 55) 369 (XMM19_REG 56) 370 (XMM20_REG 57) 371 (XMM21_REG 58) 372 (XMM22_REG 59) 373 (XMM23_REG 60) 374 (XMM24_REG 61) 375 (XMM25_REG 62) 376 (XMM26_REG 63) 377 (XMM27_REG 64) 378 (XMM28_REG 65) 379 (XMM29_REG 66) 380 (XMM30_REG 67) 381 (XMM31_REG 68) 382 (MASK0_REG 69) 383 (MASK1_REG 70) 384 (MASK2_REG 71) 385 (MASK3_REG 72) 386 (MASK4_REG 73) 387 (MASK5_REG 74) 388 (MASK6_REG 75) 389 (MASK7_REG 76) 390 (BND0_REG 77) 391 (BND1_REG 78) 392 ]) 393 394;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 395;; from i386.c. 396 397;; In C guard expressions, put expressions which may be compile-time 398;; constants first. This allows for better optimization. For 399;; example, write "TARGET_64BIT && reload_completed", not 400;; "reload_completed && TARGET_64BIT". 401 402 403;; Processor type. 404(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem, 405 atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4, 406 btver2,knl" 407 (const (symbol_ref "ix86_schedule"))) 408 409;; A basic instruction type. Refinements due to arguments to be 410;; provided in other attributes. 411(define_attr "type" 412 "other,multi, 413 alu,alu1,negnot,imov,imovx,lea, 414 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1, 415 imul,imulx,idiv,icmp,test,ibr,setcc,icmov, 416 push,pop,call,callv,leave, 417 str,bitmanip, 418 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp, 419 fxch,fistp,fisttp,frndint, 420 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1, 421 ssemul,sseimul,ssediv,sselog,sselog1, 422 sseishft,sseishft1,ssecmp,ssecomi, 423 ssecvt,ssecvt1,sseicvt,sseins, 424 sseshuf,sseshuf1,ssemuladd,sse4arg, 425 lwp,mskmov,msklog, 426 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft, 427 mpxmov,mpxmk,mpxchk,mpxld,mpxst" 428 (const_string "other")) 429 430;; Main data type used by the insn 431(define_attr "mode" 432 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF, 433 V2DF,V2SF,V1DF,V8DF" 434 (const_string "unknown")) 435 436;; The CPU unit operations uses. 437(define_attr "unit" "integer,i387,sse,mmx,unknown" 438 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp, 439 fxch,fistp,fisttp,frndint") 440 (const_string "i387") 441 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1, 442 ssemul,sseimul,ssediv,sselog,sselog1, 443 sseishft,sseishft1,ssecmp,ssecomi, 444 ssecvt,ssecvt1,sseicvt,sseins, 445 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov") 446 (const_string "sse") 447 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 448 (const_string "mmx") 449 (eq_attr "type" "other") 450 (const_string "unknown")] 451 (const_string "integer"))) 452 453;; The minimum required alignment of vector mode memory operands of the SSE 454;; (non-VEX/EVEX) instruction in bits, if it is different from 455;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has 456;; multiple alternatives, this should be conservative maximum of those minimum 457;; required alignments. 458(define_attr "ssememalign" "" (const_int 0)) 459 460;; The (bounding maximum) length of an instruction immediate. 461(define_attr "length_immediate" "" 462 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave, 463 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk, 464 mpxld,mpxst") 465 (const_int 0) 466 (eq_attr "unit" "i387,sse,mmx") 467 (const_int 0) 468 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1, 469 rotate,rotatex,rotate1,imul,icmp,push,pop") 470 (symbol_ref "ix86_attr_length_immediate_default (insn, true)") 471 (eq_attr "type" "imov,test") 472 (symbol_ref "ix86_attr_length_immediate_default (insn, false)") 473 (eq_attr "type" "call") 474 (if_then_else (match_operand 0 "constant_call_address_operand") 475 (const_int 4) 476 (const_int 0)) 477 (eq_attr "type" "callv") 478 (if_then_else (match_operand 1 "constant_call_address_operand") 479 (const_int 4) 480 (const_int 0)) 481 ;; We don't know the size before shorten_branches. Expect 482 ;; the instruction to fit for better scheduling. 483 (eq_attr "type" "ibr") 484 (const_int 1) 485 ] 486 (symbol_ref "/* Update immediate_length and other attributes! */ 487 gcc_unreachable (),1"))) 488 489;; The (bounding maximum) length of an instruction address. 490(define_attr "length_address" "" 491 (cond [(eq_attr "type" "str,other,multi,fxch") 492 (const_int 0) 493 (and (eq_attr "type" "call") 494 (match_operand 0 "constant_call_address_operand")) 495 (const_int 0) 496 (and (eq_attr "type" "callv") 497 (match_operand 1 "constant_call_address_operand")) 498 (const_int 0) 499 ] 500 (symbol_ref "ix86_attr_length_address_default (insn)"))) 501 502;; Set when length prefix is used. 503(define_attr "prefix_data16" "" 504 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 505 (const_int 0) 506 (eq_attr "mode" "HI") 507 (const_int 1) 508 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI")) 509 (const_int 1) 510 ] 511 (const_int 0))) 512 513;; Set when string REP prefix is used. 514(define_attr "prefix_rep" "" 515 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 516 (const_int 0) 517 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 518 (const_int 1) 519 (and (eq_attr "type" "ibr,call,callv") 520 (match_test "ix86_bnd_prefixed_insn_p (insn)")) 521 (const_int 1) 522 ] 523 (const_int 0))) 524 525;; Set when 0f opcode prefix is used. 526(define_attr "prefix_0f" "" 527 (if_then_else 528 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov, 529 mpxmk,mpxmov,mpxchk,mpxld,mpxst") 530 (eq_attr "unit" "sse,mmx")) 531 (const_int 1) 532 (const_int 0))) 533 534;; Set when REX opcode prefix is used. 535(define_attr "prefix_rex" "" 536 (cond [(not (match_test "TARGET_64BIT")) 537 (const_int 0) 538 (and (eq_attr "mode" "DI") 539 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr") 540 (eq_attr "unit" "!mmx"))) 541 (const_int 1) 542 (and (eq_attr "mode" "QI") 543 (match_test "x86_extended_QIreg_mentioned_p (insn)")) 544 (const_int 1) 545 (match_test "x86_extended_reg_mentioned_p (insn)") 546 (const_int 1) 547 (and (eq_attr "type" "imovx") 548 (match_operand:QI 1 "ext_QIreg_operand")) 549 (const_int 1) 550 ] 551 (const_int 0))) 552 553;; There are also additional prefixes in 3DNOW, SSSE3. 554;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte, 555;; sseiadd1,ssecvt1 to 0f7a with no DREX byte. 556;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a. 557(define_attr "prefix_extra" "" 558 (cond [(eq_attr "type" "ssemuladd,sse4arg") 559 (const_int 2) 560 (eq_attr "type" "sseiadd1,ssecvt1") 561 (const_int 1) 562 ] 563 (const_int 0))) 564 565;; Prefix used: original, VEX or maybe VEX. 566(define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex" 567 (cond [(eq_attr "mode" "OI,V8SF,V4DF") 568 (const_string "vex") 569 (eq_attr "mode" "XI,V16SF,V8DF") 570 (const_string "evex") 571 ] 572 (const_string "orig"))) 573 574;; VEX W bit is used. 575(define_attr "prefix_vex_w" "" (const_int 0)) 576 577;; The length of VEX prefix 578;; Only instructions with 0f prefix can have 2 byte VEX prefix, 579;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is 580;; still prefix_0f 1, with prefix_extra 1. 581(define_attr "length_vex" "" 582 (if_then_else (and (eq_attr "prefix_0f" "1") 583 (eq_attr "prefix_extra" "0")) 584 (if_then_else (eq_attr "prefix_vex_w" "1") 585 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)") 586 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)")) 587 (if_then_else (eq_attr "prefix_vex_w" "1") 588 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)") 589 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)")))) 590 591;; 4-bytes evex prefix and 1 byte opcode. 592(define_attr "length_evex" "" (const_int 5)) 593 594;; Set when modrm byte is used. 595(define_attr "modrm" "" 596 (cond [(eq_attr "type" "str,leave") 597 (const_int 0) 598 (eq_attr "unit" "i387") 599 (const_int 0) 600 (and (eq_attr "type" "incdec") 601 (and (not (match_test "TARGET_64BIT")) 602 (ior (match_operand:SI 1 "register_operand") 603 (match_operand:HI 1 "register_operand")))) 604 (const_int 0) 605 (and (eq_attr "type" "push") 606 (not (match_operand 1 "memory_operand"))) 607 (const_int 0) 608 (and (eq_attr "type" "pop") 609 (not (match_operand 0 "memory_operand"))) 610 (const_int 0) 611 (and (eq_attr "type" "imov") 612 (and (not (eq_attr "mode" "DI")) 613 (ior (and (match_operand 0 "register_operand") 614 (match_operand 1 "immediate_operand")) 615 (ior (and (match_operand 0 "ax_reg_operand") 616 (match_operand 1 "memory_displacement_only_operand")) 617 (and (match_operand 0 "memory_displacement_only_operand") 618 (match_operand 1 "ax_reg_operand")))))) 619 (const_int 0) 620 (and (eq_attr "type" "call") 621 (match_operand 0 "constant_call_address_operand")) 622 (const_int 0) 623 (and (eq_attr "type" "callv") 624 (match_operand 1 "constant_call_address_operand")) 625 (const_int 0) 626 (and (eq_attr "type" "alu,alu1,icmp,test") 627 (match_operand 0 "ax_reg_operand")) 628 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))") 629 ] 630 (const_int 1))) 631 632;; When this attribute is set, calculate total insn length from 633;; length_nobnd attribute, prefixed with eventual bnd prefix byte 634(define_attr "length_nobnd" "" (const_int 0)) 635 636;; The (bounding maximum) length of an instruction in bytes. 637;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 638;; Later we may want to split them and compute proper length as for 639;; other insns. 640(define_attr "length" "" 641 (cond [(eq_attr "length_nobnd" "!0") 642 (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)")) 643 (attr "length_nobnd")) 644 (eq_attr "type" "other,multi,fistp,frndint") 645 (const_int 16) 646 (eq_attr "type" "fcmp") 647 (const_int 4) 648 (eq_attr "unit" "i387") 649 (plus (const_int 2) 650 (plus (attr "prefix_data16") 651 (attr "length_address"))) 652 (ior (eq_attr "prefix" "evex") 653 (and (ior (eq_attr "prefix" "maybe_evex") 654 (eq_attr "prefix" "maybe_vex")) 655 (match_test "TARGET_AVX512F"))) 656 (plus (attr "length_evex") 657 (plus (attr "length_immediate") 658 (plus (attr "modrm") 659 (attr "length_address")))) 660 (ior (eq_attr "prefix" "vex") 661 (and (ior (eq_attr "prefix" "maybe_vex") 662 (eq_attr "prefix" "maybe_evex")) 663 (match_test "TARGET_AVX"))) 664 (plus (attr "length_vex") 665 (plus (attr "length_immediate") 666 (plus (attr "modrm") 667 (attr "length_address"))))] 668 (plus (plus (attr "modrm") 669 (plus (attr "prefix_0f") 670 (plus (attr "prefix_rex") 671 (plus (attr "prefix_extra") 672 (const_int 1))))) 673 (plus (attr "prefix_rep") 674 (plus (attr "prefix_data16") 675 (plus (attr "length_immediate") 676 (attr "length_address"))))))) 677 678;; The `memory' attribute is `none' if no memory is referenced, `load' or 679;; `store' if there is a simple memory reference therein, or `unknown' 680;; if the instruction is complex. 681 682(define_attr "memory" "none,load,store,both,unknown" 683 (cond [(eq_attr "type" "other,multi,str,lwp") 684 (const_string "unknown") 685 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk") 686 (const_string "none") 687 (eq_attr "type" "fistp,leave") 688 (const_string "both") 689 (eq_attr "type" "frndint") 690 (const_string "load") 691 (eq_attr "type" "mpxld") 692 (const_string "load") 693 (eq_attr "type" "mpxst") 694 (const_string "store") 695 (eq_attr "type" "push") 696 (if_then_else (match_operand 1 "memory_operand") 697 (const_string "both") 698 (const_string "store")) 699 (eq_attr "type" "pop") 700 (if_then_else (match_operand 0 "memory_operand") 701 (const_string "both") 702 (const_string "load")) 703 (eq_attr "type" "setcc") 704 (if_then_else (match_operand 0 "memory_operand") 705 (const_string "store") 706 (const_string "none")) 707 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 708 (if_then_else (ior (match_operand 0 "memory_operand") 709 (match_operand 1 "memory_operand")) 710 (const_string "load") 711 (const_string "none")) 712 (eq_attr "type" "ibr") 713 (if_then_else (match_operand 0 "memory_operand") 714 (const_string "load") 715 (const_string "none")) 716 (eq_attr "type" "call") 717 (if_then_else (match_operand 0 "constant_call_address_operand") 718 (const_string "none") 719 (const_string "load")) 720 (eq_attr "type" "callv") 721 (if_then_else (match_operand 1 "constant_call_address_operand") 722 (const_string "none") 723 (const_string "load")) 724 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1") 725 (match_operand 1 "memory_operand")) 726 (const_string "both") 727 (and (match_operand 0 "memory_operand") 728 (match_operand 1 "memory_operand")) 729 (const_string "both") 730 (match_operand 0 "memory_operand") 731 (const_string "store") 732 (match_operand 1 "memory_operand") 733 (const_string "load") 734 (and (eq_attr "type" 735 "!alu1,negnot,ishift1, 736 imov,imovx,icmp,test,bitmanip, 737 fmov,fcmp,fsgn, 738 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt, 739 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1, 740 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov") 741 (match_operand 2 "memory_operand")) 742 (const_string "load") 743 (and (eq_attr "type" "icmov,ssemuladd,sse4arg") 744 (match_operand 3 "memory_operand")) 745 (const_string "load") 746 ] 747 (const_string "none"))) 748 749;; Indicates if an instruction has both an immediate and a displacement. 750 751(define_attr "imm_disp" "false,true,unknown" 752 (cond [(eq_attr "type" "other,multi") 753 (const_string "unknown") 754 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 755 (and (match_operand 0 "memory_displacement_operand") 756 (match_operand 1 "immediate_operand"))) 757 (const_string "true") 758 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv") 759 (and (match_operand 0 "memory_displacement_operand") 760 (match_operand 2 "immediate_operand"))) 761 (const_string "true") 762 ] 763 (const_string "false"))) 764 765;; Indicates if an FP operation has an integer source. 766 767(define_attr "fp_int_src" "false,true" 768 (const_string "false")) 769 770;; Defines rounding mode of an FP operation. 771 772(define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any" 773 (const_string "any")) 774 775;; Define attribute to classify add/sub insns that consumes carry flag (CF) 776(define_attr "use_carry" "0,1" (const_string "0")) 777 778;; Define attribute to indicate unaligned ssemov insns 779(define_attr "movu" "0,1" (const_string "0")) 780 781;; Used to control the "enabled" attribute on a per-instruction basis. 782(define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64, 783 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx, 784 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f, 785 fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq, 786 avx512vl,noavx512vl" 787 (const_string "base")) 788 789(define_attr "enabled" "" 790 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT") 791 (eq_attr "isa" "x64_sse4") 792 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1") 793 (eq_attr "isa" "x64_sse4_noavx") 794 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX") 795 (eq_attr "isa" "x64_avx") 796 (symbol_ref "TARGET_64BIT && TARGET_AVX") 797 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT") 798 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2") 799 (eq_attr "isa" "sse2_noavx") 800 (symbol_ref "TARGET_SSE2 && !TARGET_AVX") 801 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3") 802 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1") 803 (eq_attr "isa" "sse4_noavx") 804 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX") 805 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX") 806 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX") 807 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2") 808 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2") 809 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI") 810 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2") 811 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4") 812 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA") 813 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F") 814 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F") 815 (eq_attr "isa" "fma_avx512f") 816 (symbol_ref "TARGET_FMA || TARGET_AVX512F") 817 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW") 818 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW") 819 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ") 820 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ") 821 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL") 822 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL") 823 ] 824 (const_int 1))) 825 826(define_attr "preferred_for_size" "" (const_int 1)) 827(define_attr "preferred_for_speed" "" (const_int 1)) 828 829;; Describe a user's asm statement. 830(define_asm_attributes 831 [(set_attr "length" "128") 832 (set_attr "type" "multi")]) 833 834(define_code_iterator plusminus [plus minus]) 835 836(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus]) 837 838(define_code_iterator multdiv [mult div]) 839 840;; Base name for define_insn 841(define_code_attr plusminus_insn 842 [(plus "add") (ss_plus "ssadd") (us_plus "usadd") 843 (minus "sub") (ss_minus "sssub") (us_minus "ussub")]) 844 845;; Base name for insn mnemonic. 846(define_code_attr plusminus_mnemonic 847 [(plus "add") (ss_plus "adds") (us_plus "addus") 848 (minus "sub") (ss_minus "subs") (us_minus "subus")]) 849(define_code_attr multdiv_mnemonic 850 [(mult "mul") (div "div")]) 851 852;; Mark commutative operators as such in constraints. 853(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%") 854 (minus "") (ss_minus "") (us_minus "")]) 855 856;; Mapping of max and min 857(define_code_iterator maxmin [smax smin umax umin]) 858 859;; Mapping of signed max and min 860(define_code_iterator smaxmin [smax smin]) 861 862;; Mapping of unsigned max and min 863(define_code_iterator umaxmin [umax umin]) 864 865;; Base name for integer and FP insn mnemonic 866(define_code_attr maxmin_int [(smax "maxs") (smin "mins") 867 (umax "maxu") (umin "minu")]) 868(define_code_attr maxmin_float [(smax "max") (smin "min")]) 869 870;; Mapping of logic operators 871(define_code_iterator any_logic [and ior xor]) 872(define_code_iterator any_or [ior xor]) 873(define_code_iterator fpint_logic [and xor]) 874 875;; Base name for insn mnemonic. 876(define_code_attr logic [(and "and") (ior "or") (xor "xor")]) 877 878;; Mapping of logic-shift operators 879(define_code_iterator any_lshift [ashift lshiftrt]) 880 881;; Mapping of shift-right operators 882(define_code_iterator any_shiftrt [lshiftrt ashiftrt]) 883 884;; Mapping of all shift operators 885(define_code_iterator any_shift [ashift lshiftrt ashiftrt]) 886 887;; Base name for define_insn 888(define_code_attr shift_insn 889 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")]) 890 891;; Base name for insn mnemonic. 892(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")]) 893(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")]) 894 895;; Mapping of rotate operators 896(define_code_iterator any_rotate [rotate rotatert]) 897 898;; Base name for define_insn 899(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")]) 900 901;; Base name for insn mnemonic. 902(define_code_attr rotate [(rotate "rol") (rotatert "ror")]) 903 904;; Mapping of abs neg operators 905(define_code_iterator absneg [abs neg]) 906 907;; Base name for x87 insn mnemonic. 908(define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")]) 909 910;; Used in signed and unsigned widening multiplications. 911(define_code_iterator any_extend [sign_extend zero_extend]) 912 913;; Prefix for insn menmonic. 914(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")]) 915 916;; Prefix for define_insn 917(define_code_attr u [(sign_extend "") (zero_extend "u")]) 918(define_code_attr s [(sign_extend "s") (zero_extend "u")]) 919(define_code_attr u_bool [(sign_extend "false") (zero_extend "true")]) 920 921;; Used in signed and unsigned truncations. 922(define_code_iterator any_truncate [ss_truncate truncate us_truncate]) 923;; Instruction suffix for truncations. 924(define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")]) 925 926;; Used in signed and unsigned fix. 927(define_code_iterator any_fix [fix unsigned_fix]) 928(define_code_attr fixsuffix [(fix "") (unsigned_fix "u")]) 929 930;; Used in signed and unsigned float. 931(define_code_iterator any_float [float unsigned_float]) 932(define_code_attr floatsuffix [(float "") (unsigned_float "u")]) 933 934;; All integer modes. 935(define_mode_iterator SWI1248x [QI HI SI DI]) 936 937;; All integer modes with AVX512BW. 938(define_mode_iterator SWI1248_AVX512BW 939 [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")]) 940 941;; All integer modes without QImode. 942(define_mode_iterator SWI248x [HI SI DI]) 943 944;; All integer modes without QImode and HImode. 945(define_mode_iterator SWI48x [SI DI]) 946 947;; All integer modes without SImode and DImode. 948(define_mode_iterator SWI12 [QI HI]) 949 950;; All integer modes without DImode. 951(define_mode_iterator SWI124 [QI HI SI]) 952 953;; All integer modes without QImode and DImode. 954(define_mode_iterator SWI24 [HI SI]) 955 956;; Single word integer modes. 957(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")]) 958 959;; Single word integer modes without QImode. 960(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")]) 961 962;; Single word integer modes without QImode and HImode. 963(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")]) 964 965;; All math-dependant single and double word integer modes. 966(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH") 967 (HI "TARGET_HIMODE_MATH") 968 SI DI (TI "TARGET_64BIT")]) 969 970;; Math-dependant single word integer modes. 971(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH") 972 (HI "TARGET_HIMODE_MATH") 973 SI (DI "TARGET_64BIT")]) 974 975;; Math-dependant integer modes without DImode. 976(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH") 977 (HI "TARGET_HIMODE_MATH") 978 SI]) 979 980;; Math-dependant single word integer modes without QImode. 981(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH") 982 SI (DI "TARGET_64BIT")]) 983 984;; Double word integer modes. 985(define_mode_iterator DWI [(DI "!TARGET_64BIT") 986 (TI "TARGET_64BIT")]) 987 988;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not 989;; compile time constant, it is faster to use <MODE_SIZE> than 990;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on 991;; command line options just use GET_MODE_SIZE macro. 992(define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16") 993 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)") 994 (V16QI "16") (V32QI "32") (V64QI "64") 995 (V8HI "16") (V16HI "32") (V32HI "64") 996 (V4SI "16") (V8SI "32") (V16SI "64") 997 (V2DI "16") (V4DI "32") (V8DI "64") 998 (V1TI "16") (V2TI "32") (V4TI "64") 999 (V2DF "16") (V4DF "32") (V8DF "64") 1000 (V4SF "16") (V8SF "32") (V16SF "64")]) 1001 1002;; Double word integer modes as mode attribute. 1003(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")]) 1004(define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")]) 1005 1006;; Half mode for double word integer modes. 1007(define_mode_iterator DWIH [(SI "!TARGET_64BIT") 1008 (DI "TARGET_64BIT")]) 1009 1010;; Bound modes. 1011(define_mode_iterator BND [(BND32 "!TARGET_LP64") 1012 (BND64 "TARGET_LP64")]) 1013 1014;; Pointer mode corresponding to bound mode. 1015(define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")]) 1016 1017;; MPX check types 1018(define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN]) 1019 1020;; Check name 1021(define_int_attr bndcheck [(UNSPEC_BNDCL "cl") 1022 (UNSPEC_BNDCU "cu") 1023 (UNSPEC_BNDCN "cn")]) 1024 1025;; Instruction suffix for integer modes. 1026(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")]) 1027 1028;; Instruction suffix for masks. 1029(define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")]) 1030 1031;; Pointer size prefix for integer modes (Intel asm dialect) 1032(define_mode_attr iptrsize [(QI "BYTE") 1033 (HI "WORD") 1034 (SI "DWORD") 1035 (DI "QWORD")]) 1036 1037;; Register class for integer modes. 1038(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) 1039 1040;; Immediate operand constraint for integer modes. 1041(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")]) 1042 1043;; General operand constraint for word modes. 1044(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")]) 1045 1046;; Immediate operand constraint for double integer modes. 1047(define_mode_attr di [(SI "nF") (DI "e")]) 1048 1049;; Immediate operand constraint for shifts. 1050(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")]) 1051 1052;; General operand predicate for integer modes. 1053(define_mode_attr general_operand 1054 [(QI "general_operand") 1055 (HI "general_operand") 1056 (SI "x86_64_general_operand") 1057 (DI "x86_64_general_operand") 1058 (TI "x86_64_general_operand")]) 1059 1060;; General sign extend operand predicate for integer modes, 1061;; which disallows VOIDmode operands and thus it is suitable 1062;; for use inside sign_extend. 1063(define_mode_attr general_sext_operand 1064 [(QI "sext_operand") 1065 (HI "sext_operand") 1066 (SI "x86_64_sext_operand") 1067 (DI "x86_64_sext_operand")]) 1068 1069;; General sign/zero extend operand predicate for integer modes. 1070(define_mode_attr general_szext_operand 1071 [(QI "general_operand") 1072 (HI "general_operand") 1073 (SI "x86_64_szext_general_operand") 1074 (DI "x86_64_szext_general_operand")]) 1075 1076;; Immediate operand predicate for integer modes. 1077(define_mode_attr immediate_operand 1078 [(QI "immediate_operand") 1079 (HI "immediate_operand") 1080 (SI "x86_64_immediate_operand") 1081 (DI "x86_64_immediate_operand")]) 1082 1083;; Nonmemory operand predicate for integer modes. 1084(define_mode_attr nonmemory_operand 1085 [(QI "nonmemory_operand") 1086 (HI "nonmemory_operand") 1087 (SI "x86_64_nonmemory_operand") 1088 (DI "x86_64_nonmemory_operand")]) 1089 1090;; Operand predicate for shifts. 1091(define_mode_attr shift_operand 1092 [(QI "nonimmediate_operand") 1093 (HI "nonimmediate_operand") 1094 (SI "nonimmediate_operand") 1095 (DI "shiftdi_operand") 1096 (TI "register_operand")]) 1097 1098;; Operand predicate for shift argument. 1099(define_mode_attr shift_immediate_operand 1100 [(QI "const_1_to_31_operand") 1101 (HI "const_1_to_31_operand") 1102 (SI "const_1_to_31_operand") 1103 (DI "const_1_to_63_operand")]) 1104 1105;; Input operand predicate for arithmetic left shifts. 1106(define_mode_attr ashl_input_operand 1107 [(QI "nonimmediate_operand") 1108 (HI "nonimmediate_operand") 1109 (SI "nonimmediate_operand") 1110 (DI "ashldi_input_operand") 1111 (TI "reg_or_pm1_operand")]) 1112 1113;; SSE and x87 SFmode and DFmode floating point modes 1114(define_mode_iterator MODEF [SF DF]) 1115 1116;; All x87 floating point modes 1117(define_mode_iterator X87MODEF [SF DF XF]) 1118 1119;; SSE instruction suffix for various modes 1120(define_mode_attr ssemodesuffix 1121 [(SF "ss") (DF "sd") 1122 (V16SF "ps") (V8DF "pd") 1123 (V8SF "ps") (V4DF "pd") 1124 (V4SF "ps") (V2DF "pd") 1125 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q") 1126 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q") 1127 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")]) 1128 1129;; SSE vector suffix for floating point modes 1130(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")]) 1131 1132;; SSE vector mode corresponding to a scalar mode 1133(define_mode_attr ssevecmode 1134 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")]) 1135(define_mode_attr ssevecmodelower 1136 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")]) 1137 1138;; Instruction suffix for REX 64bit operators. 1139(define_mode_attr rex64suffix [(SI "") (DI "{q}")]) 1140 1141;; This mode iterator allows :P to be used for patterns that operate on 1142;; pointer-sized quantities. Exactly one of the two alternatives will match. 1143(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 1144 1145;; This mode iterator allows :W to be used for patterns that operate on 1146;; word_mode sized quantities. 1147(define_mode_iterator W 1148 [(SI "word_mode == SImode") (DI "word_mode == DImode")]) 1149 1150;; This mode iterator allows :PTR to be used for patterns that operate on 1151;; ptr_mode sized quantities. 1152(define_mode_iterator PTR 1153 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")]) 1154 1155;; Scheduling descriptions 1156 1157(include "pentium.md") 1158(include "ppro.md") 1159(include "k6.md") 1160(include "athlon.md") 1161(include "bdver1.md") 1162(include "bdver3.md") 1163(include "btver2.md") 1164(include "geode.md") 1165(include "atom.md") 1166(include "slm.md") 1167(include "core2.md") 1168 1169 1170;; Operand and operator predicates and constraints 1171 1172(include "predicates.md") 1173(include "constraints.md") 1174 1175 1176;; Compare and branch/compare and store instructions. 1177 1178(define_expand "cbranch<mode>4" 1179 [(set (reg:CC FLAGS_REG) 1180 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand") 1181 (match_operand:SDWIM 2 "<general_operand>"))) 1182 (set (pc) (if_then_else 1183 (match_operator 0 "ordered_comparison_operator" 1184 [(reg:CC FLAGS_REG) (const_int 0)]) 1185 (label_ref (match_operand 3)) 1186 (pc)))] 1187 "" 1188{ 1189 if (MEM_P (operands[1]) && MEM_P (operands[2])) 1190 operands[1] = force_reg (<MODE>mode, operands[1]); 1191 ix86_expand_branch (GET_CODE (operands[0]), 1192 operands[1], operands[2], operands[3]); 1193 DONE; 1194}) 1195 1196(define_expand "cstore<mode>4" 1197 [(set (reg:CC FLAGS_REG) 1198 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand") 1199 (match_operand:SWIM 3 "<general_operand>"))) 1200 (set (match_operand:QI 0 "register_operand") 1201 (match_operator 1 "ordered_comparison_operator" 1202 [(reg:CC FLAGS_REG) (const_int 0)]))] 1203 "" 1204{ 1205 if (MEM_P (operands[2]) && MEM_P (operands[3])) 1206 operands[2] = force_reg (<MODE>mode, operands[2]); 1207 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1208 operands[2], operands[3]); 1209 DONE; 1210}) 1211 1212(define_expand "cmp<mode>_1" 1213 [(set (reg:CC FLAGS_REG) 1214 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand") 1215 (match_operand:SWI48 1 "<general_operand>")))]) 1216 1217(define_insn "*cmp<mode>_ccno_1" 1218 [(set (reg FLAGS_REG) 1219 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>") 1220 (match_operand:SWI 1 "const0_operand")))] 1221 "ix86_match_ccmode (insn, CCNOmode)" 1222 "@ 1223 test{<imodesuffix>}\t%0, %0 1224 cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1225 [(set_attr "type" "test,icmp") 1226 (set_attr "length_immediate" "0,1") 1227 (set_attr "mode" "<MODE>")]) 1228 1229(define_insn "*cmp<mode>_1" 1230 [(set (reg FLAGS_REG) 1231 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 1232 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))] 1233 "ix86_match_ccmode (insn, CCmode)" 1234 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1235 [(set_attr "type" "icmp") 1236 (set_attr "mode" "<MODE>")]) 1237 1238(define_insn "*cmp<mode>_minus_1" 1239 [(set (reg FLAGS_REG) 1240 (compare 1241 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 1242 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) 1243 (const_int 0)))] 1244 "ix86_match_ccmode (insn, CCGOCmode)" 1245 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1246 [(set_attr "type" "icmp") 1247 (set_attr "mode" "<MODE>")]) 1248 1249(define_insn "*cmpqi_ext_1" 1250 [(set (reg FLAGS_REG) 1251 (compare 1252 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m") 1253 (subreg:QI 1254 (zero_extract:SI 1255 (match_operand 1 "ext_register_operand" "Q,Q") 1256 (const_int 8) 1257 (const_int 8)) 0)))] 1258 "ix86_match_ccmode (insn, CCmode)" 1259 "cmp{b}\t{%h1, %0|%0, %h1}" 1260 [(set_attr "isa" "*,nox64") 1261 (set_attr "type" "icmp") 1262 (set_attr "mode" "QI")]) 1263 1264(define_insn "*cmpqi_ext_2" 1265 [(set (reg FLAGS_REG) 1266 (compare 1267 (subreg:QI 1268 (zero_extract:SI 1269 (match_operand 0 "ext_register_operand" "Q") 1270 (const_int 8) 1271 (const_int 8)) 0) 1272 (match_operand:QI 1 "const0_operand")))] 1273 "ix86_match_ccmode (insn, CCNOmode)" 1274 "test{b}\t%h0, %h0" 1275 [(set_attr "type" "test") 1276 (set_attr "length_immediate" "0") 1277 (set_attr "mode" "QI")]) 1278 1279(define_expand "cmpqi_ext_3" 1280 [(set (reg:CC FLAGS_REG) 1281 (compare:CC 1282 (subreg:QI 1283 (zero_extract:SI 1284 (match_operand 0 "ext_register_operand") 1285 (const_int 8) 1286 (const_int 8)) 0) 1287 (match_operand:QI 1 "const_int_operand")))]) 1288 1289(define_insn "*cmpqi_ext_3" 1290 [(set (reg FLAGS_REG) 1291 (compare 1292 (subreg:QI 1293 (zero_extract:SI 1294 (match_operand 0 "ext_register_operand" "Q,Q") 1295 (const_int 8) 1296 (const_int 8)) 0) 1297 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))] 1298 "ix86_match_ccmode (insn, CCmode)" 1299 "cmp{b}\t{%1, %h0|%h0, %1}" 1300 [(set_attr "isa" "*,nox64") 1301 (set_attr "type" "icmp") 1302 (set_attr "modrm" "1") 1303 (set_attr "mode" "QI")]) 1304 1305(define_insn "*cmpqi_ext_4" 1306 [(set (reg FLAGS_REG) 1307 (compare 1308 (subreg:QI 1309 (zero_extract:SI 1310 (match_operand 0 "ext_register_operand" "Q") 1311 (const_int 8) 1312 (const_int 8)) 0) 1313 (subreg:QI 1314 (zero_extract:SI 1315 (match_operand 1 "ext_register_operand" "Q") 1316 (const_int 8) 1317 (const_int 8)) 0)))] 1318 "ix86_match_ccmode (insn, CCmode)" 1319 "cmp{b}\t{%h1, %h0|%h0, %h1}" 1320 [(set_attr "type" "icmp") 1321 (set_attr "mode" "QI")]) 1322 1323;; These implement float point compares. 1324;; %%% See if we can get away with VOIDmode operands on the actual insns, 1325;; which would allow mix and match FP modes on the compares. Which is what 1326;; the old patterns did, but with many more of them. 1327 1328(define_expand "cbranchxf4" 1329 [(set (reg:CC FLAGS_REG) 1330 (compare:CC (match_operand:XF 1 "nonmemory_operand") 1331 (match_operand:XF 2 "nonmemory_operand"))) 1332 (set (pc) (if_then_else 1333 (match_operator 0 "ix86_fp_comparison_operator" 1334 [(reg:CC FLAGS_REG) 1335 (const_int 0)]) 1336 (label_ref (match_operand 3)) 1337 (pc)))] 1338 "TARGET_80387" 1339{ 1340 ix86_expand_branch (GET_CODE (operands[0]), 1341 operands[1], operands[2], operands[3]); 1342 DONE; 1343}) 1344 1345(define_expand "cstorexf4" 1346 [(set (reg:CC FLAGS_REG) 1347 (compare:CC (match_operand:XF 2 "nonmemory_operand") 1348 (match_operand:XF 3 "nonmemory_operand"))) 1349 (set (match_operand:QI 0 "register_operand") 1350 (match_operator 1 "ix86_fp_comparison_operator" 1351 [(reg:CC FLAGS_REG) 1352 (const_int 0)]))] 1353 "TARGET_80387" 1354{ 1355 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1356 operands[2], operands[3]); 1357 DONE; 1358}) 1359 1360(define_expand "cbranch<mode>4" 1361 [(set (reg:CC FLAGS_REG) 1362 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand") 1363 (match_operand:MODEF 2 "cmp_fp_expander_operand"))) 1364 (set (pc) (if_then_else 1365 (match_operator 0 "ix86_fp_comparison_operator" 1366 [(reg:CC FLAGS_REG) 1367 (const_int 0)]) 1368 (label_ref (match_operand 3)) 1369 (pc)))] 1370 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1371{ 1372 ix86_expand_branch (GET_CODE (operands[0]), 1373 operands[1], operands[2], operands[3]); 1374 DONE; 1375}) 1376 1377(define_expand "cstore<mode>4" 1378 [(set (reg:CC FLAGS_REG) 1379 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand") 1380 (match_operand:MODEF 3 "cmp_fp_expander_operand"))) 1381 (set (match_operand:QI 0 "register_operand") 1382 (match_operator 1 "ix86_fp_comparison_operator" 1383 [(reg:CC FLAGS_REG) 1384 (const_int 0)]))] 1385 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1386{ 1387 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1388 operands[2], operands[3]); 1389 DONE; 1390}) 1391 1392(define_expand "cbranchcc4" 1393 [(set (pc) (if_then_else 1394 (match_operator 0 "comparison_operator" 1395 [(match_operand 1 "flags_reg_operand") 1396 (match_operand 2 "const0_operand")]) 1397 (label_ref (match_operand 3)) 1398 (pc)))] 1399 "" 1400{ 1401 ix86_expand_branch (GET_CODE (operands[0]), 1402 operands[1], operands[2], operands[3]); 1403 DONE; 1404}) 1405 1406(define_expand "cstorecc4" 1407 [(set (match_operand:QI 0 "register_operand") 1408 (match_operator 1 "comparison_operator" 1409 [(match_operand 2 "flags_reg_operand") 1410 (match_operand 3 "const0_operand")]))] 1411 "" 1412{ 1413 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1414 operands[2], operands[3]); 1415 DONE; 1416}) 1417 1418 1419;; FP compares, step 1: 1420;; Set the FP condition codes. 1421;; 1422;; CCFPmode compare with exceptions 1423;; CCFPUmode compare with no exceptions 1424 1425;; We may not use "#" to split and emit these, since the REG_DEAD notes 1426;; used to manage the reg stack popping would not be preserved. 1427 1428(define_insn "*cmp<mode>_0_i387" 1429 [(set (match_operand:HI 0 "register_operand" "=a") 1430 (unspec:HI 1431 [(compare:CCFP 1432 (match_operand:X87MODEF 1 "register_operand" "f") 1433 (match_operand:X87MODEF 2 "const0_operand"))] 1434 UNSPEC_FNSTSW))] 1435 "TARGET_80387" 1436 "* return output_fp_compare (insn, operands, false, false);" 1437 [(set_attr "type" "multi") 1438 (set_attr "unit" "i387") 1439 (set_attr "mode" "<MODE>")]) 1440 1441(define_insn_and_split "*cmp<mode>_0_cc_i387" 1442 [(set (reg:CCFP FLAGS_REG) 1443 (compare:CCFP 1444 (match_operand:X87MODEF 1 "register_operand" "f") 1445 (match_operand:X87MODEF 2 "const0_operand"))) 1446 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1447 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" 1448 "#" 1449 "&& reload_completed" 1450 [(set (match_dup 0) 1451 (unspec:HI 1452 [(compare:CCFP (match_dup 1)(match_dup 2))] 1453 UNSPEC_FNSTSW)) 1454 (set (reg:CC FLAGS_REG) 1455 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1456 "" 1457 [(set_attr "type" "multi") 1458 (set_attr "unit" "i387") 1459 (set_attr "mode" "<MODE>")]) 1460 1461(define_insn "*cmpxf_i387" 1462 [(set (match_operand:HI 0 "register_operand" "=a") 1463 (unspec:HI 1464 [(compare:CCFP 1465 (match_operand:XF 1 "register_operand" "f") 1466 (match_operand:XF 2 "register_operand" "f"))] 1467 UNSPEC_FNSTSW))] 1468 "TARGET_80387" 1469 "* return output_fp_compare (insn, operands, false, false);" 1470 [(set_attr "type" "multi") 1471 (set_attr "unit" "i387") 1472 (set_attr "mode" "XF")]) 1473 1474(define_insn_and_split "*cmpxf_cc_i387" 1475 [(set (reg:CCFP FLAGS_REG) 1476 (compare:CCFP 1477 (match_operand:XF 1 "register_operand" "f") 1478 (match_operand:XF 2 "register_operand" "f"))) 1479 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1480 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" 1481 "#" 1482 "&& reload_completed" 1483 [(set (match_dup 0) 1484 (unspec:HI 1485 [(compare:CCFP (match_dup 1)(match_dup 2))] 1486 UNSPEC_FNSTSW)) 1487 (set (reg:CC FLAGS_REG) 1488 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1489 "" 1490 [(set_attr "type" "multi") 1491 (set_attr "unit" "i387") 1492 (set_attr "mode" "XF")]) 1493 1494(define_insn "*cmp<mode>_i387" 1495 [(set (match_operand:HI 0 "register_operand" "=a") 1496 (unspec:HI 1497 [(compare:CCFP 1498 (match_operand:MODEF 1 "register_operand" "f") 1499 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))] 1500 UNSPEC_FNSTSW))] 1501 "TARGET_80387" 1502 "* return output_fp_compare (insn, operands, false, false);" 1503 [(set_attr "type" "multi") 1504 (set_attr "unit" "i387") 1505 (set_attr "mode" "<MODE>")]) 1506 1507(define_insn_and_split "*cmp<mode>_cc_i387" 1508 [(set (reg:CCFP FLAGS_REG) 1509 (compare:CCFP 1510 (match_operand:MODEF 1 "register_operand" "f") 1511 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))) 1512 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1513 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" 1514 "#" 1515 "&& reload_completed" 1516 [(set (match_dup 0) 1517 (unspec:HI 1518 [(compare:CCFP (match_dup 1)(match_dup 2))] 1519 UNSPEC_FNSTSW)) 1520 (set (reg:CC FLAGS_REG) 1521 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1522 "" 1523 [(set_attr "type" "multi") 1524 (set_attr "unit" "i387") 1525 (set_attr "mode" "<MODE>")]) 1526 1527(define_insn "*cmpu<mode>_i387" 1528 [(set (match_operand:HI 0 "register_operand" "=a") 1529 (unspec:HI 1530 [(compare:CCFPU 1531 (match_operand:X87MODEF 1 "register_operand" "f") 1532 (match_operand:X87MODEF 2 "register_operand" "f"))] 1533 UNSPEC_FNSTSW))] 1534 "TARGET_80387" 1535 "* return output_fp_compare (insn, operands, false, true);" 1536 [(set_attr "type" "multi") 1537 (set_attr "unit" "i387") 1538 (set_attr "mode" "<MODE>")]) 1539 1540(define_insn_and_split "*cmpu<mode>_cc_i387" 1541 [(set (reg:CCFPU FLAGS_REG) 1542 (compare:CCFPU 1543 (match_operand:X87MODEF 1 "register_operand" "f") 1544 (match_operand:X87MODEF 2 "register_operand" "f"))) 1545 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1546 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE" 1547 "#" 1548 "&& reload_completed" 1549 [(set (match_dup 0) 1550 (unspec:HI 1551 [(compare:CCFPU (match_dup 1)(match_dup 2))] 1552 UNSPEC_FNSTSW)) 1553 (set (reg:CC FLAGS_REG) 1554 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1555 "" 1556 [(set_attr "type" "multi") 1557 (set_attr "unit" "i387") 1558 (set_attr "mode" "<MODE>")]) 1559 1560(define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387" 1561 [(set (match_operand:HI 0 "register_operand" "=a") 1562 (unspec:HI 1563 [(compare:CCFP 1564 (match_operand:X87MODEF 1 "register_operand" "f") 1565 (match_operator:X87MODEF 3 "float_operator" 1566 [(match_operand:SWI24 2 "memory_operand" "m")]))] 1567 UNSPEC_FNSTSW))] 1568 "TARGET_80387 1569 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 1570 || optimize_function_for_size_p (cfun))" 1571 "* return output_fp_compare (insn, operands, false, false);" 1572 [(set_attr "type" "multi") 1573 (set_attr "unit" "i387") 1574 (set_attr "fp_int_src" "true") 1575 (set_attr "mode" "<SWI24:MODE>")]) 1576 1577(define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387" 1578 [(set (reg:CCFP FLAGS_REG) 1579 (compare:CCFP 1580 (match_operand:X87MODEF 1 "register_operand" "f") 1581 (match_operator:X87MODEF 3 "float_operator" 1582 [(match_operand:SWI24 2 "memory_operand" "m")]))) 1583 (clobber (match_operand:HI 0 "register_operand" "=a"))] 1584 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE 1585 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 1586 || optimize_function_for_size_p (cfun))" 1587 "#" 1588 "&& reload_completed" 1589 [(set (match_dup 0) 1590 (unspec:HI 1591 [(compare:CCFP 1592 (match_dup 1) 1593 (match_op_dup 3 [(match_dup 2)]))] 1594 UNSPEC_FNSTSW)) 1595 (set (reg:CC FLAGS_REG) 1596 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))] 1597 "" 1598 [(set_attr "type" "multi") 1599 (set_attr "unit" "i387") 1600 (set_attr "fp_int_src" "true") 1601 (set_attr "mode" "<SWI24:MODE>")]) 1602 1603;; FP compares, step 2 1604;; Move the fpsw to ax. 1605 1606(define_insn "x86_fnstsw_1" 1607 [(set (match_operand:HI 0 "register_operand" "=a") 1608 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 1609 "TARGET_80387" 1610 "fnstsw\t%0" 1611 [(set_attr "length" "2") 1612 (set_attr "mode" "SI") 1613 (set_attr "unit" "i387")]) 1614 1615;; FP compares, step 3 1616;; Get ax into flags, general case. 1617 1618(define_insn "x86_sahf_1" 1619 [(set (reg:CC FLAGS_REG) 1620 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 1621 UNSPEC_SAHF))] 1622 "TARGET_SAHF" 1623{ 1624#ifndef HAVE_AS_IX86_SAHF 1625 if (TARGET_64BIT) 1626 return ASM_BYTE "0x9e"; 1627 else 1628#endif 1629 return "sahf"; 1630} 1631 [(set_attr "length" "1") 1632 (set_attr "athlon_decode" "vector") 1633 (set_attr "amdfam10_decode" "direct") 1634 (set_attr "bdver1_decode" "direct") 1635 (set_attr "mode" "SI")]) 1636 1637;; Pentium Pro can do steps 1 through 3 in one go. 1638;; comi*, ucomi*, fcomi*, ficomi*, fucomi* 1639;; (these i387 instructions set flags directly) 1640 1641(define_mode_iterator FPCMP [CCFP CCFPU]) 1642(define_mode_attr unord [(CCFP "") (CCFPU "u")]) 1643 1644(define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed" 1645 [(set (reg:FPCMP FLAGS_REG) 1646 (compare:FPCMP 1647 (match_operand:MODEF 0 "register_operand" "f,x") 1648 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))] 1649 "TARGET_MIX_SSE_I387 1650 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)" 1651 "* return output_fp_compare (insn, operands, true, 1652 <FPCMP:MODE>mode == CCFPUmode);" 1653 [(set_attr "type" "fcmp,ssecomi") 1654 (set_attr "prefix" "orig,maybe_vex") 1655 (set_attr "mode" "<MODEF:MODE>") 1656 (set (attr "prefix_rep") 1657 (if_then_else (eq_attr "type" "ssecomi") 1658 (const_string "0") 1659 (const_string "*"))) 1660 (set (attr "prefix_data16") 1661 (cond [(eq_attr "type" "fcmp") 1662 (const_string "*") 1663 (eq_attr "mode" "DF") 1664 (const_string "1") 1665 ] 1666 (const_string "0"))) 1667 (set_attr "athlon_decode" "vector") 1668 (set_attr "amdfam10_decode" "direct") 1669 (set_attr "bdver1_decode" "double")]) 1670 1671(define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse" 1672 [(set (reg:FPCMP FLAGS_REG) 1673 (compare:FPCMP 1674 (match_operand:MODEF 0 "register_operand" "x") 1675 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))] 1676 "TARGET_SSE_MATH 1677 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)" 1678 "* return output_fp_compare (insn, operands, true, 1679 <FPCMP:MODE>mode == CCFPUmode);" 1680 [(set_attr "type" "ssecomi") 1681 (set_attr "prefix" "maybe_vex") 1682 (set_attr "mode" "<MODEF:MODE>") 1683 (set_attr "prefix_rep" "0") 1684 (set (attr "prefix_data16") 1685 (if_then_else (eq_attr "mode" "DF") 1686 (const_string "1") 1687 (const_string "0"))) 1688 (set_attr "athlon_decode" "vector") 1689 (set_attr "amdfam10_decode" "direct") 1690 (set_attr "bdver1_decode" "double")]) 1691 1692(define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387" 1693 [(set (reg:FPCMP FLAGS_REG) 1694 (compare:FPCMP 1695 (match_operand:X87MODEF 0 "register_operand" "f") 1696 (match_operand:X87MODEF 1 "register_operand" "f")))] 1697 "TARGET_80387 && TARGET_CMOVE 1698 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)" 1699 "* return output_fp_compare (insn, operands, true, 1700 <FPCMP:MODE>mode == CCFPUmode);" 1701 [(set_attr "type" "fcmp") 1702 (set_attr "mode" "<X87MODEF:MODE>") 1703 (set_attr "athlon_decode" "vector") 1704 (set_attr "amdfam10_decode" "direct") 1705 (set_attr "bdver1_decode" "double")]) 1706 1707;; Push/pop instructions. 1708 1709(define_insn "*push<mode>2" 1710 [(set (match_operand:DWI 0 "push_operand" "=<") 1711 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))] 1712 "" 1713 "#" 1714 [(set_attr "type" "multi") 1715 (set_attr "mode" "<MODE>")]) 1716 1717(define_split 1718 [(set (match_operand:TI 0 "push_operand") 1719 (match_operand:TI 1 "general_operand"))] 1720 "TARGET_64BIT && reload_completed 1721 && !SSE_REG_P (operands[1])" 1722 [(const_int 0)] 1723 "ix86_split_long_move (operands); DONE;") 1724 1725(define_insn "*pushdi2_rex64" 1726 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1727 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1728 "TARGET_64BIT" 1729 "@ 1730 push{q}\t%1 1731 #" 1732 [(set_attr "type" "push,multi") 1733 (set_attr "mode" "DI")]) 1734 1735;; Convert impossible pushes of immediate to existing instructions. 1736;; First try to get scratch register and go through it. In case this 1737;; fails, push sign extended lower part first and then overwrite 1738;; upper part by 32bit move. 1739(define_peephole2 1740 [(match_scratch:DI 2 "r") 1741 (set (match_operand:DI 0 "push_operand") 1742 (match_operand:DI 1 "immediate_operand"))] 1743 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1744 && !x86_64_immediate_operand (operands[1], DImode)" 1745 [(set (match_dup 2) (match_dup 1)) 1746 (set (match_dup 0) (match_dup 2))]) 1747 1748;; We need to define this as both peepholer and splitter for case 1749;; peephole2 pass is not run. 1750;; "&& 1" is needed to keep it from matching the previous pattern. 1751(define_peephole2 1752 [(set (match_operand:DI 0 "push_operand") 1753 (match_operand:DI 1 "immediate_operand"))] 1754 "TARGET_64BIT && !symbolic_operand (operands[1], DImode) 1755 && !x86_64_immediate_operand (operands[1], DImode) && 1" 1756 [(set (match_dup 0) (match_dup 1)) 1757 (set (match_dup 2) (match_dup 3))] 1758{ 1759 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1760 1761 operands[1] = gen_lowpart (DImode, operands[2]); 1762 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx, 1763 GEN_INT (4))); 1764}) 1765 1766(define_split 1767 [(set (match_operand:DI 0 "push_operand") 1768 (match_operand:DI 1 "immediate_operand"))] 1769 "TARGET_64BIT && ((optimize > 0 && flag_peephole2) 1770 ? epilogue_completed : reload_completed) 1771 && !symbolic_operand (operands[1], DImode) 1772 && !x86_64_immediate_operand (operands[1], DImode)" 1773 [(set (match_dup 0) (match_dup 1)) 1774 (set (match_dup 2) (match_dup 3))] 1775{ 1776 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1777 1778 operands[1] = gen_lowpart (DImode, operands[2]); 1779 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx, 1780 GEN_INT (4))); 1781}) 1782 1783(define_split 1784 [(set (match_operand:DI 0 "push_operand") 1785 (match_operand:DI 1 "general_operand"))] 1786 "!TARGET_64BIT && reload_completed 1787 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))" 1788 [(const_int 0)] 1789 "ix86_split_long_move (operands); DONE;") 1790 1791(define_insn "*pushsi2" 1792 [(set (match_operand:SI 0 "push_operand" "=<") 1793 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1794 "!TARGET_64BIT" 1795 "push{l}\t%1" 1796 [(set_attr "type" "push") 1797 (set_attr "mode" "SI")]) 1798 1799;; emit_push_insn when it calls move_by_pieces requires an insn to 1800;; "push a byte/word". But actually we use pushl, which has the effect 1801;; of rounding the amount pushed up to a word. 1802 1803;; For TARGET_64BIT we always round up to 8 bytes. 1804(define_insn "*push<mode>2_rex64" 1805 [(set (match_operand:SWI124 0 "push_operand" "=X") 1806 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))] 1807 "TARGET_64BIT" 1808 "push{q}\t%q1" 1809 [(set_attr "type" "push") 1810 (set_attr "mode" "DI")]) 1811 1812(define_insn "*push<mode>2" 1813 [(set (match_operand:SWI12 0 "push_operand" "=X") 1814 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))] 1815 "!TARGET_64BIT" 1816 "push{l}\t%k1" 1817 [(set_attr "type" "push") 1818 (set_attr "mode" "SI")]) 1819 1820(define_insn "*push<mode>2_prologue" 1821 [(set (match_operand:W 0 "push_operand" "=<") 1822 (match_operand:W 1 "general_no_elim_operand" "r<i>*m")) 1823 (clobber (mem:BLK (scratch)))] 1824 "" 1825 "push{<imodesuffix>}\t%1" 1826 [(set_attr "type" "push") 1827 (set_attr "mode" "<MODE>")]) 1828 1829(define_insn "*pop<mode>1" 1830 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m") 1831 (match_operand:W 1 "pop_operand" ">"))] 1832 "" 1833 "pop{<imodesuffix>}\t%0" 1834 [(set_attr "type" "pop") 1835 (set_attr "mode" "<MODE>")]) 1836 1837(define_insn "*pop<mode>1_epilogue" 1838 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m") 1839 (match_operand:W 1 "pop_operand" ">")) 1840 (clobber (mem:BLK (scratch)))] 1841 "" 1842 "pop{<imodesuffix>}\t%0" 1843 [(set_attr "type" "pop") 1844 (set_attr "mode" "<MODE>")]) 1845 1846(define_insn "*pushfl<mode>2" 1847 [(set (match_operand:W 0 "push_operand" "=<") 1848 (match_operand:W 1 "flags_reg_operand"))] 1849 "" 1850 "pushf{<imodesuffix>}" 1851 [(set_attr "type" "push") 1852 (set_attr "mode" "<MODE>")]) 1853 1854(define_insn "*popfl<mode>1" 1855 [(set (match_operand:W 0 "flags_reg_operand") 1856 (match_operand:W 1 "pop_operand" ">"))] 1857 "" 1858 "popf{<imodesuffix>}" 1859 [(set_attr "type" "pop") 1860 (set_attr "mode" "<MODE>")]) 1861 1862 1863;; Move instructions. 1864 1865(define_expand "movxi" 1866 [(set (match_operand:XI 0 "nonimmediate_operand") 1867 (match_operand:XI 1 "general_operand"))] 1868 "TARGET_AVX512F" 1869 "ix86_expand_vector_move (XImode, operands); DONE;") 1870 1871;; Reload patterns to support multi-word load/store 1872;; with non-offsetable address. 1873(define_expand "reload_noff_store" 1874 [(parallel [(match_operand 0 "memory_operand" "=m") 1875 (match_operand 1 "register_operand" "r") 1876 (match_operand:DI 2 "register_operand" "=&r")])] 1877 "TARGET_64BIT" 1878{ 1879 rtx mem = operands[0]; 1880 rtx addr = XEXP (mem, 0); 1881 1882 emit_move_insn (operands[2], addr); 1883 mem = replace_equiv_address_nv (mem, operands[2]); 1884 1885 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1])); 1886 DONE; 1887}) 1888 1889(define_expand "reload_noff_load" 1890 [(parallel [(match_operand 0 "register_operand" "=r") 1891 (match_operand 1 "memory_operand" "m") 1892 (match_operand:DI 2 "register_operand" "=r")])] 1893 "TARGET_64BIT" 1894{ 1895 rtx mem = operands[1]; 1896 rtx addr = XEXP (mem, 0); 1897 1898 emit_move_insn (operands[2], addr); 1899 mem = replace_equiv_address_nv (mem, operands[2]); 1900 1901 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem)); 1902 DONE; 1903}) 1904 1905(define_expand "movoi" 1906 [(set (match_operand:OI 0 "nonimmediate_operand") 1907 (match_operand:OI 1 "general_operand"))] 1908 "TARGET_AVX" 1909 "ix86_expand_vector_move (OImode, operands); DONE;") 1910 1911(define_expand "movti" 1912 [(set (match_operand:TI 0 "nonimmediate_operand") 1913 (match_operand:TI 1 "general_operand"))] 1914 "TARGET_64BIT || TARGET_SSE" 1915{ 1916 if (TARGET_64BIT) 1917 ix86_expand_move (TImode, operands); 1918 else 1919 ix86_expand_vector_move (TImode, operands); 1920 DONE; 1921}) 1922 1923;; This expands to what emit_move_complex would generate if we didn't 1924;; have a movti pattern. Having this avoids problems with reload on 1925;; 32-bit targets when SSE is present, but doesn't seem to be harmful 1926;; to have around all the time. 1927(define_expand "movcdi" 1928 [(set (match_operand:CDI 0 "nonimmediate_operand") 1929 (match_operand:CDI 1 "general_operand"))] 1930 "" 1931{ 1932 if (push_operand (operands[0], CDImode)) 1933 emit_move_complex_push (CDImode, operands[0], operands[1]); 1934 else 1935 emit_move_complex_parts (operands[0], operands[1]); 1936 DONE; 1937}) 1938 1939(define_expand "mov<mode>" 1940 [(set (match_operand:SWI1248x 0 "nonimmediate_operand") 1941 (match_operand:SWI1248x 1 "general_operand"))] 1942 "" 1943 "ix86_expand_move (<MODE>mode, operands); DONE;") 1944 1945(define_insn "*mov<mode>_xor" 1946 [(set (match_operand:SWI48 0 "register_operand" "=r") 1947 (match_operand:SWI48 1 "const0_operand")) 1948 (clobber (reg:CC FLAGS_REG))] 1949 "reload_completed" 1950 "xor{l}\t%k0, %k0" 1951 [(set_attr "type" "alu1") 1952 (set_attr "mode" "SI") 1953 (set_attr "length_immediate" "0")]) 1954 1955(define_insn "*mov<mode>_or" 1956 [(set (match_operand:SWI48 0 "register_operand" "=r") 1957 (match_operand:SWI48 1 "const_int_operand")) 1958 (clobber (reg:CC FLAGS_REG))] 1959 "reload_completed 1960 && operands[1] == constm1_rtx" 1961 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 1962 [(set_attr "type" "alu1") 1963 (set_attr "mode" "<MODE>") 1964 (set_attr "length_immediate" "1")]) 1965 1966(define_insn "*movxi_internal_avx512f" 1967 [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m") 1968 (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))] 1969 "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1970{ 1971 switch (which_alternative) 1972 { 1973 case 0: 1974 return standard_sse_constant_opcode (insn, operands[1]); 1975 case 1: 1976 case 2: 1977 if (misaligned_operand (operands[0], XImode) 1978 || misaligned_operand (operands[1], XImode)) 1979 return "vmovdqu32\t{%1, %0|%0, %1}"; 1980 else 1981 return "vmovdqa32\t{%1, %0|%0, %1}"; 1982 default: 1983 gcc_unreachable (); 1984 } 1985} 1986 [(set_attr "type" "sselog1,ssemov,ssemov") 1987 (set_attr "prefix" "evex") 1988 (set_attr "mode" "XI")]) 1989 1990(define_insn "*movoi_internal_avx" 1991 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m") 1992 (match_operand:OI 1 "vector_move_operand" "C ,vm,v"))] 1993 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 1994{ 1995 switch (get_attr_type (insn)) 1996 { 1997 case TYPE_SSELOG1: 1998 return standard_sse_constant_opcode (insn, operands[1]); 1999 2000 case TYPE_SSEMOV: 2001 if (misaligned_operand (operands[0], OImode) 2002 || misaligned_operand (operands[1], OImode)) 2003 { 2004 if (get_attr_mode (insn) == MODE_V8SF) 2005 return "vmovups\t{%1, %0|%0, %1}"; 2006 else if (get_attr_mode (insn) == MODE_XI) 2007 return "vmovdqu32\t{%1, %0|%0, %1}"; 2008 else 2009 return "vmovdqu\t{%1, %0|%0, %1}"; 2010 } 2011 else 2012 { 2013 if (get_attr_mode (insn) == MODE_V8SF) 2014 return "vmovaps\t{%1, %0|%0, %1}"; 2015 else if (get_attr_mode (insn) == MODE_XI) 2016 return "vmovdqa32\t{%1, %0|%0, %1}"; 2017 else 2018 return "vmovdqa\t{%1, %0|%0, %1}"; 2019 } 2020 2021 default: 2022 gcc_unreachable (); 2023 } 2024} 2025 [(set_attr "type" "sselog1,ssemov,ssemov") 2026 (set_attr "prefix" "vex") 2027 (set (attr "mode") 2028 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 2029 (match_operand 1 "ext_sse_reg_operand")) 2030 (const_string "XI") 2031 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") 2032 (const_string "V8SF") 2033 (and (eq_attr "alternative" "2") 2034 (match_test "TARGET_SSE_TYPELESS_STORES")) 2035 (const_string "V8SF") 2036 ] 2037 (const_string "OI")))]) 2038 2039(define_insn "*movti_internal" 2040 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m") 2041 (match_operand:TI 1 "general_operand" "riFo,re,C,vm,v"))] 2042 "(TARGET_64BIT || TARGET_SSE) 2043 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2044{ 2045 switch (get_attr_type (insn)) 2046 { 2047 case TYPE_MULTI: 2048 return "#"; 2049 2050 case TYPE_SSELOG1: 2051 return standard_sse_constant_opcode (insn, operands[1]); 2052 2053 case TYPE_SSEMOV: 2054 /* TDmode values are passed as TImode on the stack. Moving them 2055 to stack may result in unaligned memory access. */ 2056 if (misaligned_operand (operands[0], TImode) 2057 || misaligned_operand (operands[1], TImode)) 2058 { 2059 if (get_attr_mode (insn) == MODE_V4SF) 2060 return "%vmovups\t{%1, %0|%0, %1}"; 2061 else if (get_attr_mode (insn) == MODE_XI) 2062 return "vmovdqu32\t{%1, %0|%0, %1}"; 2063 else 2064 return "%vmovdqu\t{%1, %0|%0, %1}"; 2065 } 2066 else 2067 { 2068 if (get_attr_mode (insn) == MODE_V4SF) 2069 return "%vmovaps\t{%1, %0|%0, %1}"; 2070 else if (get_attr_mode (insn) == MODE_XI) 2071 return "vmovdqa32\t{%1, %0|%0, %1}"; 2072 else 2073 return "%vmovdqa\t{%1, %0|%0, %1}"; 2074 } 2075 2076 default: 2077 gcc_unreachable (); 2078 } 2079} 2080 [(set_attr "isa" "x64,x64,*,*,*") 2081 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov") 2082 (set (attr "prefix") 2083 (if_then_else (eq_attr "type" "sselog1,ssemov") 2084 (const_string "maybe_vex") 2085 (const_string "orig"))) 2086 (set (attr "mode") 2087 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 2088 (match_operand 1 "ext_sse_reg_operand")) 2089 (const_string "XI") 2090 (eq_attr "alternative" "0,1") 2091 (const_string "DI") 2092 (ior (not (match_test "TARGET_SSE2")) 2093 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) 2094 (const_string "V4SF") 2095 (and (eq_attr "alternative" "4") 2096 (match_test "TARGET_SSE_TYPELESS_STORES")) 2097 (const_string "V4SF") 2098 (match_test "TARGET_AVX") 2099 (const_string "TI") 2100 (match_test "optimize_function_for_size_p (cfun)") 2101 (const_string "V4SF") 2102 ] 2103 (const_string "TI")))]) 2104 2105(define_split 2106 [(set (match_operand:TI 0 "nonimmediate_operand") 2107 (match_operand:TI 1 "general_operand"))] 2108 "reload_completed 2109 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])" 2110 [(const_int 0)] 2111 "ix86_split_long_move (operands); DONE;") 2112 2113(define_insn "*movdi_internal" 2114 [(set (match_operand:DI 0 "nonimmediate_operand" 2115 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m") 2116 (match_operand:DI 1 "general_operand" 2117 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn ,*r ,*km,*k,*k"))] 2118 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2119{ 2120 switch (get_attr_type (insn)) 2121 { 2122 case TYPE_MSKMOV: 2123 return "kmovq\t{%1, %0|%0, %1}"; 2124 2125 case TYPE_MULTI: 2126 return "#"; 2127 2128 case TYPE_MMX: 2129 return "pxor\t%0, %0"; 2130 2131 case TYPE_MMXMOV: 2132 /* Handle broken assemblers that require movd instead of movq. */ 2133 if (!HAVE_AS_IX86_INTERUNIT_MOVQ 2134 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))) 2135 return "movd\t{%1, %0|%0, %1}"; 2136 return "movq\t{%1, %0|%0, %1}"; 2137 2138 case TYPE_SSELOG1: 2139 if (GENERAL_REG_P (operands[0])) 2140 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}"; 2141 2142 return standard_sse_constant_opcode (insn, operands[1]); 2143 2144 case TYPE_SSEMOV: 2145 switch (get_attr_mode (insn)) 2146 { 2147 case MODE_DI: 2148 /* Handle broken assemblers that require movd instead of movq. */ 2149 if (!HAVE_AS_IX86_INTERUNIT_MOVQ 2150 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))) 2151 return "%vmovd\t{%1, %0|%0, %1}"; 2152 return "%vmovq\t{%1, %0|%0, %1}"; 2153 case MODE_TI: 2154 return "%vmovdqa\t{%1, %0|%0, %1}"; 2155 case MODE_XI: 2156 return "vmovdqa64\t{%g1, %g0|%g0, %g1}"; 2157 2158 case MODE_V2SF: 2159 gcc_assert (!TARGET_AVX); 2160 return "movlps\t{%1, %0|%0, %1}"; 2161 case MODE_V4SF: 2162 return "%vmovaps\t{%1, %0|%0, %1}"; 2163 2164 default: 2165 gcc_unreachable (); 2166 } 2167 2168 case TYPE_SSECVT: 2169 if (SSE_REG_P (operands[0])) 2170 return "movq2dq\t{%1, %0|%0, %1}"; 2171 else 2172 return "movdq2q\t{%1, %0|%0, %1}"; 2173 2174 case TYPE_LEA: 2175 return "lea{q}\t{%E1, %0|%0, %E1}"; 2176 2177 case TYPE_IMOV: 2178 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2179 if (get_attr_mode (insn) == MODE_SI) 2180 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2181 else if (which_alternative == 4) 2182 return "movabs{q}\t{%1, %0|%0, %1}"; 2183 else if (ix86_use_lea_for_mov (insn, operands)) 2184 return "lea{q}\t{%E1, %0|%0, %E1}"; 2185 else 2186 return "mov{q}\t{%1, %0|%0, %1}"; 2187 2188 default: 2189 gcc_unreachable (); 2190 } 2191} 2192 [(set (attr "isa") 2193 (cond [(eq_attr "alternative" "0,1") 2194 (const_string "nox64") 2195 (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23") 2196 (const_string "x64") 2197 (eq_attr "alternative" "17") 2198 (const_string "x64_sse4") 2199 ] 2200 (const_string "*"))) 2201 (set (attr "type") 2202 (cond [(eq_attr "alternative" "0,1") 2203 (const_string "multi") 2204 (eq_attr "alternative" "6") 2205 (const_string "mmx") 2206 (eq_attr "alternative" "7,8,9,10,11") 2207 (const_string "mmxmov") 2208 (eq_attr "alternative" "12,17") 2209 (const_string "sselog1") 2210 (eq_attr "alternative" "13,14,15,16,18") 2211 (const_string "ssemov") 2212 (eq_attr "alternative" "19,20") 2213 (const_string "ssecvt") 2214 (eq_attr "alternative" "21,22,23,24") 2215 (const_string "mskmov") 2216 (and (match_operand 0 "register_operand") 2217 (match_operand 1 "pic_32bit_operand")) 2218 (const_string "lea") 2219 ] 2220 (const_string "imov"))) 2221 (set (attr "modrm") 2222 (if_then_else 2223 (and (eq_attr "alternative" "4") (eq_attr "type" "imov")) 2224 (const_string "0") 2225 (const_string "*"))) 2226 (set (attr "length_immediate") 2227 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov")) 2228 (const_string "8") 2229 (eq_attr "alternative" "17") 2230 (const_string "1") 2231 ] 2232 (const_string "*"))) 2233 (set (attr "prefix_rex") 2234 (if_then_else (eq_attr "alternative" "10,11,16,17,18") 2235 (const_string "1") 2236 (const_string "*"))) 2237 (set (attr "prefix_extra") 2238 (if_then_else (eq_attr "alternative" "17") 2239 (const_string "1") 2240 (const_string "*"))) 2241 (set (attr "prefix") 2242 (if_then_else (eq_attr "type" "sselog1,ssemov") 2243 (const_string "maybe_vex") 2244 (const_string "orig"))) 2245 (set (attr "prefix_data16") 2246 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI")) 2247 (const_string "1") 2248 (const_string "*"))) 2249 (set (attr "mode") 2250 (cond [(eq_attr "alternative" "2") 2251 (const_string "SI") 2252 (eq_attr "alternative" "12,13") 2253 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 2254 (match_operand 1 "ext_sse_reg_operand")) 2255 (const_string "XI") 2256 (ior (not (match_test "TARGET_SSE2")) 2257 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) 2258 (const_string "V4SF") 2259 (match_test "TARGET_AVX") 2260 (const_string "TI") 2261 (match_test "optimize_function_for_size_p (cfun)") 2262 (const_string "V4SF") 2263 ] 2264 (const_string "TI")) 2265 2266 (and (eq_attr "alternative" "14,15") 2267 (not (match_test "TARGET_SSE2"))) 2268 (const_string "V2SF") 2269 (eq_attr "alternative" "17") 2270 (const_string "TI") 2271 ] 2272 (const_string "DI")))]) 2273 2274(define_split 2275 [(set (match_operand:DI 0 "nonimmediate_operand") 2276 (match_operand:DI 1 "general_operand"))] 2277 "!TARGET_64BIT && reload_completed 2278 && !(MMX_REG_P (operands[0]) 2279 || SSE_REG_P (operands[0]) 2280 || MASK_REG_P (operands[0])) 2281 && !(MMX_REG_P (operands[1]) 2282 || SSE_REG_P (operands[1]) 2283 || MASK_REG_P (operands[1]))" 2284 [(const_int 0)] 2285 "ix86_split_long_move (operands); DONE;") 2286 2287(define_insn "*movsi_internal" 2288 [(set (match_operand:SI 0 "nonimmediate_operand" 2289 "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k ,*rm") 2290 (match_operand:SI 1 "general_operand" 2291 "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r ,*krm,*k"))] 2292 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2293{ 2294 switch (get_attr_type (insn)) 2295 { 2296 case TYPE_SSELOG1: 2297 if (GENERAL_REG_P (operands[0])) 2298 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}"; 2299 2300 return standard_sse_constant_opcode (insn, operands[1]); 2301 2302 case TYPE_MSKMOV: 2303 return "kmovd\t{%1, %0|%0, %1}"; 2304 2305 case TYPE_SSEMOV: 2306 switch (get_attr_mode (insn)) 2307 { 2308 case MODE_SI: 2309 return "%vmovd\t{%1, %0|%0, %1}"; 2310 case MODE_TI: 2311 return "%vmovdqa\t{%1, %0|%0, %1}"; 2312 case MODE_XI: 2313 return "vmovdqa32\t{%g1, %g0|%g0, %g1}"; 2314 2315 case MODE_V4SF: 2316 return "%vmovaps\t{%1, %0|%0, %1}"; 2317 2318 case MODE_SF: 2319 gcc_assert (!TARGET_AVX); 2320 return "movss\t{%1, %0|%0, %1}"; 2321 2322 default: 2323 gcc_unreachable (); 2324 } 2325 2326 case TYPE_MMX: 2327 return "pxor\t%0, %0"; 2328 2329 case TYPE_MMXMOV: 2330 switch (get_attr_mode (insn)) 2331 { 2332 case MODE_DI: 2333 return "movq\t{%1, %0|%0, %1}"; 2334 case MODE_SI: 2335 return "movd\t{%1, %0|%0, %1}"; 2336 2337 default: 2338 gcc_unreachable (); 2339 } 2340 2341 case TYPE_LEA: 2342 return "lea{l}\t{%E1, %0|%0, %E1}"; 2343 2344 case TYPE_IMOV: 2345 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2346 if (ix86_use_lea_for_mov (insn, operands)) 2347 return "lea{l}\t{%E1, %0|%0, %E1}"; 2348 else 2349 return "mov{l}\t{%1, %0|%0, %1}"; 2350 2351 default: 2352 gcc_unreachable (); 2353 } 2354} 2355 [(set (attr "isa") 2356 (if_then_else (eq_attr "alternative" "11") 2357 (const_string "sse4") 2358 (const_string "*"))) 2359 (set (attr "type") 2360 (cond [(eq_attr "alternative" "2") 2361 (const_string "mmx") 2362 (eq_attr "alternative" "3,4,5") 2363 (const_string "mmxmov") 2364 (eq_attr "alternative" "6,11") 2365 (const_string "sselog1") 2366 (eq_attr "alternative" "7,8,9,10,12") 2367 (const_string "ssemov") 2368 (eq_attr "alternative" "13,14") 2369 (const_string "mskmov") 2370 (and (match_operand 0 "register_operand") 2371 (match_operand 1 "pic_32bit_operand")) 2372 (const_string "lea") 2373 ] 2374 (const_string "imov"))) 2375 (set (attr "length_immediate") 2376 (if_then_else (eq_attr "alternative" "11") 2377 (const_string "1") 2378 (const_string "*"))) 2379 (set (attr "prefix_extra") 2380 (if_then_else (eq_attr "alternative" "11") 2381 (const_string "1") 2382 (const_string "*"))) 2383 (set (attr "prefix") 2384 (if_then_else (eq_attr "type" "sselog1,ssemov") 2385 (const_string "maybe_vex") 2386 (const_string "orig"))) 2387 (set (attr "prefix_data16") 2388 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 2389 (const_string "1") 2390 (const_string "*"))) 2391 (set (attr "mode") 2392 (cond [(eq_attr "alternative" "2,3") 2393 (const_string "DI") 2394 (eq_attr "alternative" "6,7") 2395 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 2396 (match_operand 1 "ext_sse_reg_operand")) 2397 (const_string "XI") 2398 (ior (not (match_test "TARGET_SSE2")) 2399 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) 2400 (const_string "V4SF") 2401 (match_test "TARGET_AVX") 2402 (const_string "TI") 2403 (match_test "optimize_function_for_size_p (cfun)") 2404 (const_string "V4SF") 2405 ] 2406 (const_string "TI")) 2407 2408 (and (eq_attr "alternative" "8,9") 2409 (not (match_test "TARGET_SSE2"))) 2410 (const_string "SF") 2411 (eq_attr "alternative" "11") 2412 (const_string "TI") 2413 ] 2414 (const_string "SI")))]) 2415 2416(define_insn "kmovw" 2417 [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k") 2418 (unspec:HI 2419 [(match_operand:HI 1 "nonimmediate_operand" "r,km")] 2420 UNSPEC_KMOV))] 2421 "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F" 2422 "@ 2423 kmovw\t{%k1, %0|%0, %k1} 2424 kmovw\t{%1, %0|%0, %1}"; 2425 [(set_attr "mode" "HI") 2426 (set_attr "type" "mskmov") 2427 (set_attr "prefix" "vex")]) 2428 2429 2430(define_insn "*movhi_internal" 2431 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k, r,m") 2432 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))] 2433 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2434{ 2435 switch (get_attr_type (insn)) 2436 { 2437 case TYPE_IMOVX: 2438 /* movzwl is faster than movw on p2 due to partial word stalls, 2439 though not as fast as an aligned movl. */ 2440 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 2441 2442 case TYPE_MSKMOV: 2443 switch (which_alternative) 2444 { 2445 case 4: return "kmovw\t{%k1, %0|%0, %k1}"; 2446 case 5: /* FALLTHRU */ 2447 case 7: return "kmovw\t{%1, %0|%0, %1}"; 2448 case 6: return "kmovw\t{%1, %k0|%k0, %1}"; 2449 default: gcc_unreachable (); 2450 } 2451 2452 default: 2453 if (get_attr_mode (insn) == MODE_SI) 2454 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2455 else 2456 return "mov{w}\t{%1, %0|%0, %1}"; 2457 } 2458} 2459 [(set (attr "type") 2460 (cond [(eq_attr "alternative" "4,5,6,7") 2461 (const_string "mskmov") 2462 (match_test "optimize_function_for_size_p (cfun)") 2463 (const_string "imov") 2464 (and (eq_attr "alternative" "0") 2465 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2466 (not (match_test "TARGET_HIMODE_MATH")))) 2467 (const_string "imov") 2468 (and (eq_attr "alternative" "1,2") 2469 (match_operand:HI 1 "aligned_operand")) 2470 (const_string "imov") 2471 (and (match_test "TARGET_MOVX") 2472 (eq_attr "alternative" "0,2")) 2473 (const_string "imovx") 2474 ] 2475 (const_string "imov"))) 2476 (set (attr "prefix") 2477 (if_then_else (eq_attr "alternative" "4,5,6,7") 2478 (const_string "vex") 2479 (const_string "orig"))) 2480 (set (attr "mode") 2481 (cond [(eq_attr "type" "imovx") 2482 (const_string "SI") 2483 (and (eq_attr "alternative" "1,2") 2484 (match_operand:HI 1 "aligned_operand")) 2485 (const_string "SI") 2486 (and (eq_attr "alternative" "0") 2487 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2488 (not (match_test "TARGET_HIMODE_MATH")))) 2489 (const_string "SI") 2490 ] 2491 (const_string "HI")))]) 2492 2493;; Situation is quite tricky about when to choose full sized (SImode) move 2494;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 2495;; partial register dependency machines (such as AMD Athlon), where QImode 2496;; moves issue extra dependency and for partial register stalls machines 2497;; that don't use QImode patterns (and QImode move cause stall on the next 2498;; instruction). 2499;; 2500;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 2501;; register stall machines with, where we use QImode instructions, since 2502;; partial register stall can be caused there. Then we use movzx. 2503 2504(define_insn "*movqi_internal" 2505 [(set (match_operand:QI 0 "nonimmediate_operand" 2506 "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k") 2507 (match_operand:QI 1 "general_operand" 2508 "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))] 2509 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2510{ 2511 switch (get_attr_type (insn)) 2512 { 2513 case TYPE_IMOVX: 2514 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])); 2515 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 2516 2517 case TYPE_MSKMOV: 2518 switch (which_alternative) 2519 { 2520 case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}" 2521 : "kmovw\t{%k1, %0|%0, %k1}"; 2522 case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}" 2523 : "kmovw\t{%1, %0|%0, %1}"; 2524 case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}" 2525 : "kmovw\t{%1, %k0|%k0, %1}"; 2526 case 10: 2527 case 11: 2528 gcc_assert (TARGET_AVX512DQ); 2529 return "kmovb\t{%1, %0|%0, %1}"; 2530 default: gcc_unreachable (); 2531 } 2532 2533 default: 2534 if (get_attr_mode (insn) == MODE_SI) 2535 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2536 else 2537 return "mov{b}\t{%1, %0|%0, %1}"; 2538 } 2539} 2540 [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq") 2541 (set (attr "type") 2542 (cond [(eq_attr "alternative" "7,8,9,10,11") 2543 (const_string "mskmov") 2544 (and (eq_attr "alternative" "5") 2545 (not (match_operand:QI 1 "aligned_operand"))) 2546 (const_string "imovx") 2547 (match_test "optimize_function_for_size_p (cfun)") 2548 (const_string "imov") 2549 (and (eq_attr "alternative" "3") 2550 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2551 (not (match_test "TARGET_QIMODE_MATH")))) 2552 (const_string "imov") 2553 (eq_attr "alternative" "3,5") 2554 (const_string "imovx") 2555 (and (match_test "TARGET_MOVX") 2556 (eq_attr "alternative" "2")) 2557 (const_string "imovx") 2558 ] 2559 (const_string "imov"))) 2560 (set (attr "prefix") 2561 (if_then_else (eq_attr "alternative" "7,8,9") 2562 (const_string "vex") 2563 (const_string "orig"))) 2564 (set (attr "mode") 2565 (cond [(eq_attr "alternative" "3,4,5") 2566 (const_string "SI") 2567 (eq_attr "alternative" "6") 2568 (const_string "QI") 2569 (eq_attr "type" "imovx") 2570 (const_string "SI") 2571 (and (eq_attr "type" "imov") 2572 (and (eq_attr "alternative" "0,1") 2573 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY") 2574 (and (not (match_test "optimize_function_for_size_p (cfun)")) 2575 (not (match_test "TARGET_PARTIAL_REG_STALL")))))) 2576 (const_string "SI") 2577 ;; Avoid partial register stalls when not using QImode arithmetic 2578 (and (eq_attr "type" "imov") 2579 (and (eq_attr "alternative" "0,1") 2580 (and (match_test "TARGET_PARTIAL_REG_STALL") 2581 (not (match_test "TARGET_QIMODE_MATH"))))) 2582 (const_string "SI") 2583 ] 2584 (const_string "QI")))]) 2585 2586;; Stores and loads of ax to arbitrary constant address. 2587;; We fake an second form of instruction to force reload to load address 2588;; into register when rax is not available 2589(define_insn "*movabs<mode>_1" 2590 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2591 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))] 2592 "TARGET_LP64 && ix86_check_movabs (insn, 0)" 2593 "@ 2594 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1} 2595 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}" 2596 [(set_attr "type" "imov") 2597 (set_attr "modrm" "0,*") 2598 (set_attr "length_address" "8,0") 2599 (set_attr "length_immediate" "0,*") 2600 (set_attr "memory" "store") 2601 (set_attr "mode" "<MODE>")]) 2602 2603(define_insn "*movabs<mode>_2" 2604 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r") 2605 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2606 "TARGET_LP64 && ix86_check_movabs (insn, 1)" 2607 "@ 2608 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]} 2609 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}" 2610 [(set_attr "type" "imov") 2611 (set_attr "modrm" "0,*") 2612 (set_attr "length_address" "8,0") 2613 (set_attr "length_immediate" "0") 2614 (set_attr "memory" "load") 2615 (set_attr "mode" "<MODE>")]) 2616 2617(define_insn "*swap<mode>" 2618 [(set (match_operand:SWI48 0 "register_operand" "+r") 2619 (match_operand:SWI48 1 "register_operand" "+r")) 2620 (set (match_dup 1) 2621 (match_dup 0))] 2622 "" 2623 "xchg{<imodesuffix>}\t%1, %0" 2624 [(set_attr "type" "imov") 2625 (set_attr "mode" "<MODE>") 2626 (set_attr "pent_pair" "np") 2627 (set_attr "athlon_decode" "vector") 2628 (set_attr "amdfam10_decode" "double") 2629 (set_attr "bdver1_decode" "double")]) 2630 2631(define_insn "*swap<mode>_1" 2632 [(set (match_operand:SWI12 0 "register_operand" "+r") 2633 (match_operand:SWI12 1 "register_operand" "+r")) 2634 (set (match_dup 1) 2635 (match_dup 0))] 2636 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 2637 "xchg{l}\t%k1, %k0" 2638 [(set_attr "type" "imov") 2639 (set_attr "mode" "SI") 2640 (set_attr "pent_pair" "np") 2641 (set_attr "athlon_decode" "vector") 2642 (set_attr "amdfam10_decode" "double") 2643 (set_attr "bdver1_decode" "double")]) 2644 2645;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL 2646;; is disabled for AMDFAM10 2647(define_insn "*swap<mode>_2" 2648 [(set (match_operand:SWI12 0 "register_operand" "+<r>") 2649 (match_operand:SWI12 1 "register_operand" "+<r>")) 2650 (set (match_dup 1) 2651 (match_dup 0))] 2652 "TARGET_PARTIAL_REG_STALL" 2653 "xchg{<imodesuffix>}\t%1, %0" 2654 [(set_attr "type" "imov") 2655 (set_attr "mode" "<MODE>") 2656 (set_attr "pent_pair" "np") 2657 (set_attr "athlon_decode" "vector")]) 2658 2659(define_expand "movstrict<mode>" 2660 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand")) 2661 (match_operand:SWI12 1 "general_operand"))] 2662 "" 2663{ 2664 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) 2665 FAIL; 2666 if (GET_CODE (operands[0]) == SUBREG 2667 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT) 2668 FAIL; 2669 /* Don't generate memory->memory moves, go through a register */ 2670 if (MEM_P (operands[0]) && MEM_P (operands[1])) 2671 operands[1] = force_reg (<MODE>mode, operands[1]); 2672}) 2673 2674(define_insn "*movstrict<mode>_1" 2675 [(set (strict_low_part 2676 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>")) 2677 (match_operand:SWI12 1 "general_operand" "<r>n,m"))] 2678 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 2679 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 2680 "mov{<imodesuffix>}\t{%1, %0|%0, %1}" 2681 [(set_attr "type" "imov") 2682 (set_attr "mode" "<MODE>")]) 2683 2684(define_insn "*movstrict<mode>_xor" 2685 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 2686 (match_operand:SWI12 1 "const0_operand")) 2687 (clobber (reg:CC FLAGS_REG))] 2688 "reload_completed" 2689 "xor{<imodesuffix>}\t%0, %0" 2690 [(set_attr "type" "alu1") 2691 (set_attr "mode" "<MODE>") 2692 (set_attr "length_immediate" "0")]) 2693 2694(define_insn "*mov<mode>_extv_1" 2695 [(set (match_operand:SWI24 0 "register_operand" "=R") 2696 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q") 2697 (const_int 8) 2698 (const_int 8)))] 2699 "" 2700 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 2701 [(set_attr "type" "imovx") 2702 (set_attr "mode" "SI")]) 2703 2704(define_insn "*movqi_extv_1" 2705 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m") 2706 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q") 2707 (const_int 8) 2708 (const_int 8)))] 2709 "" 2710{ 2711 switch (get_attr_type (insn)) 2712 { 2713 case TYPE_IMOVX: 2714 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}"; 2715 default: 2716 return "mov{b}\t{%h1, %0|%0, %h1}"; 2717 } 2718} 2719 [(set_attr "isa" "*,*,nox64") 2720 (set (attr "type") 2721 (if_then_else (and (match_operand:QI 0 "register_operand") 2722 (ior (not (match_operand:QI 0 "QIreg_operand")) 2723 (match_test "TARGET_MOVX"))) 2724 (const_string "imovx") 2725 (const_string "imov"))) 2726 (set (attr "mode") 2727 (if_then_else (eq_attr "type" "imovx") 2728 (const_string "SI") 2729 (const_string "QI")))]) 2730 2731(define_insn "*mov<mode>_extzv_1" 2732 [(set (match_operand:SWI48 0 "register_operand" "=R") 2733 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q") 2734 (const_int 8) 2735 (const_int 8)))] 2736 "" 2737 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 2738 [(set_attr "type" "imovx") 2739 (set_attr "mode" "SI")]) 2740 2741(define_insn "*movqi_extzv_2" 2742 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m") 2743 (subreg:QI 2744 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q") 2745 (const_int 8) 2746 (const_int 8)) 0))] 2747 "" 2748{ 2749 switch (get_attr_type (insn)) 2750 { 2751 case TYPE_IMOVX: 2752 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2753 default: 2754 return "mov{b}\t{%h1, %0|%0, %h1}"; 2755 } 2756} 2757 [(set_attr "isa" "*,*,nox64") 2758 (set (attr "type") 2759 (if_then_else (and (match_operand:QI 0 "register_operand") 2760 (ior (not (match_operand:QI 0 "QIreg_operand")) 2761 (match_test "TARGET_MOVX"))) 2762 (const_string "imovx") 2763 (const_string "imov"))) 2764 (set (attr "mode") 2765 (if_then_else (eq_attr "type" "imovx") 2766 (const_string "SI") 2767 (const_string "QI")))]) 2768 2769(define_insn "mov<mode>_insv_1" 2770 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q") 2771 (const_int 8) 2772 (const_int 8)) 2773 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))] 2774 "" 2775{ 2776 if (CONST_INT_P (operands[1])) 2777 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0); 2778 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 2779} 2780 [(set_attr "isa" "*,nox64") 2781 (set_attr "type" "imov") 2782 (set_attr "mode" "QI")]) 2783 2784(define_insn "*movqi_insv_2" 2785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2786 (const_int 8) 2787 (const_int 8)) 2788 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q") 2789 (const_int 8)))] 2790 "" 2791 "mov{b}\t{%h1, %h0|%h0, %h1}" 2792 [(set_attr "type" "imov") 2793 (set_attr "mode" "QI")]) 2794 2795;; Floating point push instructions. 2796 2797(define_insn "*pushtf" 2798 [(set (match_operand:TF 0 "push_operand" "=<,<") 2799 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))] 2800 "TARGET_64BIT || TARGET_SSE" 2801{ 2802 /* This insn should be already split before reg-stack. */ 2803 gcc_unreachable (); 2804} 2805 [(set_attr "isa" "*,x64") 2806 (set_attr "type" "multi") 2807 (set_attr "unit" "sse,*") 2808 (set_attr "mode" "TF,DI")]) 2809 2810;; %%% Kill this when call knows how to work this out. 2811(define_split 2812 [(set (match_operand:TF 0 "push_operand") 2813 (match_operand:TF 1 "sse_reg_operand"))] 2814 "TARGET_SSE && reload_completed" 2815 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) 2816 (set (match_dup 0) (match_dup 1))] 2817{ 2818 /* Preserve memory attributes. */ 2819 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 2820}) 2821 2822(define_insn "*pushxf" 2823 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<") 2824 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF"))] 2825 "" 2826{ 2827 /* This insn should be already split before reg-stack. */ 2828 gcc_unreachable (); 2829} 2830 [(set_attr "type" "multi") 2831 (set_attr "unit" "i387,*,*,*") 2832 (set (attr "mode") 2833 (cond [(eq_attr "alternative" "1,2,3") 2834 (if_then_else (match_test "TARGET_64BIT") 2835 (const_string "DI") 2836 (const_string "SI")) 2837 ] 2838 (const_string "XF"))) 2839 (set (attr "preferred_for_size") 2840 (cond [(eq_attr "alternative" "1") 2841 (symbol_ref "false")] 2842 (symbol_ref "true")))]) 2843 2844;; %%% Kill this when call knows how to work this out. 2845(define_split 2846 [(set (match_operand:XF 0 "push_operand") 2847 (match_operand:XF 1 "fp_register_operand"))] 2848 "reload_completed" 2849 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 2850 (set (match_dup 0) (match_dup 1))] 2851{ 2852 operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode)); 2853 /* Preserve memory attributes. */ 2854 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 2855}) 2856 2857(define_insn "*pushdf" 2858 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<") 2859 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmF,x"))] 2860 "" 2861{ 2862 /* This insn should be already split before reg-stack. */ 2863 gcc_unreachable (); 2864} 2865 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2") 2866 (set_attr "type" "multi") 2867 (set_attr "unit" "i387,*,*,*,*,sse") 2868 (set_attr "mode" "DF,SI,SI,SI,DI,DF") 2869 (set (attr "preferred_for_size") 2870 (cond [(eq_attr "alternative" "1") 2871 (symbol_ref "false")] 2872 (symbol_ref "true"))) 2873 (set (attr "preferred_for_speed") 2874 (cond [(eq_attr "alternative" "1") 2875 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")] 2876 (symbol_ref "true")))]) 2877 2878;; %%% Kill this when call knows how to work this out. 2879(define_split 2880 [(set (match_operand:DF 0 "push_operand") 2881 (match_operand:DF 1 "any_fp_register_operand"))] 2882 "reload_completed" 2883 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 2884 (set (match_dup 0) (match_dup 1))] 2885{ 2886 /* Preserve memory attributes. */ 2887 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 2888}) 2889 2890(define_insn "*pushsf_rex64" 2891 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 2892 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 2893 "TARGET_64BIT" 2894{ 2895 /* Anything else should be already split before reg-stack. */ 2896 gcc_assert (which_alternative == 1); 2897 return "push{q}\t%q1"; 2898} 2899 [(set_attr "type" "multi,push,multi") 2900 (set_attr "unit" "i387,*,*") 2901 (set_attr "mode" "SF,DI,SF")]) 2902 2903(define_insn "*pushsf" 2904 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 2905 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))] 2906 "!TARGET_64BIT" 2907{ 2908 /* Anything else should be already split before reg-stack. */ 2909 gcc_assert (which_alternative == 1); 2910 return "push{l}\t%1"; 2911} 2912 [(set_attr "type" "multi,push,multi") 2913 (set_attr "unit" "i387,*,*") 2914 (set_attr "mode" "SF,SI,SF")]) 2915 2916;; %%% Kill this when call knows how to work this out. 2917(define_split 2918 [(set (match_operand:SF 0 "push_operand") 2919 (match_operand:SF 1 "any_fp_register_operand"))] 2920 "reload_completed" 2921 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 2922 (set (match_dup 0) (match_dup 1))] 2923{ 2924 rtx op = XEXP (operands[0], 0); 2925 if (GET_CODE (op) == PRE_DEC) 2926 { 2927 gcc_assert (!TARGET_64BIT); 2928 op = GEN_INT (-4); 2929 } 2930 else 2931 { 2932 op = XEXP (XEXP (op, 1), 1); 2933 gcc_assert (CONST_INT_P (op)); 2934 } 2935 operands[2] = op; 2936 /* Preserve memory attributes. */ 2937 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 2938}) 2939 2940(define_split 2941 [(set (match_operand:SF 0 "push_operand") 2942 (match_operand:SF 1 "memory_operand"))] 2943 "reload_completed 2944 && (operands[2] = find_constant_src (insn))" 2945 [(set (match_dup 0) (match_dup 2))]) 2946 2947(define_split 2948 [(set (match_operand 0 "push_operand") 2949 (match_operand 1 "general_operand"))] 2950 "reload_completed 2951 && (GET_MODE (operands[0]) == TFmode 2952 || GET_MODE (operands[0]) == XFmode 2953 || GET_MODE (operands[0]) == DFmode) 2954 && !ANY_FP_REG_P (operands[1])" 2955 [(const_int 0)] 2956 "ix86_split_long_move (operands); DONE;") 2957 2958;; Floating point move instructions. 2959 2960(define_expand "movtf" 2961 [(set (match_operand:TF 0 "nonimmediate_operand") 2962 (match_operand:TF 1 "nonimmediate_operand"))] 2963 "TARGET_64BIT || TARGET_SSE" 2964 "ix86_expand_move (TFmode, operands); DONE;") 2965 2966(define_expand "mov<mode>" 2967 [(set (match_operand:X87MODEF 0 "nonimmediate_operand") 2968 (match_operand:X87MODEF 1 "general_operand"))] 2969 "" 2970 "ix86_expand_move (<MODE>mode, operands); DONE;") 2971 2972(define_insn "*movtf_internal" 2973 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o") 2974 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))] 2975 "(TARGET_64BIT || TARGET_SSE) 2976 && !(MEM_P (operands[0]) && MEM_P (operands[1])) 2977 && (!can_create_pseudo_p () 2978 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 2979 || GET_CODE (operands[1]) != CONST_DOUBLE 2980 || (optimize_function_for_size_p (cfun) 2981 && standard_sse_constant_p (operands[1]) 2982 && !memory_operand (operands[0], TFmode)) 2983 || (!TARGET_MEMORY_MISMATCH_STALL 2984 && memory_operand (operands[0], TFmode)))" 2985{ 2986 switch (get_attr_type (insn)) 2987 { 2988 case TYPE_SSELOG1: 2989 return standard_sse_constant_opcode (insn, operands[1]); 2990 2991 case TYPE_SSEMOV: 2992 /* Handle misaligned load/store since we 2993 don't have movmisaligntf pattern. */ 2994 if (misaligned_operand (operands[0], TFmode) 2995 || misaligned_operand (operands[1], TFmode)) 2996 { 2997 if (get_attr_mode (insn) == MODE_V4SF) 2998 return "%vmovups\t{%1, %0|%0, %1}"; 2999 else 3000 return "%vmovdqu\t{%1, %0|%0, %1}"; 3001 } 3002 else 3003 { 3004 if (get_attr_mode (insn) == MODE_V4SF) 3005 return "%vmovaps\t{%1, %0|%0, %1}"; 3006 else 3007 return "%vmovdqa\t{%1, %0|%0, %1}"; 3008 } 3009 3010 case TYPE_MULTI: 3011 return "#"; 3012 3013 default: 3014 gcc_unreachable (); 3015 } 3016} 3017 [(set_attr "isa" "*,*,*,x64,x64") 3018 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi") 3019 (set (attr "prefix") 3020 (if_then_else (eq_attr "type" "sselog1,ssemov") 3021 (const_string "maybe_vex") 3022 (const_string "orig"))) 3023 (set (attr "mode") 3024 (cond [(eq_attr "alternative" "3,4") 3025 (const_string "DI") 3026 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") 3027 (const_string "V4SF") 3028 (and (eq_attr "alternative" "2") 3029 (match_test "TARGET_SSE_TYPELESS_STORES")) 3030 (const_string "V4SF") 3031 (match_test "TARGET_AVX") 3032 (const_string "TI") 3033 (ior (not (match_test "TARGET_SSE2")) 3034 (match_test "optimize_function_for_size_p (cfun)")) 3035 (const_string "V4SF") 3036 ] 3037 (const_string "TI")))]) 3038 3039;; Possible store forwarding (partial memory) stall 3040;; in alternatives 4, 6, 7 and 8. 3041(define_insn "*movxf_internal" 3042 [(set (match_operand:XF 0 "nonimmediate_operand" 3043 "=f,m,f,?r ,!o,?*r ,!o,!o,!o") 3044 (match_operand:XF 1 "general_operand" 3045 "fm,f,G,roF,r , *roF,*r,F ,C"))] 3046 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3047 && (!can_create_pseudo_p () 3048 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3049 || GET_CODE (operands[1]) != CONST_DOUBLE 3050 || (optimize_function_for_size_p (cfun) 3051 && standard_80387_constant_p (operands[1]) > 0 3052 && !memory_operand (operands[0], XFmode)) 3053 || (!TARGET_MEMORY_MISMATCH_STALL 3054 && memory_operand (operands[0], XFmode)))" 3055{ 3056 switch (get_attr_type (insn)) 3057 { 3058 case TYPE_FMOV: 3059 if (which_alternative == 2) 3060 return standard_80387_constant_opcode (operands[1]); 3061 return output_387_reg_move (insn, operands); 3062 3063 case TYPE_MULTI: 3064 return "#"; 3065 3066 default: 3067 gcc_unreachable (); 3068 } 3069} 3070 [(set (attr "isa") 3071 (cond [(eq_attr "alternative" "7") 3072 (const_string "nox64") 3073 (eq_attr "alternative" "8") 3074 (const_string "x64") 3075 ] 3076 (const_string "*"))) 3077 (set (attr "type") 3078 (cond [(eq_attr "alternative" "3,4,5,6,7,8") 3079 (const_string "multi") 3080 ] 3081 (const_string "fmov"))) 3082 (set (attr "mode") 3083 (cond [(eq_attr "alternative" "3,4,5,6,7,8") 3084 (if_then_else (match_test "TARGET_64BIT") 3085 (const_string "DI") 3086 (const_string "SI")) 3087 ] 3088 (const_string "XF"))) 3089 (set (attr "preferred_for_size") 3090 (cond [(eq_attr "alternative" "3,4") 3091 (symbol_ref "false")] 3092 (symbol_ref "true")))]) 3093 3094;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7. 3095(define_insn "*movdf_internal" 3096 [(set (match_operand:DF 0 "nonimmediate_operand" 3097 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi") 3098 (match_operand:DF 1 "general_operand" 3099 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))] 3100 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3101 && (!can_create_pseudo_p () 3102 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3103 || GET_CODE (operands[1]) != CONST_DOUBLE 3104 || (optimize_function_for_size_p (cfun) 3105 && ((!(TARGET_SSE2 && TARGET_SSE_MATH) 3106 && standard_80387_constant_p (operands[1]) > 0) 3107 || (TARGET_SSE2 && TARGET_SSE_MATH 3108 && standard_sse_constant_p (operands[1]))) 3109 && !memory_operand (operands[0], DFmode)) 3110 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL) 3111 && memory_operand (operands[0], DFmode)))" 3112{ 3113 switch (get_attr_type (insn)) 3114 { 3115 case TYPE_FMOV: 3116 if (which_alternative == 2) 3117 return standard_80387_constant_opcode (operands[1]); 3118 return output_387_reg_move (insn, operands); 3119 3120 case TYPE_MULTI: 3121 return "#"; 3122 3123 case TYPE_IMOV: 3124 if (get_attr_mode (insn) == MODE_SI) 3125 return "mov{l}\t{%1, %k0|%k0, %1}"; 3126 else if (which_alternative == 11) 3127 return "movabs{q}\t{%1, %0|%0, %1}"; 3128 else 3129 return "mov{q}\t{%1, %0|%0, %1}"; 3130 3131 case TYPE_SSELOG1: 3132 return standard_sse_constant_opcode (insn, operands[1]); 3133 3134 case TYPE_SSEMOV: 3135 switch (get_attr_mode (insn)) 3136 { 3137 case MODE_DF: 3138 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3139 return "vmovsd\t{%1, %0, %0|%0, %0, %1}"; 3140 return "%vmovsd\t{%1, %0|%0, %1}"; 3141 3142 case MODE_V4SF: 3143 return "%vmovaps\t{%1, %0|%0, %1}"; 3144 case MODE_V8DF: 3145 return "vmovapd\t{%g1, %g0|%g0, %g1}"; 3146 case MODE_V2DF: 3147 return "%vmovapd\t{%1, %0|%0, %1}"; 3148 3149 case MODE_V2SF: 3150 gcc_assert (!TARGET_AVX); 3151 return "movlps\t{%1, %0|%0, %1}"; 3152 case MODE_V1DF: 3153 gcc_assert (!TARGET_AVX); 3154 return "movlpd\t{%1, %0|%0, %1}"; 3155 3156 case MODE_DI: 3157 /* Handle broken assemblers that require movd instead of movq. */ 3158 if (!HAVE_AS_IX86_INTERUNIT_MOVQ 3159 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))) 3160 return "%vmovd\t{%1, %0|%0, %1}"; 3161 return "%vmovq\t{%1, %0|%0, %1}"; 3162 3163 default: 3164 gcc_unreachable (); 3165 } 3166 3167 default: 3168 gcc_unreachable (); 3169 } 3170} 3171 [(set (attr "isa") 3172 (cond [(eq_attr "alternative" "3,4,5,6,7") 3173 (const_string "nox64") 3174 (eq_attr "alternative" "8,9,10,11,20,21") 3175 (const_string "x64") 3176 (eq_attr "alternative" "12,13,14,15") 3177 (const_string "sse2") 3178 ] 3179 (const_string "*"))) 3180 (set (attr "type") 3181 (cond [(eq_attr "alternative" "0,1,2") 3182 (const_string "fmov") 3183 (eq_attr "alternative" "3,4,5,6,7") 3184 (const_string "multi") 3185 (eq_attr "alternative" "8,9,10,11") 3186 (const_string "imov") 3187 (eq_attr "alternative" "12,16") 3188 (const_string "sselog1") 3189 ] 3190 (const_string "ssemov"))) 3191 (set (attr "modrm") 3192 (if_then_else (eq_attr "alternative" "11") 3193 (const_string "0") 3194 (const_string "*"))) 3195 (set (attr "length_immediate") 3196 (if_then_else (eq_attr "alternative" "11") 3197 (const_string "8") 3198 (const_string "*"))) 3199 (set (attr "prefix") 3200 (if_then_else (eq_attr "type" "sselog1,ssemov") 3201 (const_string "maybe_vex") 3202 (const_string "orig"))) 3203 (set (attr "prefix_data16") 3204 (if_then_else 3205 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI")) 3206 (eq_attr "mode" "V1DF")) 3207 (const_string "1") 3208 (const_string "*"))) 3209 (set (attr "mode") 3210 (cond [(eq_attr "alternative" "3,4,5,6,7,10") 3211 (const_string "SI") 3212 (eq_attr "alternative" "8,9,11,20,21") 3213 (const_string "DI") 3214 3215 /* xorps is one byte shorter for non-AVX targets. */ 3216 (eq_attr "alternative" "12,16") 3217 (cond [(not (match_test "TARGET_SSE2")) 3218 (const_string "V4SF") 3219 (match_test "TARGET_AVX512F") 3220 (const_string "XI") 3221 (match_test "TARGET_AVX") 3222 (const_string "V2DF") 3223 (match_test "optimize_function_for_size_p (cfun)") 3224 (const_string "V4SF") 3225 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3226 (const_string "TI") 3227 ] 3228 (const_string "V2DF")) 3229 3230 /* For architectures resolving dependencies on 3231 whole SSE registers use movapd to break dependency 3232 chains, otherwise use short move to avoid extra work. */ 3233 3234 /* movaps is one byte shorter for non-AVX targets. */ 3235 (eq_attr "alternative" "13,17") 3236 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 3237 (match_operand 1 "ext_sse_reg_operand")) 3238 (const_string "V8DF") 3239 (ior (not (match_test "TARGET_SSE2")) 3240 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")) 3241 (const_string "V4SF") 3242 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3243 (const_string "V2DF") 3244 (match_test "TARGET_AVX") 3245 (const_string "DF") 3246 (match_test "optimize_function_for_size_p (cfun)") 3247 (const_string "V4SF") 3248 ] 3249 (const_string "DF")) 3250 3251 /* For architectures resolving dependencies on register 3252 parts we may avoid extra work to zero out upper part 3253 of register. */ 3254 (eq_attr "alternative" "14,18") 3255 (cond [(not (match_test "TARGET_SSE2")) 3256 (const_string "V2SF") 3257 (match_test "TARGET_AVX") 3258 (const_string "DF") 3259 (match_test "TARGET_SSE_SPLIT_REGS") 3260 (const_string "V1DF") 3261 ] 3262 (const_string "DF")) 3263 3264 (and (eq_attr "alternative" "15,19") 3265 (not (match_test "TARGET_SSE2"))) 3266 (const_string "V2SF") 3267 ] 3268 (const_string "DF"))) 3269 (set (attr "preferred_for_size") 3270 (cond [(eq_attr "alternative" "3,4") 3271 (symbol_ref "false")] 3272 (symbol_ref "true"))) 3273 (set (attr "preferred_for_speed") 3274 (cond [(eq_attr "alternative" "3,4") 3275 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")] 3276 (symbol_ref "true")))]) 3277 3278(define_insn "*movsf_internal" 3279 [(set (match_operand:SF 0 "nonimmediate_operand" 3280 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym") 3281 (match_operand:SF 1 "general_operand" 3282 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))] 3283 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3284 && (!can_create_pseudo_p () 3285 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) 3286 || GET_CODE (operands[1]) != CONST_DOUBLE 3287 || (optimize_function_for_size_p (cfun) 3288 && ((!TARGET_SSE_MATH 3289 && standard_80387_constant_p (operands[1]) > 0) 3290 || (TARGET_SSE_MATH 3291 && standard_sse_constant_p (operands[1])))) 3292 || memory_operand (operands[0], SFmode))" 3293{ 3294 switch (get_attr_type (insn)) 3295 { 3296 case TYPE_FMOV: 3297 if (which_alternative == 2) 3298 return standard_80387_constant_opcode (operands[1]); 3299 return output_387_reg_move (insn, operands); 3300 3301 case TYPE_IMOV: 3302 return "mov{l}\t{%1, %0|%0, %1}"; 3303 3304 case TYPE_SSELOG1: 3305 return standard_sse_constant_opcode (insn, operands[1]); 3306 3307 case TYPE_SSEMOV: 3308 switch (get_attr_mode (insn)) 3309 { 3310 case MODE_SF: 3311 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1])) 3312 return "vmovss\t{%1, %0, %0|%0, %0, %1}"; 3313 return "%vmovss\t{%1, %0|%0, %1}"; 3314 3315 case MODE_V16SF: 3316 return "vmovaps\t{%g1, %g0|%g0, %g1}"; 3317 case MODE_V4SF: 3318 return "%vmovaps\t{%1, %0|%0, %1}"; 3319 3320 case MODE_SI: 3321 return "%vmovd\t{%1, %0|%0, %1}"; 3322 3323 default: 3324 gcc_unreachable (); 3325 } 3326 3327 case TYPE_MMXMOV: 3328 switch (get_attr_mode (insn)) 3329 { 3330 case MODE_DI: 3331 return "movq\t{%1, %0|%0, %1}"; 3332 case MODE_SI: 3333 return "movd\t{%1, %0|%0, %1}"; 3334 3335 default: 3336 gcc_unreachable (); 3337 } 3338 3339 default: 3340 gcc_unreachable (); 3341 } 3342} 3343 [(set (attr "type") 3344 (cond [(eq_attr "alternative" "0,1,2") 3345 (const_string "fmov") 3346 (eq_attr "alternative" "3,4") 3347 (const_string "imov") 3348 (eq_attr "alternative" "5") 3349 (const_string "sselog1") 3350 (eq_attr "alternative" "11,12,13,14,15") 3351 (const_string "mmxmov") 3352 ] 3353 (const_string "ssemov"))) 3354 (set (attr "prefix") 3355 (if_then_else (eq_attr "type" "sselog1,ssemov") 3356 (const_string "maybe_vex") 3357 (const_string "orig"))) 3358 (set (attr "prefix_data16") 3359 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 3360 (const_string "1") 3361 (const_string "*"))) 3362 (set (attr "mode") 3363 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15") 3364 (const_string "SI") 3365 (eq_attr "alternative" "11") 3366 (const_string "DI") 3367 (eq_attr "alternative" "5") 3368 (cond [(not (match_test "TARGET_SSE2")) 3369 (const_string "V4SF") 3370 (match_test "TARGET_AVX512F") 3371 (const_string "V16SF") 3372 (match_test "TARGET_AVX") 3373 (const_string "V4SF") 3374 (match_test "optimize_function_for_size_p (cfun)") 3375 (const_string "V4SF") 3376 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3377 (const_string "TI") 3378 ] 3379 (const_string "V4SF")) 3380 3381 /* For architectures resolving dependencies on 3382 whole SSE registers use APS move to break dependency 3383 chains, otherwise use short move to avoid extra work. 3384 3385 Do the same for architectures resolving dependencies on 3386 the parts. While in DF mode it is better to always handle 3387 just register parts, the SF mode is different due to lack 3388 of instructions to load just part of the register. It is 3389 better to maintain the whole registers in single format 3390 to avoid problems on using packed logical operations. */ 3391 (eq_attr "alternative" "6") 3392 (cond [(ior (match_operand 0 "ext_sse_reg_operand") 3393 (match_operand 1 "ext_sse_reg_operand")) 3394 (const_string "V16SF") 3395 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3396 (match_test "TARGET_SSE_SPLIT_REGS")) 3397 (const_string "V4SF") 3398 ] 3399 (const_string "SF")) 3400 ] 3401 (const_string "SF")))]) 3402 3403(define_split 3404 [(set (match_operand 0 "any_fp_register_operand") 3405 (match_operand 1 "memory_operand"))] 3406 "reload_completed 3407 && (GET_MODE (operands[0]) == TFmode 3408 || GET_MODE (operands[0]) == XFmode 3409 || GET_MODE (operands[0]) == DFmode 3410 || GET_MODE (operands[0]) == SFmode) 3411 && (operands[2] = find_constant_src (insn))" 3412 [(set (match_dup 0) (match_dup 2))] 3413{ 3414 rtx c = operands[2]; 3415 int r = REGNO (operands[0]); 3416 3417 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c)) 3418 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1)) 3419 FAIL; 3420}) 3421 3422(define_split 3423 [(set (match_operand 0 "any_fp_register_operand") 3424 (float_extend (match_operand 1 "memory_operand")))] 3425 "reload_completed 3426 && (GET_MODE (operands[0]) == TFmode 3427 || GET_MODE (operands[0]) == XFmode 3428 || GET_MODE (operands[0]) == DFmode) 3429 && (operands[2] = find_constant_src (insn))" 3430 [(set (match_dup 0) (match_dup 2))] 3431{ 3432 rtx c = operands[2]; 3433 int r = REGNO (operands[0]); 3434 3435 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c)) 3436 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1)) 3437 FAIL; 3438}) 3439 3440;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence 3441(define_split 3442 [(set (match_operand:X87MODEF 0 "fp_register_operand") 3443 (match_operand:X87MODEF 1 "immediate_operand"))] 3444 "reload_completed 3445 && (standard_80387_constant_p (operands[1]) == 8 3446 || standard_80387_constant_p (operands[1]) == 9)" 3447 [(set (match_dup 0)(match_dup 1)) 3448 (set (match_dup 0) 3449 (neg:X87MODEF (match_dup 0)))] 3450{ 3451 REAL_VALUE_TYPE r; 3452 3453 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); 3454 if (real_isnegzero (&r)) 3455 operands[1] = CONST0_RTX (<MODE>mode); 3456 else 3457 operands[1] = CONST1_RTX (<MODE>mode); 3458}) 3459 3460(define_split 3461 [(set (match_operand 0 "nonimmediate_operand") 3462 (match_operand 1 "general_operand"))] 3463 "reload_completed 3464 && (GET_MODE (operands[0]) == TFmode 3465 || GET_MODE (operands[0]) == XFmode 3466 || GET_MODE (operands[0]) == DFmode) 3467 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))" 3468 [(const_int 0)] 3469 "ix86_split_long_move (operands); DONE;") 3470 3471(define_insn "swapxf" 3472 [(set (match_operand:XF 0 "register_operand" "+f") 3473 (match_operand:XF 1 "register_operand" "+f")) 3474 (set (match_dup 1) 3475 (match_dup 0))] 3476 "TARGET_80387" 3477{ 3478 if (STACK_TOP_P (operands[0])) 3479 return "fxch\t%1"; 3480 else 3481 return "fxch\t%0"; 3482} 3483 [(set_attr "type" "fxch") 3484 (set_attr "mode" "XF")]) 3485 3486(define_insn "*swap<mode>" 3487 [(set (match_operand:MODEF 0 "fp_register_operand" "+f") 3488 (match_operand:MODEF 1 "fp_register_operand" "+f")) 3489 (set (match_dup 1) 3490 (match_dup 0))] 3491 "TARGET_80387 || reload_completed" 3492{ 3493 if (STACK_TOP_P (operands[0])) 3494 return "fxch\t%1"; 3495 else 3496 return "fxch\t%0"; 3497} 3498 [(set_attr "type" "fxch") 3499 (set_attr "mode" "<MODE>")]) 3500 3501;; Zero extension instructions 3502 3503(define_expand "zero_extendsidi2" 3504 [(set (match_operand:DI 0 "nonimmediate_operand") 3505 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]) 3506 3507(define_insn "*zero_extendsidi2" 3508 [(set (match_operand:DI 0 "nonimmediate_operand" 3509 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x") 3510 (zero_extend:DI 3511 (match_operand:SI 1 "x86_64_zext_operand" 3512 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))] 3513 "" 3514{ 3515 switch (get_attr_type (insn)) 3516 { 3517 case TYPE_IMOVX: 3518 if (ix86_use_lea_for_mov (insn, operands)) 3519 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 3520 else 3521 return "mov{l}\t{%1, %k0|%k0, %1}"; 3522 3523 case TYPE_MULTI: 3524 return "#"; 3525 3526 case TYPE_MMXMOV: 3527 return "movd\t{%1, %0|%0, %1}"; 3528 3529 case TYPE_SSELOG1: 3530 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}"; 3531 3532 case TYPE_SSEMOV: 3533 if (GENERAL_REG_P (operands[0])) 3534 return "%vmovd\t{%1, %k0|%k0, %1}"; 3535 3536 return "%vmovd\t{%1, %0|%0, %1}"; 3537 3538 default: 3539 gcc_unreachable (); 3540 } 3541} 3542 [(set (attr "isa") 3543 (cond [(eq_attr "alternative" "0,1,2") 3544 (const_string "nox64") 3545 (eq_attr "alternative" "3,7") 3546 (const_string "x64") 3547 (eq_attr "alternative" "8") 3548 (const_string "x64_sse4") 3549 (eq_attr "alternative" "10") 3550 (const_string "sse2") 3551 ] 3552 (const_string "*"))) 3553 (set (attr "type") 3554 (cond [(eq_attr "alternative" "0,1,2,4") 3555 (const_string "multi") 3556 (eq_attr "alternative" "5,6") 3557 (const_string "mmxmov") 3558 (eq_attr "alternative" "7,9,10") 3559 (const_string "ssemov") 3560 (eq_attr "alternative" "8") 3561 (const_string "sselog1") 3562 ] 3563 (const_string "imovx"))) 3564 (set (attr "prefix_extra") 3565 (if_then_else (eq_attr "alternative" "8") 3566 (const_string "1") 3567 (const_string "*"))) 3568 (set (attr "length_immediate") 3569 (if_then_else (eq_attr "alternative" "8") 3570 (const_string "1") 3571 (const_string "*"))) 3572 (set (attr "prefix") 3573 (if_then_else (eq_attr "type" "ssemov,sselog1") 3574 (const_string "maybe_vex") 3575 (const_string "orig"))) 3576 (set (attr "prefix_0f") 3577 (if_then_else (eq_attr "type" "imovx") 3578 (const_string "0") 3579 (const_string "*"))) 3580 (set (attr "mode") 3581 (cond [(eq_attr "alternative" "5,6") 3582 (const_string "DI") 3583 (eq_attr "alternative" "7,8,9") 3584 (const_string "TI") 3585 ] 3586 (const_string "SI")))]) 3587 3588(define_split 3589 [(set (match_operand:DI 0 "memory_operand") 3590 (zero_extend:DI (match_operand:SI 1 "memory_operand")))] 3591 "reload_completed" 3592 [(set (match_dup 4) (const_int 0))] 3593 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3594 3595(define_split 3596 [(set (match_operand:DI 0 "register_operand") 3597 (zero_extend:DI (match_operand:SI 1 "register_operand")))] 3598 "!TARGET_64BIT && reload_completed 3599 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0])) 3600 && true_regnum (operands[0]) == true_regnum (operands[1])" 3601 [(set (match_dup 4) (const_int 0))] 3602 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3603 3604(define_split 3605 [(set (match_operand:DI 0 "nonimmediate_operand") 3606 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))] 3607 "!TARGET_64BIT && reload_completed 3608 && !(MEM_P (operands[0]) && MEM_P (operands[1])) 3609 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))" 3610 [(set (match_dup 3) (match_dup 1)) 3611 (set (match_dup 4) (const_int 0))] 3612 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3613 3614(define_insn "zero_extend<mode>di2" 3615 [(set (match_operand:DI 0 "register_operand" "=r") 3616 (zero_extend:DI 3617 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3618 "TARGET_64BIT" 3619 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}" 3620 [(set_attr "type" "imovx") 3621 (set_attr "mode" "SI")]) 3622 3623(define_expand "zero_extend<mode>si2" 3624 [(set (match_operand:SI 0 "register_operand") 3625 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))] 3626 "" 3627{ 3628 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3629 { 3630 operands[1] = force_reg (<MODE>mode, operands[1]); 3631 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1])); 3632 DONE; 3633 } 3634}) 3635 3636(define_insn_and_split "zero_extend<mode>si2_and" 3637 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>") 3638 (zero_extend:SI 3639 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m"))) 3640 (clobber (reg:CC FLAGS_REG))] 3641 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3642 "#" 3643 "&& reload_completed" 3644 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2))) 3645 (clobber (reg:CC FLAGS_REG))])] 3646{ 3647 if (true_regnum (operands[0]) != true_regnum (operands[1])) 3648 { 3649 ix86_expand_clear (operands[0]); 3650 3651 gcc_assert (!TARGET_PARTIAL_REG_STALL); 3652 emit_insn (gen_movstrict<mode> 3653 (gen_lowpart (<MODE>mode, operands[0]), operands[1])); 3654 DONE; 3655 } 3656 3657 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode)); 3658} 3659 [(set_attr "type" "alu1") 3660 (set_attr "mode" "SI")]) 3661 3662(define_insn "*zero_extend<mode>si2" 3663 [(set (match_operand:SI 0 "register_operand" "=r") 3664 (zero_extend:SI 3665 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3666 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" 3667 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}" 3668 [(set_attr "type" "imovx") 3669 (set_attr "mode" "SI")]) 3670 3671(define_expand "zero_extendqihi2" 3672 [(set (match_operand:HI 0 "register_operand") 3673 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))] 3674 "" 3675{ 3676 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3677 { 3678 operands[1] = force_reg (QImode, operands[1]); 3679 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1])); 3680 DONE; 3681 } 3682}) 3683 3684(define_insn_and_split "zero_extendqihi2_and" 3685 [(set (match_operand:HI 0 "register_operand" "=r,?&q") 3686 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3687 (clobber (reg:CC FLAGS_REG))] 3688 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3689 "#" 3690 "&& reload_completed" 3691 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) 3692 (clobber (reg:CC FLAGS_REG))])] 3693{ 3694 if (true_regnum (operands[0]) != true_regnum (operands[1])) 3695 { 3696 ix86_expand_clear (operands[0]); 3697 3698 gcc_assert (!TARGET_PARTIAL_REG_STALL); 3699 emit_insn (gen_movstrictqi 3700 (gen_lowpart (QImode, operands[0]), operands[1])); 3701 DONE; 3702 } 3703 3704 operands[0] = gen_lowpart (SImode, operands[0]); 3705} 3706 [(set_attr "type" "alu1") 3707 (set_attr "mode" "SI")]) 3708 3709; zero extend to SImode to avoid partial register stalls 3710(define_insn "*zero_extendqihi2" 3711 [(set (match_operand:HI 0 "register_operand" "=r") 3712 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3713 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" 3714 "movz{bl|x}\t{%1, %k0|%k0, %1}" 3715 [(set_attr "type" "imovx") 3716 (set_attr "mode" "SI")]) 3717 3718;; Sign extension instructions 3719 3720(define_expand "extendsidi2" 3721 [(set (match_operand:DI 0 "register_operand") 3722 (sign_extend:DI (match_operand:SI 1 "register_operand")))] 3723 "" 3724{ 3725 if (!TARGET_64BIT) 3726 { 3727 emit_insn (gen_extendsidi2_1 (operands[0], operands[1])); 3728 DONE; 3729 } 3730}) 3731 3732(define_insn "*extendsidi2_rex64" 3733 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3734 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3735 "TARGET_64BIT" 3736 "@ 3737 {cltq|cdqe} 3738 movs{lq|x}\t{%1, %0|%0, %1}" 3739 [(set_attr "type" "imovx") 3740 (set_attr "mode" "DI") 3741 (set_attr "prefix_0f" "0") 3742 (set_attr "modrm" "0,1")]) 3743 3744(define_insn "extendsidi2_1" 3745 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3746 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3747 (clobber (reg:CC FLAGS_REG)) 3748 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3749 "!TARGET_64BIT" 3750 "#") 3751 3752;; Split the memory case. If the source register doesn't die, it will stay 3753;; this way, if it does die, following peephole2s take care of it. 3754(define_split 3755 [(set (match_operand:DI 0 "memory_operand") 3756 (sign_extend:DI (match_operand:SI 1 "register_operand"))) 3757 (clobber (reg:CC FLAGS_REG)) 3758 (clobber (match_operand:SI 2 "register_operand"))] 3759 "reload_completed" 3760 [(const_int 0)] 3761{ 3762 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3763 3764 emit_move_insn (operands[3], operands[1]); 3765 3766 /* Generate a cltd if possible and doing so it profitable. */ 3767 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3768 && true_regnum (operands[1]) == AX_REG 3769 && true_regnum (operands[2]) == DX_REG) 3770 { 3771 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31))); 3772 } 3773 else 3774 { 3775 emit_move_insn (operands[2], operands[1]); 3776 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31))); 3777 } 3778 emit_move_insn (operands[4], operands[2]); 3779 DONE; 3780}) 3781 3782;; Peepholes for the case where the source register does die, after 3783;; being split with the above splitter. 3784(define_peephole2 3785 [(set (match_operand:SI 0 "memory_operand") 3786 (match_operand:SI 1 "register_operand")) 3787 (set (match_operand:SI 2 "register_operand") (match_dup 1)) 3788 (parallel [(set (match_dup 2) 3789 (ashiftrt:SI (match_dup 2) (const_int 31))) 3790 (clobber (reg:CC FLAGS_REG))]) 3791 (set (match_operand:SI 3 "memory_operand") (match_dup 2))] 3792 "REGNO (operands[1]) != REGNO (operands[2]) 3793 && peep2_reg_dead_p (2, operands[1]) 3794 && peep2_reg_dead_p (4, operands[2]) 3795 && !reg_mentioned_p (operands[2], operands[3])" 3796 [(set (match_dup 0) (match_dup 1)) 3797 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3798 (clobber (reg:CC FLAGS_REG))]) 3799 (set (match_dup 3) (match_dup 1))]) 3800 3801(define_peephole2 3802 [(set (match_operand:SI 0 "memory_operand") 3803 (match_operand:SI 1 "register_operand")) 3804 (parallel [(set (match_operand:SI 2 "register_operand") 3805 (ashiftrt:SI (match_dup 1) (const_int 31))) 3806 (clobber (reg:CC FLAGS_REG))]) 3807 (set (match_operand:SI 3 "memory_operand") (match_dup 2))] 3808 "/* cltd is shorter than sarl $31, %eax */ 3809 !optimize_function_for_size_p (cfun) 3810 && true_regnum (operands[1]) == AX_REG 3811 && true_regnum (operands[2]) == DX_REG 3812 && peep2_reg_dead_p (2, operands[1]) 3813 && peep2_reg_dead_p (3, operands[2]) 3814 && !reg_mentioned_p (operands[2], operands[3])" 3815 [(set (match_dup 0) (match_dup 1)) 3816 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3817 (clobber (reg:CC FLAGS_REG))]) 3818 (set (match_dup 3) (match_dup 1))]) 3819 3820;; Extend to register case. Optimize case where source and destination 3821;; registers match and cases where we can use cltd. 3822(define_split 3823 [(set (match_operand:DI 0 "register_operand") 3824 (sign_extend:DI (match_operand:SI 1 "register_operand"))) 3825 (clobber (reg:CC FLAGS_REG)) 3826 (clobber (match_scratch:SI 2))] 3827 "reload_completed" 3828 [(const_int 0)] 3829{ 3830 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3831 3832 if (true_regnum (operands[3]) != true_regnum (operands[1])) 3833 emit_move_insn (operands[3], operands[1]); 3834 3835 /* Generate a cltd if possible and doing so it profitable. */ 3836 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3837 && true_regnum (operands[3]) == AX_REG 3838 && true_regnum (operands[4]) == DX_REG) 3839 { 3840 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31))); 3841 DONE; 3842 } 3843 3844 if (true_regnum (operands[4]) != true_regnum (operands[1])) 3845 emit_move_insn (operands[4], operands[1]); 3846 3847 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31))); 3848 DONE; 3849}) 3850 3851(define_insn "extend<mode>di2" 3852 [(set (match_operand:DI 0 "register_operand" "=r") 3853 (sign_extend:DI 3854 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 3855 "TARGET_64BIT" 3856 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}" 3857 [(set_attr "type" "imovx") 3858 (set_attr "mode" "DI")]) 3859 3860(define_insn "extendhisi2" 3861 [(set (match_operand:SI 0 "register_operand" "=*a,r") 3862 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 3863 "" 3864{ 3865 switch (get_attr_prefix_0f (insn)) 3866 { 3867 case 0: 3868 return "{cwtl|cwde}"; 3869 default: 3870 return "movs{wl|x}\t{%1, %0|%0, %1}"; 3871 } 3872} 3873 [(set_attr "type" "imovx") 3874 (set_attr "mode" "SI") 3875 (set (attr "prefix_0f") 3876 ;; movsx is short decodable while cwtl is vector decoded. 3877 (if_then_else (and (eq_attr "cpu" "!k6") 3878 (eq_attr "alternative" "0")) 3879 (const_string "0") 3880 (const_string "1"))) 3881 (set (attr "modrm") 3882 (if_then_else (eq_attr "prefix_0f" "0") 3883 (const_string "0") 3884 (const_string "1")))]) 3885 3886(define_insn "*extendhisi2_zext" 3887 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3888 (zero_extend:DI 3889 (sign_extend:SI 3890 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 3891 "TARGET_64BIT" 3892{ 3893 switch (get_attr_prefix_0f (insn)) 3894 { 3895 case 0: 3896 return "{cwtl|cwde}"; 3897 default: 3898 return "movs{wl|x}\t{%1, %k0|%k0, %1}"; 3899 } 3900} 3901 [(set_attr "type" "imovx") 3902 (set_attr "mode" "SI") 3903 (set (attr "prefix_0f") 3904 ;; movsx is short decodable while cwtl is vector decoded. 3905 (if_then_else (and (eq_attr "cpu" "!k6") 3906 (eq_attr "alternative" "0")) 3907 (const_string "0") 3908 (const_string "1"))) 3909 (set (attr "modrm") 3910 (if_then_else (eq_attr "prefix_0f" "0") 3911 (const_string "0") 3912 (const_string "1")))]) 3913 3914(define_insn "extendqisi2" 3915 [(set (match_operand:SI 0 "register_operand" "=r") 3916 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 3917 "" 3918 "movs{bl|x}\t{%1, %0|%0, %1}" 3919 [(set_attr "type" "imovx") 3920 (set_attr "mode" "SI")]) 3921 3922(define_insn "*extendqisi2_zext" 3923 [(set (match_operand:DI 0 "register_operand" "=r") 3924 (zero_extend:DI 3925 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 3926 "TARGET_64BIT" 3927 "movs{bl|x}\t{%1, %k0|%k0, %1}" 3928 [(set_attr "type" "imovx") 3929 (set_attr "mode" "SI")]) 3930 3931(define_insn "extendqihi2" 3932 [(set (match_operand:HI 0 "register_operand" "=*a,r") 3933 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 3934 "" 3935{ 3936 switch (get_attr_prefix_0f (insn)) 3937 { 3938 case 0: 3939 return "{cbtw|cbw}"; 3940 default: 3941 return "movs{bw|x}\t{%1, %0|%0, %1}"; 3942 } 3943} 3944 [(set_attr "type" "imovx") 3945 (set_attr "mode" "HI") 3946 (set (attr "prefix_0f") 3947 ;; movsx is short decodable while cwtl is vector decoded. 3948 (if_then_else (and (eq_attr "cpu" "!k6") 3949 (eq_attr "alternative" "0")) 3950 (const_string "0") 3951 (const_string "1"))) 3952 (set (attr "modrm") 3953 (if_then_else (eq_attr "prefix_0f" "0") 3954 (const_string "0") 3955 (const_string "1")))]) 3956 3957;; Conversions between float and double. 3958 3959;; These are all no-ops in the model used for the 80387. 3960;; So just emit moves. 3961 3962;; %%% Kill these when call knows how to work out a DFmode push earlier. 3963(define_split 3964 [(set (match_operand:DF 0 "push_operand") 3965 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))] 3966 "reload_completed" 3967 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 3968 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))]) 3969 3970(define_split 3971 [(set (match_operand:XF 0 "push_operand") 3972 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))] 3973 "reload_completed" 3974 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 3975 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] 3976 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 3977 3978(define_expand "extendsfdf2" 3979 [(set (match_operand:DF 0 "nonimmediate_operand") 3980 (float_extend:DF (match_operand:SF 1 "general_operand")))] 3981 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 3982{ 3983 /* ??? Needed for compress_float_constant since all fp constants 3984 are TARGET_LEGITIMATE_CONSTANT_P. */ 3985 if (GET_CODE (operands[1]) == CONST_DOUBLE) 3986 { 3987 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 3988 && standard_80387_constant_p (operands[1]) > 0) 3989 { 3990 operands[1] = simplify_const_unary_operation 3991 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 3992 emit_move_insn_1 (operands[0], operands[1]); 3993 DONE; 3994 } 3995 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 3996 } 3997}) 3998 3999/* For converting SF(xmm2) to DF(xmm1), use the following code instead of 4000 cvtss2sd: 4001 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs 4002 cvtps2pd xmm2,xmm1 4003 We do the conversion post reload to avoid producing of 128bit spills 4004 that might lead to ICE on 32bit target. The sequence unlikely combine 4005 anyway. */ 4006(define_split 4007 [(set (match_operand:DF 0 "register_operand") 4008 (float_extend:DF 4009 (match_operand:SF 1 "nonimmediate_operand")))] 4010 "TARGET_USE_VECTOR_FP_CONVERTS 4011 && optimize_insn_for_speed_p () 4012 && reload_completed && SSE_REG_P (operands[0])" 4013 [(set (match_dup 2) 4014 (float_extend:V2DF 4015 (vec_select:V2SF 4016 (match_dup 3) 4017 (parallel [(const_int 0) (const_int 1)]))))] 4018{ 4019 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0); 4020 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0); 4021 /* Use movss for loading from memory, unpcklps reg, reg for registers. 4022 Try to avoid move when unpacking can be done in source. */ 4023 if (REG_P (operands[1])) 4024 { 4025 /* If it is unsafe to overwrite upper half of source, we need 4026 to move to destination and unpack there. */ 4027 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 4028 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4) 4029 && true_regnum (operands[0]) != true_regnum (operands[1])) 4030 { 4031 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0])); 4032 emit_move_insn (tmp, operands[1]); 4033 } 4034 else 4035 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0); 4036 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3], 4037 operands[3])); 4038 } 4039 else 4040 emit_insn (gen_vec_setv4sf_0 (operands[3], 4041 CONST0_RTX (V4SFmode), operands[1])); 4042}) 4043 4044;; It's more profitable to split and then extend in the same register. 4045(define_peephole2 4046 [(set (match_operand:DF 0 "register_operand") 4047 (float_extend:DF 4048 (match_operand:SF 1 "memory_operand")))] 4049 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS 4050 && optimize_insn_for_speed_p () 4051 && SSE_REG_P (operands[0])" 4052 [(set (match_dup 2) (match_dup 1)) 4053 (set (match_dup 0) (float_extend:DF (match_dup 2)))] 4054 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));") 4055 4056(define_insn "*extendsfdf2_mixed" 4057 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x") 4058 (float_extend:DF 4059 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))] 4060 "TARGET_SSE2 && TARGET_MIX_SSE_I387" 4061{ 4062 switch (which_alternative) 4063 { 4064 case 0: 4065 case 1: 4066 return output_387_reg_move (insn, operands); 4067 4068 case 2: 4069 return "%vcvtss2sd\t{%1, %d0|%d0, %1}"; 4070 4071 default: 4072 gcc_unreachable (); 4073 } 4074} 4075 [(set_attr "type" "fmov,fmov,ssecvt") 4076 (set_attr "prefix" "orig,orig,maybe_vex") 4077 (set_attr "mode" "SF,XF,DF")]) 4078 4079(define_insn "*extendsfdf2_sse" 4080 [(set (match_operand:DF 0 "nonimmediate_operand" "=x") 4081 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))] 4082 "TARGET_SSE2 && TARGET_SSE_MATH" 4083 "%vcvtss2sd\t{%1, %d0|%d0, %1}" 4084 [(set_attr "type" "ssecvt") 4085 (set_attr "prefix" "maybe_vex") 4086 (set_attr "mode" "DF")]) 4087 4088(define_insn "*extendsfdf2_i387" 4089 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") 4090 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] 4091 "TARGET_80387" 4092 "* return output_387_reg_move (insn, operands);" 4093 [(set_attr "type" "fmov") 4094 (set_attr "mode" "SF,XF")]) 4095 4096(define_expand "extend<mode>xf2" 4097 [(set (match_operand:XF 0 "nonimmediate_operand") 4098 (float_extend:XF (match_operand:MODEF 1 "general_operand")))] 4099 "TARGET_80387" 4100{ 4101 /* ??? Needed for compress_float_constant since all fp constants 4102 are TARGET_LEGITIMATE_CONSTANT_P. */ 4103 if (GET_CODE (operands[1]) == CONST_DOUBLE) 4104 { 4105 if (standard_80387_constant_p (operands[1]) > 0) 4106 { 4107 operands[1] = simplify_const_unary_operation 4108 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode); 4109 emit_move_insn_1 (operands[0], operands[1]); 4110 DONE; 4111 } 4112 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1])); 4113 } 4114}) 4115 4116(define_insn "*extend<mode>xf2_i387" 4117 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 4118 (float_extend:XF 4119 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))] 4120 "TARGET_80387" 4121 "* return output_387_reg_move (insn, operands);" 4122 [(set_attr "type" "fmov") 4123 (set_attr "mode" "<MODE>,XF")]) 4124 4125;; %%% This seems bad bad news. 4126;; This cannot output into an f-reg because there is no way to be sure 4127;; of truncating in that case. Otherwise this is just like a simple move 4128;; insn. So we pretend we can output to a reg in order to get better 4129;; register preferencing, but we really use a stack slot. 4130 4131;; Conversion from DFmode to SFmode. 4132 4133(define_expand "truncdfsf2" 4134 [(set (match_operand:SF 0 "nonimmediate_operand") 4135 (float_truncate:SF 4136 (match_operand:DF 1 "nonimmediate_operand")))] 4137 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4138{ 4139 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387) 4140 ; 4141 else if (flag_unsafe_math_optimizations) 4142 ; 4143 else 4144 { 4145 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP); 4146 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp)); 4147 DONE; 4148 } 4149}) 4150 4151/* For converting DF(xmm2) to SF(xmm1), use the following code instead of 4152 cvtsd2ss: 4153 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs 4154 cvtpd2ps xmm2,xmm1 4155 We do the conversion post reload to avoid producing of 128bit spills 4156 that might lead to ICE on 32bit target. The sequence unlikely combine 4157 anyway. */ 4158(define_split 4159 [(set (match_operand:SF 0 "register_operand") 4160 (float_truncate:SF 4161 (match_operand:DF 1 "nonimmediate_operand")))] 4162 "TARGET_USE_VECTOR_FP_CONVERTS 4163 && optimize_insn_for_speed_p () 4164 && reload_completed && SSE_REG_P (operands[0])" 4165 [(set (match_dup 2) 4166 (vec_concat:V4SF 4167 (float_truncate:V2SF 4168 (match_dup 4)) 4169 (match_dup 3)))] 4170{ 4171 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0); 4172 operands[3] = CONST0_RTX (V2SFmode); 4173 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0); 4174 /* Use movsd for loading from memory, unpcklpd for registers. 4175 Try to avoid move when unpacking can be done in source, or SSE3 4176 movddup is available. */ 4177 if (REG_P (operands[1])) 4178 { 4179 if (!TARGET_SSE3 4180 && true_regnum (operands[0]) != true_regnum (operands[1]) 4181 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER 4182 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8)) 4183 { 4184 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0); 4185 emit_move_insn (tmp, operands[1]); 4186 operands[1] = tmp; 4187 } 4188 else if (!TARGET_SSE3) 4189 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0); 4190 emit_insn (gen_vec_dupv2df (operands[4], operands[1])); 4191 } 4192 else 4193 emit_insn (gen_sse2_loadlpd (operands[4], 4194 CONST0_RTX (V2DFmode), operands[1])); 4195}) 4196 4197;; It's more profitable to split and then extend in the same register. 4198(define_peephole2 4199 [(set (match_operand:SF 0 "register_operand") 4200 (float_truncate:SF 4201 (match_operand:DF 1 "memory_operand")))] 4202 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS 4203 && optimize_insn_for_speed_p () 4204 && SSE_REG_P (operands[0])" 4205 [(set (match_dup 2) (match_dup 1)) 4206 (set (match_dup 0) (float_truncate:SF (match_dup 2)))] 4207 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));") 4208 4209(define_expand "truncdfsf2_with_temp" 4210 [(parallel [(set (match_operand:SF 0) 4211 (float_truncate:SF (match_operand:DF 1))) 4212 (clobber (match_operand:SF 2))])]) 4213 4214(define_insn "*truncdfsf_fast_mixed" 4215 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x") 4216 (float_truncate:SF 4217 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))] 4218 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations" 4219{ 4220 switch (which_alternative) 4221 { 4222 case 0: 4223 return output_387_reg_move (insn, operands); 4224 case 1: 4225 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4226 default: 4227 gcc_unreachable (); 4228 } 4229} 4230 [(set_attr "type" "fmov,ssecvt") 4231 (set_attr "prefix" "orig,maybe_vex") 4232 (set_attr "mode" "SF")]) 4233 4234;; Yes, this one doesn't depend on flag_unsafe_math_optimizations, 4235;; because nothing we do here is unsafe. 4236(define_insn "*truncdfsf_fast_sse" 4237 [(set (match_operand:SF 0 "nonimmediate_operand" "=x") 4238 (float_truncate:SF 4239 (match_operand:DF 1 "nonimmediate_operand" "xm")))] 4240 "TARGET_SSE2 && TARGET_SSE_MATH" 4241 "%vcvtsd2ss\t{%1, %d0|%d0, %1}" 4242 [(set_attr "type" "ssecvt") 4243 (set_attr "prefix" "maybe_vex") 4244 (set_attr "mode" "SF")]) 4245 4246(define_insn "*truncdfsf_fast_i387" 4247 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm") 4248 (float_truncate:SF 4249 (match_operand:DF 1 "nonimmediate_operand" "f")))] 4250 "TARGET_80387 && flag_unsafe_math_optimizations" 4251 "* return output_387_reg_move (insn, operands);" 4252 [(set_attr "type" "fmov") 4253 (set_attr "mode" "SF")]) 4254 4255(define_insn "*truncdfsf_mixed" 4256 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r") 4257 (float_truncate:SF 4258 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f"))) 4259 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))] 4260 "TARGET_MIX_SSE_I387" 4261{ 4262 switch (which_alternative) 4263 { 4264 case 0: 4265 return output_387_reg_move (insn, operands); 4266 case 1: 4267 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4268 4269 default: 4270 return "#"; 4271 } 4272} 4273 [(set_attr "isa" "*,sse2,*,*,*") 4274 (set_attr "type" "fmov,ssecvt,multi,multi,multi") 4275 (set_attr "unit" "*,*,i387,i387,i387") 4276 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig") 4277 (set_attr "mode" "SF")]) 4278 4279(define_insn "*truncdfsf_i387" 4280 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4281 (float_truncate:SF 4282 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f"))) 4283 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4284 "TARGET_80387" 4285{ 4286 switch (which_alternative) 4287 { 4288 case 0: 4289 return output_387_reg_move (insn, operands); 4290 4291 default: 4292 return "#"; 4293 } 4294} 4295 [(set_attr "type" "fmov,multi,multi,multi") 4296 (set_attr "unit" "*,i387,i387,i387") 4297 (set_attr "mode" "SF")]) 4298 4299(define_insn "*truncdfsf2_i387_1" 4300 [(set (match_operand:SF 0 "memory_operand" "=m") 4301 (float_truncate:SF 4302 (match_operand:DF 1 "register_operand" "f")))] 4303 "TARGET_80387 4304 && !(TARGET_SSE2 && TARGET_SSE_MATH) 4305 && !TARGET_MIX_SSE_I387" 4306 "* return output_387_reg_move (insn, operands);" 4307 [(set_attr "type" "fmov") 4308 (set_attr "mode" "SF")]) 4309 4310(define_split 4311 [(set (match_operand:SF 0 "register_operand") 4312 (float_truncate:SF 4313 (match_operand:DF 1 "fp_register_operand"))) 4314 (clobber (match_operand 2))] 4315 "reload_completed" 4316 [(set (match_dup 2) (match_dup 1)) 4317 (set (match_dup 0) (match_dup 2))] 4318 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));") 4319 4320;; Conversion from XFmode to {SF,DF}mode 4321 4322(define_expand "truncxf<mode>2" 4323 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand") 4324 (float_truncate:MODEF 4325 (match_operand:XF 1 "register_operand"))) 4326 (clobber (match_dup 2))])] 4327 "TARGET_80387" 4328{ 4329 if (flag_unsafe_math_optimizations) 4330 { 4331 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode); 4332 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1])); 4333 if (reg != operands[0]) 4334 emit_move_insn (operands[0], reg); 4335 DONE; 4336 } 4337 else 4338 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4339}) 4340 4341(define_insn "*truncxfsf2_mixed" 4342 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4343 (float_truncate:SF 4344 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4345 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))] 4346 "TARGET_80387" 4347{ 4348 gcc_assert (!which_alternative); 4349 return output_387_reg_move (insn, operands); 4350} 4351 [(set_attr "type" "fmov,multi,multi,multi") 4352 (set_attr "unit" "*,i387,i387,i387") 4353 (set_attr "mode" "SF")]) 4354 4355(define_insn "*truncxfdf2_mixed" 4356 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r") 4357 (float_truncate:DF 4358 (match_operand:XF 1 "register_operand" "f ,f ,f ,f"))) 4359 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))] 4360 "TARGET_80387" 4361{ 4362 gcc_assert (!which_alternative); 4363 return output_387_reg_move (insn, operands); 4364} 4365 [(set_attr "isa" "*,*,sse2,*") 4366 (set_attr "type" "fmov,multi,multi,multi") 4367 (set_attr "unit" "*,i387,i387,i387") 4368 (set_attr "mode" "DF")]) 4369 4370(define_insn "truncxf<mode>2_i387_noop" 4371 [(set (match_operand:MODEF 0 "register_operand" "=f") 4372 (float_truncate:MODEF 4373 (match_operand:XF 1 "register_operand" "f")))] 4374 "TARGET_80387 && flag_unsafe_math_optimizations" 4375 "* return output_387_reg_move (insn, operands);" 4376 [(set_attr "type" "fmov") 4377 (set_attr "mode" "<MODE>")]) 4378 4379(define_insn "*truncxf<mode>2_i387" 4380 [(set (match_operand:MODEF 0 "memory_operand" "=m") 4381 (float_truncate:MODEF 4382 (match_operand:XF 1 "register_operand" "f")))] 4383 "TARGET_80387" 4384 "* return output_387_reg_move (insn, operands);" 4385 [(set_attr "type" "fmov") 4386 (set_attr "mode" "<MODE>")]) 4387 4388(define_split 4389 [(set (match_operand:MODEF 0 "register_operand") 4390 (float_truncate:MODEF 4391 (match_operand:XF 1 "register_operand"))) 4392 (clobber (match_operand:MODEF 2 "memory_operand"))] 4393 "TARGET_80387 && reload_completed" 4394 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1))) 4395 (set (match_dup 0) (match_dup 2))]) 4396 4397(define_split 4398 [(set (match_operand:MODEF 0 "memory_operand") 4399 (float_truncate:MODEF 4400 (match_operand:XF 1 "register_operand"))) 4401 (clobber (match_operand:MODEF 2 "memory_operand"))] 4402 "TARGET_80387" 4403 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]) 4404 4405;; Signed conversion to DImode. 4406 4407(define_expand "fix_truncxfdi2" 4408 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand") 4409 (fix:DI (match_operand:XF 1 "register_operand"))) 4410 (clobber (reg:CC FLAGS_REG))])] 4411 "TARGET_80387" 4412{ 4413 if (TARGET_FISTTP) 4414 { 4415 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4416 DONE; 4417 } 4418}) 4419 4420(define_expand "fix_trunc<mode>di2" 4421 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand") 4422 (fix:DI (match_operand:MODEF 1 "register_operand"))) 4423 (clobber (reg:CC FLAGS_REG))])] 4424 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4425{ 4426 if (TARGET_FISTTP 4427 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4428 { 4429 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1])); 4430 DONE; 4431 } 4432 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4433 { 4434 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4435 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4436 if (out != operands[0]) 4437 emit_move_insn (operands[0], out); 4438 DONE; 4439 } 4440}) 4441 4442;; Signed conversion to SImode. 4443 4444(define_expand "fix_truncxfsi2" 4445 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 4446 (fix:SI (match_operand:XF 1 "register_operand"))) 4447 (clobber (reg:CC FLAGS_REG))])] 4448 "TARGET_80387" 4449{ 4450 if (TARGET_FISTTP) 4451 { 4452 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4453 DONE; 4454 } 4455}) 4456 4457(define_expand "fix_trunc<mode>si2" 4458 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 4459 (fix:SI (match_operand:MODEF 1 "register_operand"))) 4460 (clobber (reg:CC FLAGS_REG))])] 4461 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4462{ 4463 if (TARGET_FISTTP 4464 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4465 { 4466 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1])); 4467 DONE; 4468 } 4469 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4470 { 4471 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4472 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4473 if (out != operands[0]) 4474 emit_move_insn (operands[0], out); 4475 DONE; 4476 } 4477}) 4478 4479;; Signed conversion to HImode. 4480 4481(define_expand "fix_trunc<mode>hi2" 4482 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand") 4483 (fix:HI (match_operand:X87MODEF 1 "register_operand"))) 4484 (clobber (reg:CC FLAGS_REG))])] 4485 "TARGET_80387 4486 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4487{ 4488 if (TARGET_FISTTP) 4489 { 4490 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1])); 4491 DONE; 4492 } 4493}) 4494 4495;; Unsigned conversion to SImode. 4496 4497(define_expand "fixuns_trunc<mode>si2" 4498 [(parallel 4499 [(set (match_operand:SI 0 "register_operand") 4500 (unsigned_fix:SI 4501 (match_operand:MODEF 1 "nonimmediate_operand"))) 4502 (use (match_dup 2)) 4503 (clobber (match_scratch:<ssevecmode> 3)) 4504 (clobber (match_scratch:<ssevecmode> 4))])] 4505 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH" 4506{ 4507 machine_mode mode = <MODE>mode; 4508 machine_mode vecmode = <ssevecmode>mode; 4509 REAL_VALUE_TYPE TWO31r; 4510 rtx two31; 4511 4512 if (optimize_insn_for_size_p ()) 4513 FAIL; 4514 4515 real_ldexp (&TWO31r, &dconst1, 31); 4516 two31 = const_double_from_real_value (TWO31r, mode); 4517 two31 = ix86_build_const_vector (vecmode, true, two31); 4518 operands[2] = force_reg (vecmode, two31); 4519}) 4520 4521(define_insn_and_split "*fixuns_trunc<mode>_1" 4522 [(set (match_operand:SI 0 "register_operand" "=&x,&x") 4523 (unsigned_fix:SI 4524 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm"))) 4525 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x")) 4526 (clobber (match_scratch:<ssevecmode> 1 "=x,&x")) 4527 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))] 4528 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH 4529 && optimize_function_for_speed_p (cfun)" 4530 "#" 4531 "&& reload_completed" 4532 [(const_int 0)] 4533{ 4534 ix86_split_convert_uns_si_sse (operands); 4535 DONE; 4536}) 4537 4538;; Unsigned conversion to HImode. 4539;; Without these patterns, we'll try the unsigned SI conversion which 4540;; is complex for SSE, rather than the signed SI conversion, which isn't. 4541 4542(define_expand "fixuns_trunc<mode>hi2" 4543 [(set (match_dup 2) 4544 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand"))) 4545 (set (match_operand:HI 0 "nonimmediate_operand") 4546 (subreg:HI (match_dup 2) 0))] 4547 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 4548 "operands[2] = gen_reg_rtx (SImode);") 4549 4550;; When SSE is available, it is always faster to use it! 4551(define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse" 4552 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 4553 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))] 4554 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) 4555 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4556 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}" 4557 [(set_attr "type" "sseicvt") 4558 (set_attr "prefix" "maybe_vex") 4559 (set (attr "prefix_rex") 4560 (if_then_else 4561 (match_test "<SWI48:MODE>mode == DImode") 4562 (const_string "1") 4563 (const_string "*"))) 4564 (set_attr "mode" "<MODEF:MODE>") 4565 (set_attr "athlon_decode" "double,vector") 4566 (set_attr "amdfam10_decode" "double,double") 4567 (set_attr "bdver1_decode" "double,double")]) 4568 4569;; Avoid vector decoded forms of the instruction. 4570(define_peephole2 4571 [(match_scratch:MODEF 2 "x") 4572 (set (match_operand:SWI48 0 "register_operand") 4573 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))] 4574 "TARGET_AVOID_VECTOR_DECODE 4575 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) 4576 && optimize_insn_for_speed_p ()" 4577 [(set (match_dup 2) (match_dup 1)) 4578 (set (match_dup 0) (fix:SWI48 (match_dup 2)))]) 4579 4580(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1" 4581 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 4582 (fix:SWI248x (match_operand 1 "register_operand")))] 4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4584 && TARGET_FISTTP 4585 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4586 && (TARGET_64BIT || <MODE>mode != DImode)) 4587 && TARGET_SSE_MATH) 4588 && can_create_pseudo_p ()" 4589 "#" 4590 "&& 1" 4591 [(const_int 0)] 4592{ 4593 if (memory_operand (operands[0], VOIDmode)) 4594 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1])); 4595 else 4596 { 4597 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4598 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0], 4599 operands[1], 4600 operands[2])); 4601 } 4602 DONE; 4603} 4604 [(set_attr "type" "fisttp") 4605 (set_attr "mode" "<MODE>")]) 4606 4607(define_insn "fix_trunc<mode>_i387_fisttp" 4608 [(set (match_operand:SWI248x 0 "memory_operand" "=m") 4609 (fix:SWI248x (match_operand 1 "register_operand" "f"))) 4610 (clobber (match_scratch:XF 2 "=&1f"))] 4611 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4612 && TARGET_FISTTP 4613 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4614 && (TARGET_64BIT || <MODE>mode != DImode)) 4615 && TARGET_SSE_MATH)" 4616 "* return output_fix_trunc (insn, operands, true);" 4617 [(set_attr "type" "fisttp") 4618 (set_attr "mode" "<MODE>")]) 4619 4620(define_insn "fix_trunc<mode>_i387_fisttp_with_temp" 4621 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r") 4622 (fix:SWI248x (match_operand 1 "register_operand" "f,f"))) 4623 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m")) 4624 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 4625 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4626 && TARGET_FISTTP 4627 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4628 && (TARGET_64BIT || <MODE>mode != DImode)) 4629 && TARGET_SSE_MATH)" 4630 "#" 4631 [(set_attr "type" "fisttp") 4632 (set_attr "mode" "<MODE>")]) 4633 4634(define_split 4635 [(set (match_operand:SWI248x 0 "register_operand") 4636 (fix:SWI248x (match_operand 1 "register_operand"))) 4637 (clobber (match_operand:SWI248x 2 "memory_operand")) 4638 (clobber (match_scratch 3))] 4639 "reload_completed" 4640 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1))) 4641 (clobber (match_dup 3))]) 4642 (set (match_dup 0) (match_dup 2))]) 4643 4644(define_split 4645 [(set (match_operand:SWI248x 0 "memory_operand") 4646 (fix:SWI248x (match_operand 1 "register_operand"))) 4647 (clobber (match_operand:SWI248x 2 "memory_operand")) 4648 (clobber (match_scratch 3))] 4649 "reload_completed" 4650 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1))) 4651 (clobber (match_dup 3))])]) 4652 4653;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4654;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4655;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4656;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4657;; function in i386.c. 4658(define_insn_and_split "*fix_trunc<mode>_i387_1" 4659 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 4660 (fix:SWI248x (match_operand 1 "register_operand"))) 4661 (clobber (reg:CC FLAGS_REG))] 4662 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4663 && !TARGET_FISTTP 4664 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4665 && (TARGET_64BIT || <MODE>mode != DImode)) 4666 && can_create_pseudo_p ()" 4667 "#" 4668 "&& 1" 4669 [(const_int 0)] 4670{ 4671 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4672 4673 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4674 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4675 if (memory_operand (operands[0], VOIDmode)) 4676 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4677 operands[2], operands[3])); 4678 else 4679 { 4680 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 4681 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1], 4682 operands[2], operands[3], 4683 operands[4])); 4684 } 4685 DONE; 4686} 4687 [(set_attr "type" "fistp") 4688 (set_attr "i387_cw" "trunc") 4689 (set_attr "mode" "<MODE>")]) 4690 4691(define_insn "fix_truncdi_i387" 4692 [(set (match_operand:DI 0 "memory_operand" "=m") 4693 (fix:DI (match_operand 1 "register_operand" "f"))) 4694 (use (match_operand:HI 2 "memory_operand" "m")) 4695 (use (match_operand:HI 3 "memory_operand" "m")) 4696 (clobber (match_scratch:XF 4 "=&1f"))] 4697 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4698 && !TARGET_FISTTP 4699 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4700 "* return output_fix_trunc (insn, operands, false);" 4701 [(set_attr "type" "fistp") 4702 (set_attr "i387_cw" "trunc") 4703 (set_attr "mode" "DI")]) 4704 4705(define_insn "fix_truncdi_i387_with_temp" 4706 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 4707 (fix:DI (match_operand 1 "register_operand" "f,f"))) 4708 (use (match_operand:HI 2 "memory_operand" "m,m")) 4709 (use (match_operand:HI 3 "memory_operand" "m,m")) 4710 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 4711 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 4712 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4713 && !TARGET_FISTTP 4714 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4715 "#" 4716 [(set_attr "type" "fistp") 4717 (set_attr "i387_cw" "trunc") 4718 (set_attr "mode" "DI")]) 4719 4720(define_split 4721 [(set (match_operand:DI 0 "register_operand") 4722 (fix:DI (match_operand 1 "register_operand"))) 4723 (use (match_operand:HI 2 "memory_operand")) 4724 (use (match_operand:HI 3 "memory_operand")) 4725 (clobber (match_operand:DI 4 "memory_operand")) 4726 (clobber (match_scratch 5))] 4727 "reload_completed" 4728 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) 4729 (use (match_dup 2)) 4730 (use (match_dup 3)) 4731 (clobber (match_dup 5))]) 4732 (set (match_dup 0) (match_dup 4))]) 4733 4734(define_split 4735 [(set (match_operand:DI 0 "memory_operand") 4736 (fix:DI (match_operand 1 "register_operand"))) 4737 (use (match_operand:HI 2 "memory_operand")) 4738 (use (match_operand:HI 3 "memory_operand")) 4739 (clobber (match_operand:DI 4 "memory_operand")) 4740 (clobber (match_scratch 5))] 4741 "reload_completed" 4742 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1))) 4743 (use (match_dup 2)) 4744 (use (match_dup 3)) 4745 (clobber (match_dup 5))])]) 4746 4747(define_insn "fix_trunc<mode>_i387" 4748 [(set (match_operand:SWI24 0 "memory_operand" "=m") 4749 (fix:SWI24 (match_operand 1 "register_operand" "f"))) 4750 (use (match_operand:HI 2 "memory_operand" "m")) 4751 (use (match_operand:HI 3 "memory_operand" "m"))] 4752 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4753 && !TARGET_FISTTP 4754 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4755 "* return output_fix_trunc (insn, operands, false);" 4756 [(set_attr "type" "fistp") 4757 (set_attr "i387_cw" "trunc") 4758 (set_attr "mode" "<MODE>")]) 4759 4760(define_insn "fix_trunc<mode>_i387_with_temp" 4761 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 4762 (fix:SWI24 (match_operand 1 "register_operand" "f,f"))) 4763 (use (match_operand:HI 2 "memory_operand" "m,m")) 4764 (use (match_operand:HI 3 "memory_operand" "m,m")) 4765 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 4766 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4767 && !TARGET_FISTTP 4768 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4769 "#" 4770 [(set_attr "type" "fistp") 4771 (set_attr "i387_cw" "trunc") 4772 (set_attr "mode" "<MODE>")]) 4773 4774(define_split 4775 [(set (match_operand:SWI24 0 "register_operand") 4776 (fix:SWI24 (match_operand 1 "register_operand"))) 4777 (use (match_operand:HI 2 "memory_operand")) 4778 (use (match_operand:HI 3 "memory_operand")) 4779 (clobber (match_operand:SWI24 4 "memory_operand"))] 4780 "reload_completed" 4781 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1))) 4782 (use (match_dup 2)) 4783 (use (match_dup 3))]) 4784 (set (match_dup 0) (match_dup 4))]) 4785 4786(define_split 4787 [(set (match_operand:SWI24 0 "memory_operand") 4788 (fix:SWI24 (match_operand 1 "register_operand"))) 4789 (use (match_operand:HI 2 "memory_operand")) 4790 (use (match_operand:HI 3 "memory_operand")) 4791 (clobber (match_operand:SWI24 4 "memory_operand"))] 4792 "reload_completed" 4793 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1))) 4794 (use (match_dup 2)) 4795 (use (match_dup 3))])]) 4796 4797(define_insn "x86_fnstcw_1" 4798 [(set (match_operand:HI 0 "memory_operand" "=m") 4799 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))] 4800 "TARGET_80387" 4801 "fnstcw\t%0" 4802 [(set (attr "length") 4803 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4804 (set_attr "mode" "HI") 4805 (set_attr "unit" "i387") 4806 (set_attr "bdver1_decode" "vector")]) 4807 4808(define_insn "x86_fldcw_1" 4809 [(set (reg:HI FPCR_REG) 4810 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))] 4811 "TARGET_80387" 4812 "fldcw\t%0" 4813 [(set (attr "length") 4814 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4815 (set_attr "mode" "HI") 4816 (set_attr "unit" "i387") 4817 (set_attr "athlon_decode" "vector") 4818 (set_attr "amdfam10_decode" "vector") 4819 (set_attr "bdver1_decode" "vector")]) 4820 4821;; Conversion between fixed point and floating point. 4822 4823;; Even though we only accept memory inputs, the backend _really_ 4824;; wants to be able to do this between registers. Thankfully, LRA 4825;; will fix this up for us during register allocation. 4826 4827(define_insn "floathi<mode>2" 4828 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 4829 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))] 4830 "TARGET_80387 4831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4832 || TARGET_MIX_SSE_I387)" 4833 "fild%Z1\t%1" 4834 [(set_attr "type" "fmov") 4835 (set_attr "mode" "<MODE>") 4836 (set_attr "fp_int_src" "true")]) 4837 4838(define_insn "float<SWI48x:mode>xf2" 4839 [(set (match_operand:XF 0 "register_operand" "=f") 4840 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))] 4841 "TARGET_80387" 4842 "fild%Z1\t%1" 4843 [(set_attr "type" "fmov") 4844 (set_attr "mode" "XF") 4845 (set_attr "fp_int_src" "true")]) 4846 4847(define_expand "float<SWI48:mode><MODEF:mode>2" 4848 [(set (match_operand:MODEF 0 "register_operand") 4849 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))] 4850 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)" 4851{ 4852 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 4853 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode)) 4854 { 4855 rtx reg = gen_reg_rtx (XFmode); 4856 rtx (*insn)(rtx, rtx); 4857 4858 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1])); 4859 4860 if (<MODEF:MODE>mode == SFmode) 4861 insn = gen_truncxfsf2; 4862 else if (<MODEF:MODE>mode == DFmode) 4863 insn = gen_truncxfdf2; 4864 else 4865 gcc_unreachable (); 4866 4867 emit_insn (insn (operands[0], reg)); 4868 DONE; 4869 } 4870}) 4871 4872(define_insn "*float<SWI48:mode><MODEF:mode>2_sse" 4873 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") 4874 (float:MODEF 4875 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))] 4876 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" 4877 "@ 4878 fild%Z1\t%1 4879 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1} 4880 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}" 4881 [(set_attr "type" "fmov,sseicvt,sseicvt") 4882 (set_attr "prefix" "orig,maybe_vex,maybe_vex") 4883 (set_attr "mode" "<MODEF:MODE>") 4884 (set (attr "prefix_rex") 4885 (if_then_else 4886 (and (eq_attr "prefix" "maybe_vex") 4887 (match_test "<SWI48:MODE>mode == DImode")) 4888 (const_string "1") 4889 (const_string "*"))) 4890 (set_attr "unit" "i387,*,*") 4891 (set_attr "athlon_decode" "*,double,direct") 4892 (set_attr "amdfam10_decode" "*,vector,double") 4893 (set_attr "bdver1_decode" "*,double,direct") 4894 (set_attr "fp_int_src" "true") 4895 (set (attr "enabled") 4896 (cond [(eq_attr "alternative" "0") 4897 (symbol_ref "TARGET_MIX_SSE_I387 4898 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, 4899 <SWI48:MODE>mode)") 4900 ] 4901 (symbol_ref "true"))) 4902 (set (attr "preferred_for_speed") 4903 (cond [(eq_attr "alternative" "1") 4904 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")] 4905 (symbol_ref "true")))]) 4906 4907(define_insn "*float<SWI48x:mode><MODEF:mode>2_i387" 4908 [(set (match_operand:MODEF 0 "register_operand" "=f") 4909 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))] 4910 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)" 4911 "fild%Z1\t%1" 4912 [(set_attr "type" "fmov") 4913 (set_attr "mode" "<MODEF:MODE>") 4914 (set_attr "fp_int_src" "true")]) 4915 4916;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory 4917;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs 4918;; alternative in sse2_loadld. 4919(define_split 4920 [(set (match_operand:MODEF 0 "register_operand") 4921 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))] 4922 "TARGET_SSE2 && TARGET_SSE_MATH 4923 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun) 4924 && reload_completed && SSE_REG_P (operands[0]) 4925 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)" 4926 [(const_int 0)] 4927{ 4928 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0], 4929 <MODE>mode, 0); 4930 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0); 4931 4932 emit_insn (gen_sse2_loadld (operands[4], 4933 CONST0_RTX (V4SImode), operands[1])); 4934 4935 if (<ssevecmode>mode == V4SFmode) 4936 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 4937 else 4938 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 4939 DONE; 4940}) 4941 4942;; Avoid partial SSE register dependency stalls 4943(define_split 4944 [(set (match_operand:MODEF 0 "register_operand") 4945 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))] 4946 "TARGET_SSE2 && TARGET_SSE_MATH 4947 && TARGET_SSE_PARTIAL_REG_DEPENDENCY 4948 && optimize_function_for_speed_p (cfun) 4949 && reload_completed && SSE_REG_P (operands[0])" 4950 [(const_int 0)] 4951{ 4952 const machine_mode vmode = <MODEF:ssevecmode>mode; 4953 const machine_mode mode = <MODEF:MODE>mode; 4954 rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0); 4955 4956 emit_move_insn (op0, CONST0_RTX (vmode)); 4957 4958 t = gen_rtx_FLOAT (mode, operands[1]); 4959 t = gen_rtx_VEC_DUPLICATE (vmode, t); 4960 t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx); 4961 emit_insn (gen_rtx_SET (VOIDmode, op0, t)); 4962 DONE; 4963}) 4964 4965;; Break partial reg stall for cvtsd2ss. 4966 4967(define_peephole2 4968 [(set (match_operand:SF 0 "register_operand") 4969 (float_truncate:SF 4970 (match_operand:DF 1 "nonimmediate_operand")))] 4971 "TARGET_SSE2 && TARGET_SSE_MATH 4972 && TARGET_SSE_PARTIAL_REG_DEPENDENCY 4973 && optimize_function_for_speed_p (cfun) 4974 && SSE_REG_P (operands[0]) 4975 && (!SSE_REG_P (operands[1]) 4976 || REGNO (operands[0]) != REGNO (operands[1]))" 4977 [(set (match_dup 0) 4978 (vec_merge:V4SF 4979 (vec_duplicate:V4SF 4980 (float_truncate:V2SF 4981 (match_dup 1))) 4982 (match_dup 0) 4983 (const_int 1)))] 4984{ 4985 operands[0] = simplify_gen_subreg (V4SFmode, operands[0], 4986 SFmode, 0); 4987 operands[1] = simplify_gen_subreg (V2DFmode, operands[1], 4988 DFmode, 0); 4989 emit_move_insn (operands[0], CONST0_RTX (V4SFmode)); 4990}) 4991 4992;; Break partial reg stall for cvtss2sd. 4993 4994(define_peephole2 4995 [(set (match_operand:DF 0 "register_operand") 4996 (float_extend:DF 4997 (match_operand:SF 1 "nonimmediate_operand")))] 4998 "TARGET_SSE2 && TARGET_SSE_MATH 4999 && TARGET_SSE_PARTIAL_REG_DEPENDENCY 5000 && optimize_function_for_speed_p (cfun) 5001 && SSE_REG_P (operands[0]) 5002 && (!SSE_REG_P (operands[1]) 5003 || REGNO (operands[0]) != REGNO (operands[1]))" 5004 [(set (match_dup 0) 5005 (vec_merge:V2DF 5006 (float_extend:V2DF 5007 (vec_select:V2SF 5008 (match_dup 1) 5009 (parallel [(const_int 0) (const_int 1)]))) 5010 (match_dup 0) 5011 (const_int 1)))] 5012{ 5013 operands[0] = simplify_gen_subreg (V2DFmode, operands[0], 5014 DFmode, 0); 5015 operands[1] = simplify_gen_subreg (V4SFmode, operands[1], 5016 SFmode, 0); 5017 emit_move_insn (operands[0], CONST0_RTX (V2DFmode)); 5018}) 5019 5020;; Avoid store forwarding (partial memory) stall penalty 5021;; by passing DImode value through XMM registers. */ 5022 5023(define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm" 5024 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 5025 (float:X87MODEF 5026 (match_operand:DI 1 "nonimmediate_operand" "m,?r"))) 5027 (clobber (match_scratch:V4SI 3 "=X,x")) 5028 (clobber (match_scratch:V4SI 4 "=X,x")) 5029 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))] 5030 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5031 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC 5032 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)" 5033 "#" 5034 [(set_attr "type" "multi") 5035 (set_attr "mode" "<X87MODEF:MODE>") 5036 (set_attr "unit" "i387") 5037 (set_attr "fp_int_src" "true")]) 5038 5039(define_split 5040 [(set (match_operand:X87MODEF 0 "fp_register_operand") 5041 (float:X87MODEF (match_operand:DI 1 "register_operand"))) 5042 (clobber (match_scratch:V4SI 3)) 5043 (clobber (match_scratch:V4SI 4)) 5044 (clobber (match_operand:DI 2 "memory_operand"))] 5045 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5046 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC 5047 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5048 && reload_completed" 5049 [(set (match_dup 2) (match_dup 3)) 5050 (set (match_dup 0) (float:X87MODEF (match_dup 2)))] 5051{ 5052 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). 5053 Assemble the 64-bit DImode value in an xmm register. */ 5054 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode), 5055 gen_lowpart (SImode, operands[1]))); 5056 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode), 5057 gen_highpart (SImode, operands[1]))); 5058 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3], 5059 operands[4])); 5060 5061 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); 5062}) 5063 5064(define_split 5065 [(set (match_operand:X87MODEF 0 "fp_register_operand") 5066 (float:X87MODEF (match_operand:DI 1 "memory_operand"))) 5067 (clobber (match_scratch:V4SI 3)) 5068 (clobber (match_scratch:V4SI 4)) 5069 (clobber (match_operand:DI 2 "memory_operand"))] 5070 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5071 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC 5072 && !TARGET_64BIT && optimize_function_for_speed_p (cfun) 5073 && reload_completed" 5074 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]) 5075 5076(define_expand "floatuns<SWI12:mode><MODEF:mode>2" 5077 [(set (match_operand:MODEF 0 "register_operand") 5078 (unsigned_float:MODEF 5079 (match_operand:SWI12 1 "nonimmediate_operand")))] 5080 "!TARGET_64BIT 5081 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" 5082{ 5083 operands[1] = convert_to_mode (SImode, operands[1], 1); 5084 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1])); 5085 DONE; 5086}) 5087 5088;; Avoid store forwarding (partial memory) stall penalty by extending 5089;; SImode value to DImode through XMM register instead of pushing two 5090;; SImode values to stack. Also note that fild loads from memory only. 5091 5092(define_insn_and_split "*floatunssi<mode>2_i387_with_xmm" 5093 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 5094 (unsigned_float:X87MODEF 5095 (match_operand:SI 1 "nonimmediate_operand" "rm"))) 5096 (clobber (match_scratch:DI 3 "=x")) 5097 (clobber (match_operand:DI 2 "memory_operand" "=m"))] 5098 "!TARGET_64BIT 5099 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5100 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC" 5101 "#" 5102 "&& reload_completed" 5103 [(set (match_dup 3) (zero_extend:DI (match_dup 1))) 5104 (set (match_dup 2) (match_dup 3)) 5105 (set (match_dup 0) 5106 (float:X87MODEF (match_dup 2)))] 5107 "" 5108 [(set_attr "type" "multi") 5109 (set_attr "mode" "<MODE>")]) 5110 5111(define_expand "floatunssi<mode>2" 5112 [(parallel 5113 [(set (match_operand:X87MODEF 0 "register_operand") 5114 (unsigned_float:X87MODEF 5115 (match_operand:SI 1 "nonimmediate_operand"))) 5116 (clobber (match_scratch:DI 3)) 5117 (clobber (match_dup 2))])] 5118 "!TARGET_64BIT 5119 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5120 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC) 5121 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 5122{ 5123 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 5124 { 5125 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]); 5126 DONE; 5127 } 5128 else 5129 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 5130}) 5131 5132(define_expand "floatunsdisf2" 5133 [(use (match_operand:SF 0 "register_operand")) 5134 (use (match_operand:DI 1 "nonimmediate_operand"))] 5135 "TARGET_64BIT && TARGET_SSE_MATH" 5136 "x86_emit_floatuns (operands); DONE;") 5137 5138(define_expand "floatunsdidf2" 5139 [(use (match_operand:DF 0 "register_operand")) 5140 (use (match_operand:DI 1 "nonimmediate_operand"))] 5141 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK) 5142 && TARGET_SSE2 && TARGET_SSE_MATH" 5143{ 5144 if (TARGET_64BIT) 5145 x86_emit_floatuns (operands); 5146 else 5147 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]); 5148 DONE; 5149}) 5150 5151;; Load effective address instructions 5152 5153(define_insn_and_split "*lea<mode>" 5154 [(set (match_operand:SWI48 0 "register_operand" "=r") 5155 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))] 5156 "" 5157{ 5158 if (SImode_address_operand (operands[1], VOIDmode)) 5159 { 5160 gcc_assert (TARGET_64BIT); 5161 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 5162 } 5163 else 5164 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"; 5165} 5166 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)" 5167 [(const_int 0)] 5168{ 5169 machine_mode mode = <MODE>mode; 5170 rtx pat; 5171 5172 /* ix86_avoid_lea_for_addr re-recognizes insn and may 5173 change operands[] array behind our back. */ 5174 pat = PATTERN (curr_insn); 5175 5176 operands[0] = SET_DEST (pat); 5177 operands[1] = SET_SRC (pat); 5178 5179 /* Emit all operations in SImode for zero-extended addresses. */ 5180 if (SImode_address_operand (operands[1], VOIDmode)) 5181 mode = SImode; 5182 5183 ix86_split_lea_for_addr (curr_insn, operands, mode); 5184 5185 /* Zero-extend return register to DImode for zero-extended addresses. */ 5186 if (mode != <MODE>mode) 5187 emit_insn (gen_zero_extendsidi2 5188 (operands[0], gen_lowpart (mode, operands[0]))); 5189 5190 DONE; 5191} 5192 [(set_attr "type" "lea") 5193 (set (attr "mode") 5194 (if_then_else 5195 (match_operand 1 "SImode_address_operand") 5196 (const_string "SI") 5197 (const_string "<MODE>")))]) 5198 5199;; Add instructions 5200 5201(define_expand "add<mode>3" 5202 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 5203 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand") 5204 (match_operand:SDWIM 2 "<general_operand>")))] 5205 "" 5206 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;") 5207 5208(define_insn_and_split "*add<dwi>3_doubleword" 5209 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 5210 (plus:<DWI> 5211 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0") 5212 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>"))) 5213 (clobber (reg:CC FLAGS_REG))] 5214 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)" 5215 "#" 5216 "reload_completed" 5217 [(parallel [(set (reg:CCC FLAGS_REG) 5218 (compare:CCC 5219 (plus:DWIH (match_dup 1) (match_dup 2)) 5220 (match_dup 1))) 5221 (set (match_dup 0) 5222 (plus:DWIH (match_dup 1) (match_dup 2)))]) 5223 (parallel [(set (match_dup 3) 5224 (plus:DWIH 5225 (plus:DWIH 5226 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5227 (match_dup 4)) 5228 (match_dup 5))) 5229 (clobber (reg:CC FLAGS_REG))])] 5230 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);") 5231 5232(define_insn "*add<mode>_1" 5233 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r") 5234 (plus:SWI48 5235 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") 5236 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le"))) 5237 (clobber (reg:CC FLAGS_REG))] 5238 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5239{ 5240 switch (get_attr_type (insn)) 5241 { 5242 case TYPE_LEA: 5243 return "#"; 5244 5245 case TYPE_INCDEC: 5246 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5247 if (operands[2] == const1_rtx) 5248 return "inc{<imodesuffix>}\t%0"; 5249 else 5250 { 5251 gcc_assert (operands[2] == constm1_rtx); 5252 return "dec{<imodesuffix>}\t%0"; 5253 } 5254 5255 default: 5256 /* For most processors, ADD is faster than LEA. This alternative 5257 was added to use ADD as much as possible. */ 5258 if (which_alternative == 2) 5259 std::swap (operands[1], operands[2]); 5260 5261 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5262 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5263 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5264 5265 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5266 } 5267} 5268 [(set (attr "type") 5269 (cond [(eq_attr "alternative" "3") 5270 (const_string "lea") 5271 (match_operand:SWI48 2 "incdec_operand") 5272 (const_string "incdec") 5273 ] 5274 (const_string "alu"))) 5275 (set (attr "length_immediate") 5276 (if_then_else 5277 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5278 (const_string "1") 5279 (const_string "*"))) 5280 (set_attr "mode" "<MODE>")]) 5281 5282;; It may seem that nonimmediate operand is proper one for operand 1. 5283;; The addsi_1 pattern allows nonimmediate operand at that place and 5284;; we take care in ix86_binary_operator_ok to not allow two memory 5285;; operands so proper swapping will be done in reload. This allow 5286;; patterns constructed from addsi_1 to match. 5287 5288(define_insn "addsi_1_zext" 5289 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 5290 (zero_extend:DI 5291 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") 5292 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) 5293 (clobber (reg:CC FLAGS_REG))] 5294 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5295{ 5296 switch (get_attr_type (insn)) 5297 { 5298 case TYPE_LEA: 5299 return "#"; 5300 5301 case TYPE_INCDEC: 5302 if (operands[2] == const1_rtx) 5303 return "inc{l}\t%k0"; 5304 else 5305 { 5306 gcc_assert (operands[2] == constm1_rtx); 5307 return "dec{l}\t%k0"; 5308 } 5309 5310 default: 5311 /* For most processors, ADD is faster than LEA. This alternative 5312 was added to use ADD as much as possible. */ 5313 if (which_alternative == 1) 5314 std::swap (operands[1], operands[2]); 5315 5316 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5317 return "sub{l}\t{%2, %k0|%k0, %2}"; 5318 5319 return "add{l}\t{%2, %k0|%k0, %2}"; 5320 } 5321} 5322 [(set (attr "type") 5323 (cond [(eq_attr "alternative" "2") 5324 (const_string "lea") 5325 (match_operand:SI 2 "incdec_operand") 5326 (const_string "incdec") 5327 ] 5328 (const_string "alu"))) 5329 (set (attr "length_immediate") 5330 (if_then_else 5331 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5332 (const_string "1") 5333 (const_string "*"))) 5334 (set_attr "mode" "SI")]) 5335 5336(define_insn "*addhi_1" 5337 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp") 5338 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp") 5339 (match_operand:HI 2 "general_operand" "rn,rm,0,ln"))) 5340 (clobber (reg:CC FLAGS_REG))] 5341 "ix86_binary_operator_ok (PLUS, HImode, operands)" 5342{ 5343 switch (get_attr_type (insn)) 5344 { 5345 case TYPE_LEA: 5346 return "#"; 5347 5348 case TYPE_INCDEC: 5349 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5350 if (operands[2] == const1_rtx) 5351 return "inc{w}\t%0"; 5352 else 5353 { 5354 gcc_assert (operands[2] == constm1_rtx); 5355 return "dec{w}\t%0"; 5356 } 5357 5358 default: 5359 /* For most processors, ADD is faster than LEA. This alternative 5360 was added to use ADD as much as possible. */ 5361 if (which_alternative == 2) 5362 std::swap (operands[1], operands[2]); 5363 5364 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5365 if (x86_maybe_negate_const_int (&operands[2], HImode)) 5366 return "sub{w}\t{%2, %0|%0, %2}"; 5367 5368 return "add{w}\t{%2, %0|%0, %2}"; 5369 } 5370} 5371 [(set (attr "type") 5372 (cond [(eq_attr "alternative" "3") 5373 (const_string "lea") 5374 (match_operand:HI 2 "incdec_operand") 5375 (const_string "incdec") 5376 ] 5377 (const_string "alu"))) 5378 (set (attr "length_immediate") 5379 (if_then_else 5380 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5381 (const_string "1") 5382 (const_string "*"))) 5383 (set_attr "mode" "HI,HI,HI,SI")]) 5384 5385;; %%% Potential partial reg stall on alternatives 3 and 4. What to do? 5386(define_insn "*addqi_1" 5387 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp") 5388 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp") 5389 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln"))) 5390 (clobber (reg:CC FLAGS_REG))] 5391 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5392{ 5393 bool widen = (which_alternative == 3 || which_alternative == 4); 5394 5395 switch (get_attr_type (insn)) 5396 { 5397 case TYPE_LEA: 5398 return "#"; 5399 5400 case TYPE_INCDEC: 5401 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5402 if (operands[2] == const1_rtx) 5403 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 5404 else 5405 { 5406 gcc_assert (operands[2] == constm1_rtx); 5407 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 5408 } 5409 5410 default: 5411 /* For most processors, ADD is faster than LEA. These alternatives 5412 were added to use ADD as much as possible. */ 5413 if (which_alternative == 2 || which_alternative == 4) 5414 std::swap (operands[1], operands[2]); 5415 5416 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5417 if (x86_maybe_negate_const_int (&operands[2], QImode)) 5418 { 5419 if (widen) 5420 return "sub{l}\t{%2, %k0|%k0, %2}"; 5421 else 5422 return "sub{b}\t{%2, %0|%0, %2}"; 5423 } 5424 if (widen) 5425 return "add{l}\t{%k2, %k0|%k0, %k2}"; 5426 else 5427 return "add{b}\t{%2, %0|%0, %2}"; 5428 } 5429} 5430 [(set (attr "type") 5431 (cond [(eq_attr "alternative" "5") 5432 (const_string "lea") 5433 (match_operand:QI 2 "incdec_operand") 5434 (const_string "incdec") 5435 ] 5436 (const_string "alu"))) 5437 (set (attr "length_immediate") 5438 (if_then_else 5439 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5440 (const_string "1") 5441 (const_string "*"))) 5442 (set_attr "mode" "QI,QI,QI,SI,SI,SI")]) 5443 5444(define_insn "*addqi_1_slp" 5445 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 5446 (plus:QI (match_dup 0) 5447 (match_operand:QI 1 "general_operand" "qn,qm"))) 5448 (clobber (reg:CC FLAGS_REG))] 5449 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 5450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 5451{ 5452 switch (get_attr_type (insn)) 5453 { 5454 case TYPE_INCDEC: 5455 if (operands[1] == const1_rtx) 5456 return "inc{b}\t%0"; 5457 else 5458 { 5459 gcc_assert (operands[1] == constm1_rtx); 5460 return "dec{b}\t%0"; 5461 } 5462 5463 default: 5464 if (x86_maybe_negate_const_int (&operands[1], QImode)) 5465 return "sub{b}\t{%1, %0|%0, %1}"; 5466 5467 return "add{b}\t{%1, %0|%0, %1}"; 5468 } 5469} 5470 [(set (attr "type") 5471 (if_then_else (match_operand:QI 1 "incdec_operand") 5472 (const_string "incdec") 5473 (const_string "alu1"))) 5474 (set (attr "memory") 5475 (if_then_else (match_operand 1 "memory_operand") 5476 (const_string "load") 5477 (const_string "none"))) 5478 (set_attr "mode" "QI")]) 5479 5480;; Split non destructive adds if we cannot use lea. 5481(define_split 5482 [(set (match_operand:SWI48 0 "register_operand") 5483 (plus:SWI48 (match_operand:SWI48 1 "register_operand") 5484 (match_operand:SWI48 2 "x86_64_nonmemory_operand"))) 5485 (clobber (reg:CC FLAGS_REG))] 5486 "reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5487 [(set (match_dup 0) (match_dup 1)) 5488 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2))) 5489 (clobber (reg:CC FLAGS_REG))])]) 5490 5491;; Convert add to the lea pattern to avoid flags dependency. 5492(define_split 5493 [(set (match_operand:SWI 0 "register_operand") 5494 (plus:SWI (match_operand:SWI 1 "register_operand") 5495 (match_operand:SWI 2 "<nonmemory_operand>"))) 5496 (clobber (reg:CC FLAGS_REG))] 5497 "reload_completed && ix86_lea_for_add_ok (insn, operands)" 5498 [(const_int 0)] 5499{ 5500 machine_mode mode = <MODE>mode; 5501 rtx pat; 5502 5503 if (<MODE_SIZE> < GET_MODE_SIZE (SImode)) 5504 { 5505 mode = SImode; 5506 operands[0] = gen_lowpart (mode, operands[0]); 5507 operands[1] = gen_lowpart (mode, operands[1]); 5508 operands[2] = gen_lowpart (mode, operands[2]); 5509 } 5510 5511 pat = gen_rtx_PLUS (mode, operands[1], operands[2]); 5512 5513 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 5514 DONE; 5515}) 5516 5517;; Split non destructive adds if we cannot use lea. 5518(define_split 5519 [(set (match_operand:DI 0 "register_operand") 5520 (zero_extend:DI 5521 (plus:SI (match_operand:SI 1 "register_operand") 5522 (match_operand:SI 2 "x86_64_nonmemory_operand")))) 5523 (clobber (reg:CC FLAGS_REG))] 5524 "TARGET_64BIT 5525 && reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5526 [(set (match_dup 3) (match_dup 1)) 5527 (parallel [(set (match_dup 0) 5528 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2)))) 5529 (clobber (reg:CC FLAGS_REG))])] 5530 "operands[3] = gen_lowpart (SImode, operands[0]);") 5531 5532;; Convert add to the lea pattern to avoid flags dependency. 5533(define_split 5534 [(set (match_operand:DI 0 "register_operand") 5535 (zero_extend:DI 5536 (plus:SI (match_operand:SI 1 "register_operand") 5537 (match_operand:SI 2 "x86_64_nonmemory_operand")))) 5538 (clobber (reg:CC FLAGS_REG))] 5539 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" 5540 [(set (match_dup 0) 5541 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]) 5542 5543(define_insn "*add<mode>_2" 5544 [(set (reg FLAGS_REG) 5545 (compare 5546 (plus:SWI 5547 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") 5548 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0")) 5549 (const_int 0))) 5550 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>") 5551 (plus:SWI (match_dup 1) (match_dup 2)))] 5552 "ix86_match_ccmode (insn, CCGOCmode) 5553 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5554{ 5555 switch (get_attr_type (insn)) 5556 { 5557 case TYPE_INCDEC: 5558 if (operands[2] == const1_rtx) 5559 return "inc{<imodesuffix>}\t%0"; 5560 else 5561 { 5562 gcc_assert (operands[2] == constm1_rtx); 5563 return "dec{<imodesuffix>}\t%0"; 5564 } 5565 5566 default: 5567 if (which_alternative == 2) 5568 std::swap (operands[1], operands[2]); 5569 5570 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5571 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5572 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5573 5574 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5575 } 5576} 5577 [(set (attr "type") 5578 (if_then_else (match_operand:SWI 2 "incdec_operand") 5579 (const_string "incdec") 5580 (const_string "alu"))) 5581 (set (attr "length_immediate") 5582 (if_then_else 5583 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5584 (const_string "1") 5585 (const_string "*"))) 5586 (set_attr "mode" "<MODE>")]) 5587 5588;; See comment for addsi_1_zext why we do use nonimmediate_operand 5589(define_insn "*addsi_2_zext" 5590 [(set (reg FLAGS_REG) 5591 (compare 5592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5593 (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5594 (const_int 0))) 5595 (set (match_operand:DI 0 "register_operand" "=r,r") 5596 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5597 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5598 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5599{ 5600 switch (get_attr_type (insn)) 5601 { 5602 case TYPE_INCDEC: 5603 if (operands[2] == const1_rtx) 5604 return "inc{l}\t%k0"; 5605 else 5606 { 5607 gcc_assert (operands[2] == constm1_rtx); 5608 return "dec{l}\t%k0"; 5609 } 5610 5611 default: 5612 if (which_alternative == 1) 5613 std::swap (operands[1], operands[2]); 5614 5615 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5616 return "sub{l}\t{%2, %k0|%k0, %2}"; 5617 5618 return "add{l}\t{%2, %k0|%k0, %2}"; 5619 } 5620} 5621 [(set (attr "type") 5622 (if_then_else (match_operand:SI 2 "incdec_operand") 5623 (const_string "incdec") 5624 (const_string "alu"))) 5625 (set (attr "length_immediate") 5626 (if_then_else 5627 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5628 (const_string "1") 5629 (const_string "*"))) 5630 (set_attr "mode" "SI")]) 5631 5632(define_insn "*add<mode>_3" 5633 [(set (reg FLAGS_REG) 5634 (compare 5635 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0")) 5636 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>"))) 5637 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 5638 "ix86_match_ccmode (insn, CCZmode) 5639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 5640{ 5641 switch (get_attr_type (insn)) 5642 { 5643 case TYPE_INCDEC: 5644 if (operands[2] == const1_rtx) 5645 return "inc{<imodesuffix>}\t%0"; 5646 else 5647 { 5648 gcc_assert (operands[2] == constm1_rtx); 5649 return "dec{<imodesuffix>}\t%0"; 5650 } 5651 5652 default: 5653 if (which_alternative == 1) 5654 std::swap (operands[1], operands[2]); 5655 5656 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5657 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5658 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5659 5660 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5661 } 5662} 5663 [(set (attr "type") 5664 (if_then_else (match_operand:SWI 2 "incdec_operand") 5665 (const_string "incdec") 5666 (const_string "alu"))) 5667 (set (attr "length_immediate") 5668 (if_then_else 5669 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5670 (const_string "1") 5671 (const_string "*"))) 5672 (set_attr "mode" "<MODE>")]) 5673 5674;; See comment for addsi_1_zext why we do use nonimmediate_operand 5675(define_insn "*addsi_3_zext" 5676 [(set (reg FLAGS_REG) 5677 (compare 5678 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5679 (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) 5680 (set (match_operand:DI 0 "register_operand" "=r,r") 5681 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5682 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5683 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5684{ 5685 switch (get_attr_type (insn)) 5686 { 5687 case TYPE_INCDEC: 5688 if (operands[2] == const1_rtx) 5689 return "inc{l}\t%k0"; 5690 else 5691 { 5692 gcc_assert (operands[2] == constm1_rtx); 5693 return "dec{l}\t%k0"; 5694 } 5695 5696 default: 5697 if (which_alternative == 1) 5698 std::swap (operands[1], operands[2]); 5699 5700 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5701 return "sub{l}\t{%2, %k0|%k0, %2}"; 5702 5703 return "add{l}\t{%2, %k0|%k0, %2}"; 5704 } 5705} 5706 [(set (attr "type") 5707 (if_then_else (match_operand:SI 2 "incdec_operand") 5708 (const_string "incdec") 5709 (const_string "alu"))) 5710 (set (attr "length_immediate") 5711 (if_then_else 5712 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5713 (const_string "1") 5714 (const_string "*"))) 5715 (set_attr "mode" "SI")]) 5716 5717; For comparisons against 1, -1 and 128, we may generate better code 5718; by converting cmp to add, inc or dec as done by peephole2. This pattern 5719; is matched then. We can't accept general immediate, because for 5720; case of overflows, the result is messed up. 5721; Also carry flag is reversed compared to cmp, so this conversion is valid 5722; only for comparisons not depending on it. 5723 5724(define_insn "*adddi_4" 5725 [(set (reg FLAGS_REG) 5726 (compare 5727 (match_operand:DI 1 "nonimmediate_operand" "0") 5728 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 5729 (clobber (match_scratch:DI 0 "=rm"))] 5730 "TARGET_64BIT 5731 && ix86_match_ccmode (insn, CCGCmode)" 5732{ 5733 switch (get_attr_type (insn)) 5734 { 5735 case TYPE_INCDEC: 5736 if (operands[2] == constm1_rtx) 5737 return "inc{q}\t%0"; 5738 else 5739 { 5740 gcc_assert (operands[2] == const1_rtx); 5741 return "dec{q}\t%0"; 5742 } 5743 5744 default: 5745 if (x86_maybe_negate_const_int (&operands[2], DImode)) 5746 return "add{q}\t{%2, %0|%0, %2}"; 5747 5748 return "sub{q}\t{%2, %0|%0, %2}"; 5749 } 5750} 5751 [(set (attr "type") 5752 (if_then_else (match_operand:DI 2 "incdec_operand") 5753 (const_string "incdec") 5754 (const_string "alu"))) 5755 (set (attr "length_immediate") 5756 (if_then_else 5757 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5758 (const_string "1") 5759 (const_string "*"))) 5760 (set_attr "mode" "DI")]) 5761 5762; For comparisons against 1, -1 and 128, we may generate better code 5763; by converting cmp to add, inc or dec as done by peephole2. This pattern 5764; is matched then. We can't accept general immediate, because for 5765; case of overflows, the result is messed up. 5766; Also carry flag is reversed compared to cmp, so this conversion is valid 5767; only for comparisons not depending on it. 5768 5769(define_insn "*add<mode>_4" 5770 [(set (reg FLAGS_REG) 5771 (compare 5772 (match_operand:SWI124 1 "nonimmediate_operand" "0") 5773 (match_operand:SWI124 2 "const_int_operand" "n"))) 5774 (clobber (match_scratch:SWI124 0 "=<r>m"))] 5775 "ix86_match_ccmode (insn, CCGCmode)" 5776{ 5777 switch (get_attr_type (insn)) 5778 { 5779 case TYPE_INCDEC: 5780 if (operands[2] == constm1_rtx) 5781 return "inc{<imodesuffix>}\t%0"; 5782 else 5783 { 5784 gcc_assert (operands[2] == const1_rtx); 5785 return "dec{<imodesuffix>}\t%0"; 5786 } 5787 5788 default: 5789 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5790 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5791 5792 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5793 } 5794} 5795 [(set (attr "type") 5796 (if_then_else (match_operand:<MODE> 2 "incdec_operand") 5797 (const_string "incdec") 5798 (const_string "alu"))) 5799 (set (attr "length_immediate") 5800 (if_then_else 5801 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5802 (const_string "1") 5803 (const_string "*"))) 5804 (set_attr "mode" "<MODE>")]) 5805 5806(define_insn "*add<mode>_5" 5807 [(set (reg FLAGS_REG) 5808 (compare 5809 (plus:SWI 5810 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>") 5811 (match_operand:SWI 2 "<general_operand>" "<g>,0")) 5812 (const_int 0))) 5813 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 5814 "ix86_match_ccmode (insn, CCGOCmode) 5815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 5816{ 5817 switch (get_attr_type (insn)) 5818 { 5819 case TYPE_INCDEC: 5820 if (operands[2] == const1_rtx) 5821 return "inc{<imodesuffix>}\t%0"; 5822 else 5823 { 5824 gcc_assert (operands[2] == constm1_rtx); 5825 return "dec{<imodesuffix>}\t%0"; 5826 } 5827 5828 default: 5829 if (which_alternative == 1) 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], <MODE>mode)) 5834 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5835 5836 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5837 } 5838} 5839 [(set (attr "type") 5840 (if_then_else (match_operand:SWI 2 "incdec_operand") 5841 (const_string "incdec") 5842 (const_string "alu"))) 5843 (set (attr "length_immediate") 5844 (if_then_else 5845 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5846 (const_string "1") 5847 (const_string "*"))) 5848 (set_attr "mode" "<MODE>")]) 5849 5850(define_insn "addqi_ext_1" 5851 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") 5852 (const_int 8) 5853 (const_int 8)) 5854 (plus:SI 5855 (zero_extract:SI 5856 (match_operand 1 "ext_register_operand" "0,0") 5857 (const_int 8) 5858 (const_int 8)) 5859 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))) 5860 (clobber (reg:CC FLAGS_REG))] 5861 "" 5862{ 5863 switch (get_attr_type (insn)) 5864 { 5865 case TYPE_INCDEC: 5866 if (operands[2] == const1_rtx) 5867 return "inc{b}\t%h0"; 5868 else 5869 { 5870 gcc_assert (operands[2] == constm1_rtx); 5871 return "dec{b}\t%h0"; 5872 } 5873 5874 default: 5875 return "add{b}\t{%2, %h0|%h0, %2}"; 5876 } 5877} 5878 [(set_attr "isa" "*,nox64") 5879 (set (attr "type") 5880 (if_then_else (match_operand:QI 2 "incdec_operand") 5881 (const_string "incdec") 5882 (const_string "alu"))) 5883 (set_attr "modrm" "1") 5884 (set_attr "mode" "QI")]) 5885 5886(define_insn "*addqi_ext_2" 5887 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 5888 (const_int 8) 5889 (const_int 8)) 5890 (plus:SI 5891 (zero_extract:SI 5892 (match_operand 1 "ext_register_operand" "%0") 5893 (const_int 8) 5894 (const_int 8)) 5895 (zero_extract:SI 5896 (match_operand 2 "ext_register_operand" "Q") 5897 (const_int 8) 5898 (const_int 8)))) 5899 (clobber (reg:CC FLAGS_REG))] 5900 "" 5901 "add{b}\t{%h2, %h0|%h0, %h2}" 5902 [(set_attr "type" "alu") 5903 (set_attr "mode" "QI")]) 5904 5905;; Add with jump on overflow. 5906(define_expand "addv<mode>4" 5907 [(parallel [(set (reg:CCO FLAGS_REG) 5908 (eq:CCO (plus:<DWI> 5909 (sign_extend:<DWI> 5910 (match_operand:SWI 1 "nonimmediate_operand")) 5911 (match_dup 4)) 5912 (sign_extend:<DWI> 5913 (plus:SWI (match_dup 1) 5914 (match_operand:SWI 2 5915 "<general_operand>"))))) 5916 (set (match_operand:SWI 0 "register_operand") 5917 (plus:SWI (match_dup 1) (match_dup 2)))]) 5918 (set (pc) (if_then_else 5919 (eq (reg:CCO FLAGS_REG) (const_int 0)) 5920 (label_ref (match_operand 3)) 5921 (pc)))] 5922 "" 5923{ 5924 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands); 5925 if (CONST_INT_P (operands[2])) 5926 operands[4] = operands[2]; 5927 else 5928 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]); 5929}) 5930 5931(define_insn "*addv<mode>4" 5932 [(set (reg:CCO FLAGS_REG) 5933 (eq:CCO (plus:<DWI> 5934 (sign_extend:<DWI> 5935 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) 5936 (sign_extend:<DWI> 5937 (match_operand:SWI 2 "<general_sext_operand>" 5938 "<r>mWe,<r>We"))) 5939 (sign_extend:<DWI> 5940 (plus:SWI (match_dup 1) (match_dup 2))))) 5941 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 5942 (plus:SWI (match_dup 1) (match_dup 2)))] 5943 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5944 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 5945 [(set_attr "type" "alu") 5946 (set_attr "mode" "<MODE>")]) 5947 5948(define_insn "*addv<mode>4_1" 5949 [(set (reg:CCO FLAGS_REG) 5950 (eq:CCO (plus:<DWI> 5951 (sign_extend:<DWI> 5952 (match_operand:SWI 1 "nonimmediate_operand" "0")) 5953 (match_operand:<DWI> 3 "const_int_operand" "i")) 5954 (sign_extend:<DWI> 5955 (plus:SWI (match_dup 1) 5956 (match_operand:SWI 2 "x86_64_immediate_operand" 5957 "<i>"))))) 5958 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 5959 (plus:SWI (match_dup 1) (match_dup 2)))] 5960 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands) 5961 && CONST_INT_P (operands[2]) 5962 && INTVAL (operands[2]) == INTVAL (operands[3])" 5963 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 5964 [(set_attr "type" "alu") 5965 (set_attr "mode" "<MODE>") 5966 (set (attr "length_immediate") 5967 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 5968 (const_string "1") 5969 (match_test "<MODE_SIZE> == 8") 5970 (const_string "4")] 5971 (const_string "<MODE_SIZE>")))]) 5972 5973;; The lea patterns for modes less than 32 bits need to be matched by 5974;; several insns converted to real lea by splitters. 5975 5976(define_insn_and_split "*lea_general_1" 5977 [(set (match_operand 0 "register_operand" "=r") 5978 (plus (plus (match_operand 1 "index_register_operand" "l") 5979 (match_operand 2 "register_operand" "r")) 5980 (match_operand 3 "immediate_operand" "i")))] 5981 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 5982 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 5983 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 5984 && GET_MODE (operands[0]) == GET_MODE (operands[2]) 5985 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 5986 || GET_MODE (operands[3]) == VOIDmode)" 5987 "#" 5988 "&& reload_completed" 5989 [(const_int 0)] 5990{ 5991 machine_mode mode = SImode; 5992 rtx pat; 5993 5994 operands[0] = gen_lowpart (mode, operands[0]); 5995 operands[1] = gen_lowpart (mode, operands[1]); 5996 operands[2] = gen_lowpart (mode, operands[2]); 5997 operands[3] = gen_lowpart (mode, operands[3]); 5998 5999 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]), 6000 operands[3]); 6001 6002 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6003 DONE; 6004} 6005 [(set_attr "type" "lea") 6006 (set_attr "mode" "SI")]) 6007 6008(define_insn_and_split "*lea_general_2" 6009 [(set (match_operand 0 "register_operand" "=r") 6010 (plus (mult (match_operand 1 "index_register_operand" "l") 6011 (match_operand 2 "const248_operand" "n")) 6012 (match_operand 3 "nonmemory_operand" "ri")))] 6013 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6014 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6015 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6016 && (GET_MODE (operands[0]) == GET_MODE (operands[3]) 6017 || GET_MODE (operands[3]) == VOIDmode)" 6018 "#" 6019 "&& reload_completed" 6020 [(const_int 0)] 6021{ 6022 machine_mode mode = SImode; 6023 rtx pat; 6024 6025 operands[0] = gen_lowpart (mode, operands[0]); 6026 operands[1] = gen_lowpart (mode, operands[1]); 6027 operands[3] = gen_lowpart (mode, operands[3]); 6028 6029 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]), 6030 operands[3]); 6031 6032 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6033 DONE; 6034} 6035 [(set_attr "type" "lea") 6036 (set_attr "mode" "SI")]) 6037 6038(define_insn_and_split "*lea_general_3" 6039 [(set (match_operand 0 "register_operand" "=r") 6040 (plus (plus (mult (match_operand 1 "index_register_operand" "l") 6041 (match_operand 2 "const248_operand" "n")) 6042 (match_operand 3 "register_operand" "r")) 6043 (match_operand 4 "immediate_operand" "i")))] 6044 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6045 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6046 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6047 && GET_MODE (operands[0]) == GET_MODE (operands[3])" 6048 "#" 6049 "&& reload_completed" 6050 [(const_int 0)] 6051{ 6052 machine_mode mode = SImode; 6053 rtx pat; 6054 6055 operands[0] = gen_lowpart (mode, operands[0]); 6056 operands[1] = gen_lowpart (mode, operands[1]); 6057 operands[3] = gen_lowpart (mode, operands[3]); 6058 operands[4] = gen_lowpart (mode, operands[4]); 6059 6060 pat = gen_rtx_PLUS (mode, 6061 gen_rtx_PLUS (mode, 6062 gen_rtx_MULT (mode, operands[1], 6063 operands[2]), 6064 operands[3]), 6065 operands[4]); 6066 6067 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6068 DONE; 6069} 6070 [(set_attr "type" "lea") 6071 (set_attr "mode" "SI")]) 6072 6073(define_insn_and_split "*lea_general_4" 6074 [(set (match_operand 0 "register_operand" "=r") 6075 (any_or (ashift 6076 (match_operand 1 "index_register_operand" "l") 6077 (match_operand 2 "const_int_operand" "n")) 6078 (match_operand 3 "const_int_operand" "n")))] 6079 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode) 6080 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))) 6081 || GET_MODE (operands[0]) == SImode 6082 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 6083 && GET_MODE (operands[0]) == GET_MODE (operands[1]) 6084 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3 6085 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3]) 6086 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))" 6087 "#" 6088 "&& reload_completed" 6089 [(const_int 0)] 6090{ 6091 machine_mode mode = GET_MODE (operands[0]); 6092 rtx pat; 6093 6094 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 6095 { 6096 mode = SImode; 6097 operands[0] = gen_lowpart (mode, operands[0]); 6098 operands[1] = gen_lowpart (mode, operands[1]); 6099 } 6100 6101 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 6102 6103 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]), 6104 INTVAL (operands[3])); 6105 6106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 6107 DONE; 6108} 6109 [(set_attr "type" "lea") 6110 (set (attr "mode") 6111 (if_then_else (match_operand:DI 0) 6112 (const_string "DI") 6113 (const_string "SI")))]) 6114 6115;; Subtract instructions 6116 6117(define_expand "sub<mode>3" 6118 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 6119 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand") 6120 (match_operand:SDWIM 2 "<general_operand>")))] 6121 "" 6122 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;") 6123 6124(define_insn_and_split "*sub<dwi>3_doubleword" 6125 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o") 6126 (minus:<DWI> 6127 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0") 6128 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>"))) 6129 (clobber (reg:CC FLAGS_REG))] 6130 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6131 "#" 6132 "reload_completed" 6133 [(parallel [(set (reg:CC FLAGS_REG) 6134 (compare:CC (match_dup 1) (match_dup 2))) 6135 (set (match_dup 0) 6136 (minus:DWIH (match_dup 1) (match_dup 2)))]) 6137 (parallel [(set (match_dup 3) 6138 (minus:DWIH 6139 (minus:DWIH 6140 (match_dup 4) 6141 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))) 6142 (match_dup 5))) 6143 (clobber (reg:CC FLAGS_REG))])] 6144 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);") 6145 6146(define_insn "*sub<mode>_1" 6147 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6148 (minus:SWI 6149 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6150 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6151 (clobber (reg:CC FLAGS_REG))] 6152 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6153 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6154 [(set_attr "type" "alu") 6155 (set_attr "mode" "<MODE>")]) 6156 6157(define_insn "*subsi_1_zext" 6158 [(set (match_operand:DI 0 "register_operand" "=r") 6159 (zero_extend:DI 6160 (minus:SI (match_operand:SI 1 "register_operand" "0") 6161 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6162 (clobber (reg:CC FLAGS_REG))] 6163 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6164 "sub{l}\t{%2, %k0|%k0, %2}" 6165 [(set_attr "type" "alu") 6166 (set_attr "mode" "SI")]) 6167 6168(define_insn "*subqi_1_slp" 6169 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 6170 (minus:QI (match_dup 0) 6171 (match_operand:QI 1 "general_operand" "qn,qm"))) 6172 (clobber (reg:CC FLAGS_REG))] 6173 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6174 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 6175 "sub{b}\t{%1, %0|%0, %1}" 6176 [(set_attr "type" "alu1") 6177 (set_attr "mode" "QI")]) 6178 6179(define_insn "*sub<mode>_2" 6180 [(set (reg FLAGS_REG) 6181 (compare 6182 (minus:SWI 6183 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6184 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6185 (const_int 0))) 6186 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6187 (minus:SWI (match_dup 1) (match_dup 2)))] 6188 "ix86_match_ccmode (insn, CCGOCmode) 6189 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6190 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6191 [(set_attr "type" "alu") 6192 (set_attr "mode" "<MODE>")]) 6193 6194(define_insn "*subsi_2_zext" 6195 [(set (reg FLAGS_REG) 6196 (compare 6197 (minus:SI (match_operand:SI 1 "register_operand" "0") 6198 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6199 (const_int 0))) 6200 (set (match_operand:DI 0 "register_operand" "=r") 6201 (zero_extend:DI 6202 (minus:SI (match_dup 1) 6203 (match_dup 2))))] 6204 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6205 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6206 "sub{l}\t{%2, %k0|%k0, %2}" 6207 [(set_attr "type" "alu") 6208 (set_attr "mode" "SI")]) 6209 6210;; Subtract with jump on overflow. 6211(define_expand "subv<mode>4" 6212 [(parallel [(set (reg:CCO FLAGS_REG) 6213 (eq:CCO (minus:<DWI> 6214 (sign_extend:<DWI> 6215 (match_operand:SWI 1 "nonimmediate_operand")) 6216 (match_dup 4)) 6217 (sign_extend:<DWI> 6218 (minus:SWI (match_dup 1) 6219 (match_operand:SWI 2 6220 "<general_operand>"))))) 6221 (set (match_operand:SWI 0 "register_operand") 6222 (minus:SWI (match_dup 1) (match_dup 2)))]) 6223 (set (pc) (if_then_else 6224 (eq (reg:CCO FLAGS_REG) (const_int 0)) 6225 (label_ref (match_operand 3)) 6226 (pc)))] 6227 "" 6228{ 6229 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands); 6230 if (CONST_INT_P (operands[2])) 6231 operands[4] = operands[2]; 6232 else 6233 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]); 6234}) 6235 6236(define_insn "*subv<mode>4" 6237 [(set (reg:CCO FLAGS_REG) 6238 (eq:CCO (minus:<DWI> 6239 (sign_extend:<DWI> 6240 (match_operand:SWI 1 "nonimmediate_operand" "0,0")) 6241 (sign_extend:<DWI> 6242 (match_operand:SWI 2 "<general_sext_operand>" 6243 "<r>We,<r>m"))) 6244 (sign_extend:<DWI> 6245 (minus:SWI (match_dup 1) (match_dup 2))))) 6246 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6247 (minus:SWI (match_dup 1) (match_dup 2)))] 6248 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6249 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6250 [(set_attr "type" "alu") 6251 (set_attr "mode" "<MODE>")]) 6252 6253(define_insn "*subv<mode>4_1" 6254 [(set (reg:CCO FLAGS_REG) 6255 (eq:CCO (minus:<DWI> 6256 (sign_extend:<DWI> 6257 (match_operand:SWI 1 "nonimmediate_operand" "0")) 6258 (match_operand:<DWI> 3 "const_int_operand" "i")) 6259 (sign_extend:<DWI> 6260 (minus:SWI (match_dup 1) 6261 (match_operand:SWI 2 "x86_64_immediate_operand" 6262 "<i>"))))) 6263 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 6264 (minus:SWI (match_dup 1) (match_dup 2)))] 6265 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) 6266 && CONST_INT_P (operands[2]) 6267 && INTVAL (operands[2]) == INTVAL (operands[3])" 6268 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6269 [(set_attr "type" "alu") 6270 (set_attr "mode" "<MODE>") 6271 (set (attr "length_immediate") 6272 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 6273 (const_string "1") 6274 (match_test "<MODE_SIZE> == 8") 6275 (const_string "4")] 6276 (const_string "<MODE_SIZE>")))]) 6277 6278(define_insn "*sub<mode>_3" 6279 [(set (reg FLAGS_REG) 6280 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6281 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6282 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6283 (minus:SWI (match_dup 1) (match_dup 2)))] 6284 "ix86_match_ccmode (insn, CCmode) 6285 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6286 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6287 [(set_attr "type" "alu") 6288 (set_attr "mode" "<MODE>")]) 6289 6290(define_insn "*subsi_3_zext" 6291 [(set (reg FLAGS_REG) 6292 (compare (match_operand:SI 1 "register_operand" "0") 6293 (match_operand:SI 2 "x86_64_general_operand" "rme"))) 6294 (set (match_operand:DI 0 "register_operand" "=r") 6295 (zero_extend:DI 6296 (minus:SI (match_dup 1) 6297 (match_dup 2))))] 6298 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6299 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6300 "sub{l}\t{%2, %1|%1, %2}" 6301 [(set_attr "type" "alu") 6302 (set_attr "mode" "SI")]) 6303 6304;; Add with carry and subtract with borrow 6305 6306(define_insn "add<mode>3_carry" 6307 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6308 (plus:SWI 6309 (plus:SWI 6310 (match_operator:SWI 4 "ix86_carry_flag_operator" 6311 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6312 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) 6313 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6314 (clobber (reg:CC FLAGS_REG))] 6315 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6316 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6317 [(set_attr "type" "alu") 6318 (set_attr "use_carry" "1") 6319 (set_attr "pent_pair" "pu") 6320 (set_attr "mode" "<MODE>")]) 6321 6322(define_insn "*addsi3_carry_zext" 6323 [(set (match_operand:DI 0 "register_operand" "=r") 6324 (zero_extend:DI 6325 (plus:SI 6326 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator" 6327 [(reg FLAGS_REG) (const_int 0)]) 6328 (match_operand:SI 1 "register_operand" "%0")) 6329 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6330 (clobber (reg:CC FLAGS_REG))] 6331 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6332 "adc{l}\t{%2, %k0|%k0, %2}" 6333 [(set_attr "type" "alu") 6334 (set_attr "use_carry" "1") 6335 (set_attr "pent_pair" "pu") 6336 (set_attr "mode" "SI")]) 6337 6338;; There is no point to generate ADCX instruction. ADC is shorter and faster. 6339 6340(define_insn "addcarry<mode>" 6341 [(set (reg:CCC FLAGS_REG) 6342 (compare:CCC 6343 (plus:SWI48 6344 (plus:SWI48 6345 (match_operator:SWI48 4 "ix86_carry_flag_operator" 6346 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6347 (match_operand:SWI48 1 "nonimmediate_operand" "%0")) 6348 (match_operand:SWI48 2 "nonimmediate_operand" "rm")) 6349 (match_dup 1))) 6350 (set (match_operand:SWI48 0 "register_operand" "=r") 6351 (plus:SWI48 (plus:SWI48 (match_op_dup 4 6352 [(match_dup 3) (const_int 0)]) 6353 (match_dup 1)) 6354 (match_dup 2)))] 6355 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6356 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6357 [(set_attr "type" "alu") 6358 (set_attr "use_carry" "1") 6359 (set_attr "pent_pair" "pu") 6360 (set_attr "mode" "<MODE>")]) 6361 6362(define_insn "sub<mode>3_carry" 6363 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6364 (minus:SWI 6365 (minus:SWI 6366 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6367 (match_operator:SWI 4 "ix86_carry_flag_operator" 6368 [(match_operand 3 "flags_reg_operand") (const_int 0)])) 6369 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))) 6370 (clobber (reg:CC FLAGS_REG))] 6371 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6372 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6373 [(set_attr "type" "alu") 6374 (set_attr "use_carry" "1") 6375 (set_attr "pent_pair" "pu") 6376 (set_attr "mode" "<MODE>")]) 6377 6378(define_insn "*subsi3_carry_zext" 6379 [(set (match_operand:DI 0 "register_operand" "=r") 6380 (zero_extend:DI 6381 (minus:SI 6382 (minus:SI 6383 (match_operand:SI 1 "register_operand" "0") 6384 (match_operator:SI 3 "ix86_carry_flag_operator" 6385 [(reg FLAGS_REG) (const_int 0)])) 6386 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6387 (clobber (reg:CC FLAGS_REG))] 6388 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6389 "sbb{l}\t{%2, %k0|%k0, %2}" 6390 [(set_attr "type" "alu") 6391 (set_attr "use_carry" "1") 6392 (set_attr "pent_pair" "pu") 6393 (set_attr "mode" "SI")]) 6394 6395(define_insn "subborrow<mode>" 6396 [(set (reg:CCC FLAGS_REG) 6397 (compare:CCC 6398 (match_operand:SWI48 1 "nonimmediate_operand" "0") 6399 (plus:SWI48 6400 (match_operator:SWI48 4 "ix86_carry_flag_operator" 6401 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6402 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))) 6403 (set (match_operand:SWI48 0 "register_operand" "=r") 6404 (minus:SWI48 (minus:SWI48 (match_dup 1) 6405 (match_op_dup 4 6406 [(match_dup 3) (const_int 0)])) 6407 (match_dup 2)))] 6408 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6409 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6410 [(set_attr "type" "alu") 6411 (set_attr "use_carry" "1") 6412 (set_attr "pent_pair" "pu") 6413 (set_attr "mode" "<MODE>")]) 6414 6415;; Overflow setting add instructions 6416 6417(define_expand "addqi3_cconly_overflow" 6418 [(parallel 6419 [(set (reg:CCC FLAGS_REG) 6420 (compare:CCC 6421 (plus:QI 6422 (match_operand:QI 0 "nonimmediate_operand") 6423 (match_operand:QI 1 "general_operand")) 6424 (match_dup 0))) 6425 (clobber (match_scratch:QI 2))])] 6426 "!(MEM_P (operands[0]) && MEM_P (operands[1]))") 6427 6428(define_insn "*add<mode>3_cconly_overflow" 6429 [(set (reg:CCC FLAGS_REG) 6430 (compare:CCC 6431 (plus:SWI 6432 (match_operand:SWI 1 "nonimmediate_operand" "%0") 6433 (match_operand:SWI 2 "<general_operand>" "<g>")) 6434 (match_dup 1))) 6435 (clobber (match_scratch:SWI 0 "=<r>"))] 6436 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6437 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6438 [(set_attr "type" "alu") 6439 (set_attr "mode" "<MODE>")]) 6440 6441(define_insn "*add<mode>3_cc_overflow" 6442 [(set (reg:CCC FLAGS_REG) 6443 (compare:CCC 6444 (plus:SWI 6445 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 6446 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")) 6447 (match_dup 1))) 6448 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6449 (plus:SWI (match_dup 1) (match_dup 2)))] 6450 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6451 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6452 [(set_attr "type" "alu") 6453 (set_attr "mode" "<MODE>")]) 6454 6455(define_insn "*addsi3_zext_cc_overflow" 6456 [(set (reg:CCC FLAGS_REG) 6457 (compare:CCC 6458 (plus:SI 6459 (match_operand:SI 1 "nonimmediate_operand" "%0") 6460 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6461 (match_dup 1))) 6462 (set (match_operand:DI 0 "register_operand" "=r") 6463 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 6464 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6465 "add{l}\t{%2, %k0|%k0, %2}" 6466 [(set_attr "type" "alu") 6467 (set_attr "mode" "SI")]) 6468 6469;; The patterns that match these are at the end of this file. 6470 6471(define_expand "<plusminus_insn>xf3" 6472 [(set (match_operand:XF 0 "register_operand") 6473 (plusminus:XF 6474 (match_operand:XF 1 "register_operand") 6475 (match_operand:XF 2 "register_operand")))] 6476 "TARGET_80387") 6477 6478(define_expand "<plusminus_insn><mode>3" 6479 [(set (match_operand:MODEF 0 "register_operand") 6480 (plusminus:MODEF 6481 (match_operand:MODEF 1 "register_operand") 6482 (match_operand:MODEF 2 "nonimmediate_operand")))] 6483 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 6484 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 6485 6486;; Multiply instructions 6487 6488(define_expand "mul<mode>3" 6489 [(parallel [(set (match_operand:SWIM248 0 "register_operand") 6490 (mult:SWIM248 6491 (match_operand:SWIM248 1 "register_operand") 6492 (match_operand:SWIM248 2 "<general_operand>"))) 6493 (clobber (reg:CC FLAGS_REG))])]) 6494 6495(define_expand "mulqi3" 6496 [(parallel [(set (match_operand:QI 0 "register_operand") 6497 (mult:QI 6498 (match_operand:QI 1 "register_operand") 6499 (match_operand:QI 2 "nonimmediate_operand"))) 6500 (clobber (reg:CC FLAGS_REG))])] 6501 "TARGET_QIMODE_MATH") 6502 6503;; On AMDFAM10 6504;; IMUL reg32/64, reg32/64, imm8 Direct 6505;; IMUL reg32/64, mem32/64, imm8 VectorPath 6506;; IMUL reg32/64, reg32/64, imm32 Direct 6507;; IMUL reg32/64, mem32/64, imm32 VectorPath 6508;; IMUL reg32/64, reg32/64 Direct 6509;; IMUL reg32/64, mem32/64 Direct 6510;; 6511;; On BDVER1, all above IMULs use DirectPath 6512 6513(define_insn "*mul<mode>3_1" 6514 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r") 6515 (mult:SWI48 6516 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0") 6517 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr"))) 6518 (clobber (reg:CC FLAGS_REG))] 6519 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6520 "@ 6521 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6522 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6523 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 6524 [(set_attr "type" "imul") 6525 (set_attr "prefix_0f" "0,0,1") 6526 (set (attr "athlon_decode") 6527 (cond [(eq_attr "cpu" "athlon") 6528 (const_string "vector") 6529 (eq_attr "alternative" "1") 6530 (const_string "vector") 6531 (and (eq_attr "alternative" "2") 6532 (match_operand 1 "memory_operand")) 6533 (const_string "vector")] 6534 (const_string "direct"))) 6535 (set (attr "amdfam10_decode") 6536 (cond [(and (eq_attr "alternative" "0,1") 6537 (match_operand 1 "memory_operand")) 6538 (const_string "vector")] 6539 (const_string "direct"))) 6540 (set_attr "bdver1_decode" "direct") 6541 (set_attr "mode" "<MODE>")]) 6542 6543(define_insn "*mulsi3_1_zext" 6544 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 6545 (zero_extend:DI 6546 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 6547 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) 6548 (clobber (reg:CC FLAGS_REG))] 6549 "TARGET_64BIT 6550 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6551 "@ 6552 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6553 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 6554 imul{l}\t{%2, %k0|%k0, %2}" 6555 [(set_attr "type" "imul") 6556 (set_attr "prefix_0f" "0,0,1") 6557 (set (attr "athlon_decode") 6558 (cond [(eq_attr "cpu" "athlon") 6559 (const_string "vector") 6560 (eq_attr "alternative" "1") 6561 (const_string "vector") 6562 (and (eq_attr "alternative" "2") 6563 (match_operand 1 "memory_operand")) 6564 (const_string "vector")] 6565 (const_string "direct"))) 6566 (set (attr "amdfam10_decode") 6567 (cond [(and (eq_attr "alternative" "0,1") 6568 (match_operand 1 "memory_operand")) 6569 (const_string "vector")] 6570 (const_string "direct"))) 6571 (set_attr "bdver1_decode" "direct") 6572 (set_attr "mode" "SI")]) 6573 6574;; On AMDFAM10 6575;; IMUL reg16, reg16, imm8 VectorPath 6576;; IMUL reg16, mem16, imm8 VectorPath 6577;; IMUL reg16, reg16, imm16 VectorPath 6578;; IMUL reg16, mem16, imm16 VectorPath 6579;; IMUL reg16, reg16 Direct 6580;; IMUL reg16, mem16 Direct 6581;; 6582;; On BDVER1, all HI MULs use DoublePath 6583 6584(define_insn "*mulhi3_1" 6585 [(set (match_operand:HI 0 "register_operand" "=r,r,r") 6586 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0") 6587 (match_operand:HI 2 "general_operand" "K,n,mr"))) 6588 (clobber (reg:CC FLAGS_REG))] 6589 "TARGET_HIMODE_MATH 6590 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6591 "@ 6592 imul{w}\t{%2, %1, %0|%0, %1, %2} 6593 imul{w}\t{%2, %1, %0|%0, %1, %2} 6594 imul{w}\t{%2, %0|%0, %2}" 6595 [(set_attr "type" "imul") 6596 (set_attr "prefix_0f" "0,0,1") 6597 (set (attr "athlon_decode") 6598 (cond [(eq_attr "cpu" "athlon") 6599 (const_string "vector") 6600 (eq_attr "alternative" "1,2") 6601 (const_string "vector")] 6602 (const_string "direct"))) 6603 (set (attr "amdfam10_decode") 6604 (cond [(eq_attr "alternative" "0,1") 6605 (const_string "vector")] 6606 (const_string "direct"))) 6607 (set_attr "bdver1_decode" "double") 6608 (set_attr "mode" "HI")]) 6609 6610;;On AMDFAM10 and BDVER1 6611;; MUL reg8 Direct 6612;; MUL mem8 Direct 6613 6614(define_insn "*mulqi3_1" 6615 [(set (match_operand:QI 0 "register_operand" "=a") 6616 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 6617 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 6618 (clobber (reg:CC FLAGS_REG))] 6619 "TARGET_QIMODE_MATH 6620 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6621 "mul{b}\t%2" 6622 [(set_attr "type" "imul") 6623 (set_attr "length_immediate" "0") 6624 (set (attr "athlon_decode") 6625 (if_then_else (eq_attr "cpu" "athlon") 6626 (const_string "vector") 6627 (const_string "direct"))) 6628 (set_attr "amdfam10_decode" "direct") 6629 (set_attr "bdver1_decode" "direct") 6630 (set_attr "mode" "QI")]) 6631 6632;; Multiply with jump on overflow. 6633(define_expand "mulv<mode>4" 6634 [(parallel [(set (reg:CCO FLAGS_REG) 6635 (eq:CCO (mult:<DWI> 6636 (sign_extend:<DWI> 6637 (match_operand:SWI48 1 "register_operand")) 6638 (match_dup 4)) 6639 (sign_extend:<DWI> 6640 (mult:SWI48 (match_dup 1) 6641 (match_operand:SWI48 2 6642 "<general_operand>"))))) 6643 (set (match_operand:SWI48 0 "register_operand") 6644 (mult:SWI48 (match_dup 1) (match_dup 2)))]) 6645 (set (pc) (if_then_else 6646 (eq (reg:CCO FLAGS_REG) (const_int 0)) 6647 (label_ref (match_operand 3)) 6648 (pc)))] 6649 "" 6650{ 6651 if (CONST_INT_P (operands[2])) 6652 operands[4] = operands[2]; 6653 else 6654 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]); 6655}) 6656 6657(define_insn "*mulv<mode>4" 6658 [(set (reg:CCO FLAGS_REG) 6659 (eq:CCO (mult:<DWI> 6660 (sign_extend:<DWI> 6661 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0")) 6662 (sign_extend:<DWI> 6663 (match_operand:SWI48 2 "<general_sext_operand>" 6664 "We,mr"))) 6665 (sign_extend:<DWI> 6666 (mult:SWI48 (match_dup 1) (match_dup 2))))) 6667 (set (match_operand:SWI48 0 "register_operand" "=r,r") 6668 (mult:SWI48 (match_dup 1) (match_dup 2)))] 6669 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6670 "@ 6671 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6672 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 6673 [(set_attr "type" "imul") 6674 (set_attr "prefix_0f" "0,1") 6675 (set (attr "athlon_decode") 6676 (cond [(eq_attr "cpu" "athlon") 6677 (const_string "vector") 6678 (eq_attr "alternative" "0") 6679 (const_string "vector") 6680 (and (eq_attr "alternative" "1") 6681 (match_operand 1 "memory_operand")) 6682 (const_string "vector")] 6683 (const_string "direct"))) 6684 (set (attr "amdfam10_decode") 6685 (cond [(and (eq_attr "alternative" "1") 6686 (match_operand 1 "memory_operand")) 6687 (const_string "vector")] 6688 (const_string "direct"))) 6689 (set_attr "bdver1_decode" "direct") 6690 (set_attr "mode" "<MODE>")]) 6691 6692(define_insn "*mulv<mode>4_1" 6693 [(set (reg:CCO FLAGS_REG) 6694 (eq:CCO (mult:<DWI> 6695 (sign_extend:<DWI> 6696 (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm")) 6697 (match_operand:<DWI> 3 "const_int_operand" "K,i")) 6698 (sign_extend:<DWI> 6699 (mult:SWI48 (match_dup 1) 6700 (match_operand:SWI 2 "x86_64_immediate_operand" 6701 "K,<i>"))))) 6702 (set (match_operand:SWI48 0 "register_operand" "=r,r") 6703 (mult:SWI48 (match_dup 1) (match_dup 2)))] 6704 "!(MEM_P (operands[1]) && MEM_P (operands[2])) 6705 && CONST_INT_P (operands[2]) 6706 && INTVAL (operands[2]) == INTVAL (operands[3])" 6707 "@ 6708 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 6709 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" 6710 [(set_attr "type" "imul") 6711 (set (attr "athlon_decode") 6712 (cond [(eq_attr "cpu" "athlon") 6713 (const_string "vector") 6714 (eq_attr "alternative" "1") 6715 (const_string "vector")] 6716 (const_string "direct"))) 6717 (set (attr "amdfam10_decode") 6718 (cond [(match_operand 1 "memory_operand") 6719 (const_string "vector")] 6720 (const_string "direct"))) 6721 (set_attr "bdver1_decode" "direct") 6722 (set_attr "mode" "<MODE>") 6723 (set (attr "length_immediate") 6724 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 6725 (const_string "1") 6726 (match_test "<MODE_SIZE> == 8") 6727 (const_string "4")] 6728 (const_string "<MODE_SIZE>")))]) 6729 6730(define_expand "umulv<mode>4" 6731 [(parallel [(set (reg:CCO FLAGS_REG) 6732 (eq:CCO (mult:<DWI> 6733 (zero_extend:<DWI> 6734 (match_operand:SWI48 1 6735 "nonimmediate_operand")) 6736 (zero_extend:<DWI> 6737 (match_operand:SWI48 2 6738 "nonimmediate_operand"))) 6739 (zero_extend:<DWI> 6740 (mult:SWI48 (match_dup 1) (match_dup 2))))) 6741 (set (match_operand:SWI48 0 "register_operand") 6742 (mult:SWI48 (match_dup 1) (match_dup 2))) 6743 (clobber (match_scratch:SWI48 4))]) 6744 (set (pc) (if_then_else 6745 (eq (reg:CCO FLAGS_REG) (const_int 0)) 6746 (label_ref (match_operand 3)) 6747 (pc)))] 6748 "" 6749{ 6750 if (MEM_P (operands[1]) && MEM_P (operands[2])) 6751 operands[1] = force_reg (<MODE>mode, operands[1]); 6752}) 6753 6754(define_insn "*umulv<mode>4" 6755 [(set (reg:CCO FLAGS_REG) 6756 (eq:CCO (mult:<DWI> 6757 (zero_extend:<DWI> 6758 (match_operand:SWI48 1 "nonimmediate_operand" "%0")) 6759 (zero_extend:<DWI> 6760 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))) 6761 (zero_extend:<DWI> 6762 (mult:SWI48 (match_dup 1) (match_dup 2))))) 6763 (set (match_operand:SWI48 0 "register_operand" "=a") 6764 (mult:SWI48 (match_dup 1) (match_dup 2))) 6765 (clobber (match_scratch:SWI48 3 "=d"))] 6766 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6767 "mul{<imodesuffix>}\t%2" 6768 [(set_attr "type" "imul") 6769 (set_attr "length_immediate" "0") 6770 (set (attr "athlon_decode") 6771 (if_then_else (eq_attr "cpu" "athlon") 6772 (const_string "vector") 6773 (const_string "double"))) 6774 (set_attr "amdfam10_decode" "double") 6775 (set_attr "bdver1_decode" "direct") 6776 (set_attr "mode" "<MODE>")]) 6777 6778(define_expand "<u>mulvqi4" 6779 [(parallel [(set (reg:CCO FLAGS_REG) 6780 (eq:CCO (mult:HI 6781 (any_extend:HI 6782 (match_operand:QI 1 "nonimmediate_operand")) 6783 (any_extend:HI 6784 (match_operand:QI 2 "nonimmediate_operand"))) 6785 (any_extend:HI 6786 (mult:QI (match_dup 1) (match_dup 2))))) 6787 (set (match_operand:QI 0 "register_operand") 6788 (mult:QI (match_dup 1) (match_dup 2)))]) 6789 (set (pc) (if_then_else 6790 (eq (reg:CCO FLAGS_REG) (const_int 0)) 6791 (label_ref (match_operand 3)) 6792 (pc)))] 6793 "TARGET_QIMODE_MATH" 6794{ 6795 if (MEM_P (operands[1]) && MEM_P (operands[2])) 6796 operands[1] = force_reg (QImode, operands[1]); 6797}) 6798 6799(define_insn "*<u>mulvqi4" 6800 [(set (reg:CCO FLAGS_REG) 6801 (eq:CCO (mult:HI 6802 (any_extend:HI 6803 (match_operand:QI 1 "nonimmediate_operand" "%0")) 6804 (any_extend:HI 6805 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 6806 (any_extend:HI 6807 (mult:QI (match_dup 1) (match_dup 2))))) 6808 (set (match_operand:QI 0 "register_operand" "=a") 6809 (mult:QI (match_dup 1) (match_dup 2)))] 6810 "TARGET_QIMODE_MATH 6811 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6812 "<sgnprefix>mul{b}\t%2" 6813 [(set_attr "type" "imul") 6814 (set_attr "length_immediate" "0") 6815 (set (attr "athlon_decode") 6816 (if_then_else (eq_attr "cpu" "athlon") 6817 (const_string "vector") 6818 (const_string "direct"))) 6819 (set_attr "amdfam10_decode" "direct") 6820 (set_attr "bdver1_decode" "direct") 6821 (set_attr "mode" "QI")]) 6822 6823(define_expand "<u>mul<mode><dwi>3" 6824 [(parallel [(set (match_operand:<DWI> 0 "register_operand") 6825 (mult:<DWI> 6826 (any_extend:<DWI> 6827 (match_operand:DWIH 1 "nonimmediate_operand")) 6828 (any_extend:<DWI> 6829 (match_operand:DWIH 2 "register_operand")))) 6830 (clobber (reg:CC FLAGS_REG))])]) 6831 6832(define_expand "<u>mulqihi3" 6833 [(parallel [(set (match_operand:HI 0 "register_operand") 6834 (mult:HI 6835 (any_extend:HI 6836 (match_operand:QI 1 "nonimmediate_operand")) 6837 (any_extend:HI 6838 (match_operand:QI 2 "register_operand")))) 6839 (clobber (reg:CC FLAGS_REG))])] 6840 "TARGET_QIMODE_MATH") 6841 6842(define_insn "*bmi2_umulditi3_1" 6843 [(set (match_operand:DI 0 "register_operand" "=r") 6844 (mult:DI 6845 (match_operand:DI 2 "nonimmediate_operand" "%d") 6846 (match_operand:DI 3 "nonimmediate_operand" "rm"))) 6847 (set (match_operand:DI 1 "register_operand" "=r") 6848 (truncate:DI 6849 (lshiftrt:TI 6850 (mult:TI (zero_extend:TI (match_dup 2)) 6851 (zero_extend:TI (match_dup 3))) 6852 (const_int 64))))] 6853 "TARGET_64BIT && TARGET_BMI2 6854 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6855 "mulx\t{%3, %0, %1|%1, %0, %3}" 6856 [(set_attr "type" "imulx") 6857 (set_attr "prefix" "vex") 6858 (set_attr "mode" "DI")]) 6859 6860(define_insn "*bmi2_umulsidi3_1" 6861 [(set (match_operand:SI 0 "register_operand" "=r") 6862 (mult:SI 6863 (match_operand:SI 2 "nonimmediate_operand" "%d") 6864 (match_operand:SI 3 "nonimmediate_operand" "rm"))) 6865 (set (match_operand:SI 1 "register_operand" "=r") 6866 (truncate:SI 6867 (lshiftrt:DI 6868 (mult:DI (zero_extend:DI (match_dup 2)) 6869 (zero_extend:DI (match_dup 3))) 6870 (const_int 32))))] 6871 "!TARGET_64BIT && TARGET_BMI2 6872 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6873 "mulx\t{%3, %0, %1|%1, %0, %3}" 6874 [(set_attr "type" "imulx") 6875 (set_attr "prefix" "vex") 6876 (set_attr "mode" "SI")]) 6877 6878(define_insn "*umul<mode><dwi>3_1" 6879 [(set (match_operand:<DWI> 0 "register_operand" "=r,A") 6880 (mult:<DWI> 6881 (zero_extend:<DWI> 6882 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0")) 6883 (zero_extend:<DWI> 6884 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm")))) 6885 (clobber (reg:CC FLAGS_REG))] 6886 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6887 "@ 6888 # 6889 mul{<imodesuffix>}\t%2" 6890 [(set_attr "isa" "bmi2,*") 6891 (set_attr "type" "imulx,imul") 6892 (set_attr "length_immediate" "*,0") 6893 (set (attr "athlon_decode") 6894 (cond [(eq_attr "alternative" "1") 6895 (if_then_else (eq_attr "cpu" "athlon") 6896 (const_string "vector") 6897 (const_string "double"))] 6898 (const_string "*"))) 6899 (set_attr "amdfam10_decode" "*,double") 6900 (set_attr "bdver1_decode" "*,direct") 6901 (set_attr "prefix" "vex,orig") 6902 (set_attr "mode" "<MODE>")]) 6903 6904;; Convert mul to the mulx pattern to avoid flags dependency. 6905(define_split 6906 [(set (match_operand:<DWI> 0 "register_operand") 6907 (mult:<DWI> 6908 (zero_extend:<DWI> 6909 (match_operand:DWIH 1 "register_operand")) 6910 (zero_extend:<DWI> 6911 (match_operand:DWIH 2 "nonimmediate_operand")))) 6912 (clobber (reg:CC FLAGS_REG))] 6913 "TARGET_BMI2 && reload_completed 6914 && true_regnum (operands[1]) == DX_REG" 6915 [(parallel [(set (match_dup 3) 6916 (mult:DWIH (match_dup 1) (match_dup 2))) 6917 (set (match_dup 4) 6918 (truncate:DWIH 6919 (lshiftrt:<DWI> 6920 (mult:<DWI> (zero_extend:<DWI> (match_dup 1)) 6921 (zero_extend:<DWI> (match_dup 2))) 6922 (match_dup 5))))])] 6923{ 6924 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]); 6925 6926 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 6927}) 6928 6929(define_insn "*mul<mode><dwi>3_1" 6930 [(set (match_operand:<DWI> 0 "register_operand" "=A") 6931 (mult:<DWI> 6932 (sign_extend:<DWI> 6933 (match_operand:DWIH 1 "nonimmediate_operand" "%0")) 6934 (sign_extend:<DWI> 6935 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))) 6936 (clobber (reg:CC FLAGS_REG))] 6937 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6938 "imul{<imodesuffix>}\t%2" 6939 [(set_attr "type" "imul") 6940 (set_attr "length_immediate" "0") 6941 (set (attr "athlon_decode") 6942 (if_then_else (eq_attr "cpu" "athlon") 6943 (const_string "vector") 6944 (const_string "double"))) 6945 (set_attr "amdfam10_decode" "double") 6946 (set_attr "bdver1_decode" "direct") 6947 (set_attr "mode" "<MODE>")]) 6948 6949(define_insn "*<u>mulqihi3_1" 6950 [(set (match_operand:HI 0 "register_operand" "=a") 6951 (mult:HI 6952 (any_extend:HI 6953 (match_operand:QI 1 "nonimmediate_operand" "%0")) 6954 (any_extend:HI 6955 (match_operand:QI 2 "nonimmediate_operand" "qm")))) 6956 (clobber (reg:CC FLAGS_REG))] 6957 "TARGET_QIMODE_MATH 6958 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6959 "<sgnprefix>mul{b}\t%2" 6960 [(set_attr "type" "imul") 6961 (set_attr "length_immediate" "0") 6962 (set (attr "athlon_decode") 6963 (if_then_else (eq_attr "cpu" "athlon") 6964 (const_string "vector") 6965 (const_string "direct"))) 6966 (set_attr "amdfam10_decode" "direct") 6967 (set_attr "bdver1_decode" "direct") 6968 (set_attr "mode" "QI")]) 6969 6970(define_expand "<s>mul<mode>3_highpart" 6971 [(parallel [(set (match_operand:SWI48 0 "register_operand") 6972 (truncate:SWI48 6973 (lshiftrt:<DWI> 6974 (mult:<DWI> 6975 (any_extend:<DWI> 6976 (match_operand:SWI48 1 "nonimmediate_operand")) 6977 (any_extend:<DWI> 6978 (match_operand:SWI48 2 "register_operand"))) 6979 (match_dup 4)))) 6980 (clobber (match_scratch:SWI48 3)) 6981 (clobber (reg:CC FLAGS_REG))])] 6982 "" 6983 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 6984 6985(define_insn "*<s>muldi3_highpart_1" 6986 [(set (match_operand:DI 0 "register_operand" "=d") 6987 (truncate:DI 6988 (lshiftrt:TI 6989 (mult:TI 6990 (any_extend:TI 6991 (match_operand:DI 1 "nonimmediate_operand" "%a")) 6992 (any_extend:TI 6993 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 6994 (const_int 64)))) 6995 (clobber (match_scratch:DI 3 "=1")) 6996 (clobber (reg:CC FLAGS_REG))] 6997 "TARGET_64BIT 6998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 6999 "<sgnprefix>mul{q}\t%2" 7000 [(set_attr "type" "imul") 7001 (set_attr "length_immediate" "0") 7002 (set (attr "athlon_decode") 7003 (if_then_else (eq_attr "cpu" "athlon") 7004 (const_string "vector") 7005 (const_string "double"))) 7006 (set_attr "amdfam10_decode" "double") 7007 (set_attr "bdver1_decode" "direct") 7008 (set_attr "mode" "DI")]) 7009 7010(define_insn "*<s>mulsi3_highpart_1" 7011 [(set (match_operand:SI 0 "register_operand" "=d") 7012 (truncate:SI 7013 (lshiftrt:DI 7014 (mult:DI 7015 (any_extend:DI 7016 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7017 (any_extend:DI 7018 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7019 (const_int 32)))) 7020 (clobber (match_scratch:SI 3 "=1")) 7021 (clobber (reg:CC FLAGS_REG))] 7022 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7023 "<sgnprefix>mul{l}\t%2" 7024 [(set_attr "type" "imul") 7025 (set_attr "length_immediate" "0") 7026 (set (attr "athlon_decode") 7027 (if_then_else (eq_attr "cpu" "athlon") 7028 (const_string "vector") 7029 (const_string "double"))) 7030 (set_attr "amdfam10_decode" "double") 7031 (set_attr "bdver1_decode" "direct") 7032 (set_attr "mode" "SI")]) 7033 7034(define_insn "*<s>mulsi3_highpart_zext" 7035 [(set (match_operand:DI 0 "register_operand" "=d") 7036 (zero_extend:DI (truncate:SI 7037 (lshiftrt:DI 7038 (mult:DI (any_extend:DI 7039 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7040 (any_extend:DI 7041 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7042 (const_int 32))))) 7043 (clobber (match_scratch:SI 3 "=1")) 7044 (clobber (reg:CC FLAGS_REG))] 7045 "TARGET_64BIT 7046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7047 "<sgnprefix>mul{l}\t%2" 7048 [(set_attr "type" "imul") 7049 (set_attr "length_immediate" "0") 7050 (set (attr "athlon_decode") 7051 (if_then_else (eq_attr "cpu" "athlon") 7052 (const_string "vector") 7053 (const_string "double"))) 7054 (set_attr "amdfam10_decode" "double") 7055 (set_attr "bdver1_decode" "direct") 7056 (set_attr "mode" "SI")]) 7057 7058;; The patterns that match these are at the end of this file. 7059 7060(define_expand "mulxf3" 7061 [(set (match_operand:XF 0 "register_operand") 7062 (mult:XF (match_operand:XF 1 "register_operand") 7063 (match_operand:XF 2 "register_operand")))] 7064 "TARGET_80387") 7065 7066(define_expand "mul<mode>3" 7067 [(set (match_operand:MODEF 0 "register_operand") 7068 (mult:MODEF (match_operand:MODEF 1 "register_operand") 7069 (match_operand:MODEF 2 "nonimmediate_operand")))] 7070 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7071 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 7072 7073;; Divide instructions 7074 7075;; The patterns that match these are at the end of this file. 7076 7077(define_expand "divxf3" 7078 [(set (match_operand:XF 0 "register_operand") 7079 (div:XF (match_operand:XF 1 "register_operand") 7080 (match_operand:XF 2 "register_operand")))] 7081 "TARGET_80387") 7082 7083(define_expand "divdf3" 7084 [(set (match_operand:DF 0 "register_operand") 7085 (div:DF (match_operand:DF 1 "register_operand") 7086 (match_operand:DF 2 "nonimmediate_operand")))] 7087 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode)) 7088 || (TARGET_SSE2 && TARGET_SSE_MATH)") 7089 7090(define_expand "divsf3" 7091 [(set (match_operand:SF 0 "register_operand") 7092 (div:SF (match_operand:SF 1 "register_operand") 7093 (match_operand:SF 2 "nonimmediate_operand")))] 7094 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode)) 7095 || TARGET_SSE_MATH" 7096{ 7097 if (TARGET_SSE_MATH 7098 && TARGET_RECIP_DIV 7099 && optimize_insn_for_speed_p () 7100 && flag_finite_math_only && !flag_trapping_math 7101 && flag_unsafe_math_optimizations) 7102 { 7103 ix86_emit_swdivsf (operands[0], operands[1], 7104 operands[2], SFmode); 7105 DONE; 7106 } 7107}) 7108 7109;; Divmod instructions. 7110 7111(define_expand "divmod<mode>4" 7112 [(parallel [(set (match_operand:SWIM248 0 "register_operand") 7113 (div:SWIM248 7114 (match_operand:SWIM248 1 "register_operand") 7115 (match_operand:SWIM248 2 "nonimmediate_operand"))) 7116 (set (match_operand:SWIM248 3 "register_operand") 7117 (mod:SWIM248 (match_dup 1) (match_dup 2))) 7118 (clobber (reg:CC FLAGS_REG))])]) 7119 7120;; Split with 8bit unsigned divide: 7121;; if (dividend an divisor are in [0-255]) 7122;; use 8bit unsigned integer divide 7123;; else 7124;; use original integer divide 7125(define_split 7126 [(set (match_operand:SWI48 0 "register_operand") 7127 (div:SWI48 (match_operand:SWI48 2 "register_operand") 7128 (match_operand:SWI48 3 "nonimmediate_operand"))) 7129 (set (match_operand:SWI48 1 "register_operand") 7130 (mod:SWI48 (match_dup 2) (match_dup 3))) 7131 (clobber (reg:CC FLAGS_REG))] 7132 "TARGET_USE_8BIT_IDIV 7133 && TARGET_QIMODE_MATH 7134 && can_create_pseudo_p () 7135 && !optimize_insn_for_size_p ()" 7136 [(const_int 0)] 7137 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;") 7138 7139(define_insn_and_split "divmod<mode>4_1" 7140 [(set (match_operand:SWI48 0 "register_operand" "=a") 7141 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7142 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7143 (set (match_operand:SWI48 1 "register_operand" "=&d") 7144 (mod:SWI48 (match_dup 2) (match_dup 3))) 7145 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7146 (clobber (reg:CC FLAGS_REG))] 7147 "" 7148 "#" 7149 "reload_completed" 7150 [(parallel [(set (match_dup 1) 7151 (ashiftrt:SWI48 (match_dup 4) (match_dup 5))) 7152 (clobber (reg:CC FLAGS_REG))]) 7153 (parallel [(set (match_dup 0) 7154 (div:SWI48 (match_dup 2) (match_dup 3))) 7155 (set (match_dup 1) 7156 (mod:SWI48 (match_dup 2) (match_dup 3))) 7157 (use (match_dup 1)) 7158 (clobber (reg:CC FLAGS_REG))])] 7159{ 7160 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7161 7162 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 7163 operands[4] = operands[2]; 7164 else 7165 { 7166 /* Avoid use of cltd in favor of a mov+shift. */ 7167 emit_move_insn (operands[1], operands[2]); 7168 operands[4] = operands[1]; 7169 } 7170} 7171 [(set_attr "type" "multi") 7172 (set_attr "mode" "<MODE>")]) 7173 7174(define_insn_and_split "*divmod<mode>4" 7175 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7176 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7177 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7178 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7179 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7180 (clobber (reg:CC FLAGS_REG))] 7181 "" 7182 "#" 7183 "reload_completed" 7184 [(parallel [(set (match_dup 1) 7185 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5))) 7186 (clobber (reg:CC FLAGS_REG))]) 7187 (parallel [(set (match_dup 0) 7188 (div:SWIM248 (match_dup 2) (match_dup 3))) 7189 (set (match_dup 1) 7190 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7191 (use (match_dup 1)) 7192 (clobber (reg:CC FLAGS_REG))])] 7193{ 7194 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 7195 7196 if (<MODE>mode != HImode 7197 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)) 7198 operands[4] = operands[2]; 7199 else 7200 { 7201 /* Avoid use of cltd in favor of a mov+shift. */ 7202 emit_move_insn (operands[1], operands[2]); 7203 operands[4] = operands[1]; 7204 } 7205} 7206 [(set_attr "type" "multi") 7207 (set_attr "mode" "<MODE>")]) 7208 7209(define_insn "*divmod<mode>4_noext" 7210 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7211 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7212 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7213 (set (match_operand:SWIM248 1 "register_operand" "=d") 7214 (mod:SWIM248 (match_dup 2) (match_dup 3))) 7215 (use (match_operand:SWIM248 4 "register_operand" "1")) 7216 (clobber (reg:CC FLAGS_REG))] 7217 "" 7218 "idiv{<imodesuffix>}\t%3" 7219 [(set_attr "type" "idiv") 7220 (set_attr "mode" "<MODE>")]) 7221 7222(define_expand "divmodqi4" 7223 [(parallel [(set (match_operand:QI 0 "register_operand") 7224 (div:QI 7225 (match_operand:QI 1 "register_operand") 7226 (match_operand:QI 2 "nonimmediate_operand"))) 7227 (set (match_operand:QI 3 "register_operand") 7228 (mod:QI (match_dup 1) (match_dup 2))) 7229 (clobber (reg:CC FLAGS_REG))])] 7230 "TARGET_QIMODE_MATH" 7231{ 7232 rtx div, mod, insn; 7233 rtx tmp0, tmp1; 7234 7235 tmp0 = gen_reg_rtx (HImode); 7236 tmp1 = gen_reg_rtx (HImode); 7237 7238 /* Extend operands[1] to HImode. Generate 8bit divide. Result is 7239 in AX. */ 7240 emit_insn (gen_extendqihi2 (tmp1, operands[1])); 7241 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2])); 7242 7243 /* Extract remainder from AH. */ 7244 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8)); 7245 insn = emit_move_insn (operands[3], tmp1); 7246 7247 mod = gen_rtx_MOD (QImode, operands[1], operands[2]); 7248 set_unique_reg_note (insn, REG_EQUAL, mod); 7249 7250 /* Extract quotient from AL. */ 7251 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 7252 7253 div = gen_rtx_DIV (QImode, operands[1], operands[2]); 7254 set_unique_reg_note (insn, REG_EQUAL, div); 7255 7256 DONE; 7257}) 7258 7259;; Divide AX by r/m8, with result stored in 7260;; AL <- Quotient 7261;; AH <- Remainder 7262;; Change div/mod to HImode and extend the second argument to HImode 7263;; so that mode of div/mod matches with mode of arguments. Otherwise 7264;; combine may fail. 7265(define_insn "divmodhiqi3" 7266 [(set (match_operand:HI 0 "register_operand" "=a") 7267 (ior:HI 7268 (ashift:HI 7269 (zero_extend:HI 7270 (truncate:QI 7271 (mod:HI (match_operand:HI 1 "register_operand" "0") 7272 (sign_extend:HI 7273 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 7274 (const_int 8)) 7275 (zero_extend:HI 7276 (truncate:QI 7277 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2))))))) 7278 (clobber (reg:CC FLAGS_REG))] 7279 "TARGET_QIMODE_MATH" 7280 "idiv{b}\t%2" 7281 [(set_attr "type" "idiv") 7282 (set_attr "mode" "QI")]) 7283 7284(define_expand "udivmod<mode>4" 7285 [(parallel [(set (match_operand:SWIM248 0 "register_operand") 7286 (udiv:SWIM248 7287 (match_operand:SWIM248 1 "register_operand") 7288 (match_operand:SWIM248 2 "nonimmediate_operand"))) 7289 (set (match_operand:SWIM248 3 "register_operand") 7290 (umod:SWIM248 (match_dup 1) (match_dup 2))) 7291 (clobber (reg:CC FLAGS_REG))])]) 7292 7293;; Split with 8bit unsigned divide: 7294;; if (dividend an divisor are in [0-255]) 7295;; use 8bit unsigned integer divide 7296;; else 7297;; use original integer divide 7298(define_split 7299 [(set (match_operand:SWI48 0 "register_operand") 7300 (udiv:SWI48 (match_operand:SWI48 2 "register_operand") 7301 (match_operand:SWI48 3 "nonimmediate_operand"))) 7302 (set (match_operand:SWI48 1 "register_operand") 7303 (umod:SWI48 (match_dup 2) (match_dup 3))) 7304 (clobber (reg:CC FLAGS_REG))] 7305 "TARGET_USE_8BIT_IDIV 7306 && TARGET_QIMODE_MATH 7307 && can_create_pseudo_p () 7308 && !optimize_insn_for_size_p ()" 7309 [(const_int 0)] 7310 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;") 7311 7312(define_insn_and_split "udivmod<mode>4_1" 7313 [(set (match_operand:SWI48 0 "register_operand" "=a") 7314 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7315 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 7316 (set (match_operand:SWI48 1 "register_operand" "=&d") 7317 (umod:SWI48 (match_dup 2) (match_dup 3))) 7318 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 7319 (clobber (reg:CC FLAGS_REG))] 7320 "" 7321 "#" 7322 "reload_completed" 7323 [(set (match_dup 1) (const_int 0)) 7324 (parallel [(set (match_dup 0) 7325 (udiv:SWI48 (match_dup 2) (match_dup 3))) 7326 (set (match_dup 1) 7327 (umod:SWI48 (match_dup 2) (match_dup 3))) 7328 (use (match_dup 1)) 7329 (clobber (reg:CC FLAGS_REG))])] 7330 "" 7331 [(set_attr "type" "multi") 7332 (set_attr "mode" "<MODE>")]) 7333 7334(define_insn_and_split "*udivmod<mode>4" 7335 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7336 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7337 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7338 (set (match_operand:SWIM248 1 "register_operand" "=&d") 7339 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7340 (clobber (reg:CC FLAGS_REG))] 7341 "" 7342 "#" 7343 "reload_completed" 7344 [(set (match_dup 1) (const_int 0)) 7345 (parallel [(set (match_dup 0) 7346 (udiv:SWIM248 (match_dup 2) (match_dup 3))) 7347 (set (match_dup 1) 7348 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7349 (use (match_dup 1)) 7350 (clobber (reg:CC FLAGS_REG))])] 7351 "" 7352 [(set_attr "type" "multi") 7353 (set_attr "mode" "<MODE>")]) 7354 7355;; Optimize division or modulo by constant power of 2, if the constant 7356;; materializes only after expansion. 7357(define_insn_and_split "*udivmod<mode>4_pow2" 7358 [(set (match_operand:SWI48 0 "register_operand" "=r") 7359 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 7360 (match_operand:SWI48 3 "const_int_operand" "n"))) 7361 (set (match_operand:SWI48 1 "register_operand" "=r") 7362 (umod:SWI48 (match_dup 2) (match_dup 3))) 7363 (clobber (reg:CC FLAGS_REG))] 7364 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000)) 7365 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0" 7366 "#" 7367 "&& 1" 7368 [(set (match_dup 1) (match_dup 2)) 7369 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4))) 7370 (clobber (reg:CC FLAGS_REG))]) 7371 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5))) 7372 (clobber (reg:CC FLAGS_REG))])] 7373{ 7374 int v = exact_log2 (UINTVAL (operands[3])); 7375 operands[4] = GEN_INT (v); 7376 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); 7377} 7378 [(set_attr "type" "multi") 7379 (set_attr "mode" "<MODE>")]) 7380 7381(define_insn "*udivmod<mode>4_noext" 7382 [(set (match_operand:SWIM248 0 "register_operand" "=a") 7383 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 7384 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 7385 (set (match_operand:SWIM248 1 "register_operand" "=d") 7386 (umod:SWIM248 (match_dup 2) (match_dup 3))) 7387 (use (match_operand:SWIM248 4 "register_operand" "1")) 7388 (clobber (reg:CC FLAGS_REG))] 7389 "" 7390 "div{<imodesuffix>}\t%3" 7391 [(set_attr "type" "idiv") 7392 (set_attr "mode" "<MODE>")]) 7393 7394(define_expand "udivmodqi4" 7395 [(parallel [(set (match_operand:QI 0 "register_operand") 7396 (udiv:QI 7397 (match_operand:QI 1 "register_operand") 7398 (match_operand:QI 2 "nonimmediate_operand"))) 7399 (set (match_operand:QI 3 "register_operand") 7400 (umod:QI (match_dup 1) (match_dup 2))) 7401 (clobber (reg:CC FLAGS_REG))])] 7402 "TARGET_QIMODE_MATH" 7403{ 7404 rtx div, mod, insn; 7405 rtx tmp0, tmp1; 7406 7407 tmp0 = gen_reg_rtx (HImode); 7408 tmp1 = gen_reg_rtx (HImode); 7409 7410 /* Extend operands[1] to HImode. Generate 8bit divide. Result is 7411 in AX. */ 7412 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1])); 7413 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2])); 7414 7415 /* Extract remainder from AH. */ 7416 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8)); 7417 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0); 7418 insn = emit_move_insn (operands[3], tmp1); 7419 7420 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]); 7421 set_unique_reg_note (insn, REG_EQUAL, mod); 7422 7423 /* Extract quotient from AL. */ 7424 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 7425 7426 div = gen_rtx_UDIV (QImode, operands[1], operands[2]); 7427 set_unique_reg_note (insn, REG_EQUAL, div); 7428 7429 DONE; 7430}) 7431 7432(define_insn "udivmodhiqi3" 7433 [(set (match_operand:HI 0 "register_operand" "=a") 7434 (ior:HI 7435 (ashift:HI 7436 (zero_extend:HI 7437 (truncate:QI 7438 (mod:HI (match_operand:HI 1 "register_operand" "0") 7439 (zero_extend:HI 7440 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 7441 (const_int 8)) 7442 (zero_extend:HI 7443 (truncate:QI 7444 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2))))))) 7445 (clobber (reg:CC FLAGS_REG))] 7446 "TARGET_QIMODE_MATH" 7447 "div{b}\t%2" 7448 [(set_attr "type" "idiv") 7449 (set_attr "mode" "QI")]) 7450 7451;; We cannot use div/idiv for double division, because it causes 7452;; "division by zero" on the overflow and that's not what we expect 7453;; from truncate. Because true (non truncating) double division is 7454;; never generated, we can't create this insn anyway. 7455; 7456;(define_insn "" 7457; [(set (match_operand:SI 0 "register_operand" "=a") 7458; (truncate:SI 7459; (udiv:DI (match_operand:DI 1 "register_operand" "A") 7460; (zero_extend:DI 7461; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 7462; (set (match_operand:SI 3 "register_operand" "=d") 7463; (truncate:SI 7464; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 7465; (clobber (reg:CC FLAGS_REG))] 7466; "" 7467; "div{l}\t{%2, %0|%0, %2}" 7468; [(set_attr "type" "idiv")]) 7469 7470;;- Logical AND instructions 7471 7472;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 7473;; Note that this excludes ah. 7474 7475(define_expand "testsi_ccno_1" 7476 [(set (reg:CCNO FLAGS_REG) 7477 (compare:CCNO 7478 (and:SI (match_operand:SI 0 "nonimmediate_operand") 7479 (match_operand:SI 1 "x86_64_nonmemory_operand")) 7480 (const_int 0)))]) 7481 7482(define_expand "testqi_ccz_1" 7483 [(set (reg:CCZ FLAGS_REG) 7484 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand") 7485 (match_operand:QI 1 "nonmemory_operand")) 7486 (const_int 0)))]) 7487 7488(define_expand "testdi_ccno_1" 7489 [(set (reg:CCNO FLAGS_REG) 7490 (compare:CCNO 7491 (and:DI (match_operand:DI 0 "nonimmediate_operand") 7492 (match_operand:DI 1 "x86_64_szext_general_operand")) 7493 (const_int 0)))] 7494 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))") 7495 7496(define_insn "*testdi_1" 7497 [(set (reg FLAGS_REG) 7498 (compare 7499 (and:DI 7500 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm") 7501 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re")) 7502 (const_int 0)))] 7503 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 7504 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7505 "@ 7506 test{l}\t{%k1, %k0|%k0, %k1} 7507 test{l}\t{%k1, %k0|%k0, %k1} 7508 test{q}\t{%1, %0|%0, %1} 7509 test{q}\t{%1, %0|%0, %1} 7510 test{q}\t{%1, %0|%0, %1}" 7511 [(set_attr "type" "test") 7512 (set_attr "modrm" "0,1,0,1,1") 7513 (set_attr "mode" "SI,SI,DI,DI,DI")]) 7514 7515(define_insn "*testqi_1_maybe_si" 7516 [(set (reg FLAGS_REG) 7517 (compare 7518 (and:QI 7519 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r") 7520 (match_operand:QI 1 "general_operand" "n,n,qn,n")) 7521 (const_int 0)))] 7522 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 7523 && ix86_match_ccmode (insn, 7524 CONST_INT_P (operands[1]) 7525 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 7526{ 7527 if (which_alternative == 3) 7528 { 7529 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0) 7530 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 7531 return "test{l}\t{%1, %k0|%k0, %1}"; 7532 } 7533 return "test{b}\t{%1, %0|%0, %1}"; 7534} 7535 [(set_attr "type" "test") 7536 (set_attr "modrm" "0,1,1,1") 7537 (set_attr "mode" "QI,QI,QI,SI") 7538 (set_attr "pent_pair" "uv,np,uv,np")]) 7539 7540(define_insn "*test<mode>_1" 7541 [(set (reg FLAGS_REG) 7542 (compare 7543 (and:SWI124 7544 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m") 7545 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>")) 7546 (const_int 0)))] 7547 "ix86_match_ccmode (insn, CCNOmode) 7548 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7549 "test{<imodesuffix>}\t{%1, %0|%0, %1}" 7550 [(set_attr "type" "test") 7551 (set_attr "modrm" "0,1,1") 7552 (set_attr "mode" "<MODE>") 7553 (set_attr "pent_pair" "uv,np,uv")]) 7554 7555(define_expand "testqi_ext_ccno_0" 7556 [(set (reg:CCNO FLAGS_REG) 7557 (compare:CCNO 7558 (and:SI 7559 (zero_extract:SI 7560 (match_operand 0 "ext_register_operand") 7561 (const_int 8) 7562 (const_int 8)) 7563 (match_operand 1 "const_int_operand")) 7564 (const_int 0)))]) 7565 7566(define_insn "*testqi_ext_0" 7567 [(set (reg FLAGS_REG) 7568 (compare 7569 (and:SI 7570 (zero_extract:SI 7571 (match_operand 0 "ext_register_operand" "Q") 7572 (const_int 8) 7573 (const_int 8)) 7574 (match_operand 1 "const_int_operand" "n")) 7575 (const_int 0)))] 7576 "ix86_match_ccmode (insn, CCNOmode)" 7577 "test{b}\t{%1, %h0|%h0, %1}" 7578 [(set_attr "type" "test") 7579 (set_attr "mode" "QI") 7580 (set_attr "length_immediate" "1") 7581 (set_attr "modrm" "1") 7582 (set_attr "pent_pair" "np")]) 7583 7584(define_insn "*testqi_ext_1" 7585 [(set (reg FLAGS_REG) 7586 (compare 7587 (and:SI 7588 (zero_extract:SI 7589 (match_operand 0 "ext_register_operand" "Q,Q") 7590 (const_int 8) 7591 (const_int 8)) 7592 (zero_extend:SI 7593 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m"))) 7594 (const_int 0)))] 7595 "ix86_match_ccmode (insn, CCNOmode)" 7596 "test{b}\t{%1, %h0|%h0, %1}" 7597 [(set_attr "isa" "*,nox64") 7598 (set_attr "type" "test") 7599 (set_attr "mode" "QI")]) 7600 7601(define_insn "*testqi_ext_2" 7602 [(set (reg FLAGS_REG) 7603 (compare 7604 (and:SI 7605 (zero_extract:SI 7606 (match_operand 0 "ext_register_operand" "Q") 7607 (const_int 8) 7608 (const_int 8)) 7609 (zero_extract:SI 7610 (match_operand 1 "ext_register_operand" "Q") 7611 (const_int 8) 7612 (const_int 8))) 7613 (const_int 0)))] 7614 "ix86_match_ccmode (insn, CCNOmode)" 7615 "test{b}\t{%h1, %h0|%h0, %h1}" 7616 [(set_attr "type" "test") 7617 (set_attr "mode" "QI")]) 7618 7619;; Combine likes to form bit extractions for some tests. Humor it. 7620(define_insn "*testqi_ext_3" 7621 [(set (reg FLAGS_REG) 7622 (compare (zero_extract:SWI48 7623 (match_operand 0 "nonimmediate_operand" "rm") 7624 (match_operand:SWI48 1 "const_int_operand") 7625 (match_operand:SWI48 2 "const_int_operand")) 7626 (const_int 0)))] 7627 "ix86_match_ccmode (insn, CCNOmode) 7628 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode) 7629 || GET_MODE (operands[0]) == SImode 7630 || GET_MODE (operands[0]) == HImode 7631 || GET_MODE (operands[0]) == QImode) 7632 /* Ensure that resulting mask is zero or sign extended operand. */ 7633 && INTVAL (operands[2]) >= 0 7634 && ((INTVAL (operands[1]) > 0 7635 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32) 7636 || (<MODE>mode == DImode 7637 && INTVAL (operands[1]) > 32 7638 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))" 7639 "#") 7640 7641(define_split 7642 [(set (match_operand 0 "flags_reg_operand") 7643 (match_operator 1 "compare_operator" 7644 [(zero_extract 7645 (match_operand 2 "nonimmediate_operand") 7646 (match_operand 3 "const_int_operand") 7647 (match_operand 4 "const_int_operand")) 7648 (const_int 0)]))] 7649 "ix86_match_ccmode (insn, CCNOmode)" 7650 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 7651{ 7652 rtx val = operands[2]; 7653 HOST_WIDE_INT len = INTVAL (operands[3]); 7654 HOST_WIDE_INT pos = INTVAL (operands[4]); 7655 HOST_WIDE_INT mask; 7656 machine_mode mode, submode; 7657 7658 mode = GET_MODE (val); 7659 if (MEM_P (val)) 7660 { 7661 /* ??? Combine likes to put non-volatile mem extractions in QImode 7662 no matter the size of the test. So find a mode that works. */ 7663 if (! MEM_VOLATILE_P (val)) 7664 { 7665 mode = smallest_mode_for_size (pos + len, MODE_INT); 7666 val = adjust_address (val, mode, 0); 7667 } 7668 } 7669 else if (GET_CODE (val) == SUBREG 7670 && (submode = GET_MODE (SUBREG_REG (val)), 7671 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)) 7672 && pos + len <= GET_MODE_BITSIZE (submode) 7673 && GET_MODE_CLASS (submode) == MODE_INT) 7674 { 7675 /* Narrow a paradoxical subreg to prevent partial register stalls. */ 7676 mode = submode; 7677 val = SUBREG_REG (val); 7678 } 7679 else if (mode == HImode && pos + len <= 8) 7680 { 7681 /* Small HImode tests can be converted to QImode. */ 7682 mode = QImode; 7683 val = gen_lowpart (QImode, val); 7684 } 7685 7686 if (len == HOST_BITS_PER_WIDE_INT) 7687 mask = -1; 7688 else 7689 mask = ((HOST_WIDE_INT)1 << len) - 1; 7690 mask <<= pos; 7691 7692 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode)); 7693}) 7694 7695;; Convert HImode/SImode test instructions with immediate to QImode ones. 7696;; i386 does not allow to encode test with 8bit sign extended immediate, so 7697;; this is relatively important trick. 7698;; Do the conversion only post-reload to avoid limiting of the register class 7699;; to QI regs. 7700(define_split 7701 [(set (match_operand 0 "flags_reg_operand") 7702 (match_operator 1 "compare_operator" 7703 [(and (match_operand 2 "register_operand") 7704 (match_operand 3 "const_int_operand")) 7705 (const_int 0)]))] 7706 "reload_completed 7707 && QI_REG_P (operands[2]) 7708 && GET_MODE (operands[2]) != QImode 7709 && ((ix86_match_ccmode (insn, CCZmode) 7710 && !(INTVAL (operands[3]) & ~(255 << 8))) 7711 || (ix86_match_ccmode (insn, CCNOmode) 7712 && !(INTVAL (operands[3]) & ~(127 << 8))))" 7713 [(set (match_dup 0) 7714 (match_op_dup 1 7715 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8)) 7716 (match_dup 3)) 7717 (const_int 0)]))] 7718{ 7719 operands[2] = gen_lowpart (SImode, operands[2]); 7720 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode); 7721}) 7722 7723(define_split 7724 [(set (match_operand 0 "flags_reg_operand") 7725 (match_operator 1 "compare_operator" 7726 [(and (match_operand 2 "nonimmediate_operand") 7727 (match_operand 3 "const_int_operand")) 7728 (const_int 0)]))] 7729 "reload_completed 7730 && GET_MODE (operands[2]) != QImode 7731 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 7732 && ((ix86_match_ccmode (insn, CCZmode) 7733 && !(INTVAL (operands[3]) & ~255)) 7734 || (ix86_match_ccmode (insn, CCNOmode) 7735 && !(INTVAL (operands[3]) & ~127)))" 7736 [(set (match_dup 0) 7737 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 7738 (const_int 0)]))] 7739{ 7740 operands[2] = gen_lowpart (QImode, operands[2]); 7741 operands[3] = gen_lowpart (QImode, operands[3]); 7742}) 7743 7744(define_split 7745 [(set (match_operand:SWI1248x 0 "mask_reg_operand") 7746 (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand") 7747 (match_operand:SWI1248x 2 "mask_reg_operand"))) 7748 (clobber (reg:CC FLAGS_REG))] 7749 "TARGET_AVX512F && reload_completed" 7750 [(set (match_dup 0) 7751 (any_logic:SWI1248x (match_dup 1) 7752 (match_dup 2)))]) 7753 7754(define_insn "*k<logic><mode>" 7755 [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k") 7756 (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k") 7757 (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))] 7758 "TARGET_AVX512F" 7759 { 7760 if (!TARGET_AVX512DQ && <MODE>mode == QImode) 7761 return "k<logic>w\t{%2, %1, %0|%0, %1, %2}"; 7762 else 7763 return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"; 7764 } 7765 [(set_attr "mode" "<MODE>") 7766 (set_attr "type" "msklog") 7767 (set_attr "prefix" "vex")]) 7768 7769;; %%% This used to optimize known byte-wide and operations to memory, 7770;; and sometimes to QImode registers. If this is considered useful, 7771;; it should be done with splitters. 7772 7773(define_expand "and<mode>3" 7774 [(set (match_operand:SWIM 0 "nonimmediate_operand") 7775 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand") 7776 (match_operand:SWIM 2 "<general_szext_operand>")))] 7777 "" 7778{ 7779 machine_mode mode = <MODE>mode; 7780 rtx (*insn) (rtx, rtx); 7781 7782 if (CONST_INT_P (operands[2]) && REG_P (operands[0])) 7783 { 7784 HOST_WIDE_INT ival = INTVAL (operands[2]); 7785 7786 if (ival == (HOST_WIDE_INT) 0xffffffff) 7787 mode = SImode; 7788 else if (ival == 0xffff) 7789 mode = HImode; 7790 else if (ival == 0xff) 7791 mode = QImode; 7792 } 7793 7794 if (mode == <MODE>mode) 7795 { 7796 ix86_expand_binary_operator (AND, <MODE>mode, operands); 7797 DONE; 7798 } 7799 7800 if (<MODE>mode == DImode) 7801 insn = (mode == SImode) 7802 ? gen_zero_extendsidi2 7803 : (mode == HImode) 7804 ? gen_zero_extendhidi2 7805 : gen_zero_extendqidi2; 7806 else if (<MODE>mode == SImode) 7807 insn = (mode == HImode) 7808 ? gen_zero_extendhisi2 7809 : gen_zero_extendqisi2; 7810 else if (<MODE>mode == HImode) 7811 insn = gen_zero_extendqihi2; 7812 else 7813 gcc_unreachable (); 7814 7815 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1]))); 7816 DONE; 7817}) 7818 7819(define_insn "*anddi_1" 7820 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k") 7821 (and:DI 7822 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k") 7823 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k"))) 7824 (clobber (reg:CC FLAGS_REG))] 7825 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 7826{ 7827 switch (get_attr_type (insn)) 7828 { 7829 case TYPE_IMOVX: 7830 return "#"; 7831 7832 case TYPE_MSKLOG: 7833 return "kandq\t{%2, %1, %0|%0, %1, %2}"; 7834 7835 default: 7836 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7837 if (get_attr_mode (insn) == MODE_SI) 7838 return "and{l}\t{%k2, %k0|%k0, %k2}"; 7839 else 7840 return "and{q}\t{%2, %0|%0, %2}"; 7841 } 7842} 7843 [(set_attr "type" "alu,alu,alu,imovx,msklog") 7844 (set_attr "length_immediate" "*,*,*,0,0") 7845 (set (attr "prefix_rex") 7846 (if_then_else 7847 (and (eq_attr "type" "imovx") 7848 (and (match_test "INTVAL (operands[2]) == 0xff") 7849 (match_operand 1 "ext_QIreg_operand"))) 7850 (const_string "1") 7851 (const_string "*"))) 7852 (set_attr "mode" "SI,DI,DI,SI,DI")]) 7853 7854(define_insn "*andsi_1" 7855 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k") 7856 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k") 7857 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k"))) 7858 (clobber (reg:CC FLAGS_REG))] 7859 "ix86_binary_operator_ok (AND, SImode, operands)" 7860{ 7861 switch (get_attr_type (insn)) 7862 { 7863 case TYPE_IMOVX: 7864 return "#"; 7865 7866 case TYPE_MSKLOG: 7867 return "kandd\t{%2, %1, %0|%0, %1, %2}"; 7868 7869 default: 7870 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7871 return "and{l}\t{%2, %0|%0, %2}"; 7872 } 7873} 7874 [(set_attr "type" "alu,alu,imovx,msklog") 7875 (set (attr "prefix_rex") 7876 (if_then_else 7877 (and (eq_attr "type" "imovx") 7878 (and (match_test "INTVAL (operands[2]) == 0xff") 7879 (match_operand 1 "ext_QIreg_operand"))) 7880 (const_string "1") 7881 (const_string "*"))) 7882 (set_attr "length_immediate" "*,*,0,0") 7883 (set_attr "mode" "SI")]) 7884 7885;; See comment for addsi_1_zext why we do use nonimmediate_operand 7886(define_insn "*andsi_1_zext" 7887 [(set (match_operand:DI 0 "register_operand" "=r") 7888 (zero_extend:DI 7889 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 7890 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 7891 (clobber (reg:CC FLAGS_REG))] 7892 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 7893 "and{l}\t{%2, %k0|%k0, %2}" 7894 [(set_attr "type" "alu") 7895 (set_attr "mode" "SI")]) 7896 7897(define_insn "*andhi_1" 7898 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k") 7899 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k") 7900 (match_operand:HI 2 "general_operand" "rn,rm,L,k"))) 7901 (clobber (reg:CC FLAGS_REG))] 7902 "ix86_binary_operator_ok (AND, HImode, operands)" 7903{ 7904 switch (get_attr_type (insn)) 7905 { 7906 case TYPE_IMOVX: 7907 return "#"; 7908 7909 case TYPE_MSKLOG: 7910 return "kandw\t{%2, %1, %0|%0, %1, %2}"; 7911 7912 default: 7913 gcc_assert (rtx_equal_p (operands[0], operands[1])); 7914 return "and{w}\t{%2, %0|%0, %2}"; 7915 } 7916} 7917 [(set_attr "type" "alu,alu,imovx,msklog") 7918 (set_attr "length_immediate" "*,*,0,*") 7919 (set (attr "prefix_rex") 7920 (if_then_else 7921 (and (eq_attr "type" "imovx") 7922 (match_operand 1 "ext_QIreg_operand")) 7923 (const_string "1") 7924 (const_string "*"))) 7925 (set_attr "mode" "HI,HI,SI,HI")]) 7926 7927;; %%% Potential partial reg stall on alternative 2. What to do? 7928(define_insn "*andqi_1" 7929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k") 7930 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k") 7931 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k"))) 7932 (clobber (reg:CC FLAGS_REG))] 7933 "ix86_binary_operator_ok (AND, QImode, operands)" 7934{ 7935 switch (which_alternative) 7936 { 7937 case 0: 7938 case 1: 7939 return "and{b}\t{%2, %0|%0, %2}"; 7940 case 2: 7941 return "and{l}\t{%k2, %k0|%k0, %k2}"; 7942 case 3: 7943 return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}" 7944 : "kandw\t{%2, %1, %0|%0, %1, %2}"; 7945 default: 7946 gcc_unreachable (); 7947 } 7948} 7949 [(set_attr "type" "alu,alu,alu,msklog") 7950 (set_attr "mode" "QI,QI,SI,HI")]) 7951 7952(define_insn "*andqi_1_slp" 7953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) 7954 (and:QI (match_dup 0) 7955 (match_operand:QI 1 "general_operand" "qn,qmn"))) 7956 (clobber (reg:CC FLAGS_REG))] 7957 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 7958 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 7959 "and{b}\t{%1, %0|%0, %1}" 7960 [(set_attr "type" "alu1") 7961 (set_attr "mode" "QI")]) 7962 7963(define_insn "kandn<mode>" 7964 [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k") 7965 (and:SWI12 7966 (not:SWI12 7967 (match_operand:SWI12 1 "register_operand" "r,0,k")) 7968 (match_operand:SWI12 2 "register_operand" "r,r,k"))) 7969 (clobber (reg:CC FLAGS_REG))] 7970 "TARGET_AVX512F" 7971{ 7972 switch (which_alternative) 7973 { 7974 case 0: 7975 return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"; 7976 case 1: 7977 return "#"; 7978 case 2: 7979 if (TARGET_AVX512DQ && <MODE>mode == QImode) 7980 return "kandnb\t{%2, %1, %0|%0, %1, %2}"; 7981 else 7982 return "kandnw\t{%2, %1, %0|%0, %1, %2}"; 7983 default: 7984 gcc_unreachable (); 7985 } 7986} 7987 [(set_attr "isa" "bmi,*,avx512f") 7988 (set_attr "type" "bitmanip,*,msklog") 7989 (set_attr "prefix" "*,*,vex") 7990 (set_attr "btver2_decode" "direct,*,*") 7991 (set_attr "mode" "<MODE>")]) 7992 7993(define_split 7994 [(set (match_operand:SWI12 0 "general_reg_operand") 7995 (and:SWI12 7996 (not:SWI12 7997 (match_dup 0)) 7998 (match_operand:SWI12 1 "general_reg_operand"))) 7999 (clobber (reg:CC FLAGS_REG))] 8000 "TARGET_AVX512F && !TARGET_BMI && reload_completed" 8001 [(set (match_dup 0) 8002 (not:SWI12 (match_dup 0))) 8003 (parallel [(set (match_dup 0) 8004 (and:SWI12 (match_dup 0) 8005 (match_dup 1))) 8006 (clobber (reg:CC FLAGS_REG))])]) 8007 8008;; Turn *anddi_1 into *andsi_1_zext if possible. 8009(define_split 8010 [(set (match_operand:DI 0 "register_operand") 8011 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0) 8012 (match_operand:DI 2 "x86_64_zext_immediate_operand"))) 8013 (clobber (reg:CC FLAGS_REG))] 8014 "TARGET_64BIT" 8015 [(parallel [(set (match_dup 0) 8016 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2)))) 8017 (clobber (reg:CC FLAGS_REG))])] 8018 "operands[2] = gen_lowpart (SImode, operands[2]);") 8019 8020(define_split 8021 [(set (match_operand:SWI248 0 "register_operand") 8022 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand") 8023 (match_operand:SWI248 2 "const_int_operand"))) 8024 (clobber (reg:CC FLAGS_REG))] 8025 "reload_completed 8026 && true_regnum (operands[0]) != true_regnum (operands[1])" 8027 [(const_int 0)] 8028{ 8029 HOST_WIDE_INT ival = INTVAL (operands[2]); 8030 machine_mode mode; 8031 rtx (*insn) (rtx, rtx); 8032 8033 if (ival == (HOST_WIDE_INT) 0xffffffff) 8034 mode = SImode; 8035 else if (ival == 0xffff) 8036 mode = HImode; 8037 else 8038 { 8039 gcc_assert (ival == 0xff); 8040 mode = QImode; 8041 } 8042 8043 if (<MODE>mode == DImode) 8044 insn = (mode == SImode) 8045 ? gen_zero_extendsidi2 8046 : (mode == HImode) 8047 ? gen_zero_extendhidi2 8048 : gen_zero_extendqidi2; 8049 else 8050 { 8051 if (<MODE>mode != SImode) 8052 /* Zero extend to SImode to avoid partial register stalls. */ 8053 operands[0] = gen_lowpart (SImode, operands[0]); 8054 8055 insn = (mode == HImode) 8056 ? gen_zero_extendhisi2 8057 : gen_zero_extendqisi2; 8058 } 8059 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1]))); 8060 DONE; 8061}) 8062 8063(define_split 8064 [(set (match_operand 0 "register_operand") 8065 (and (match_dup 0) 8066 (const_int -65536))) 8067 (clobber (reg:CC FLAGS_REG))] 8068 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL) 8069 || optimize_function_for_size_p (cfun)" 8070 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8071 "operands[1] = gen_lowpart (HImode, operands[0]);") 8072 8073(define_split 8074 [(set (match_operand 0 "ext_register_operand") 8075 (and (match_dup 0) 8076 (const_int -256))) 8077 (clobber (reg:CC FLAGS_REG))] 8078 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8079 && reload_completed" 8080 [(set (strict_low_part (match_dup 1)) (const_int 0))] 8081 "operands[1] = gen_lowpart (QImode, operands[0]);") 8082 8083(define_split 8084 [(set (match_operand 0 "ext_register_operand") 8085 (and (match_dup 0) 8086 (const_int -65281))) 8087 (clobber (reg:CC FLAGS_REG))] 8088 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8089 && reload_completed" 8090 [(parallel [(set (zero_extract:SI (match_dup 0) 8091 (const_int 8) 8092 (const_int 8)) 8093 (xor:SI 8094 (zero_extract:SI (match_dup 0) 8095 (const_int 8) 8096 (const_int 8)) 8097 (zero_extract:SI (match_dup 0) 8098 (const_int 8) 8099 (const_int 8)))) 8100 (clobber (reg:CC FLAGS_REG))])] 8101 "operands[0] = gen_lowpart (SImode, operands[0]);") 8102 8103(define_insn "*anddi_2" 8104 [(set (reg FLAGS_REG) 8105 (compare 8106 (and:DI 8107 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 8108 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re")) 8109 (const_int 0))) 8110 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm") 8111 (and:DI (match_dup 1) (match_dup 2)))] 8112 "TARGET_64BIT 8113 && ix86_match_ccmode 8114 (insn, 8115 /* If we are going to emit andl instead of andq, and the operands[2] 8116 constant might have the SImode sign bit set, make sure the sign 8117 flag isn't tested, because the instruction will set the sign flag 8118 based on bit 31 rather than bit 63. If it isn't CONST_INT, 8119 conservatively assume it might have bit 31 set. */ 8120 (satisfies_constraint_Z (operands[2]) 8121 && (!CONST_INT_P (operands[2]) 8122 || val_signbit_known_set_p (SImode, INTVAL (operands[2])))) 8123 ? CCZmode : CCNOmode) 8124 && ix86_binary_operator_ok (AND, DImode, operands)" 8125 "@ 8126 and{l}\t{%k2, %k0|%k0, %k2} 8127 and{q}\t{%2, %0|%0, %2} 8128 and{q}\t{%2, %0|%0, %2}" 8129 [(set_attr "type" "alu") 8130 (set_attr "mode" "SI,DI,DI")]) 8131 8132(define_insn "*andqi_2_maybe_si" 8133 [(set (reg FLAGS_REG) 8134 (compare (and:QI 8135 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 8136 (match_operand:QI 2 "general_operand" "qmn,qn,n")) 8137 (const_int 0))) 8138 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r") 8139 (and:QI (match_dup 1) (match_dup 2)))] 8140 "ix86_binary_operator_ok (AND, QImode, operands) 8141 && ix86_match_ccmode (insn, 8142 CONST_INT_P (operands[2]) 8143 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 8144{ 8145 if (which_alternative == 2) 8146 { 8147 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 8148 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 8149 return "and{l}\t{%2, %k0|%k0, %2}"; 8150 } 8151 return "and{b}\t{%2, %0|%0, %2}"; 8152} 8153 [(set_attr "type" "alu") 8154 (set_attr "mode" "QI,QI,SI")]) 8155 8156(define_insn "*and<mode>_2" 8157 [(set (reg FLAGS_REG) 8158 (compare (and:SWI124 8159 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") 8160 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>")) 8161 (const_int 0))) 8162 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m") 8163 (and:SWI124 (match_dup 1) (match_dup 2)))] 8164 "ix86_match_ccmode (insn, CCNOmode) 8165 && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 8166 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 8167 [(set_attr "type" "alu") 8168 (set_attr "mode" "<MODE>")]) 8169 8170;; See comment for addsi_1_zext why we do use nonimmediate_operand 8171(define_insn "*andsi_2_zext" 8172 [(set (reg FLAGS_REG) 8173 (compare (and:SI 8174 (match_operand:SI 1 "nonimmediate_operand" "%0") 8175 (match_operand:SI 2 "x86_64_general_operand" "rme")) 8176 (const_int 0))) 8177 (set (match_operand:DI 0 "register_operand" "=r") 8178 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 8179 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8180 && ix86_binary_operator_ok (AND, SImode, operands)" 8181 "and{l}\t{%2, %k0|%k0, %2}" 8182 [(set_attr "type" "alu") 8183 (set_attr "mode" "SI")]) 8184 8185(define_insn "*andqi_2_slp" 8186 [(set (reg FLAGS_REG) 8187 (compare (and:QI 8188 (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8189 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn")) 8190 (const_int 0))) 8191 (set (strict_low_part (match_dup 0)) 8192 (and:QI (match_dup 0) (match_dup 1)))] 8193 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8194 && ix86_match_ccmode (insn, CCNOmode) 8195 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8196 "and{b}\t{%1, %0|%0, %1}" 8197 [(set_attr "type" "alu1") 8198 (set_attr "mode" "QI")]) 8199 8200;; ??? A bug in recog prevents it from recognizing a const_int as an 8201;; operand to zero_extend in andqi_ext_1. It was checking explicitly 8202;; for a QImode operand, which of course failed. 8203(define_insn "andqi_ext_0" 8204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8205 (const_int 8) 8206 (const_int 8)) 8207 (and:SI 8208 (zero_extract:SI 8209 (match_operand 1 "ext_register_operand" "0") 8210 (const_int 8) 8211 (const_int 8)) 8212 (match_operand 2 "const_int_operand" "n"))) 8213 (clobber (reg:CC FLAGS_REG))] 8214 "" 8215 "and{b}\t{%2, %h0|%h0, %2}" 8216 [(set_attr "type" "alu") 8217 (set_attr "length_immediate" "1") 8218 (set_attr "modrm" "1") 8219 (set_attr "mode" "QI")]) 8220 8221;; Generated by peephole translating test to and. This shows up 8222;; often in fp comparisons. 8223(define_insn "*andqi_ext_0_cc" 8224 [(set (reg FLAGS_REG) 8225 (compare 8226 (and:SI 8227 (zero_extract:SI 8228 (match_operand 1 "ext_register_operand" "0") 8229 (const_int 8) 8230 (const_int 8)) 8231 (match_operand 2 "const_int_operand" "n")) 8232 (const_int 0))) 8233 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8234 (const_int 8) 8235 (const_int 8)) 8236 (and:SI 8237 (zero_extract:SI 8238 (match_dup 1) 8239 (const_int 8) 8240 (const_int 8)) 8241 (match_dup 2)))] 8242 "ix86_match_ccmode (insn, CCNOmode)" 8243 "and{b}\t{%2, %h0|%h0, %2}" 8244 [(set_attr "type" "alu") 8245 (set_attr "length_immediate" "1") 8246 (set_attr "modrm" "1") 8247 (set_attr "mode" "QI")]) 8248 8249(define_insn "*andqi_ext_1" 8250 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") 8251 (const_int 8) 8252 (const_int 8)) 8253 (and:SI 8254 (zero_extract:SI 8255 (match_operand 1 "ext_register_operand" "0,0") 8256 (const_int 8) 8257 (const_int 8)) 8258 (zero_extend:SI 8259 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m")))) 8260 (clobber (reg:CC FLAGS_REG))] 8261 "" 8262 "and{b}\t{%2, %h0|%h0, %2}" 8263 [(set_attr "isa" "*,nox64") 8264 (set_attr "type" "alu") 8265 (set_attr "length_immediate" "0") 8266 (set_attr "mode" "QI")]) 8267 8268(define_insn "*andqi_ext_2" 8269 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8270 (const_int 8) 8271 (const_int 8)) 8272 (and:SI 8273 (zero_extract:SI 8274 (match_operand 1 "ext_register_operand" "%0") 8275 (const_int 8) 8276 (const_int 8)) 8277 (zero_extract:SI 8278 (match_operand 2 "ext_register_operand" "Q") 8279 (const_int 8) 8280 (const_int 8)))) 8281 (clobber (reg:CC FLAGS_REG))] 8282 "" 8283 "and{b}\t{%h2, %h0|%h0, %h2}" 8284 [(set_attr "type" "alu") 8285 (set_attr "length_immediate" "0") 8286 (set_attr "mode" "QI")]) 8287 8288;; Convert wide AND instructions with immediate operand to shorter QImode 8289;; equivalents when possible. 8290;; Don't do the splitting with memory operands, since it introduces risk 8291;; of memory mismatch stalls. We may want to do the splitting for optimizing 8292;; for size, but that can (should?) be handled by generic code instead. 8293(define_split 8294 [(set (match_operand 0 "register_operand") 8295 (and (match_operand 1 "register_operand") 8296 (match_operand 2 "const_int_operand"))) 8297 (clobber (reg:CC FLAGS_REG))] 8298 "reload_completed 8299 && QI_REG_P (operands[0]) 8300 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8301 && !(~INTVAL (operands[2]) & ~(255 << 8)) 8302 && GET_MODE (operands[0]) != QImode" 8303 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8304 (and:SI (zero_extract:SI (match_dup 1) 8305 (const_int 8) (const_int 8)) 8306 (match_dup 2))) 8307 (clobber (reg:CC FLAGS_REG))])] 8308{ 8309 operands[0] = gen_lowpart (SImode, operands[0]); 8310 operands[1] = gen_lowpart (SImode, operands[1]); 8311 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); 8312}) 8313 8314;; Since AND can be encoded with sign extended immediate, this is only 8315;; profitable when 7th bit is not set. 8316(define_split 8317 [(set (match_operand 0 "register_operand") 8318 (and (match_operand 1 "general_operand") 8319 (match_operand 2 "const_int_operand"))) 8320 (clobber (reg:CC FLAGS_REG))] 8321 "reload_completed 8322 && ANY_QI_REG_P (operands[0]) 8323 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8324 && !(~INTVAL (operands[2]) & ~255) 8325 && !(INTVAL (operands[2]) & 128) 8326 && GET_MODE (operands[0]) != QImode" 8327 [(parallel [(set (strict_low_part (match_dup 0)) 8328 (and:QI (match_dup 1) 8329 (match_dup 2))) 8330 (clobber (reg:CC FLAGS_REG))])] 8331{ 8332 operands[0] = gen_lowpart (QImode, operands[0]); 8333 operands[1] = gen_lowpart (QImode, operands[1]); 8334 operands[2] = gen_lowpart (QImode, operands[2]); 8335}) 8336 8337;; Logical inclusive and exclusive OR instructions 8338 8339;; %%% This used to optimize known byte-wide and operations to memory. 8340;; If this is considered useful, it should be done with splitters. 8341 8342(define_expand "<code><mode>3" 8343 [(set (match_operand:SWIM 0 "nonimmediate_operand") 8344 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand") 8345 (match_operand:SWIM 2 "<general_operand>")))] 8346 "" 8347 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 8348 8349(define_insn "*<code><mode>_1" 8350 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k") 8351 (any_or:SWI48 8352 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k") 8353 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k"))) 8354 (clobber (reg:CC FLAGS_REG))] 8355 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 8356 "@ 8357 <logic>{<imodesuffix>}\t{%2, %0|%0, %2} 8358 <logic>{<imodesuffix>}\t{%2, %0|%0, %2} 8359 k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}" 8360 [(set_attr "type" "alu,alu,msklog") 8361 (set_attr "mode" "<MODE>")]) 8362 8363(define_insn "*<code>hi_1" 8364 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k") 8365 (any_or:HI 8366 (match_operand:HI 1 "nonimmediate_operand" "%0,0,k") 8367 (match_operand:HI 2 "general_operand" "<g>,r<i>,k"))) 8368 (clobber (reg:CC FLAGS_REG))] 8369 "ix86_binary_operator_ok (<CODE>, HImode, operands)" 8370 "@ 8371 <logic>{w}\t{%2, %0|%0, %2} 8372 <logic>{w}\t{%2, %0|%0, %2} 8373 k<logic>w\t{%2, %1, %0|%0, %1, %2}" 8374 [(set_attr "type" "alu,alu,msklog") 8375 (set_attr "mode" "HI")]) 8376 8377;; %%% Potential partial reg stall on alternative 2. What to do? 8378(define_insn "*<code>qi_1" 8379 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k") 8380 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k") 8381 (match_operand:QI 2 "general_operand" "qmn,qn,rn,k"))) 8382 (clobber (reg:CC FLAGS_REG))] 8383 "ix86_binary_operator_ok (<CODE>, QImode, operands)" 8384 "@ 8385 <logic>{b}\t{%2, %0|%0, %2} 8386 <logic>{b}\t{%2, %0|%0, %2} 8387 <logic>{l}\t{%k2, %k0|%k0, %k2} 8388 k<logic>w\t{%2, %1, %0|%0, %1, %2}" 8389 [(set_attr "type" "alu,alu,alu,msklog") 8390 (set_attr "mode" "QI,QI,SI,HI")]) 8391 8392;; See comment for addsi_1_zext why we do use nonimmediate_operand 8393(define_insn "*<code>si_1_zext" 8394 [(set (match_operand:DI 0 "register_operand" "=r") 8395 (zero_extend:DI 8396 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8397 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 8398 (clobber (reg:CC FLAGS_REG))] 8399 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8400 "<logic>{l}\t{%2, %k0|%k0, %2}" 8401 [(set_attr "type" "alu") 8402 (set_attr "mode" "SI")]) 8403 8404(define_insn "*<code>si_1_zext_imm" 8405 [(set (match_operand:DI 0 "register_operand" "=r") 8406 (any_or:DI 8407 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 8408 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 8409 (clobber (reg:CC FLAGS_REG))] 8410 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8411 "<logic>{l}\t{%2, %k0|%k0, %2}" 8412 [(set_attr "type" "alu") 8413 (set_attr "mode" "SI")]) 8414 8415(define_insn "*<code>qi_1_slp" 8416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m")) 8417 (any_or:QI (match_dup 0) 8418 (match_operand:QI 1 "general_operand" "qmn,qn"))) 8419 (clobber (reg:CC FLAGS_REG))] 8420 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8422 "<logic>{b}\t{%1, %0|%0, %1}" 8423 [(set_attr "type" "alu1") 8424 (set_attr "mode" "QI")]) 8425 8426(define_insn "*<code><mode>_2" 8427 [(set (reg FLAGS_REG) 8428 (compare (any_or:SWI 8429 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 8430 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>")) 8431 (const_int 0))) 8432 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m") 8433 (any_or:SWI (match_dup 1) (match_dup 2)))] 8434 "ix86_match_ccmode (insn, CCNOmode) 8435 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 8436 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8437 [(set_attr "type" "alu") 8438 (set_attr "mode" "<MODE>")]) 8439 8440(define_insn "kxnor<mode>" 8441 [(set (match_operand:SWI12 0 "register_operand" "=r,!k") 8442 (not:SWI12 8443 (xor:SWI12 8444 (match_operand:SWI12 1 "register_operand" "0,k") 8445 (match_operand:SWI12 2 "register_operand" "r,k")))) 8446 (clobber (reg:CC FLAGS_REG))] 8447 "TARGET_AVX512F" 8448{ 8449 if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ) 8450 return "kxnorb\t{%2, %1, %0|%0, %1, %2}"; 8451 return "kxnorw\t{%2, %1, %0|%0, %1, %2}"; 8452} 8453 [(set_attr "type" "*,msklog") 8454 (set_attr "prefix" "*,vex") 8455 (set_attr "mode" "<MODE>")]) 8456 8457(define_insn "kxnor<mode>" 8458 [(set (match_operand:SWI48x 0 "register_operand" "=r,!k") 8459 (not:SWI48x 8460 (xor:SWI48x 8461 (match_operand:SWI48x 1 "register_operand" "0,k") 8462 (match_operand:SWI48x 2 "register_operand" "r,k")))) 8463 (clobber (reg:CC FLAGS_REG))] 8464 "TARGET_AVX512BW" 8465 "@ 8466 # 8467 kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}" 8468 [(set_attr "type" "*,msklog") 8469 (set_attr "prefix" "*,vex") 8470 (set_attr "mode" "<MODE>")]) 8471 8472(define_split 8473 [(set (match_operand:SWI1248x 0 "general_reg_operand") 8474 (not:SWI1248x 8475 (xor:SWI1248x 8476 (match_dup 0) 8477 (match_operand:SWI1248x 1 "general_reg_operand")))) 8478 (clobber (reg:CC FLAGS_REG))] 8479 "TARGET_AVX512F && reload_completed" 8480 [(parallel [(set (match_dup 0) 8481 (xor:SWI1248x (match_dup 0) 8482 (match_dup 1))) 8483 (clobber (reg:CC FLAGS_REG))]) 8484 (set (match_dup 0) 8485 (not:SWI1248x (match_dup 0)))]) 8486 8487;;There are kortrest[bdq] but no intrinsics for them. 8488;;We probably don't need to implement them. 8489(define_insn "kortestzhi" 8490 [(set (reg:CCZ FLAGS_REG) 8491 (compare:CCZ 8492 (ior:HI 8493 (match_operand:HI 0 "register_operand" "k") 8494 (match_operand:HI 1 "register_operand" "k")) 8495 (const_int 0)))] 8496 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)" 8497 "kortestw\t{%1, %0|%0, %1}" 8498 [(set_attr "mode" "HI") 8499 (set_attr "type" "msklog") 8500 (set_attr "prefix" "vex")]) 8501 8502(define_insn "kortestchi" 8503 [(set (reg:CCC FLAGS_REG) 8504 (compare:CCC 8505 (ior:HI 8506 (match_operand:HI 0 "register_operand" "k") 8507 (match_operand:HI 1 "register_operand" "k")) 8508 (const_int -1)))] 8509 "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)" 8510 "kortestw\t{%1, %0|%0, %1}" 8511 [(set_attr "mode" "HI") 8512 (set_attr "type" "msklog") 8513 (set_attr "prefix" "vex")]) 8514 8515(define_insn "kunpckhi" 8516 [(set (match_operand:HI 0 "register_operand" "=k") 8517 (ior:HI 8518 (ashift:HI 8519 (zero_extend:HI (match_operand:QI 1 "register_operand" "k")) 8520 (const_int 8)) 8521 (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))] 8522 "TARGET_AVX512F" 8523 "kunpckbw\t{%2, %1, %0|%0, %1, %2}" 8524 [(set_attr "mode" "HI") 8525 (set_attr "type" "msklog") 8526 (set_attr "prefix" "vex")]) 8527 8528(define_insn "kunpcksi" 8529 [(set (match_operand:SI 0 "register_operand" "=k") 8530 (ior:SI 8531 (ashift:SI 8532 (zero_extend:SI (match_operand:HI 1 "register_operand" "k")) 8533 (const_int 16)) 8534 (zero_extend:SI (match_operand:HI 2 "register_operand" "k"))))] 8535 "TARGET_AVX512BW" 8536 "kunpckwd\t{%2, %1, %0|%0, %1, %2}" 8537 [(set_attr "mode" "SI")]) 8538 8539(define_insn "kunpckdi" 8540 [(set (match_operand:DI 0 "register_operand" "=k") 8541 (ior:DI 8542 (ashift:DI 8543 (zero_extend:DI (match_operand:SI 1 "register_operand" "k")) 8544 (const_int 32)) 8545 (zero_extend:DI (match_operand:SI 2 "register_operand" "k"))))] 8546 "TARGET_AVX512BW" 8547 "kunpckdq\t{%2, %1, %0|%0, %1, %2}" 8548 [(set_attr "mode" "DI")]) 8549 8550;; See comment for addsi_1_zext why we do use nonimmediate_operand 8551;; ??? Special case for immediate operand is missing - it is tricky. 8552(define_insn "*<code>si_2_zext" 8553 [(set (reg FLAGS_REG) 8554 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 8555 (match_operand:SI 2 "x86_64_general_operand" "rme")) 8556 (const_int 0))) 8557 (set (match_operand:DI 0 "register_operand" "=r") 8558 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] 8559 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8560 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8561 "<logic>{l}\t{%2, %k0|%k0, %2}" 8562 [(set_attr "type" "alu") 8563 (set_attr "mode" "SI")]) 8564 8565(define_insn "*<code>si_2_zext_imm" 8566 [(set (reg FLAGS_REG) 8567 (compare (any_or:SI 8568 (match_operand:SI 1 "nonimmediate_operand" "%0") 8569 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z")) 8570 (const_int 0))) 8571 (set (match_operand:DI 0 "register_operand" "=r") 8572 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 8573 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 8574 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 8575 "<logic>{l}\t{%2, %k0|%k0, %2}" 8576 [(set_attr "type" "alu") 8577 (set_attr "mode" "SI")]) 8578 8579(define_insn "*<code>qi_2_slp" 8580 [(set (reg FLAGS_REG) 8581 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm") 8582 (match_operand:QI 1 "general_operand" "qmn,qn")) 8583 (const_int 0))) 8584 (set (strict_low_part (match_dup 0)) 8585 (any_or:QI (match_dup 0) (match_dup 1)))] 8586 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8587 && ix86_match_ccmode (insn, CCNOmode) 8588 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 8589 "<logic>{b}\t{%1, %0|%0, %1}" 8590 [(set_attr "type" "alu1") 8591 (set_attr "mode" "QI")]) 8592 8593(define_insn "*<code><mode>_3" 8594 [(set (reg FLAGS_REG) 8595 (compare (any_or:SWI 8596 (match_operand:SWI 1 "nonimmediate_operand" "%0") 8597 (match_operand:SWI 2 "<general_operand>" "<g>")) 8598 (const_int 0))) 8599 (clobber (match_scratch:SWI 0 "=<r>"))] 8600 "ix86_match_ccmode (insn, CCNOmode) 8601 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 8602 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 8603 [(set_attr "type" "alu") 8604 (set_attr "mode" "<MODE>")]) 8605 8606(define_insn "*<code>qi_ext_0" 8607 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8608 (const_int 8) 8609 (const_int 8)) 8610 (any_or:SI 8611 (zero_extract:SI 8612 (match_operand 1 "ext_register_operand" "0") 8613 (const_int 8) 8614 (const_int 8)) 8615 (match_operand 2 "const_int_operand" "n"))) 8616 (clobber (reg:CC FLAGS_REG))] 8617 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8618 "<logic>{b}\t{%2, %h0|%h0, %2}" 8619 [(set_attr "type" "alu") 8620 (set_attr "length_immediate" "1") 8621 (set_attr "modrm" "1") 8622 (set_attr "mode" "QI")]) 8623 8624(define_insn "*<code>qi_ext_1" 8625 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") 8626 (const_int 8) 8627 (const_int 8)) 8628 (any_or:SI 8629 (zero_extract:SI 8630 (match_operand 1 "ext_register_operand" "0,0") 8631 (const_int 8) 8632 (const_int 8)) 8633 (zero_extend:SI 8634 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m")))) 8635 (clobber (reg:CC FLAGS_REG))] 8636 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8637 "<logic>{b}\t{%2, %h0|%h0, %2}" 8638 [(set_attr "isa" "*,nox64") 8639 (set_attr "type" "alu") 8640 (set_attr "length_immediate" "0") 8641 (set_attr "mode" "QI")]) 8642 8643(define_insn "*<code>qi_ext_2" 8644 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q") 8645 (const_int 8) 8646 (const_int 8)) 8647 (any_or:SI 8648 (zero_extract:SI (match_operand 1 "ext_register_operand" "0") 8649 (const_int 8) 8650 (const_int 8)) 8651 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 8652 (const_int 8) 8653 (const_int 8)))) 8654 (clobber (reg:CC FLAGS_REG))] 8655 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 8656 "<logic>{b}\t{%h2, %h0|%h0, %h2}" 8657 [(set_attr "type" "alu") 8658 (set_attr "length_immediate" "0") 8659 (set_attr "mode" "QI")]) 8660 8661(define_split 8662 [(set (match_operand 0 "register_operand") 8663 (any_or (match_operand 1 "register_operand") 8664 (match_operand 2 "const_int_operand"))) 8665 (clobber (reg:CC FLAGS_REG))] 8666 "reload_completed 8667 && QI_REG_P (operands[0]) 8668 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8669 && !(INTVAL (operands[2]) & ~(255 << 8)) 8670 && GET_MODE (operands[0]) != QImode" 8671 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8)) 8672 (any_or:SI (zero_extract:SI (match_dup 1) 8673 (const_int 8) (const_int 8)) 8674 (match_dup 2))) 8675 (clobber (reg:CC FLAGS_REG))])] 8676{ 8677 operands[0] = gen_lowpart (SImode, operands[0]); 8678 operands[1] = gen_lowpart (SImode, operands[1]); 8679 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode); 8680}) 8681 8682;; Since OR can be encoded with sign extended immediate, this is only 8683;; profitable when 7th bit is set. 8684(define_split 8685 [(set (match_operand 0 "register_operand") 8686 (any_or (match_operand 1 "general_operand") 8687 (match_operand 2 "const_int_operand"))) 8688 (clobber (reg:CC FLAGS_REG))] 8689 "reload_completed 8690 && ANY_QI_REG_P (operands[0]) 8691 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 8692 && !(INTVAL (operands[2]) & ~255) 8693 && (INTVAL (operands[2]) & 128) 8694 && GET_MODE (operands[0]) != QImode" 8695 [(parallel [(set (strict_low_part (match_dup 0)) 8696 (any_or:QI (match_dup 1) 8697 (match_dup 2))) 8698 (clobber (reg:CC FLAGS_REG))])] 8699{ 8700 operands[0] = gen_lowpart (QImode, operands[0]); 8701 operands[1] = gen_lowpart (QImode, operands[1]); 8702 operands[2] = gen_lowpart (QImode, operands[2]); 8703}) 8704 8705(define_expand "xorqi_cc_ext_1" 8706 [(parallel [ 8707 (set (reg:CCNO FLAGS_REG) 8708 (compare:CCNO 8709 (xor:SI 8710 (zero_extract:SI 8711 (match_operand 1 "ext_register_operand") 8712 (const_int 8) 8713 (const_int 8)) 8714 (match_operand:QI 2 "const_int_operand")) 8715 (const_int 0))) 8716 (set (zero_extract:SI (match_operand 0 "ext_register_operand") 8717 (const_int 8) 8718 (const_int 8)) 8719 (xor:SI 8720 (zero_extract:SI 8721 (match_dup 1) 8722 (const_int 8) 8723 (const_int 8)) 8724 (match_dup 2)))])]) 8725 8726(define_insn "*xorqi_cc_ext_1" 8727 [(set (reg FLAGS_REG) 8728 (compare 8729 (xor:SI 8730 (zero_extract:SI 8731 (match_operand 1 "ext_register_operand" "0,0") 8732 (const_int 8) 8733 (const_int 8)) 8734 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")) 8735 (const_int 0))) 8736 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q") 8737 (const_int 8) 8738 (const_int 8)) 8739 (xor:SI 8740 (zero_extract:SI 8741 (match_dup 1) 8742 (const_int 8) 8743 (const_int 8)) 8744 (match_dup 2)))] 8745 "ix86_match_ccmode (insn, CCNOmode)" 8746 "xor{b}\t{%2, %h0|%h0, %2}" 8747 [(set_attr "isa" "*,nox64") 8748 (set_attr "type" "alu") 8749 (set_attr "modrm" "1") 8750 (set_attr "mode" "QI")]) 8751 8752;; Negation instructions 8753 8754(define_expand "neg<mode>2" 8755 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 8756 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))] 8757 "" 8758 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;") 8759 8760(define_insn_and_split "*neg<dwi>2_doubleword" 8761 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 8762 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0"))) 8763 (clobber (reg:CC FLAGS_REG))] 8764 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)" 8765 "#" 8766 "reload_completed" 8767 [(parallel 8768 [(set (reg:CCZ FLAGS_REG) 8769 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0))) 8770 (set (match_dup 0) (neg:DWIH (match_dup 1)))]) 8771 (parallel 8772 [(set (match_dup 2) 8773 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 8774 (match_dup 3)) 8775 (const_int 0))) 8776 (clobber (reg:CC FLAGS_REG))]) 8777 (parallel 8778 [(set (match_dup 2) 8779 (neg:DWIH (match_dup 2))) 8780 (clobber (reg:CC FLAGS_REG))])] 8781 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);") 8782 8783(define_insn "*neg<mode>2_1" 8784 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8785 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) 8786 (clobber (reg:CC FLAGS_REG))] 8787 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 8788 "neg{<imodesuffix>}\t%0" 8789 [(set_attr "type" "negnot") 8790 (set_attr "mode" "<MODE>")]) 8791 8792;; Combine is quite creative about this pattern. 8793(define_insn "*negsi2_1_zext" 8794 [(set (match_operand:DI 0 "register_operand" "=r") 8795 (lshiftrt:DI 8796 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0") 8797 (const_int 32))) 8798 (const_int 32))) 8799 (clobber (reg:CC FLAGS_REG))] 8800 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 8801 "neg{l}\t%k0" 8802 [(set_attr "type" "negnot") 8803 (set_attr "mode" "SI")]) 8804 8805;; The problem with neg is that it does not perform (compare x 0), 8806;; it really performs (compare 0 x), which leaves us with the zero 8807;; flag being the only useful item. 8808 8809(define_insn "*neg<mode>2_cmpz" 8810 [(set (reg:CCZ FLAGS_REG) 8811 (compare:CCZ 8812 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 8813 (const_int 0))) 8814 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8815 (neg:SWI (match_dup 1)))] 8816 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 8817 "neg{<imodesuffix>}\t%0" 8818 [(set_attr "type" "negnot") 8819 (set_attr "mode" "<MODE>")]) 8820 8821(define_insn "*negsi2_cmpz_zext" 8822 [(set (reg:CCZ FLAGS_REG) 8823 (compare:CCZ 8824 (lshiftrt:DI 8825 (neg:DI (ashift:DI 8826 (match_operand:DI 1 "register_operand" "0") 8827 (const_int 32))) 8828 (const_int 32)) 8829 (const_int 0))) 8830 (set (match_operand:DI 0 "register_operand" "=r") 8831 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1) 8832 (const_int 32))) 8833 (const_int 32)))] 8834 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 8835 "neg{l}\t%k0" 8836 [(set_attr "type" "negnot") 8837 (set_attr "mode" "SI")]) 8838 8839;; Negate with jump on overflow. 8840(define_expand "negv<mode>3" 8841 [(parallel [(set (reg:CCO FLAGS_REG) 8842 (ne:CCO (match_operand:SWI 1 "register_operand") 8843 (match_dup 3))) 8844 (set (match_operand:SWI 0 "register_operand") 8845 (neg:SWI (match_dup 1)))]) 8846 (set (pc) (if_then_else 8847 (eq (reg:CCO FLAGS_REG) (const_int 0)) 8848 (label_ref (match_operand 2)) 8849 (pc)))] 8850 "" 8851{ 8852 operands[3] 8853 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1), 8854 <MODE>mode); 8855}) 8856 8857(define_insn "*negv<mode>3" 8858 [(set (reg:CCO FLAGS_REG) 8859 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") 8860 (match_operand:SWI 2 "const_int_operand"))) 8861 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 8862 (neg:SWI (match_dup 1)))] 8863 "ix86_unary_operator_ok (NEG, <MODE>mode, operands) 8864 && mode_signbit_p (<MODE>mode, operands[2])" 8865 "neg{<imodesuffix>}\t%0" 8866 [(set_attr "type" "negnot") 8867 (set_attr "mode" "<MODE>")]) 8868 8869;; Changing of sign for FP values is doable using integer unit too. 8870 8871(define_expand "<code><mode>2" 8872 [(set (match_operand:X87MODEF 0 "register_operand") 8873 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))] 8874 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 8875 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 8876 8877(define_insn "*absneg<mode>2_mixed" 8878 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r") 8879 (match_operator:MODEF 3 "absneg_operator" 8880 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")])) 8881 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X")) 8882 (clobber (reg:CC FLAGS_REG))] 8883 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)" 8884 "#") 8885 8886(define_insn "*absneg<mode>2_sse" 8887 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r") 8888 (match_operator:MODEF 3 "absneg_operator" 8889 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")])) 8890 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X")) 8891 (clobber (reg:CC FLAGS_REG))] 8892 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 8893 "#") 8894 8895(define_insn "*absneg<mode>2_i387" 8896 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r") 8897 (match_operator:X87MODEF 3 "absneg_operator" 8898 [(match_operand:X87MODEF 1 "register_operand" "0,0")])) 8899 (use (match_operand 2)) 8900 (clobber (reg:CC FLAGS_REG))] 8901 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 8902 "#") 8903 8904(define_expand "<code>tf2" 8905 [(set (match_operand:TF 0 "register_operand") 8906 (absneg:TF (match_operand:TF 1 "register_operand")))] 8907 "TARGET_SSE" 8908 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") 8909 8910(define_insn "*absnegtf2_sse" 8911 [(set (match_operand:TF 0 "register_operand" "=x,x") 8912 (match_operator:TF 3 "absneg_operator" 8913 [(match_operand:TF 1 "register_operand" "0,x")])) 8914 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0")) 8915 (clobber (reg:CC FLAGS_REG))] 8916 "TARGET_SSE" 8917 "#") 8918 8919;; Splitters for fp abs and neg. 8920 8921(define_split 8922 [(set (match_operand 0 "fp_register_operand") 8923 (match_operator 1 "absneg_operator" [(match_dup 0)])) 8924 (use (match_operand 2)) 8925 (clobber (reg:CC FLAGS_REG))] 8926 "reload_completed" 8927 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))]) 8928 8929(define_split 8930 [(set (match_operand 0 "register_operand") 8931 (match_operator 3 "absneg_operator" 8932 [(match_operand 1 "register_operand")])) 8933 (use (match_operand 2 "nonimmediate_operand")) 8934 (clobber (reg:CC FLAGS_REG))] 8935 "reload_completed && SSE_REG_P (operands[0])" 8936 [(set (match_dup 0) (match_dup 3))] 8937{ 8938 machine_mode mode = GET_MODE (operands[0]); 8939 machine_mode vmode = GET_MODE (operands[2]); 8940 rtx tmp; 8941 8942 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0); 8943 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0); 8944 if (operands_match_p (operands[0], operands[2])) 8945 std::swap (operands[1], operands[2]); 8946 if (GET_CODE (operands[3]) == ABS) 8947 tmp = gen_rtx_AND (vmode, operands[1], operands[2]); 8948 else 8949 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]); 8950 operands[3] = tmp; 8951}) 8952 8953(define_split 8954 [(set (match_operand:SF 0 "register_operand") 8955 (match_operator:SF 1 "absneg_operator" [(match_dup 0)])) 8956 (use (match_operand:V4SF 2)) 8957 (clobber (reg:CC FLAGS_REG))] 8958 "reload_completed" 8959 [(parallel [(set (match_dup 0) (match_dup 1)) 8960 (clobber (reg:CC FLAGS_REG))])] 8961{ 8962 rtx tmp; 8963 operands[0] = gen_lowpart (SImode, operands[0]); 8964 if (GET_CODE (operands[1]) == ABS) 8965 { 8966 tmp = gen_int_mode (0x7fffffff, SImode); 8967 tmp = gen_rtx_AND (SImode, operands[0], tmp); 8968 } 8969 else 8970 { 8971 tmp = gen_int_mode (0x80000000, SImode); 8972 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 8973 } 8974 operands[1] = tmp; 8975}) 8976 8977(define_split 8978 [(set (match_operand:DF 0 "register_operand") 8979 (match_operator:DF 1 "absneg_operator" [(match_dup 0)])) 8980 (use (match_operand 2)) 8981 (clobber (reg:CC FLAGS_REG))] 8982 "reload_completed" 8983 [(parallel [(set (match_dup 0) (match_dup 1)) 8984 (clobber (reg:CC FLAGS_REG))])] 8985{ 8986 rtx tmp; 8987 if (TARGET_64BIT) 8988 { 8989 tmp = gen_lowpart (DImode, operands[0]); 8990 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63)); 8991 operands[0] = tmp; 8992 8993 if (GET_CODE (operands[1]) == ABS) 8994 tmp = const0_rtx; 8995 else 8996 tmp = gen_rtx_NOT (DImode, tmp); 8997 } 8998 else 8999 { 9000 operands[0] = gen_highpart (SImode, operands[0]); 9001 if (GET_CODE (operands[1]) == ABS) 9002 { 9003 tmp = gen_int_mode (0x7fffffff, SImode); 9004 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9005 } 9006 else 9007 { 9008 tmp = gen_int_mode (0x80000000, SImode); 9009 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9010 } 9011 } 9012 operands[1] = tmp; 9013}) 9014 9015(define_split 9016 [(set (match_operand:XF 0 "register_operand") 9017 (match_operator:XF 1 "absneg_operator" [(match_dup 0)])) 9018 (use (match_operand 2)) 9019 (clobber (reg:CC FLAGS_REG))] 9020 "reload_completed" 9021 [(parallel [(set (match_dup 0) (match_dup 1)) 9022 (clobber (reg:CC FLAGS_REG))])] 9023{ 9024 rtx tmp; 9025 operands[0] = gen_rtx_REG (SImode, 9026 true_regnum (operands[0]) 9027 + (TARGET_64BIT ? 1 : 2)); 9028 if (GET_CODE (operands[1]) == ABS) 9029 { 9030 tmp = GEN_INT (0x7fff); 9031 tmp = gen_rtx_AND (SImode, operands[0], tmp); 9032 } 9033 else 9034 { 9035 tmp = GEN_INT (0x8000); 9036 tmp = gen_rtx_XOR (SImode, operands[0], tmp); 9037 } 9038 operands[1] = tmp; 9039}) 9040 9041;; Conditionalize these after reload. If they match before reload, we 9042;; lose the clobber and ability to use integer instructions. 9043 9044(define_insn "*<code><mode>2_1" 9045 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 9046 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] 9047 "TARGET_80387 9048 && (reload_completed 9049 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))" 9050 "f<absneg_mnemonic>" 9051 [(set_attr "type" "fsgn") 9052 (set_attr "mode" "<MODE>")]) 9053 9054(define_insn "*<code>extendsfdf2" 9055 [(set (match_operand:DF 0 "register_operand" "=f") 9056 (absneg:DF (float_extend:DF 9057 (match_operand:SF 1 "register_operand" "0"))))] 9058 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)" 9059 "f<absneg_mnemonic>" 9060 [(set_attr "type" "fsgn") 9061 (set_attr "mode" "DF")]) 9062 9063(define_insn "*<code>extendsfxf2" 9064 [(set (match_operand:XF 0 "register_operand" "=f") 9065 (absneg:XF (float_extend:XF 9066 (match_operand:SF 1 "register_operand" "0"))))] 9067 "TARGET_80387" 9068 "f<absneg_mnemonic>" 9069 [(set_attr "type" "fsgn") 9070 (set_attr "mode" "XF")]) 9071 9072(define_insn "*<code>extenddfxf2" 9073 [(set (match_operand:XF 0 "register_operand" "=f") 9074 (absneg:XF (float_extend:XF 9075 (match_operand:DF 1 "register_operand" "0"))))] 9076 "TARGET_80387" 9077 "f<absneg_mnemonic>" 9078 [(set_attr "type" "fsgn") 9079 (set_attr "mode" "XF")]) 9080 9081;; Copysign instructions 9082 9083(define_mode_iterator CSGNMODE [SF DF TF]) 9084(define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")]) 9085 9086(define_expand "copysign<mode>3" 9087 [(match_operand:CSGNMODE 0 "register_operand") 9088 (match_operand:CSGNMODE 1 "nonmemory_operand") 9089 (match_operand:CSGNMODE 2 "register_operand")] 9090 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 9091 || (TARGET_SSE && (<MODE>mode == TFmode))" 9092 "ix86_expand_copysign (operands); DONE;") 9093 9094(define_insn_and_split "copysign<mode>3_const" 9095 [(set (match_operand:CSGNMODE 0 "register_operand" "=x") 9096 (unspec:CSGNMODE 9097 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC") 9098 (match_operand:CSGNMODE 2 "register_operand" "0") 9099 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")] 9100 UNSPEC_COPYSIGN))] 9101 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 9102 || (TARGET_SSE && (<MODE>mode == TFmode))" 9103 "#" 9104 "&& reload_completed" 9105 [(const_int 0)] 9106 "ix86_split_copysign_const (operands); DONE;") 9107 9108(define_insn "copysign<mode>3_var" 9109 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x") 9110 (unspec:CSGNMODE 9111 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x") 9112 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x") 9113 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0") 9114 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")] 9115 UNSPEC_COPYSIGN)) 9116 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))] 9117 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 9118 || (TARGET_SSE && (<MODE>mode == TFmode))" 9119 "#") 9120 9121(define_split 9122 [(set (match_operand:CSGNMODE 0 "register_operand") 9123 (unspec:CSGNMODE 9124 [(match_operand:CSGNMODE 2 "register_operand") 9125 (match_operand:CSGNMODE 3 "register_operand") 9126 (match_operand:<CSGNVMODE> 4) 9127 (match_operand:<CSGNVMODE> 5)] 9128 UNSPEC_COPYSIGN)) 9129 (clobber (match_scratch:<CSGNVMODE> 1))] 9130 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 9131 || (TARGET_SSE && (<MODE>mode == TFmode))) 9132 && reload_completed" 9133 [(const_int 0)] 9134 "ix86_split_copysign_var (operands); DONE;") 9135 9136;; One complement instructions 9137 9138(define_expand "one_cmpl<mode>2" 9139 [(set (match_operand:SWIM 0 "nonimmediate_operand") 9140 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))] 9141 "" 9142 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") 9143 9144(define_insn "*one_cmpl<mode>2_1" 9145 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k") 9146 (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))] 9147 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 9148 "@ 9149 not{<imodesuffix>}\t%0 9150 knot<mskmodesuffix>\t{%1, %0|%0, %1}" 9151 [(set_attr "isa" "*,avx512bw") 9152 (set_attr "type" "negnot,msklog") 9153 (set_attr "prefix" "*,vex") 9154 (set_attr "mode" "<MODE>")]) 9155 9156(define_insn "*one_cmplhi2_1" 9157 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k") 9158 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))] 9159 "ix86_unary_operator_ok (NOT, HImode, operands)" 9160 "@ 9161 not{w}\t%0 9162 knotw\t{%1, %0|%0, %1}" 9163 [(set_attr "isa" "*,avx512f") 9164 (set_attr "type" "negnot,msklog") 9165 (set_attr "prefix" "*,vex") 9166 (set_attr "mode" "HI")]) 9167 9168;; %%% Potential partial reg stall on alternative 1. What to do? 9169(define_insn "*one_cmplqi2_1" 9170 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k") 9171 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))] 9172 "ix86_unary_operator_ok (NOT, QImode, operands)" 9173{ 9174 switch (which_alternative) 9175 { 9176 case 0: 9177 return "not{b}\t%0"; 9178 case 1: 9179 return "not{l}\t%k0"; 9180 case 2: 9181 if (TARGET_AVX512DQ) 9182 return "knotb\t{%1, %0|%0, %1}"; 9183 return "knotw\t{%1, %0|%0, %1}"; 9184 default: 9185 gcc_unreachable (); 9186 } 9187} 9188 [(set_attr "isa" "*,*,avx512f") 9189 (set_attr "type" "negnot,negnot,msklog") 9190 (set_attr "prefix" "*,*,vex") 9191 (set_attr "mode" "QI,SI,QI")]) 9192 9193;; ??? Currently never generated - xor is used instead. 9194(define_insn "*one_cmplsi2_1_zext" 9195 [(set (match_operand:DI 0 "register_operand" "=r") 9196 (zero_extend:DI 9197 (not:SI (match_operand:SI 1 "register_operand" "0"))))] 9198 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 9199 "not{l}\t%k0" 9200 [(set_attr "type" "negnot") 9201 (set_attr "mode" "SI")]) 9202 9203(define_insn "*one_cmpl<mode>2_2" 9204 [(set (reg FLAGS_REG) 9205 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 9206 (const_int 0))) 9207 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9208 (not:SWI (match_dup 1)))] 9209 "ix86_match_ccmode (insn, CCNOmode) 9210 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 9211 "#" 9212 [(set_attr "type" "alu1") 9213 (set_attr "mode" "<MODE>")]) 9214 9215(define_split 9216 [(set (match_operand 0 "flags_reg_operand") 9217 (match_operator 2 "compare_operator" 9218 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand")) 9219 (const_int 0)])) 9220 (set (match_operand:SWI 1 "nonimmediate_operand") 9221 (not:SWI (match_dup 3)))] 9222 "ix86_match_ccmode (insn, CCNOmode)" 9223 [(parallel [(set (match_dup 0) 9224 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1)) 9225 (const_int 0)])) 9226 (set (match_dup 1) 9227 (xor:SWI (match_dup 3) (const_int -1)))])]) 9228 9229;; ??? Currently never generated - xor is used instead. 9230(define_insn "*one_cmplsi2_2_zext" 9231 [(set (reg FLAGS_REG) 9232 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 9233 (const_int 0))) 9234 (set (match_operand:DI 0 "register_operand" "=r") 9235 (zero_extend:DI (not:SI (match_dup 1))))] 9236 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9237 && ix86_unary_operator_ok (NOT, SImode, operands)" 9238 "#" 9239 [(set_attr "type" "alu1") 9240 (set_attr "mode" "SI")]) 9241 9242(define_split 9243 [(set (match_operand 0 "flags_reg_operand") 9244 (match_operator 2 "compare_operator" 9245 [(not:SI (match_operand:SI 3 "register_operand")) 9246 (const_int 0)])) 9247 (set (match_operand:DI 1 "register_operand") 9248 (zero_extend:DI (not:SI (match_dup 3))))] 9249 "ix86_match_ccmode (insn, CCNOmode)" 9250 [(parallel [(set (match_dup 0) 9251 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 9252 (const_int 0)])) 9253 (set (match_dup 1) 9254 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]) 9255 9256;; Shift instructions 9257 9258;; DImode shifts are implemented using the i386 "shift double" opcode, 9259;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 9260;; is variable, then the count is in %cl and the "imm" operand is dropped 9261;; from the assembler input. 9262;; 9263;; This instruction shifts the target reg/mem as usual, but instead of 9264;; shifting in zeros, bits are shifted in from reg operand. If the insn 9265;; is a left shift double, bits are taken from the high order bits of 9266;; reg, else if the insn is a shift right double, bits are taken from the 9267;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 9268;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 9269;; 9270;; Since sh[lr]d does not change the `reg' operand, that is done 9271;; separately, making all shifts emit pairs of shift double and normal 9272;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 9273;; support a 63 bit shift, each shift where the count is in a reg expands 9274;; to a pair of shifts, a branch, a shift by 32 and a label. 9275;; 9276;; If the shift count is a constant, we need never emit more than one 9277;; shift pair, instead using moves and sign extension for counts greater 9278;; than 31. 9279 9280(define_expand "ashl<mode>3" 9281 [(set (match_operand:SDWIM 0 "<shift_operand>") 9282 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>") 9283 (match_operand:QI 2 "nonmemory_operand")))] 9284 "" 9285 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") 9286 9287(define_insn "*ashl<mode>3_doubleword" 9288 [(set (match_operand:DWI 0 "register_operand" "=&r,r") 9289 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0") 9290 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c"))) 9291 (clobber (reg:CC FLAGS_REG))] 9292 "" 9293 "#" 9294 [(set_attr "type" "multi")]) 9295 9296(define_split 9297 [(set (match_operand:DWI 0 "register_operand") 9298 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand") 9299 (match_operand:QI 2 "nonmemory_operand"))) 9300 (clobber (reg:CC FLAGS_REG))] 9301 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 9302 [(const_int 0)] 9303 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;") 9304 9305;; By default we don't ask for a scratch register, because when DWImode 9306;; values are manipulated, registers are already at a premium. But if 9307;; we have one handy, we won't turn it away. 9308 9309(define_peephole2 9310 [(match_scratch:DWIH 3 "r") 9311 (parallel [(set (match_operand:<DWI> 0 "register_operand") 9312 (ashift:<DWI> 9313 (match_operand:<DWI> 1 "nonmemory_operand") 9314 (match_operand:QI 2 "nonmemory_operand"))) 9315 (clobber (reg:CC FLAGS_REG))]) 9316 (match_dup 3)] 9317 "TARGET_CMOVE" 9318 [(const_int 0)] 9319 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;") 9320 9321(define_insn "x86_64_shld" 9322 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 9323 (ior:DI (ashift:DI (match_dup 0) 9324 (match_operand:QI 2 "nonmemory_operand" "Jc")) 9325 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 9326 (minus:QI (const_int 64) (match_dup 2))))) 9327 (clobber (reg:CC FLAGS_REG))] 9328 "TARGET_64BIT" 9329 "shld{q}\t{%s2%1, %0|%0, %1, %2}" 9330 [(set_attr "type" "ishift") 9331 (set_attr "prefix_0f" "1") 9332 (set_attr "mode" "DI") 9333 (set_attr "athlon_decode" "vector") 9334 (set_attr "amdfam10_decode" "vector") 9335 (set_attr "bdver1_decode" "vector")]) 9336 9337(define_insn "x86_shld" 9338 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 9339 (ior:SI (ashift:SI (match_dup 0) 9340 (match_operand:QI 2 "nonmemory_operand" "Ic")) 9341 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 9342 (minus:QI (const_int 32) (match_dup 2))))) 9343 (clobber (reg:CC FLAGS_REG))] 9344 "" 9345 "shld{l}\t{%s2%1, %0|%0, %1, %2}" 9346 [(set_attr "type" "ishift") 9347 (set_attr "prefix_0f" "1") 9348 (set_attr "mode" "SI") 9349 (set_attr "pent_pair" "np") 9350 (set_attr "athlon_decode" "vector") 9351 (set_attr "amdfam10_decode" "vector") 9352 (set_attr "bdver1_decode" "vector")]) 9353 9354(define_expand "x86_shift<mode>_adj_1" 9355 [(set (reg:CCZ FLAGS_REG) 9356 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand") 9357 (match_dup 4)) 9358 (const_int 0))) 9359 (set (match_operand:SWI48 0 "register_operand") 9360 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 9361 (match_operand:SWI48 1 "register_operand") 9362 (match_dup 0))) 9363 (set (match_dup 1) 9364 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 9365 (match_operand:SWI48 3 "register_operand") 9366 (match_dup 1)))] 9367 "TARGET_CMOVE" 9368 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 9369 9370(define_expand "x86_shift<mode>_adj_2" 9371 [(use (match_operand:SWI48 0 "register_operand")) 9372 (use (match_operand:SWI48 1 "register_operand")) 9373 (use (match_operand:QI 2 "register_operand"))] 9374 "" 9375{ 9376 rtx_code_label *label = gen_label_rtx (); 9377 rtx tmp; 9378 9379 emit_insn (gen_testqi_ccz_1 (operands[2], 9380 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 9381 9382 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 9383 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 9384 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 9385 gen_rtx_LABEL_REF (VOIDmode, label), 9386 pc_rtx); 9387 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 9388 JUMP_LABEL (tmp) = label; 9389 9390 emit_move_insn (operands[0], operands[1]); 9391 ix86_expand_clear (operands[1]); 9392 9393 emit_label (label); 9394 LABEL_NUSES (label) = 1; 9395 9396 DONE; 9397}) 9398 9399;; Avoid useless masking of count operand. 9400(define_insn "*ashl<mode>3_mask" 9401 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 9402 (ashift:SWI48 9403 (match_operand:SWI48 1 "nonimmediate_operand" "0") 9404 (subreg:QI 9405 (and:SI 9406 (match_operand:SI 2 "register_operand" "c") 9407 (match_operand:SI 3 "const_int_operand" "n")) 0))) 9408 (clobber (reg:CC FLAGS_REG))] 9409 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 9410 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 9411 == GET_MODE_BITSIZE (<MODE>mode)-1" 9412{ 9413 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 9414} 9415 [(set_attr "type" "ishift") 9416 (set_attr "mode" "<MODE>")]) 9417 9418(define_insn "*bmi2_ashl<mode>3_1" 9419 [(set (match_operand:SWI48 0 "register_operand" "=r") 9420 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 9421 (match_operand:SWI48 2 "register_operand" "r")))] 9422 "TARGET_BMI2" 9423 "shlx\t{%2, %1, %0|%0, %1, %2}" 9424 [(set_attr "type" "ishiftx") 9425 (set_attr "mode" "<MODE>")]) 9426 9427(define_insn "*ashl<mode>3_1" 9428 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") 9429 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm") 9430 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r"))) 9431 (clobber (reg:CC FLAGS_REG))] 9432 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 9433{ 9434 switch (get_attr_type (insn)) 9435 { 9436 case TYPE_LEA: 9437 case TYPE_ISHIFTX: 9438 return "#"; 9439 9440 case TYPE_ALU: 9441 gcc_assert (operands[2] == const1_rtx); 9442 gcc_assert (rtx_equal_p (operands[0], operands[1])); 9443 return "add{<imodesuffix>}\t%0, %0"; 9444 9445 default: 9446 if (operands[2] == const1_rtx 9447 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9448 return "sal{<imodesuffix>}\t%0"; 9449 else 9450 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9451 } 9452} 9453 [(set_attr "isa" "*,*,bmi2") 9454 (set (attr "type") 9455 (cond [(eq_attr "alternative" "1") 9456 (const_string "lea") 9457 (eq_attr "alternative" "2") 9458 (const_string "ishiftx") 9459 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9460 (match_operand 0 "register_operand")) 9461 (match_operand 2 "const1_operand")) 9462 (const_string "alu") 9463 ] 9464 (const_string "ishift"))) 9465 (set (attr "length_immediate") 9466 (if_then_else 9467 (ior (eq_attr "type" "alu") 9468 (and (eq_attr "type" "ishift") 9469 (and (match_operand 2 "const1_operand") 9470 (ior (match_test "TARGET_SHIFT1") 9471 (match_test "optimize_function_for_size_p (cfun)"))))) 9472 (const_string "0") 9473 (const_string "*"))) 9474 (set_attr "mode" "<MODE>")]) 9475 9476;; Convert shift to the shiftx pattern to avoid flags dependency. 9477(define_split 9478 [(set (match_operand:SWI48 0 "register_operand") 9479 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 9480 (match_operand:QI 2 "register_operand"))) 9481 (clobber (reg:CC FLAGS_REG))] 9482 "TARGET_BMI2 && reload_completed" 9483 [(set (match_dup 0) 9484 (ashift:SWI48 (match_dup 1) (match_dup 2)))] 9485 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 9486 9487(define_insn "*bmi2_ashlsi3_1_zext" 9488 [(set (match_operand:DI 0 "register_operand" "=r") 9489 (zero_extend:DI 9490 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 9491 (match_operand:SI 2 "register_operand" "r"))))] 9492 "TARGET_64BIT && TARGET_BMI2" 9493 "shlx\t{%2, %1, %k0|%k0, %1, %2}" 9494 [(set_attr "type" "ishiftx") 9495 (set_attr "mode" "SI")]) 9496 9497(define_insn "*ashlsi3_1_zext" 9498 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 9499 (zero_extend:DI 9500 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm") 9501 (match_operand:QI 2 "nonmemory_operand" "cI,M,r")))) 9502 (clobber (reg:CC FLAGS_REG))] 9503 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 9504{ 9505 switch (get_attr_type (insn)) 9506 { 9507 case TYPE_LEA: 9508 case TYPE_ISHIFTX: 9509 return "#"; 9510 9511 case TYPE_ALU: 9512 gcc_assert (operands[2] == const1_rtx); 9513 return "add{l}\t%k0, %k0"; 9514 9515 default: 9516 if (operands[2] == const1_rtx 9517 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9518 return "sal{l}\t%k0"; 9519 else 9520 return "sal{l}\t{%2, %k0|%k0, %2}"; 9521 } 9522} 9523 [(set_attr "isa" "*,*,bmi2") 9524 (set (attr "type") 9525 (cond [(eq_attr "alternative" "1") 9526 (const_string "lea") 9527 (eq_attr "alternative" "2") 9528 (const_string "ishiftx") 9529 (and (match_test "TARGET_DOUBLE_WITH_ADD") 9530 (match_operand 2 "const1_operand")) 9531 (const_string "alu") 9532 ] 9533 (const_string "ishift"))) 9534 (set (attr "length_immediate") 9535 (if_then_else 9536 (ior (eq_attr "type" "alu") 9537 (and (eq_attr "type" "ishift") 9538 (and (match_operand 2 "const1_operand") 9539 (ior (match_test "TARGET_SHIFT1") 9540 (match_test "optimize_function_for_size_p (cfun)"))))) 9541 (const_string "0") 9542 (const_string "*"))) 9543 (set_attr "mode" "SI")]) 9544 9545;; Convert shift to the shiftx pattern to avoid flags dependency. 9546(define_split 9547 [(set (match_operand:DI 0 "register_operand") 9548 (zero_extend:DI 9549 (ashift:SI (match_operand:SI 1 "nonimmediate_operand") 9550 (match_operand:QI 2 "register_operand")))) 9551 (clobber (reg:CC FLAGS_REG))] 9552 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 9553 [(set (match_dup 0) 9554 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 9555 "operands[2] = gen_lowpart (SImode, operands[2]);") 9556 9557(define_insn "*ashlhi3_1" 9558 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") 9559 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 9560 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 9561 (clobber (reg:CC FLAGS_REG))] 9562 "ix86_binary_operator_ok (ASHIFT, HImode, operands)" 9563{ 9564 switch (get_attr_type (insn)) 9565 { 9566 case TYPE_LEA: 9567 return "#"; 9568 9569 case TYPE_ALU: 9570 gcc_assert (operands[2] == const1_rtx); 9571 return "add{w}\t%0, %0"; 9572 9573 default: 9574 if (operands[2] == const1_rtx 9575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9576 return "sal{w}\t%0"; 9577 else 9578 return "sal{w}\t{%2, %0|%0, %2}"; 9579 } 9580} 9581 [(set (attr "type") 9582 (cond [(eq_attr "alternative" "1") 9583 (const_string "lea") 9584 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9585 (match_operand 0 "register_operand")) 9586 (match_operand 2 "const1_operand")) 9587 (const_string "alu") 9588 ] 9589 (const_string "ishift"))) 9590 (set (attr "length_immediate") 9591 (if_then_else 9592 (ior (eq_attr "type" "alu") 9593 (and (eq_attr "type" "ishift") 9594 (and (match_operand 2 "const1_operand") 9595 (ior (match_test "TARGET_SHIFT1") 9596 (match_test "optimize_function_for_size_p (cfun)"))))) 9597 (const_string "0") 9598 (const_string "*"))) 9599 (set_attr "mode" "HI,SI")]) 9600 9601;; %%% Potential partial reg stall on alternative 1. What to do? 9602(define_insn "*ashlqi3_1" 9603 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") 9604 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 9605 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 9606 (clobber (reg:CC FLAGS_REG))] 9607 "ix86_binary_operator_ok (ASHIFT, QImode, operands)" 9608{ 9609 switch (get_attr_type (insn)) 9610 { 9611 case TYPE_LEA: 9612 return "#"; 9613 9614 case TYPE_ALU: 9615 gcc_assert (operands[2] == const1_rtx); 9616 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1])) 9617 return "add{l}\t%k0, %k0"; 9618 else 9619 return "add{b}\t%0, %0"; 9620 9621 default: 9622 if (operands[2] == const1_rtx 9623 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9624 { 9625 if (get_attr_mode (insn) == MODE_SI) 9626 return "sal{l}\t%k0"; 9627 else 9628 return "sal{b}\t%0"; 9629 } 9630 else 9631 { 9632 if (get_attr_mode (insn) == MODE_SI) 9633 return "sal{l}\t{%2, %k0|%k0, %2}"; 9634 else 9635 return "sal{b}\t{%2, %0|%0, %2}"; 9636 } 9637 } 9638} 9639 [(set (attr "type") 9640 (cond [(eq_attr "alternative" "2") 9641 (const_string "lea") 9642 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9643 (match_operand 0 "register_operand")) 9644 (match_operand 2 "const1_operand")) 9645 (const_string "alu") 9646 ] 9647 (const_string "ishift"))) 9648 (set (attr "length_immediate") 9649 (if_then_else 9650 (ior (eq_attr "type" "alu") 9651 (and (eq_attr "type" "ishift") 9652 (and (match_operand 2 "const1_operand") 9653 (ior (match_test "TARGET_SHIFT1") 9654 (match_test "optimize_function_for_size_p (cfun)"))))) 9655 (const_string "0") 9656 (const_string "*"))) 9657 (set_attr "mode" "QI,SI,SI")]) 9658 9659(define_insn "*ashlqi3_1_slp" 9660 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 9661 (ashift:QI (match_dup 0) 9662 (match_operand:QI 1 "nonmemory_operand" "cI"))) 9663 (clobber (reg:CC FLAGS_REG))] 9664 "(optimize_function_for_size_p (cfun) 9665 || !TARGET_PARTIAL_FLAG_REG_STALL 9666 || (operands[1] == const1_rtx 9667 && (TARGET_SHIFT1 9668 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))" 9669{ 9670 switch (get_attr_type (insn)) 9671 { 9672 case TYPE_ALU: 9673 gcc_assert (operands[1] == const1_rtx); 9674 return "add{b}\t%0, %0"; 9675 9676 default: 9677 if (operands[1] == const1_rtx 9678 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9679 return "sal{b}\t%0"; 9680 else 9681 return "sal{b}\t{%1, %0|%0, %1}"; 9682 } 9683} 9684 [(set (attr "type") 9685 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9686 (match_operand 0 "register_operand")) 9687 (match_operand 1 "const1_operand")) 9688 (const_string "alu") 9689 ] 9690 (const_string "ishift1"))) 9691 (set (attr "length_immediate") 9692 (if_then_else 9693 (ior (eq_attr "type" "alu") 9694 (and (eq_attr "type" "ishift1") 9695 (and (match_operand 1 "const1_operand") 9696 (ior (match_test "TARGET_SHIFT1") 9697 (match_test "optimize_function_for_size_p (cfun)"))))) 9698 (const_string "0") 9699 (const_string "*"))) 9700 (set_attr "mode" "QI")]) 9701 9702;; Convert ashift to the lea pattern to avoid flags dependency. 9703(define_split 9704 [(set (match_operand 0 "register_operand") 9705 (ashift (match_operand 1 "index_register_operand") 9706 (match_operand:QI 2 "const_int_operand"))) 9707 (clobber (reg:CC FLAGS_REG))] 9708 "GET_MODE (operands[0]) == GET_MODE (operands[1]) 9709 && reload_completed 9710 && true_regnum (operands[0]) != true_regnum (operands[1])" 9711 [(const_int 0)] 9712{ 9713 machine_mode mode = GET_MODE (operands[0]); 9714 rtx pat; 9715 9716 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode)) 9717 { 9718 mode = SImode; 9719 operands[0] = gen_lowpart (mode, operands[0]); 9720 operands[1] = gen_lowpart (mode, operands[1]); 9721 } 9722 9723 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode); 9724 9725 pat = gen_rtx_MULT (mode, operands[1], operands[2]); 9726 9727 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat)); 9728 DONE; 9729}) 9730 9731;; Convert ashift to the lea pattern to avoid flags dependency. 9732(define_split 9733 [(set (match_operand:DI 0 "register_operand") 9734 (zero_extend:DI 9735 (ashift:SI (match_operand:SI 1 "index_register_operand") 9736 (match_operand:QI 2 "const_int_operand")))) 9737 (clobber (reg:CC FLAGS_REG))] 9738 "TARGET_64BIT && reload_completed 9739 && true_regnum (operands[0]) != true_regnum (operands[1])" 9740 [(set (match_dup 0) 9741 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))] 9742{ 9743 operands[1] = gen_lowpart (SImode, operands[1]); 9744 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode); 9745}) 9746 9747;; This pattern can't accept a variable shift count, since shifts by 9748;; zero don't affect the flags. We assume that shifts by constant 9749;; zero are optimized away. 9750(define_insn "*ashl<mode>3_cmp" 9751 [(set (reg FLAGS_REG) 9752 (compare 9753 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") 9754 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9755 (const_int 0))) 9756 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9757 (ashift:SWI (match_dup 1) (match_dup 2)))] 9758 "(optimize_function_for_size_p (cfun) 9759 || !TARGET_PARTIAL_FLAG_REG_STALL 9760 || (operands[2] == const1_rtx 9761 && (TARGET_SHIFT1 9762 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) 9763 && ix86_match_ccmode (insn, CCGOCmode) 9764 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 9765{ 9766 switch (get_attr_type (insn)) 9767 { 9768 case TYPE_ALU: 9769 gcc_assert (operands[2] == const1_rtx); 9770 return "add{<imodesuffix>}\t%0, %0"; 9771 9772 default: 9773 if (operands[2] == const1_rtx 9774 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9775 return "sal{<imodesuffix>}\t%0"; 9776 else 9777 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9778 } 9779} 9780 [(set (attr "type") 9781 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9782 (match_operand 0 "register_operand")) 9783 (match_operand 2 "const1_operand")) 9784 (const_string "alu") 9785 ] 9786 (const_string "ishift"))) 9787 (set (attr "length_immediate") 9788 (if_then_else 9789 (ior (eq_attr "type" "alu") 9790 (and (eq_attr "type" "ishift") 9791 (and (match_operand 2 "const1_operand") 9792 (ior (match_test "TARGET_SHIFT1") 9793 (match_test "optimize_function_for_size_p (cfun)"))))) 9794 (const_string "0") 9795 (const_string "*"))) 9796 (set_attr "mode" "<MODE>")]) 9797 9798(define_insn "*ashlsi3_cmp_zext" 9799 [(set (reg FLAGS_REG) 9800 (compare 9801 (ashift:SI (match_operand:SI 1 "register_operand" "0") 9802 (match_operand:QI 2 "const_1_to_31_operand" "I")) 9803 (const_int 0))) 9804 (set (match_operand:DI 0 "register_operand" "=r") 9805 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 9806 "TARGET_64BIT 9807 && (optimize_function_for_size_p (cfun) 9808 || !TARGET_PARTIAL_FLAG_REG_STALL 9809 || (operands[2] == const1_rtx 9810 && (TARGET_SHIFT1 9811 || TARGET_DOUBLE_WITH_ADD))) 9812 && ix86_match_ccmode (insn, CCGOCmode) 9813 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 9814{ 9815 switch (get_attr_type (insn)) 9816 { 9817 case TYPE_ALU: 9818 gcc_assert (operands[2] == const1_rtx); 9819 return "add{l}\t%k0, %k0"; 9820 9821 default: 9822 if (operands[2] == const1_rtx 9823 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9824 return "sal{l}\t%k0"; 9825 else 9826 return "sal{l}\t{%2, %k0|%k0, %2}"; 9827 } 9828} 9829 [(set (attr "type") 9830 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 9831 (match_operand 2 "const1_operand")) 9832 (const_string "alu") 9833 ] 9834 (const_string "ishift"))) 9835 (set (attr "length_immediate") 9836 (if_then_else 9837 (ior (eq_attr "type" "alu") 9838 (and (eq_attr "type" "ishift") 9839 (and (match_operand 2 "const1_operand") 9840 (ior (match_test "TARGET_SHIFT1") 9841 (match_test "optimize_function_for_size_p (cfun)"))))) 9842 (const_string "0") 9843 (const_string "*"))) 9844 (set_attr "mode" "SI")]) 9845 9846(define_insn "*ashl<mode>3_cconly" 9847 [(set (reg FLAGS_REG) 9848 (compare 9849 (ashift:SWI (match_operand:SWI 1 "register_operand" "0") 9850 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 9851 (const_int 0))) 9852 (clobber (match_scratch:SWI 0 "=<r>"))] 9853 "(optimize_function_for_size_p (cfun) 9854 || !TARGET_PARTIAL_FLAG_REG_STALL 9855 || (operands[2] == const1_rtx 9856 && (TARGET_SHIFT1 9857 || TARGET_DOUBLE_WITH_ADD))) 9858 && ix86_match_ccmode (insn, CCGOCmode)" 9859{ 9860 switch (get_attr_type (insn)) 9861 { 9862 case TYPE_ALU: 9863 gcc_assert (operands[2] == const1_rtx); 9864 return "add{<imodesuffix>}\t%0, %0"; 9865 9866 default: 9867 if (operands[2] == const1_rtx 9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 9869 return "sal{<imodesuffix>}\t%0"; 9870 else 9871 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 9872 } 9873} 9874 [(set (attr "type") 9875 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 9876 (match_operand 0 "register_operand")) 9877 (match_operand 2 "const1_operand")) 9878 (const_string "alu") 9879 ] 9880 (const_string "ishift"))) 9881 (set (attr "length_immediate") 9882 (if_then_else 9883 (ior (eq_attr "type" "alu") 9884 (and (eq_attr "type" "ishift") 9885 (and (match_operand 2 "const1_operand") 9886 (ior (match_test "TARGET_SHIFT1") 9887 (match_test "optimize_function_for_size_p (cfun)"))))) 9888 (const_string "0") 9889 (const_string "*"))) 9890 (set_attr "mode" "<MODE>")]) 9891 9892;; See comment above `ashl<mode>3' about how this works. 9893 9894(define_expand "<shift_insn><mode>3" 9895 [(set (match_operand:SDWIM 0 "<shift_operand>") 9896 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>") 9897 (match_operand:QI 2 "nonmemory_operand")))] 9898 "" 9899 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 9900 9901;; Avoid useless masking of count operand. 9902(define_insn "*<shift_insn><mode>3_mask" 9903 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 9904 (any_shiftrt:SWI48 9905 (match_operand:SWI48 1 "nonimmediate_operand" "0") 9906 (subreg:QI 9907 (and:SI 9908 (match_operand:SI 2 "register_operand" "c") 9909 (match_operand:SI 3 "const_int_operand" "n")) 0))) 9910 (clobber (reg:CC FLAGS_REG))] 9911 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 9912 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 9913 == GET_MODE_BITSIZE (<MODE>mode)-1" 9914{ 9915 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 9916} 9917 [(set_attr "type" "ishift") 9918 (set_attr "mode" "<MODE>")]) 9919 9920(define_insn_and_split "*<shift_insn><mode>3_doubleword" 9921 [(set (match_operand:DWI 0 "register_operand" "=r") 9922 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") 9923 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 9924 (clobber (reg:CC FLAGS_REG))] 9925 "" 9926 "#" 9927 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed" 9928 [(const_int 0)] 9929 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;" 9930 [(set_attr "type" "multi")]) 9931 9932;; By default we don't ask for a scratch register, because when DWImode 9933;; values are manipulated, registers are already at a premium. But if 9934;; we have one handy, we won't turn it away. 9935 9936(define_peephole2 9937 [(match_scratch:DWIH 3 "r") 9938 (parallel [(set (match_operand:<DWI> 0 "register_operand") 9939 (any_shiftrt:<DWI> 9940 (match_operand:<DWI> 1 "register_operand") 9941 (match_operand:QI 2 "nonmemory_operand"))) 9942 (clobber (reg:CC FLAGS_REG))]) 9943 (match_dup 3)] 9944 "TARGET_CMOVE" 9945 [(const_int 0)] 9946 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;") 9947 9948(define_insn "x86_64_shrd" 9949 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 9950 (ior:DI (lshiftrt:DI (match_dup 0) 9951 (match_operand:QI 2 "nonmemory_operand" "Jc")) 9952 (ashift:DI (match_operand:DI 1 "register_operand" "r") 9953 (minus:QI (const_int 64) (match_dup 2))))) 9954 (clobber (reg:CC FLAGS_REG))] 9955 "TARGET_64BIT" 9956 "shrd{q}\t{%s2%1, %0|%0, %1, %2}" 9957 [(set_attr "type" "ishift") 9958 (set_attr "prefix_0f" "1") 9959 (set_attr "mode" "DI") 9960 (set_attr "athlon_decode" "vector") 9961 (set_attr "amdfam10_decode" "vector") 9962 (set_attr "bdver1_decode" "vector")]) 9963 9964(define_insn "x86_shrd" 9965 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 9966 (ior:SI (lshiftrt:SI (match_dup 0) 9967 (match_operand:QI 2 "nonmemory_operand" "Ic")) 9968 (ashift:SI (match_operand:SI 1 "register_operand" "r") 9969 (minus:QI (const_int 32) (match_dup 2))))) 9970 (clobber (reg:CC FLAGS_REG))] 9971 "" 9972 "shrd{l}\t{%s2%1, %0|%0, %1, %2}" 9973 [(set_attr "type" "ishift") 9974 (set_attr "prefix_0f" "1") 9975 (set_attr "mode" "SI") 9976 (set_attr "pent_pair" "np") 9977 (set_attr "athlon_decode" "vector") 9978 (set_attr "amdfam10_decode" "vector") 9979 (set_attr "bdver1_decode" "vector")]) 9980 9981(define_insn "ashrdi3_cvt" 9982 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm") 9983 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0") 9984 (match_operand:QI 2 "const_int_operand"))) 9985 (clobber (reg:CC FLAGS_REG))] 9986 "TARGET_64BIT && INTVAL (operands[2]) == 63 9987 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 9988 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)" 9989 "@ 9990 {cqto|cqo} 9991 sar{q}\t{%2, %0|%0, %2}" 9992 [(set_attr "type" "imovx,ishift") 9993 (set_attr "prefix_0f" "0,*") 9994 (set_attr "length_immediate" "0,*") 9995 (set_attr "modrm" "0,1") 9996 (set_attr "mode" "DI")]) 9997 9998(define_insn "ashrsi3_cvt" 9999 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm") 10000 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0") 10001 (match_operand:QI 2 "const_int_operand"))) 10002 (clobber (reg:CC FLAGS_REG))] 10003 "INTVAL (operands[2]) == 31 10004 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 10005 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 10006 "@ 10007 {cltd|cdq} 10008 sar{l}\t{%2, %0|%0, %2}" 10009 [(set_attr "type" "imovx,ishift") 10010 (set_attr "prefix_0f" "0,*") 10011 (set_attr "length_immediate" "0,*") 10012 (set_attr "modrm" "0,1") 10013 (set_attr "mode" "SI")]) 10014 10015(define_insn "*ashrsi3_cvt_zext" 10016 [(set (match_operand:DI 0 "register_operand" "=*d,r") 10017 (zero_extend:DI 10018 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 10019 (match_operand:QI 2 "const_int_operand")))) 10020 (clobber (reg:CC FLAGS_REG))] 10021 "TARGET_64BIT && INTVAL (operands[2]) == 31 10022 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 10023 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 10024 "@ 10025 {cltd|cdq} 10026 sar{l}\t{%2, %k0|%k0, %2}" 10027 [(set_attr "type" "imovx,ishift") 10028 (set_attr "prefix_0f" "0,*") 10029 (set_attr "length_immediate" "0,*") 10030 (set_attr "modrm" "0,1") 10031 (set_attr "mode" "SI")]) 10032 10033(define_expand "x86_shift<mode>_adj_3" 10034 [(use (match_operand:SWI48 0 "register_operand")) 10035 (use (match_operand:SWI48 1 "register_operand")) 10036 (use (match_operand:QI 2 "register_operand"))] 10037 "" 10038{ 10039 rtx_code_label *label = gen_label_rtx (); 10040 rtx tmp; 10041 10042 emit_insn (gen_testqi_ccz_1 (operands[2], 10043 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 10044 10045 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10046 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10047 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10048 gen_rtx_LABEL_REF (VOIDmode, label), 10049 pc_rtx); 10050 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp)); 10051 JUMP_LABEL (tmp) = label; 10052 10053 emit_move_insn (operands[0], operands[1]); 10054 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1], 10055 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1))); 10056 emit_label (label); 10057 LABEL_NUSES (label) = 1; 10058 10059 DONE; 10060}) 10061 10062(define_insn "*bmi2_<shift_insn><mode>3_1" 10063 [(set (match_operand:SWI48 0 "register_operand" "=r") 10064 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10065 (match_operand:SWI48 2 "register_operand" "r")))] 10066 "TARGET_BMI2" 10067 "<shift>x\t{%2, %1, %0|%0, %1, %2}" 10068 [(set_attr "type" "ishiftx") 10069 (set_attr "mode" "<MODE>")]) 10070 10071(define_insn "*<shift_insn><mode>3_1" 10072 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 10073 (any_shiftrt:SWI48 10074 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 10075 (match_operand:QI 2 "nonmemory_operand" "c<S>,r"))) 10076 (clobber (reg:CC FLAGS_REG))] 10077 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10078{ 10079 switch (get_attr_type (insn)) 10080 { 10081 case TYPE_ISHIFTX: 10082 return "#"; 10083 10084 default: 10085 if (operands[2] == const1_rtx 10086 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10087 return "<shift>{<imodesuffix>}\t%0"; 10088 else 10089 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10090 } 10091} 10092 [(set_attr "isa" "*,bmi2") 10093 (set_attr "type" "ishift,ishiftx") 10094 (set (attr "length_immediate") 10095 (if_then_else 10096 (and (match_operand 2 "const1_operand") 10097 (ior (match_test "TARGET_SHIFT1") 10098 (match_test "optimize_function_for_size_p (cfun)"))) 10099 (const_string "0") 10100 (const_string "*"))) 10101 (set_attr "mode" "<MODE>")]) 10102 10103;; Convert shift to the shiftx pattern to avoid flags dependency. 10104(define_split 10105 [(set (match_operand:SWI48 0 "register_operand") 10106 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 10107 (match_operand:QI 2 "register_operand"))) 10108 (clobber (reg:CC FLAGS_REG))] 10109 "TARGET_BMI2 && reload_completed" 10110 [(set (match_dup 0) 10111 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))] 10112 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 10113 10114(define_insn "*bmi2_<shift_insn>si3_1_zext" 10115 [(set (match_operand:DI 0 "register_operand" "=r") 10116 (zero_extend:DI 10117 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10118 (match_operand:SI 2 "register_operand" "r"))))] 10119 "TARGET_64BIT && TARGET_BMI2" 10120 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}" 10121 [(set_attr "type" "ishiftx") 10122 (set_attr "mode" "SI")]) 10123 10124(define_insn "*<shift_insn>si3_1_zext" 10125 [(set (match_operand:DI 0 "register_operand" "=r,r") 10126 (zero_extend:DI 10127 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 10128 (match_operand:QI 2 "nonmemory_operand" "cI,r")))) 10129 (clobber (reg:CC FLAGS_REG))] 10130 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 10131{ 10132 switch (get_attr_type (insn)) 10133 { 10134 case TYPE_ISHIFTX: 10135 return "#"; 10136 10137 default: 10138 if (operands[2] == const1_rtx 10139 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10140 return "<shift>{l}\t%k0"; 10141 else 10142 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 10143 } 10144} 10145 [(set_attr "isa" "*,bmi2") 10146 (set_attr "type" "ishift,ishiftx") 10147 (set (attr "length_immediate") 10148 (if_then_else 10149 (and (match_operand 2 "const1_operand") 10150 (ior (match_test "TARGET_SHIFT1") 10151 (match_test "optimize_function_for_size_p (cfun)"))) 10152 (const_string "0") 10153 (const_string "*"))) 10154 (set_attr "mode" "SI")]) 10155 10156;; Convert shift to the shiftx pattern to avoid flags dependency. 10157(define_split 10158 [(set (match_operand:DI 0 "register_operand") 10159 (zero_extend:DI 10160 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand") 10161 (match_operand:QI 2 "register_operand")))) 10162 (clobber (reg:CC FLAGS_REG))] 10163 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10164 [(set (match_dup 0) 10165 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 10166 "operands[2] = gen_lowpart (SImode, operands[2]);") 10167 10168(define_insn "*<shift_insn><mode>3_1" 10169 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 10170 (any_shiftrt:SWI12 10171 (match_operand:SWI12 1 "nonimmediate_operand" "0") 10172 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 10173 (clobber (reg:CC FLAGS_REG))] 10174 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10175{ 10176 if (operands[2] == const1_rtx 10177 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10178 return "<shift>{<imodesuffix>}\t%0"; 10179 else 10180 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10181} 10182 [(set_attr "type" "ishift") 10183 (set (attr "length_immediate") 10184 (if_then_else 10185 (and (match_operand 2 "const1_operand") 10186 (ior (match_test "TARGET_SHIFT1") 10187 (match_test "optimize_function_for_size_p (cfun)"))) 10188 (const_string "0") 10189 (const_string "*"))) 10190 (set_attr "mode" "<MODE>")]) 10191 10192(define_insn "*<shift_insn>qi3_1_slp" 10193 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10194 (any_shiftrt:QI (match_dup 0) 10195 (match_operand:QI 1 "nonmemory_operand" "cI"))) 10196 (clobber (reg:CC FLAGS_REG))] 10197 "(optimize_function_for_size_p (cfun) 10198 || !TARGET_PARTIAL_REG_STALL 10199 || (operands[1] == const1_rtx 10200 && TARGET_SHIFT1))" 10201{ 10202 if (operands[1] == const1_rtx 10203 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10204 return "<shift>{b}\t%0"; 10205 else 10206 return "<shift>{b}\t{%1, %0|%0, %1}"; 10207} 10208 [(set_attr "type" "ishift1") 10209 (set (attr "length_immediate") 10210 (if_then_else 10211 (and (match_operand 1 "const1_operand") 10212 (ior (match_test "TARGET_SHIFT1") 10213 (match_test "optimize_function_for_size_p (cfun)"))) 10214 (const_string "0") 10215 (const_string "*"))) 10216 (set_attr "mode" "QI")]) 10217 10218;; This pattern can't accept a variable shift count, since shifts by 10219;; zero don't affect the flags. We assume that shifts by constant 10220;; zero are optimized away. 10221(define_insn "*<shift_insn><mode>3_cmp" 10222 [(set (reg FLAGS_REG) 10223 (compare 10224 (any_shiftrt:SWI 10225 (match_operand:SWI 1 "nonimmediate_operand" "0") 10226 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10227 (const_int 0))) 10228 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10229 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] 10230 "(optimize_function_for_size_p (cfun) 10231 || !TARGET_PARTIAL_FLAG_REG_STALL 10232 || (operands[2] == const1_rtx 10233 && TARGET_SHIFT1)) 10234 && ix86_match_ccmode (insn, CCGOCmode) 10235 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10236{ 10237 if (operands[2] == const1_rtx 10238 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10239 return "<shift>{<imodesuffix>}\t%0"; 10240 else 10241 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10242} 10243 [(set_attr "type" "ishift") 10244 (set (attr "length_immediate") 10245 (if_then_else 10246 (and (match_operand 2 "const1_operand") 10247 (ior (match_test "TARGET_SHIFT1") 10248 (match_test "optimize_function_for_size_p (cfun)"))) 10249 (const_string "0") 10250 (const_string "*"))) 10251 (set_attr "mode" "<MODE>")]) 10252 10253(define_insn "*<shift_insn>si3_cmp_zext" 10254 [(set (reg FLAGS_REG) 10255 (compare 10256 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") 10257 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10258 (const_int 0))) 10259 (set (match_operand:DI 0 "register_operand" "=r") 10260 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 10261 "TARGET_64BIT 10262 && (optimize_function_for_size_p (cfun) 10263 || !TARGET_PARTIAL_FLAG_REG_STALL 10264 || (operands[2] == const1_rtx 10265 && TARGET_SHIFT1)) 10266 && ix86_match_ccmode (insn, CCGOCmode) 10267 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 10268{ 10269 if (operands[2] == const1_rtx 10270 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10271 return "<shift>{l}\t%k0"; 10272 else 10273 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 10274} 10275 [(set_attr "type" "ishift") 10276 (set (attr "length_immediate") 10277 (if_then_else 10278 (and (match_operand 2 "const1_operand") 10279 (ior (match_test "TARGET_SHIFT1") 10280 (match_test "optimize_function_for_size_p (cfun)"))) 10281 (const_string "0") 10282 (const_string "*"))) 10283 (set_attr "mode" "SI")]) 10284 10285(define_insn "*<shift_insn><mode>3_cconly" 10286 [(set (reg FLAGS_REG) 10287 (compare 10288 (any_shiftrt:SWI 10289 (match_operand:SWI 1 "register_operand" "0") 10290 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10291 (const_int 0))) 10292 (clobber (match_scratch:SWI 0 "=<r>"))] 10293 "(optimize_function_for_size_p (cfun) 10294 || !TARGET_PARTIAL_FLAG_REG_STALL 10295 || (operands[2] == const1_rtx 10296 && TARGET_SHIFT1)) 10297 && ix86_match_ccmode (insn, CCGOCmode)" 10298{ 10299 if (operands[2] == const1_rtx 10300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10301 return "<shift>{<imodesuffix>}\t%0"; 10302 else 10303 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10304} 10305 [(set_attr "type" "ishift") 10306 (set (attr "length_immediate") 10307 (if_then_else 10308 (and (match_operand 2 "const1_operand") 10309 (ior (match_test "TARGET_SHIFT1") 10310 (match_test "optimize_function_for_size_p (cfun)"))) 10311 (const_string "0") 10312 (const_string "*"))) 10313 (set_attr "mode" "<MODE>")]) 10314 10315;; Rotate instructions 10316 10317(define_expand "<rotate_insn>ti3" 10318 [(set (match_operand:TI 0 "register_operand") 10319 (any_rotate:TI (match_operand:TI 1 "register_operand") 10320 (match_operand:QI 2 "nonmemory_operand")))] 10321 "TARGET_64BIT" 10322{ 10323 if (const_1_to_63_operand (operands[2], VOIDmode)) 10324 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword 10325 (operands[0], operands[1], operands[2])); 10326 else 10327 FAIL; 10328 10329 DONE; 10330}) 10331 10332(define_expand "<rotate_insn>di3" 10333 [(set (match_operand:DI 0 "shiftdi_operand") 10334 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand") 10335 (match_operand:QI 2 "nonmemory_operand")))] 10336 "" 10337{ 10338 if (TARGET_64BIT) 10339 ix86_expand_binary_operator (<CODE>, DImode, operands); 10340 else if (const_1_to_31_operand (operands[2], VOIDmode)) 10341 emit_insn (gen_ix86_<rotate_insn>di3_doubleword 10342 (operands[0], operands[1], operands[2])); 10343 else 10344 FAIL; 10345 10346 DONE; 10347}) 10348 10349(define_expand "<rotate_insn><mode>3" 10350 [(set (match_operand:SWIM124 0 "nonimmediate_operand") 10351 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand") 10352 (match_operand:QI 2 "nonmemory_operand")))] 10353 "" 10354 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 10355 10356;; Avoid useless masking of count operand. 10357(define_insn "*<rotate_insn><mode>3_mask" 10358 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 10359 (any_rotate:SWI48 10360 (match_operand:SWI48 1 "nonimmediate_operand" "0") 10361 (subreg:QI 10362 (and:SI 10363 (match_operand:SI 2 "register_operand" "c") 10364 (match_operand:SI 3 "const_int_operand" "n")) 0))) 10365 (clobber (reg:CC FLAGS_REG))] 10366 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 10367 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10368 == GET_MODE_BITSIZE (<MODE>mode)-1" 10369{ 10370 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}"; 10371} 10372 [(set_attr "type" "rotate") 10373 (set_attr "mode" "<MODE>")]) 10374 10375;; Implement rotation using two double-precision 10376;; shift instructions and a scratch register. 10377 10378(define_insn_and_split "ix86_rotl<dwi>3_doubleword" 10379 [(set (match_operand:<DWI> 0 "register_operand" "=r") 10380 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 10381 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 10382 (clobber (reg:CC FLAGS_REG)) 10383 (clobber (match_scratch:DWIH 3 "=&r"))] 10384 "" 10385 "#" 10386 "reload_completed" 10387 [(set (match_dup 3) (match_dup 4)) 10388 (parallel 10389 [(set (match_dup 4) 10390 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) 10391 (lshiftrt:DWIH (match_dup 5) 10392 (minus:QI (match_dup 6) (match_dup 2))))) 10393 (clobber (reg:CC FLAGS_REG))]) 10394 (parallel 10395 [(set (match_dup 5) 10396 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) 10397 (lshiftrt:DWIH (match_dup 3) 10398 (minus:QI (match_dup 6) (match_dup 2))))) 10399 (clobber (reg:CC FLAGS_REG))])] 10400{ 10401 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 10402 10403 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 10404}) 10405 10406(define_insn_and_split "ix86_rotr<dwi>3_doubleword" 10407 [(set (match_operand:<DWI> 0 "register_operand" "=r") 10408 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 10409 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 10410 (clobber (reg:CC FLAGS_REG)) 10411 (clobber (match_scratch:DWIH 3 "=&r"))] 10412 "" 10413 "#" 10414 "reload_completed" 10415 [(set (match_dup 3) (match_dup 4)) 10416 (parallel 10417 [(set (match_dup 4) 10418 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) 10419 (ashift:DWIH (match_dup 5) 10420 (minus:QI (match_dup 6) (match_dup 2))))) 10421 (clobber (reg:CC FLAGS_REG))]) 10422 (parallel 10423 [(set (match_dup 5) 10424 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2)) 10425 (ashift:DWIH (match_dup 3) 10426 (minus:QI (match_dup 6) (match_dup 2))))) 10427 (clobber (reg:CC FLAGS_REG))])] 10428{ 10429 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 10430 10431 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 10432}) 10433 10434(define_insn "*bmi2_rorx<mode>3_1" 10435 [(set (match_operand:SWI48 0 "register_operand" "=r") 10436 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10437 (match_operand:QI 2 "immediate_operand" "<S>")))] 10438 "TARGET_BMI2" 10439 "rorx\t{%2, %1, %0|%0, %1, %2}" 10440 [(set_attr "type" "rotatex") 10441 (set_attr "mode" "<MODE>")]) 10442 10443(define_insn "*<rotate_insn><mode>3_1" 10444 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 10445 (any_rotate:SWI48 10446 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 10447 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>"))) 10448 (clobber (reg:CC FLAGS_REG))] 10449 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10450{ 10451 switch (get_attr_type (insn)) 10452 { 10453 case TYPE_ROTATEX: 10454 return "#"; 10455 10456 default: 10457 if (operands[2] == const1_rtx 10458 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10459 return "<rotate>{<imodesuffix>}\t%0"; 10460 else 10461 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10462 } 10463} 10464 [(set_attr "isa" "*,bmi2") 10465 (set_attr "type" "rotate,rotatex") 10466 (set (attr "length_immediate") 10467 (if_then_else 10468 (and (eq_attr "type" "rotate") 10469 (and (match_operand 2 "const1_operand") 10470 (ior (match_test "TARGET_SHIFT1") 10471 (match_test "optimize_function_for_size_p (cfun)")))) 10472 (const_string "0") 10473 (const_string "*"))) 10474 (set_attr "mode" "<MODE>")]) 10475 10476;; Convert rotate to the rotatex pattern to avoid flags dependency. 10477(define_split 10478 [(set (match_operand:SWI48 0 "register_operand") 10479 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 10480 (match_operand:QI 2 "immediate_operand"))) 10481 (clobber (reg:CC FLAGS_REG))] 10482 "TARGET_BMI2 && reload_completed" 10483 [(set (match_dup 0) 10484 (rotatert:SWI48 (match_dup 1) (match_dup 2)))] 10485{ 10486 operands[2] 10487 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2])); 10488}) 10489 10490(define_split 10491 [(set (match_operand:SWI48 0 "register_operand") 10492 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 10493 (match_operand:QI 2 "immediate_operand"))) 10494 (clobber (reg:CC FLAGS_REG))] 10495 "TARGET_BMI2 && reload_completed" 10496 [(set (match_dup 0) 10497 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]) 10498 10499(define_insn "*bmi2_rorxsi3_1_zext" 10500 [(set (match_operand:DI 0 "register_operand" "=r") 10501 (zero_extend:DI 10502 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10503 (match_operand:QI 2 "immediate_operand" "I"))))] 10504 "TARGET_64BIT && TARGET_BMI2" 10505 "rorx\t{%2, %1, %k0|%k0, %1, %2}" 10506 [(set_attr "type" "rotatex") 10507 (set_attr "mode" "SI")]) 10508 10509(define_insn "*<rotate_insn>si3_1_zext" 10510 [(set (match_operand:DI 0 "register_operand" "=r,r") 10511 (zero_extend:DI 10512 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 10513 (match_operand:QI 2 "nonmemory_operand" "cI,I")))) 10514 (clobber (reg:CC FLAGS_REG))] 10515 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 10516{ 10517 switch (get_attr_type (insn)) 10518 { 10519 case TYPE_ROTATEX: 10520 return "#"; 10521 10522 default: 10523 if (operands[2] == const1_rtx 10524 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10525 return "<rotate>{l}\t%k0"; 10526 else 10527 return "<rotate>{l}\t{%2, %k0|%k0, %2}"; 10528 } 10529} 10530 [(set_attr "isa" "*,bmi2") 10531 (set_attr "type" "rotate,rotatex") 10532 (set (attr "length_immediate") 10533 (if_then_else 10534 (and (eq_attr "type" "rotate") 10535 (and (match_operand 2 "const1_operand") 10536 (ior (match_test "TARGET_SHIFT1") 10537 (match_test "optimize_function_for_size_p (cfun)")))) 10538 (const_string "0") 10539 (const_string "*"))) 10540 (set_attr "mode" "SI")]) 10541 10542;; Convert rotate to the rotatex pattern to avoid flags dependency. 10543(define_split 10544 [(set (match_operand:DI 0 "register_operand") 10545 (zero_extend:DI 10546 (rotate:SI (match_operand:SI 1 "nonimmediate_operand") 10547 (match_operand:QI 2 "immediate_operand")))) 10548 (clobber (reg:CC FLAGS_REG))] 10549 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10550 [(set (match_dup 0) 10551 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))] 10552{ 10553 operands[2] 10554 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2])); 10555}) 10556 10557(define_split 10558 [(set (match_operand:DI 0 "register_operand") 10559 (zero_extend:DI 10560 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand") 10561 (match_operand:QI 2 "immediate_operand")))) 10562 (clobber (reg:CC FLAGS_REG))] 10563 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10564 [(set (match_dup 0) 10565 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) 10566 10567(define_insn "*<rotate_insn><mode>3_1" 10568 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 10569 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0") 10570 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 10571 (clobber (reg:CC FLAGS_REG))] 10572 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 10573{ 10574 if (operands[2] == const1_rtx 10575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10576 return "<rotate>{<imodesuffix>}\t%0"; 10577 else 10578 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 10579} 10580 [(set_attr "type" "rotate") 10581 (set (attr "length_immediate") 10582 (if_then_else 10583 (and (match_operand 2 "const1_operand") 10584 (ior (match_test "TARGET_SHIFT1") 10585 (match_test "optimize_function_for_size_p (cfun)"))) 10586 (const_string "0") 10587 (const_string "*"))) 10588 (set_attr "mode" "<MODE>")]) 10589 10590(define_insn "*<rotate_insn>qi3_1_slp" 10591 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10592 (any_rotate:QI (match_dup 0) 10593 (match_operand:QI 1 "nonmemory_operand" "cI"))) 10594 (clobber (reg:CC FLAGS_REG))] 10595 "(optimize_function_for_size_p (cfun) 10596 || !TARGET_PARTIAL_REG_STALL 10597 || (operands[1] == const1_rtx 10598 && TARGET_SHIFT1))" 10599{ 10600 if (operands[1] == const1_rtx 10601 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10602 return "<rotate>{b}\t%0"; 10603 else 10604 return "<rotate>{b}\t{%1, %0|%0, %1}"; 10605} 10606 [(set_attr "type" "rotate1") 10607 (set (attr "length_immediate") 10608 (if_then_else 10609 (and (match_operand 1 "const1_operand") 10610 (ior (match_test "TARGET_SHIFT1") 10611 (match_test "optimize_function_for_size_p (cfun)"))) 10612 (const_string "0") 10613 (const_string "*"))) 10614 (set_attr "mode" "QI")]) 10615 10616(define_split 10617 [(set (match_operand:HI 0 "register_operand") 10618 (any_rotate:HI (match_dup 0) (const_int 8))) 10619 (clobber (reg:CC FLAGS_REG))] 10620 "reload_completed 10621 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" 10622 [(parallel [(set (strict_low_part (match_dup 0)) 10623 (bswap:HI (match_dup 0))) 10624 (clobber (reg:CC FLAGS_REG))])]) 10625 10626;; Bit set / bit test instructions 10627 10628(define_expand "extv" 10629 [(set (match_operand:SI 0 "register_operand") 10630 (sign_extract:SI (match_operand:SI 1 "register_operand") 10631 (match_operand:SI 2 "const8_operand") 10632 (match_operand:SI 3 "const8_operand")))] 10633 "" 10634{ 10635 /* Handle extractions from %ah et al. */ 10636 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 10637 FAIL; 10638 10639 /* From mips.md: extract_bit_field doesn't verify that our source 10640 matches the predicate, so check it again here. */ 10641 if (! ext_register_operand (operands[1], VOIDmode)) 10642 FAIL; 10643}) 10644 10645(define_expand "extzv" 10646 [(set (match_operand:SI 0 "register_operand") 10647 (zero_extract:SI (match_operand 1 "ext_register_operand") 10648 (match_operand:SI 2 "const8_operand") 10649 (match_operand:SI 3 "const8_operand")))] 10650 "" 10651{ 10652 /* Handle extractions from %ah et al. */ 10653 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 10654 FAIL; 10655 10656 /* From mips.md: extract_bit_field doesn't verify that our source 10657 matches the predicate, so check it again here. */ 10658 if (! ext_register_operand (operands[1], VOIDmode)) 10659 FAIL; 10660}) 10661 10662(define_expand "insv" 10663 [(set (zero_extract (match_operand 0 "register_operand") 10664 (match_operand 1 "const_int_operand") 10665 (match_operand 2 "const_int_operand")) 10666 (match_operand 3 "register_operand"))] 10667 "" 10668{ 10669 rtx (*gen_mov_insv_1) (rtx, rtx); 10670 10671 if (ix86_expand_pinsr (operands)) 10672 DONE; 10673 10674 /* Handle insertions to %ah et al. */ 10675 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 10676 FAIL; 10677 10678 /* From mips.md: insert_bit_field doesn't verify that our source 10679 matches the predicate, so check it again here. */ 10680 if (! ext_register_operand (operands[0], VOIDmode)) 10681 FAIL; 10682 10683 gen_mov_insv_1 = (TARGET_64BIT 10684 ? gen_movdi_insv_1 : gen_movsi_insv_1); 10685 10686 emit_insn (gen_mov_insv_1 (operands[0], operands[3])); 10687 DONE; 10688}) 10689 10690;; %%% bts, btr, btc, bt. 10691;; In general these instructions are *slow* when applied to memory, 10692;; since they enforce atomic operation. When applied to registers, 10693;; it depends on the cpu implementation. They're never faster than 10694;; the corresponding and/ior/xor operations, so with 32-bit there's 10695;; no point. But in 64-bit, we can't hold the relevant immediates 10696;; within the instruction itself, so operating on bits in the high 10697;; 32-bits of a register becomes easier. 10698;; 10699;; These are slow on Nocona, but fast on Athlon64. We do require the use 10700;; of btrq and btcq for corner cases of post-reload expansion of absdf and 10701;; negdf respectively, so they can never be disabled entirely. 10702 10703(define_insn "*btsq" 10704 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10705 (const_int 1) 10706 (match_operand:DI 1 "const_0_to_63_operand")) 10707 (const_int 1)) 10708 (clobber (reg:CC FLAGS_REG))] 10709 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10710 "bts{q}\t{%1, %0|%0, %1}" 10711 [(set_attr "type" "alu1") 10712 (set_attr "prefix_0f" "1") 10713 (set_attr "mode" "DI")]) 10714 10715(define_insn "*btrq" 10716 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10717 (const_int 1) 10718 (match_operand:DI 1 "const_0_to_63_operand")) 10719 (const_int 0)) 10720 (clobber (reg:CC FLAGS_REG))] 10721 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10722 "btr{q}\t{%1, %0|%0, %1}" 10723 [(set_attr "type" "alu1") 10724 (set_attr "prefix_0f" "1") 10725 (set_attr "mode" "DI")]) 10726 10727(define_insn "*btcq" 10728 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") 10729 (const_int 1) 10730 (match_operand:DI 1 "const_0_to_63_operand")) 10731 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 10732 (clobber (reg:CC FLAGS_REG))] 10733 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 10734 "btc{q}\t{%1, %0|%0, %1}" 10735 [(set_attr "type" "alu1") 10736 (set_attr "prefix_0f" "1") 10737 (set_attr "mode" "DI")]) 10738 10739;; Allow Nocona to avoid these instructions if a register is available. 10740 10741(define_peephole2 10742 [(match_scratch:DI 2 "r") 10743 (parallel [(set (zero_extract:DI 10744 (match_operand:DI 0 "register_operand") 10745 (const_int 1) 10746 (match_operand:DI 1 "const_0_to_63_operand")) 10747 (const_int 1)) 10748 (clobber (reg:CC FLAGS_REG))])] 10749 "TARGET_64BIT && !TARGET_USE_BT" 10750 [(const_int 0)] 10751{ 10752 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10753 rtx op1; 10754 10755 if (HOST_BITS_PER_WIDE_INT >= 64) 10756 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10757 else if (i < HOST_BITS_PER_WIDE_INT) 10758 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10759 else 10760 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10761 10762 op1 = immed_double_const (lo, hi, DImode); 10763 if (i >= 31) 10764 { 10765 emit_move_insn (operands[2], op1); 10766 op1 = operands[2]; 10767 } 10768 10769 emit_insn (gen_iordi3 (operands[0], operands[0], op1)); 10770 DONE; 10771}) 10772 10773(define_peephole2 10774 [(match_scratch:DI 2 "r") 10775 (parallel [(set (zero_extract:DI 10776 (match_operand:DI 0 "register_operand") 10777 (const_int 1) 10778 (match_operand:DI 1 "const_0_to_63_operand")) 10779 (const_int 0)) 10780 (clobber (reg:CC FLAGS_REG))])] 10781 "TARGET_64BIT && !TARGET_USE_BT" 10782 [(const_int 0)] 10783{ 10784 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10785 rtx op1; 10786 10787 if (HOST_BITS_PER_WIDE_INT >= 64) 10788 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10789 else if (i < HOST_BITS_PER_WIDE_INT) 10790 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10791 else 10792 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10793 10794 op1 = immed_double_const (~lo, ~hi, DImode); 10795 if (i >= 32) 10796 { 10797 emit_move_insn (operands[2], op1); 10798 op1 = operands[2]; 10799 } 10800 10801 emit_insn (gen_anddi3 (operands[0], operands[0], op1)); 10802 DONE; 10803}) 10804 10805(define_peephole2 10806 [(match_scratch:DI 2 "r") 10807 (parallel [(set (zero_extract:DI 10808 (match_operand:DI 0 "register_operand") 10809 (const_int 1) 10810 (match_operand:DI 1 "const_0_to_63_operand")) 10811 (not:DI (zero_extract:DI 10812 (match_dup 0) (const_int 1) (match_dup 1)))) 10813 (clobber (reg:CC FLAGS_REG))])] 10814 "TARGET_64BIT && !TARGET_USE_BT" 10815 [(const_int 0)] 10816{ 10817 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo; 10818 rtx op1; 10819 10820 if (HOST_BITS_PER_WIDE_INT >= 64) 10821 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10822 else if (i < HOST_BITS_PER_WIDE_INT) 10823 lo = (HOST_WIDE_INT)1 << i, hi = 0; 10824 else 10825 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT); 10826 10827 op1 = immed_double_const (lo, hi, DImode); 10828 if (i >= 31) 10829 { 10830 emit_move_insn (operands[2], op1); 10831 op1 = operands[2]; 10832 } 10833 10834 emit_insn (gen_xordi3 (operands[0], operands[0], op1)); 10835 DONE; 10836}) 10837 10838(define_insn "*bt<mode>" 10839 [(set (reg:CCC FLAGS_REG) 10840 (compare:CCC 10841 (zero_extract:SWI48 10842 (match_operand:SWI48 0 "register_operand" "r") 10843 (const_int 1) 10844 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN")) 10845 (const_int 0)))] 10846 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 10847 "bt{<imodesuffix>}\t{%1, %0|%0, %1}" 10848 [(set_attr "type" "alu1") 10849 (set_attr "prefix_0f" "1") 10850 (set_attr "mode" "<MODE>")]) 10851 10852;; Store-flag instructions. 10853 10854;; For all sCOND expanders, also expand the compare or test insn that 10855;; generates cc0. Generate an equality comparison if `seq' or `sne'. 10856 10857(define_insn_and_split "*setcc_di_1" 10858 [(set (match_operand:DI 0 "register_operand" "=q") 10859 (match_operator:DI 1 "ix86_comparison_operator" 10860 [(reg FLAGS_REG) (const_int 0)]))] 10861 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL" 10862 "#" 10863 "&& reload_completed" 10864 [(set (match_dup 2) (match_dup 1)) 10865 (set (match_dup 0) (zero_extend:DI (match_dup 2)))] 10866{ 10867 operands[1] = shallow_copy_rtx (operands[1]); 10868 PUT_MODE (operands[1], QImode); 10869 operands[2] = gen_lowpart (QImode, operands[0]); 10870}) 10871 10872(define_insn_and_split "*setcc_si_1_and" 10873 [(set (match_operand:SI 0 "register_operand" "=q") 10874 (match_operator:SI 1 "ix86_comparison_operator" 10875 [(reg FLAGS_REG) (const_int 0)])) 10876 (clobber (reg:CC FLAGS_REG))] 10877 "!TARGET_PARTIAL_REG_STALL 10878 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 10879 "#" 10880 "&& reload_completed" 10881 [(set (match_dup 2) (match_dup 1)) 10882 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) 10883 (clobber (reg:CC FLAGS_REG))])] 10884{ 10885 operands[1] = shallow_copy_rtx (operands[1]); 10886 PUT_MODE (operands[1], QImode); 10887 operands[2] = gen_lowpart (QImode, operands[0]); 10888}) 10889 10890(define_insn_and_split "*setcc_si_1_movzbl" 10891 [(set (match_operand:SI 0 "register_operand" "=q") 10892 (match_operator:SI 1 "ix86_comparison_operator" 10893 [(reg FLAGS_REG) (const_int 0)]))] 10894 "!TARGET_PARTIAL_REG_STALL 10895 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 10896 "#" 10897 "&& reload_completed" 10898 [(set (match_dup 2) (match_dup 1)) 10899 (set (match_dup 0) (zero_extend:SI (match_dup 2)))] 10900{ 10901 operands[1] = shallow_copy_rtx (operands[1]); 10902 PUT_MODE (operands[1], QImode); 10903 operands[2] = gen_lowpart (QImode, operands[0]); 10904}) 10905 10906(define_insn "*setcc_qi" 10907 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 10908 (match_operator:QI 1 "ix86_comparison_operator" 10909 [(reg FLAGS_REG) (const_int 0)]))] 10910 "" 10911 "set%C1\t%0" 10912 [(set_attr "type" "setcc") 10913 (set_attr "mode" "QI")]) 10914 10915(define_insn "*setcc_qi_slp" 10916 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) 10917 (match_operator:QI 1 "ix86_comparison_operator" 10918 [(reg FLAGS_REG) (const_int 0)]))] 10919 "" 10920 "set%C1\t%0" 10921 [(set_attr "type" "setcc") 10922 (set_attr "mode" "QI")]) 10923 10924;; In general it is not safe to assume too much about CCmode registers, 10925;; so simplify-rtx stops when it sees a second one. Under certain 10926;; conditions this is safe on x86, so help combine not create 10927;; 10928;; seta %al 10929;; testb %al, %al 10930;; sete %al 10931 10932(define_split 10933 [(set (match_operand:QI 0 "nonimmediate_operand") 10934 (ne:QI (match_operator 1 "ix86_comparison_operator" 10935 [(reg FLAGS_REG) (const_int 0)]) 10936 (const_int 0)))] 10937 "" 10938 [(set (match_dup 0) (match_dup 1))] 10939{ 10940 operands[1] = shallow_copy_rtx (operands[1]); 10941 PUT_MODE (operands[1], QImode); 10942}) 10943 10944(define_split 10945 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) 10946 (ne:QI (match_operator 1 "ix86_comparison_operator" 10947 [(reg FLAGS_REG) (const_int 0)]) 10948 (const_int 0)))] 10949 "" 10950 [(set (match_dup 0) (match_dup 1))] 10951{ 10952 operands[1] = shallow_copy_rtx (operands[1]); 10953 PUT_MODE (operands[1], QImode); 10954}) 10955 10956(define_split 10957 [(set (match_operand:QI 0 "nonimmediate_operand") 10958 (eq:QI (match_operator 1 "ix86_comparison_operator" 10959 [(reg FLAGS_REG) (const_int 0)]) 10960 (const_int 0)))] 10961 "" 10962 [(set (match_dup 0) (match_dup 1))] 10963{ 10964 operands[1] = shallow_copy_rtx (operands[1]); 10965 PUT_MODE (operands[1], QImode); 10966 PUT_CODE (operands[1], 10967 ix86_reverse_condition (GET_CODE (operands[1]), 10968 GET_MODE (XEXP (operands[1], 0)))); 10969 10970 /* Make sure that (a) the CCmode we have for the flags is strong 10971 enough for the reversed compare or (b) we have a valid FP compare. */ 10972 if (! ix86_comparison_operator (operands[1], VOIDmode)) 10973 FAIL; 10974}) 10975 10976(define_split 10977 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) 10978 (eq:QI (match_operator 1 "ix86_comparison_operator" 10979 [(reg FLAGS_REG) (const_int 0)]) 10980 (const_int 0)))] 10981 "" 10982 [(set (match_dup 0) (match_dup 1))] 10983{ 10984 operands[1] = shallow_copy_rtx (operands[1]); 10985 PUT_MODE (operands[1], QImode); 10986 PUT_CODE (operands[1], 10987 ix86_reverse_condition (GET_CODE (operands[1]), 10988 GET_MODE (XEXP (operands[1], 0)))); 10989 10990 /* Make sure that (a) the CCmode we have for the flags is strong 10991 enough for the reversed compare or (b) we have a valid FP compare. */ 10992 if (! ix86_comparison_operator (operands[1], VOIDmode)) 10993 FAIL; 10994}) 10995 10996;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 10997;; subsequent logical operations are used to imitate conditional moves. 10998;; 0xffffffff is NaN, but not in normalized form, so we can't represent 10999;; it directly. 11000 11001(define_insn "setcc_<mode>_sse" 11002 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 11003 (match_operator:MODEF 3 "sse_comparison_operator" 11004 [(match_operand:MODEF 1 "register_operand" "0,x") 11005 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 11006 "SSE_FLOAT_MODE_P (<MODE>mode)" 11007 "@ 11008 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2} 11009 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 11010 [(set_attr "isa" "noavx,avx") 11011 (set_attr "type" "ssecmp") 11012 (set_attr "length_immediate" "1") 11013 (set_attr "prefix" "orig,vex") 11014 (set_attr "mode" "<MODE>")]) 11015 11016;; Basic conditional jump instructions. 11017;; We ignore the overflow flag for signed branch instructions. 11018 11019(define_insn "*jcc_1_bnd" 11020 [(set (pc) 11021 (if_then_else (match_operator 1 "ix86_comparison_operator" 11022 [(reg FLAGS_REG) (const_int 0)]) 11023 (label_ref (match_operand 0)) 11024 (pc)))] 11025 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)" 11026 "bnd %+j%C1\t%l0" 11027 [(set_attr "type" "ibr") 11028 (set_attr "modrm" "0") 11029 (set (attr "length") 11030 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11031 (const_int -126)) 11032 (lt (minus (match_dup 0) (pc)) 11033 (const_int 128))) 11034 (const_int 3) 11035 (const_int 7)))]) 11036 11037(define_insn "*jcc_1" 11038 [(set (pc) 11039 (if_then_else (match_operator 1 "ix86_comparison_operator" 11040 [(reg FLAGS_REG) (const_int 0)]) 11041 (label_ref (match_operand 0)) 11042 (pc)))] 11043 "" 11044 "%+j%C1\t%l0" 11045 [(set_attr "type" "ibr") 11046 (set_attr "modrm" "0") 11047 (set (attr "length") 11048 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11049 (const_int -126)) 11050 (lt (minus (match_dup 0) (pc)) 11051 (const_int 128))) 11052 (const_int 2) 11053 (const_int 6)))]) 11054 11055(define_insn "*jcc_2_bnd" 11056 [(set (pc) 11057 (if_then_else (match_operator 1 "ix86_comparison_operator" 11058 [(reg FLAGS_REG) (const_int 0)]) 11059 (pc) 11060 (label_ref (match_operand 0))))] 11061 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)" 11062 "bnd %+j%c1\t%l0" 11063 [(set_attr "type" "ibr") 11064 (set_attr "modrm" "0") 11065 (set (attr "length") 11066 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11067 (const_int -126)) 11068 (lt (minus (match_dup 0) (pc)) 11069 (const_int 128))) 11070 (const_int 3) 11071 (const_int 7)))]) 11072 11073(define_insn "*jcc_2" 11074 [(set (pc) 11075 (if_then_else (match_operator 1 "ix86_comparison_operator" 11076 [(reg FLAGS_REG) (const_int 0)]) 11077 (pc) 11078 (label_ref (match_operand 0))))] 11079 "" 11080 "%+j%c1\t%l0" 11081 [(set_attr "type" "ibr") 11082 (set_attr "modrm" "0") 11083 (set (attr "length") 11084 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11085 (const_int -126)) 11086 (lt (minus (match_dup 0) (pc)) 11087 (const_int 128))) 11088 (const_int 2) 11089 (const_int 6)))]) 11090 11091;; In general it is not safe to assume too much about CCmode registers, 11092;; so simplify-rtx stops when it sees a second one. Under certain 11093;; conditions this is safe on x86, so help combine not create 11094;; 11095;; seta %al 11096;; testb %al, %al 11097;; je Lfoo 11098 11099(define_split 11100 [(set (pc) 11101 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 11102 [(reg FLAGS_REG) (const_int 0)]) 11103 (const_int 0)) 11104 (label_ref (match_operand 1)) 11105 (pc)))] 11106 "" 11107 [(set (pc) 11108 (if_then_else (match_dup 0) 11109 (label_ref (match_dup 1)) 11110 (pc)))] 11111{ 11112 operands[0] = shallow_copy_rtx (operands[0]); 11113 PUT_MODE (operands[0], VOIDmode); 11114}) 11115 11116(define_split 11117 [(set (pc) 11118 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 11119 [(reg FLAGS_REG) (const_int 0)]) 11120 (const_int 0)) 11121 (label_ref (match_operand 1)) 11122 (pc)))] 11123 "" 11124 [(set (pc) 11125 (if_then_else (match_dup 0) 11126 (label_ref (match_dup 1)) 11127 (pc)))] 11128{ 11129 operands[0] = shallow_copy_rtx (operands[0]); 11130 PUT_MODE (operands[0], VOIDmode); 11131 PUT_CODE (operands[0], 11132 ix86_reverse_condition (GET_CODE (operands[0]), 11133 GET_MODE (XEXP (operands[0], 0)))); 11134 11135 /* Make sure that (a) the CCmode we have for the flags is strong 11136 enough for the reversed compare or (b) we have a valid FP compare. */ 11137 if (! ix86_comparison_operator (operands[0], VOIDmode)) 11138 FAIL; 11139}) 11140 11141;; zero_extend in SImode is correct also for DImode, since this is what combine 11142;; pass generates from shift insn with QImode operand. Actually, the mode 11143;; of operand 2 (bit offset operand) doesn't matter since bt insn takes 11144;; appropriate modulo of the bit offset value. 11145 11146(define_insn_and_split "*jcc_bt<mode>" 11147 [(set (pc) 11148 (if_then_else (match_operator 0 "bt_comparison_operator" 11149 [(zero_extract:SWI48 11150 (match_operand:SWI48 1 "register_operand" "r") 11151 (const_int 1) 11152 (zero_extend:SI 11153 (match_operand:QI 2 "register_operand" "r"))) 11154 (const_int 0)]) 11155 (label_ref (match_operand 3)) 11156 (pc))) 11157 (clobber (reg:CC FLAGS_REG))] 11158 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 11159 "#" 11160 "&& 1" 11161 [(set (reg:CCC FLAGS_REG) 11162 (compare:CCC 11163 (zero_extract:SWI48 11164 (match_dup 1) 11165 (const_int 1) 11166 (match_dup 2)) 11167 (const_int 0))) 11168 (set (pc) 11169 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 11170 (label_ref (match_dup 3)) 11171 (pc)))] 11172{ 11173 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0); 11174 operands[0] = shallow_copy_rtx (operands[0]); 11175 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 11176}) 11177 11178;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode 11179;; zero extended to SImode. 11180(define_insn_and_split "*jcc_bt<mode>_1" 11181 [(set (pc) 11182 (if_then_else (match_operator 0 "bt_comparison_operator" 11183 [(zero_extract:SWI48 11184 (match_operand:SWI48 1 "register_operand" "r") 11185 (const_int 1) 11186 (match_operand:SI 2 "register_operand" "r")) 11187 (const_int 0)]) 11188 (label_ref (match_operand 3)) 11189 (pc))) 11190 (clobber (reg:CC FLAGS_REG))] 11191 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 11192 "#" 11193 "&& 1" 11194 [(set (reg:CCC FLAGS_REG) 11195 (compare:CCC 11196 (zero_extract:SWI48 11197 (match_dup 1) 11198 (const_int 1) 11199 (match_dup 2)) 11200 (const_int 0))) 11201 (set (pc) 11202 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 11203 (label_ref (match_dup 3)) 11204 (pc)))] 11205{ 11206 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0); 11207 operands[0] = shallow_copy_rtx (operands[0]); 11208 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 11209}) 11210 11211;; Avoid useless masking of bit offset operand. "and" in SImode is correct 11212;; also for DImode, this is what combine produces. 11213(define_insn_and_split "*jcc_bt<mode>_mask" 11214 [(set (pc) 11215 (if_then_else (match_operator 0 "bt_comparison_operator" 11216 [(zero_extract:SWI48 11217 (match_operand:SWI48 1 "register_operand" "r") 11218 (const_int 1) 11219 (and:SI 11220 (match_operand:SI 2 "register_operand" "r") 11221 (match_operand:SI 3 "const_int_operand" "n")))]) 11222 (label_ref (match_operand 4)) 11223 (pc))) 11224 (clobber (reg:CC FLAGS_REG))] 11225 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 11226 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11227 == GET_MODE_BITSIZE (<MODE>mode)-1" 11228 "#" 11229 "&& 1" 11230 [(set (reg:CCC FLAGS_REG) 11231 (compare:CCC 11232 (zero_extract:SWI48 11233 (match_dup 1) 11234 (const_int 1) 11235 (match_dup 2)) 11236 (const_int 0))) 11237 (set (pc) 11238 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 11239 (label_ref (match_dup 4)) 11240 (pc)))] 11241{ 11242 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0); 11243 operands[0] = shallow_copy_rtx (operands[0]); 11244 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 11245}) 11246 11247(define_insn_and_split "*jcc_btsi_1" 11248 [(set (pc) 11249 (if_then_else (match_operator 0 "bt_comparison_operator" 11250 [(and:SI 11251 (lshiftrt:SI 11252 (match_operand:SI 1 "register_operand" "r") 11253 (match_operand:QI 2 "register_operand" "r")) 11254 (const_int 1)) 11255 (const_int 0)]) 11256 (label_ref (match_operand 3)) 11257 (pc))) 11258 (clobber (reg:CC FLAGS_REG))] 11259 "TARGET_USE_BT || optimize_function_for_size_p (cfun)" 11260 "#" 11261 "&& 1" 11262 [(set (reg:CCC FLAGS_REG) 11263 (compare:CCC 11264 (zero_extract:SI 11265 (match_dup 1) 11266 (const_int 1) 11267 (match_dup 2)) 11268 (const_int 0))) 11269 (set (pc) 11270 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 11271 (label_ref (match_dup 3)) 11272 (pc)))] 11273{ 11274 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); 11275 operands[0] = shallow_copy_rtx (operands[0]); 11276 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 11277}) 11278 11279;; avoid useless masking of bit offset operand 11280(define_insn_and_split "*jcc_btsi_mask_1" 11281 [(set (pc) 11282 (if_then_else 11283 (match_operator 0 "bt_comparison_operator" 11284 [(and:SI 11285 (lshiftrt:SI 11286 (match_operand:SI 1 "register_operand" "r") 11287 (subreg:QI 11288 (and:SI 11289 (match_operand:SI 2 "register_operand" "r") 11290 (match_operand:SI 3 "const_int_operand" "n")) 0)) 11291 (const_int 1)) 11292 (const_int 0)]) 11293 (label_ref (match_operand 4)) 11294 (pc))) 11295 (clobber (reg:CC FLAGS_REG))] 11296 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 11297 && (INTVAL (operands[3]) & 0x1f) == 0x1f" 11298 "#" 11299 "&& 1" 11300 [(set (reg:CCC FLAGS_REG) 11301 (compare:CCC 11302 (zero_extract:SI 11303 (match_dup 1) 11304 (const_int 1) 11305 (match_dup 2)) 11306 (const_int 0))) 11307 (set (pc) 11308 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 11309 (label_ref (match_dup 4)) 11310 (pc)))] 11311{ 11312 operands[0] = shallow_copy_rtx (operands[0]); 11313 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 11314}) 11315 11316;; Define combination compare-and-branch fp compare instructions to help 11317;; combine. 11318 11319(define_insn "*jcc<mode>_0_i387" 11320 [(set (pc) 11321 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator" 11322 [(match_operand:X87MODEF 1 "register_operand" "f") 11323 (match_operand:X87MODEF 2 "const0_operand")]) 11324 (label_ref (match_operand 3)) 11325 (pc))) 11326 (clobber (reg:CCFP FPSR_REG)) 11327 (clobber (reg:CCFP FLAGS_REG)) 11328 (clobber (match_scratch:HI 4 "=a"))] 11329 "TARGET_80387 && !TARGET_CMOVE" 11330 "#") 11331 11332(define_insn "*jcc<mode>_0_r_i387" 11333 [(set (pc) 11334 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator" 11335 [(match_operand:X87MODEF 1 "register_operand" "f") 11336 (match_operand:X87MODEF 2 "const0_operand")]) 11337 (pc) 11338 (label_ref (match_operand 3)))) 11339 (clobber (reg:CCFP FPSR_REG)) 11340 (clobber (reg:CCFP FLAGS_REG)) 11341 (clobber (match_scratch:HI 4 "=a"))] 11342 "TARGET_80387 && !TARGET_CMOVE" 11343 "#") 11344 11345(define_insn "*jccxf_i387" 11346 [(set (pc) 11347 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator" 11348 [(match_operand:XF 1 "register_operand" "f") 11349 (match_operand:XF 2 "register_operand" "f")]) 11350 (label_ref (match_operand 3)) 11351 (pc))) 11352 (clobber (reg:CCFP FPSR_REG)) 11353 (clobber (reg:CCFP FLAGS_REG)) 11354 (clobber (match_scratch:HI 4 "=a"))] 11355 "TARGET_80387 && !TARGET_CMOVE" 11356 "#") 11357 11358(define_insn "*jccxf_r_i387" 11359 [(set (pc) 11360 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator" 11361 [(match_operand:XF 1 "register_operand" "f") 11362 (match_operand:XF 2 "register_operand" "f")]) 11363 (pc) 11364 (label_ref (match_operand 3)))) 11365 (clobber (reg:CCFP FPSR_REG)) 11366 (clobber (reg:CCFP FLAGS_REG)) 11367 (clobber (match_scratch:HI 4 "=a"))] 11368 "TARGET_80387 && !TARGET_CMOVE" 11369 "#") 11370 11371(define_insn "*jcc<mode>_i387" 11372 [(set (pc) 11373 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator" 11374 [(match_operand:MODEF 1 "register_operand" "f") 11375 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]) 11376 (label_ref (match_operand 3)) 11377 (pc))) 11378 (clobber (reg:CCFP FPSR_REG)) 11379 (clobber (reg:CCFP FLAGS_REG)) 11380 (clobber (match_scratch:HI 4 "=a"))] 11381 "TARGET_80387 && !TARGET_CMOVE" 11382 "#") 11383 11384(define_insn "*jcc<mode>_r_i387" 11385 [(set (pc) 11386 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator" 11387 [(match_operand:MODEF 1 "register_operand" "f") 11388 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]) 11389 (pc) 11390 (label_ref (match_operand 3)))) 11391 (clobber (reg:CCFP FPSR_REG)) 11392 (clobber (reg:CCFP FLAGS_REG)) 11393 (clobber (match_scratch:HI 4 "=a"))] 11394 "TARGET_80387 && !TARGET_CMOVE" 11395 "#") 11396 11397(define_insn "*jccu<mode>_i387" 11398 [(set (pc) 11399 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator" 11400 [(match_operand:X87MODEF 1 "register_operand" "f") 11401 (match_operand:X87MODEF 2 "register_operand" "f")]) 11402 (label_ref (match_operand 3)) 11403 (pc))) 11404 (clobber (reg:CCFP FPSR_REG)) 11405 (clobber (reg:CCFP FLAGS_REG)) 11406 (clobber (match_scratch:HI 4 "=a"))] 11407 "TARGET_80387 && !TARGET_CMOVE" 11408 "#") 11409 11410(define_insn "*jccu<mode>_r_i387" 11411 [(set (pc) 11412 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator" 11413 [(match_operand:X87MODEF 1 "register_operand" "f") 11414 (match_operand:X87MODEF 2 "register_operand" "f")]) 11415 (pc) 11416 (label_ref (match_operand 3)))) 11417 (clobber (reg:CCFP FPSR_REG)) 11418 (clobber (reg:CCFP FLAGS_REG)) 11419 (clobber (match_scratch:HI 4 "=a"))] 11420 "TARGET_80387 && !TARGET_CMOVE" 11421 "#") 11422 11423(define_split 11424 [(set (pc) 11425 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 11426 [(match_operand:X87MODEF 1 "register_operand") 11427 (match_operand:X87MODEF 2 "nonimmediate_operand")]) 11428 (match_operand 3) 11429 (match_operand 4))) 11430 (clobber (reg:CCFP FPSR_REG)) 11431 (clobber (reg:CCFP FLAGS_REG))] 11432 "TARGET_80387 && !TARGET_CMOVE 11433 && reload_completed" 11434 [(const_int 0)] 11435{ 11436 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 11437 operands[3], operands[4], NULL_RTX); 11438 DONE; 11439}) 11440 11441(define_split 11442 [(set (pc) 11443 (if_then_else (match_operator 0 "ix86_fp_comparison_operator" 11444 [(match_operand:X87MODEF 1 "register_operand") 11445 (match_operand:X87MODEF 2 "general_operand")]) 11446 (match_operand 3) 11447 (match_operand 4))) 11448 (clobber (reg:CCFP FPSR_REG)) 11449 (clobber (reg:CCFP FLAGS_REG)) 11450 (clobber (match_scratch:HI 5))] 11451 "TARGET_80387 && !TARGET_CMOVE 11452 && reload_completed" 11453 [(const_int 0)] 11454{ 11455 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2], 11456 operands[3], operands[4], operands[5]); 11457 DONE; 11458}) 11459 11460;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in 11461;; simplify_comparison () function. Float operator is treated as RTX_OBJ 11462;; with a precedence over other operators and is always put in the first 11463;; place. Swap condition and operands to match ficom instruction. 11464 11465(define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387" 11466 [(set (pc) 11467 (if_then_else 11468 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator" 11469 [(match_operator:X87MODEF 1 "float_operator" 11470 [(match_operand:SWI24 2 "nonimmediate_operand" "m")]) 11471 (match_operand:X87MODEF 3 "register_operand" "f")]) 11472 (label_ref (match_operand 4)) 11473 (pc))) 11474 (clobber (reg:CCFP FPSR_REG)) 11475 (clobber (reg:CCFP FLAGS_REG)) 11476 (clobber (match_scratch:HI 5 "=a"))] 11477 "TARGET_80387 && !TARGET_CMOVE 11478 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 11479 || optimize_function_for_size_p (cfun))" 11480 "#") 11481 11482(define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387" 11483 [(set (pc) 11484 (if_then_else 11485 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator" 11486 [(match_operator:X87MODEF 1 "float_operator" 11487 [(match_operand:SWI24 2 "nonimmediate_operand" "m")]) 11488 (match_operand:X87MODEF 3 "register_operand" "f")]) 11489 (pc) 11490 (label_ref (match_operand 4)))) 11491 (clobber (reg:CCFP FPSR_REG)) 11492 (clobber (reg:CCFP FLAGS_REG)) 11493 (clobber (match_scratch:HI 5 "=a"))] 11494 "TARGET_80387 && !TARGET_CMOVE 11495 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 11496 || optimize_function_for_size_p (cfun))" 11497 "#") 11498 11499(define_split 11500 [(set (pc) 11501 (if_then_else 11502 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator" 11503 [(match_operator:X87MODEF 1 "float_operator" 11504 [(match_operand:SWI24 2 "memory_operand")]) 11505 (match_operand:X87MODEF 3 "register_operand")]) 11506 (match_operand 4) 11507 (match_operand 5))) 11508 (clobber (reg:CCFP FPSR_REG)) 11509 (clobber (reg:CCFP FLAGS_REG)) 11510 (clobber (match_scratch:HI 6))] 11511 "TARGET_80387 && !TARGET_CMOVE 11512 && reload_completed" 11513 [(const_int 0)] 11514{ 11515 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3], 11516 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]), 11517 operands[4], operands[5], operands[6]); 11518 DONE; 11519}) 11520 11521;; Unconditional and other jump instructions 11522 11523(define_insn "jump_bnd" 11524 [(set (pc) 11525 (label_ref (match_operand 0)))] 11526 "TARGET_MPX && ix86_bnd_prefixed_insn_p (insn)" 11527 "bnd jmp\t%l0" 11528 [(set_attr "type" "ibr") 11529 (set (attr "length") 11530 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11531 (const_int -126)) 11532 (lt (minus (match_dup 0) (pc)) 11533 (const_int 128))) 11534 (const_int 3) 11535 (const_int 6))) 11536 (set_attr "modrm" "0")]) 11537 11538(define_insn "jump" 11539 [(set (pc) 11540 (label_ref (match_operand 0)))] 11541 "" 11542 "jmp\t%l0" 11543 [(set_attr "type" "ibr") 11544 (set (attr "length") 11545 (if_then_else (and (ge (minus (match_dup 0) (pc)) 11546 (const_int -126)) 11547 (lt (minus (match_dup 0) (pc)) 11548 (const_int 128))) 11549 (const_int 2) 11550 (const_int 5))) 11551 (set_attr "modrm" "0")]) 11552 11553(define_expand "indirect_jump" 11554 [(set (pc) (match_operand 0 "indirect_branch_operand"))] 11555 "" 11556{ 11557 if (TARGET_X32) 11558 operands[0] = convert_memory_address (word_mode, operands[0]); 11559}) 11560 11561(define_insn "*indirect_jump" 11562 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] 11563 "" 11564 "%!jmp\t%A0" 11565 [(set_attr "type" "ibr") 11566 (set_attr "length_immediate" "0")]) 11567 11568(define_expand "tablejump" 11569 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand")) 11570 (use (label_ref (match_operand 1)))])] 11571 "" 11572{ 11573 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 11574 relative. Convert the relative address to an absolute address. */ 11575 if (flag_pic) 11576 { 11577 rtx op0, op1; 11578 enum rtx_code code; 11579 11580 /* We can't use @GOTOFF for text labels on VxWorks; 11581 see gotoff_operand. */ 11582 if (TARGET_64BIT || TARGET_VXWORKS_RTP) 11583 { 11584 code = PLUS; 11585 op0 = operands[0]; 11586 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 11587 } 11588 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 11589 { 11590 code = PLUS; 11591 op0 = operands[0]; 11592 op1 = pic_offset_table_rtx; 11593 } 11594 else 11595 { 11596 code = MINUS; 11597 op0 = pic_offset_table_rtx; 11598 op1 = operands[0]; 11599 } 11600 11601 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 11602 OPTAB_DIRECT); 11603 } 11604 11605 if (TARGET_X32) 11606 operands[0] = convert_memory_address (word_mode, operands[0]); 11607}) 11608 11609(define_insn "*tablejump_1" 11610 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) 11611 (use (label_ref (match_operand 1)))] 11612 "" 11613 "%!jmp\t%A0" 11614 [(set_attr "type" "ibr") 11615 (set_attr "length_immediate" "0")]) 11616 11617;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 11618 11619(define_peephole2 11620 [(set (reg FLAGS_REG) (match_operand 0)) 11621 (set (match_operand:QI 1 "register_operand") 11622 (match_operator:QI 2 "ix86_comparison_operator" 11623 [(reg FLAGS_REG) (const_int 0)])) 11624 (set (match_operand 3 "q_regs_operand") 11625 (zero_extend (match_dup 1)))] 11626 "(peep2_reg_dead_p (3, operands[1]) 11627 || operands_match_p (operands[1], operands[3])) 11628 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11629 [(set (match_dup 4) (match_dup 0)) 11630 (set (strict_low_part (match_dup 5)) 11631 (match_dup 2))] 11632{ 11633 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11634 operands[5] = gen_lowpart (QImode, operands[3]); 11635 ix86_expand_clear (operands[3]); 11636}) 11637 11638(define_peephole2 11639 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 11640 (match_operand 4)]) 11641 (set (match_operand:QI 1 "register_operand") 11642 (match_operator:QI 2 "ix86_comparison_operator" 11643 [(reg FLAGS_REG) (const_int 0)])) 11644 (set (match_operand 3 "q_regs_operand") 11645 (zero_extend (match_dup 1)))] 11646 "(peep2_reg_dead_p (3, operands[1]) 11647 || operands_match_p (operands[1], operands[3])) 11648 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11649 [(parallel [(set (match_dup 5) (match_dup 0)) 11650 (match_dup 4)]) 11651 (set (strict_low_part (match_dup 6)) 11652 (match_dup 2))] 11653{ 11654 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11655 operands[6] = gen_lowpart (QImode, operands[3]); 11656 ix86_expand_clear (operands[3]); 11657}) 11658 11659;; Similar, but match zero extend with andsi3. 11660 11661(define_peephole2 11662 [(set (reg FLAGS_REG) (match_operand 0)) 11663 (set (match_operand:QI 1 "register_operand") 11664 (match_operator:QI 2 "ix86_comparison_operator" 11665 [(reg FLAGS_REG) (const_int 0)])) 11666 (parallel [(set (match_operand:SI 3 "q_regs_operand") 11667 (and:SI (match_dup 3) (const_int 255))) 11668 (clobber (reg:CC FLAGS_REG))])] 11669 "REGNO (operands[1]) == REGNO (operands[3]) 11670 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11671 [(set (match_dup 4) (match_dup 0)) 11672 (set (strict_low_part (match_dup 5)) 11673 (match_dup 2))] 11674{ 11675 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11676 operands[5] = gen_lowpart (QImode, operands[3]); 11677 ix86_expand_clear (operands[3]); 11678}) 11679 11680(define_peephole2 11681 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 11682 (match_operand 4)]) 11683 (set (match_operand:QI 1 "register_operand") 11684 (match_operator:QI 2 "ix86_comparison_operator" 11685 [(reg FLAGS_REG) (const_int 0)])) 11686 (parallel [(set (match_operand 3 "q_regs_operand") 11687 (zero_extend (match_dup 1))) 11688 (clobber (reg:CC FLAGS_REG))])] 11689 "(peep2_reg_dead_p (3, operands[1]) 11690 || operands_match_p (operands[1], operands[3])) 11691 && ! reg_overlap_mentioned_p (operands[3], operands[0])" 11692 [(parallel [(set (match_dup 5) (match_dup 0)) 11693 (match_dup 4)]) 11694 (set (strict_low_part (match_dup 6)) 11695 (match_dup 2))] 11696{ 11697 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 11698 operands[6] = gen_lowpart (QImode, operands[3]); 11699 ix86_expand_clear (operands[3]); 11700}) 11701 11702;; Call instructions. 11703 11704;; The predicates normally associated with named expanders are not properly 11705;; checked for calls. This is a bug in the generic code, but it isn't that 11706;; easy to fix. Ignore it for now and be prepared to fix things up. 11707 11708;; P6 processors will jump to the address after the decrement when %esp 11709;; is used as a call operand, so they will execute return address as a code. 11710;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 11711 11712;; Register constraint for call instruction. 11713(define_mode_attr c [(SI "l") (DI "r")]) 11714 11715;; Call subroutine returning no value. 11716 11717(define_expand "call" 11718 [(call (match_operand:QI 0) 11719 (match_operand 1)) 11720 (use (match_operand 2))] 11721 "" 11722{ 11723 ix86_expand_call (NULL, operands[0], operands[1], 11724 operands[2], NULL, false); 11725 DONE; 11726}) 11727 11728(define_expand "sibcall" 11729 [(call (match_operand:QI 0) 11730 (match_operand 1)) 11731 (use (match_operand 2))] 11732 "" 11733{ 11734 ix86_expand_call (NULL, operands[0], operands[1], 11735 operands[2], NULL, true); 11736 DONE; 11737}) 11738 11739(define_insn "*call" 11740 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz")) 11741 (match_operand 1))] 11742 "!SIBLING_CALL_P (insn)" 11743 "* return ix86_output_call_insn (insn, operands[0]);" 11744 [(set_attr "type" "call")]) 11745 11746(define_insn "*sibcall" 11747 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz")) 11748 (match_operand 1))] 11749 "SIBLING_CALL_P (insn)" 11750 "* return ix86_output_call_insn (insn, operands[0]);" 11751 [(set_attr "type" "call")]) 11752 11753(define_insn "*sibcall_memory" 11754 [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) 11755 (match_operand 1)) 11756 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 11757 "!TARGET_X32" 11758 "* return ix86_output_call_insn (insn, operands[0]);" 11759 [(set_attr "type" "call")]) 11760 11761(define_peephole2 11762 [(set (match_operand:W 0 "register_operand") 11763 (match_operand:W 1 "memory_operand")) 11764 (call (mem:QI (match_dup 0)) 11765 (match_operand 3))] 11766 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) 11767 && peep2_reg_dead_p (2, operands[0])" 11768 [(parallel [(call (mem:QI (match_dup 1)) 11769 (match_dup 3)) 11770 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 11771 11772(define_peephole2 11773 [(set (match_operand:W 0 "register_operand") 11774 (match_operand:W 1 "memory_operand")) 11775 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 11776 (call (mem:QI (match_dup 0)) 11777 (match_operand 3))] 11778 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) 11779 && peep2_reg_dead_p (3, operands[0])" 11780 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 11781 (parallel [(call (mem:QI (match_dup 1)) 11782 (match_dup 3)) 11783 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 11784 11785(define_expand "call_pop" 11786 [(parallel [(call (match_operand:QI 0) 11787 (match_operand:SI 1)) 11788 (set (reg:SI SP_REG) 11789 (plus:SI (reg:SI SP_REG) 11790 (match_operand:SI 3)))])] 11791 "!TARGET_64BIT" 11792{ 11793 ix86_expand_call (NULL, operands[0], operands[1], 11794 operands[2], operands[3], false); 11795 DONE; 11796}) 11797 11798(define_insn "*call_pop" 11799 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz")) 11800 (match_operand 1)) 11801 (set (reg:SI SP_REG) 11802 (plus:SI (reg:SI SP_REG) 11803 (match_operand:SI 2 "immediate_operand" "i")))] 11804 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 11805 "* return ix86_output_call_insn (insn, operands[0]);" 11806 [(set_attr "type" "call")]) 11807 11808(define_insn "*sibcall_pop" 11809 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz")) 11810 (match_operand 1)) 11811 (set (reg:SI SP_REG) 11812 (plus:SI (reg:SI SP_REG) 11813 (match_operand:SI 2 "immediate_operand" "i")))] 11814 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 11815 "* return ix86_output_call_insn (insn, operands[0]);" 11816 [(set_attr "type" "call")]) 11817 11818(define_insn "*sibcall_pop_memory" 11819 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m")) 11820 (match_operand 1)) 11821 (set (reg:SI SP_REG) 11822 (plus:SI (reg:SI SP_REG) 11823 (match_operand:SI 2 "immediate_operand" "i"))) 11824 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 11825 "!TARGET_64BIT" 11826 "* return ix86_output_call_insn (insn, operands[0]);" 11827 [(set_attr "type" "call")]) 11828 11829(define_peephole2 11830 [(set (match_operand:SI 0 "register_operand") 11831 (match_operand:SI 1 "memory_operand")) 11832 (parallel [(call (mem:QI (match_dup 0)) 11833 (match_operand 3)) 11834 (set (reg:SI SP_REG) 11835 (plus:SI (reg:SI SP_REG) 11836 (match_operand:SI 4 "immediate_operand")))])] 11837 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 11838 && peep2_reg_dead_p (2, operands[0])" 11839 [(parallel [(call (mem:QI (match_dup 1)) 11840 (match_dup 3)) 11841 (set (reg:SI SP_REG) 11842 (plus:SI (reg:SI SP_REG) 11843 (match_dup 4))) 11844 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 11845 11846(define_peephole2 11847 [(set (match_operand:SI 0 "register_operand") 11848 (match_operand:SI 1 "memory_operand")) 11849 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 11850 (parallel [(call (mem:QI (match_dup 0)) 11851 (match_operand 3)) 11852 (set (reg:SI SP_REG) 11853 (plus:SI (reg:SI SP_REG) 11854 (match_operand:SI 4 "immediate_operand")))])] 11855 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 11856 && peep2_reg_dead_p (3, operands[0])" 11857 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 11858 (parallel [(call (mem:QI (match_dup 1)) 11859 (match_dup 3)) 11860 (set (reg:SI SP_REG) 11861 (plus:SI (reg:SI SP_REG) 11862 (match_dup 4))) 11863 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 11864 11865;; Combining simple memory jump instruction 11866 11867(define_peephole2 11868 [(set (match_operand:W 0 "register_operand") 11869 (match_operand:W 1 "memory_operand")) 11870 (set (pc) (match_dup 0))] 11871 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])" 11872 [(set (pc) (match_dup 1))]) 11873 11874;; Call subroutine, returning value in operand 0 11875 11876(define_expand "call_value" 11877 [(set (match_operand 0) 11878 (call (match_operand:QI 1) 11879 (match_operand 2))) 11880 (use (match_operand 3))] 11881 "" 11882{ 11883 ix86_expand_call (operands[0], operands[1], operands[2], 11884 operands[3], NULL, false); 11885 DONE; 11886}) 11887 11888(define_expand "sibcall_value" 11889 [(set (match_operand 0) 11890 (call (match_operand:QI 1) 11891 (match_operand 2))) 11892 (use (match_operand 3))] 11893 "" 11894{ 11895 ix86_expand_call (operands[0], operands[1], operands[2], 11896 operands[3], NULL, true); 11897 DONE; 11898}) 11899 11900(define_insn "*call_value" 11901 [(set (match_operand 0) 11902 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz")) 11903 (match_operand 2)))] 11904 "!SIBLING_CALL_P (insn)" 11905 "* return ix86_output_call_insn (insn, operands[1]);" 11906 [(set_attr "type" "callv")]) 11907 11908(define_insn "*sibcall_value" 11909 [(set (match_operand 0) 11910 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz")) 11911 (match_operand 2)))] 11912 "SIBLING_CALL_P (insn)" 11913 "* return ix86_output_call_insn (insn, operands[1]);" 11914 [(set_attr "type" "callv")]) 11915 11916(define_insn "*sibcall_value_memory" 11917 [(set (match_operand 0) 11918 (call (mem:QI (match_operand:W 1 "memory_operand" "m")) 11919 (match_operand 2))) 11920 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 11921 "!TARGET_X32" 11922 "* return ix86_output_call_insn (insn, operands[1]);" 11923 [(set_attr "type" "callv")]) 11924 11925(define_peephole2 11926 [(set (match_operand:W 0 "register_operand") 11927 (match_operand:W 1 "memory_operand")) 11928 (set (match_operand 2) 11929 (call (mem:QI (match_dup 0)) 11930 (match_operand 3)))] 11931 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1)) 11932 && peep2_reg_dead_p (2, operands[0])" 11933 [(parallel [(set (match_dup 2) 11934 (call (mem:QI (match_dup 1)) 11935 (match_dup 3))) 11936 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 11937 11938(define_peephole2 11939 [(set (match_operand:W 0 "register_operand") 11940 (match_operand:W 1 "memory_operand")) 11941 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 11942 (set (match_operand 2) 11943 (call (mem:QI (match_dup 0)) 11944 (match_operand 3)))] 11945 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2)) 11946 && peep2_reg_dead_p (3, operands[0])" 11947 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 11948 (parallel [(set (match_dup 2) 11949 (call (mem:QI (match_dup 1)) 11950 (match_dup 3))) 11951 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 11952 11953(define_expand "call_value_pop" 11954 [(parallel [(set (match_operand 0) 11955 (call (match_operand:QI 1) 11956 (match_operand:SI 2))) 11957 (set (reg:SI SP_REG) 11958 (plus:SI (reg:SI SP_REG) 11959 (match_operand:SI 4)))])] 11960 "!TARGET_64BIT" 11961{ 11962 ix86_expand_call (operands[0], operands[1], operands[2], 11963 operands[3], operands[4], false); 11964 DONE; 11965}) 11966 11967(define_insn "*call_value_pop" 11968 [(set (match_operand 0) 11969 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz")) 11970 (match_operand 2))) 11971 (set (reg:SI SP_REG) 11972 (plus:SI (reg:SI SP_REG) 11973 (match_operand:SI 3 "immediate_operand" "i")))] 11974 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 11975 "* return ix86_output_call_insn (insn, operands[1]);" 11976 [(set_attr "type" "callv")]) 11977 11978(define_insn "*sibcall_value_pop" 11979 [(set (match_operand 0) 11980 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz")) 11981 (match_operand 2))) 11982 (set (reg:SI SP_REG) 11983 (plus:SI (reg:SI SP_REG) 11984 (match_operand:SI 3 "immediate_operand" "i")))] 11985 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 11986 "* return ix86_output_call_insn (insn, operands[1]);" 11987 [(set_attr "type" "callv")]) 11988 11989(define_insn "*sibcall_value_pop_memory" 11990 [(set (match_operand 0) 11991 (call (mem:QI (match_operand:SI 1 "memory_operand" "m")) 11992 (match_operand 2))) 11993 (set (reg:SI SP_REG) 11994 (plus:SI (reg:SI SP_REG) 11995 (match_operand:SI 3 "immediate_operand" "i"))) 11996 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 11997 "!TARGET_64BIT" 11998 "* return ix86_output_call_insn (insn, operands[1]);" 11999 [(set_attr "type" "callv")]) 12000 12001(define_peephole2 12002 [(set (match_operand:SI 0 "register_operand") 12003 (match_operand:SI 1 "memory_operand")) 12004 (parallel [(set (match_operand 2) 12005 (call (mem:QI (match_dup 0)) 12006 (match_operand 3))) 12007 (set (reg:SI SP_REG) 12008 (plus:SI (reg:SI SP_REG) 12009 (match_operand:SI 4 "immediate_operand")))])] 12010 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 12011 && peep2_reg_dead_p (2, operands[0])" 12012 [(parallel [(set (match_dup 2) 12013 (call (mem:QI (match_dup 1)) 12014 (match_dup 3))) 12015 (set (reg:SI SP_REG) 12016 (plus:SI (reg:SI SP_REG) 12017 (match_dup 4))) 12018 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12019 12020(define_peephole2 12021 [(set (match_operand:SI 0 "register_operand") 12022 (match_operand:SI 1 "memory_operand")) 12023 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12024 (parallel [(set (match_operand 2) 12025 (call (mem:QI (match_dup 0)) 12026 (match_operand 3))) 12027 (set (reg:SI SP_REG) 12028 (plus:SI (reg:SI SP_REG) 12029 (match_operand:SI 4 "immediate_operand")))])] 12030 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 12031 && peep2_reg_dead_p (3, operands[0])" 12032 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12033 (parallel [(set (match_dup 2) 12034 (call (mem:QI (match_dup 1)) 12035 (match_dup 3))) 12036 (set (reg:SI SP_REG) 12037 (plus:SI (reg:SI SP_REG) 12038 (match_dup 4))) 12039 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12040 12041;; Call subroutine returning any type. 12042 12043(define_expand "untyped_call" 12044 [(parallel [(call (match_operand 0) 12045 (const_int 0)) 12046 (match_operand 1) 12047 (match_operand 2)])] 12048 "" 12049{ 12050 int i; 12051 12052 /* In order to give reg-stack an easier job in validating two 12053 coprocessor registers as containing a possible return value, 12054 simply pretend the untyped call returns a complex long double 12055 value. 12056 12057 We can't use SSE_REGPARM_MAX here since callee is unprototyped 12058 and should have the default ABI. */ 12059 12060 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 12061 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 12062 operands[0], const0_rtx, 12063 GEN_INT ((TARGET_64BIT 12064 ? (ix86_abi == SYSV_ABI 12065 ? X86_64_SSE_REGPARM_MAX 12066 : X86_64_MS_SSE_REGPARM_MAX) 12067 : X86_32_SSE_REGPARM_MAX) 12068 - 1), 12069 NULL, false); 12070 12071 for (i = 0; i < XVECLEN (operands[2], 0); i++) 12072 { 12073 rtx set = XVECEXP (operands[2], 0, i); 12074 emit_move_insn (SET_DEST (set), SET_SRC (set)); 12075 } 12076 12077 /* The optimizer does not know that the call sets the function value 12078 registers we stored in the result block. We avoid problems by 12079 claiming that all hard registers are used and clobbered at this 12080 point. */ 12081 emit_insn (gen_blockage ()); 12082 12083 DONE; 12084}) 12085 12086;; Prologue and epilogue instructions 12087 12088;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 12089;; all of memory. This blocks insns from being moved across this point. 12090 12091(define_insn "blockage" 12092 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 12093 "" 12094 "" 12095 [(set_attr "length" "0")]) 12096 12097;; Do not schedule instructions accessing memory across this point. 12098 12099(define_expand "memory_blockage" 12100 [(set (match_dup 0) 12101 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 12102 "" 12103{ 12104 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 12105 MEM_VOLATILE_P (operands[0]) = 1; 12106}) 12107 12108(define_insn "*memory_blockage" 12109 [(set (match_operand:BLK 0) 12110 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 12111 "" 12112 "" 12113 [(set_attr "length" "0")]) 12114 12115;; As USE insns aren't meaningful after reload, this is used instead 12116;; to prevent deleting instructions setting registers for PIC code 12117(define_insn "prologue_use" 12118 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)] 12119 "" 12120 "" 12121 [(set_attr "length" "0")]) 12122 12123;; Insn emitted into the body of a function to return from a function. 12124;; This is only done if the function's epilogue is known to be simple. 12125;; See comments for ix86_can_use_return_insn_p in i386.c. 12126 12127(define_expand "return" 12128 [(simple_return)] 12129 "ix86_can_use_return_insn_p ()" 12130{ 12131 if (crtl->args.pops_args) 12132 { 12133 rtx popc = GEN_INT (crtl->args.pops_args); 12134 emit_jump_insn (gen_simple_return_pop_internal (popc)); 12135 DONE; 12136 } 12137}) 12138 12139;; We need to disable this for TARGET_SEH, as otherwise 12140;; shrink-wrapped prologue gets enabled too. This might exceed 12141;; the maximum size of prologue in unwind information. 12142;; Also disallow shrink-wrapping if using stack slot to pass the 12143;; static chain pointer - the first instruction has to be pushl %esi 12144;; and it can't be moved around, as we use alternate entry points 12145;; in that case. 12146 12147(define_expand "simple_return" 12148 [(simple_return)] 12149 "!TARGET_SEH && !ix86_static_chain_on_stack" 12150{ 12151 if (crtl->args.pops_args) 12152 { 12153 rtx popc = GEN_INT (crtl->args.pops_args); 12154 emit_jump_insn (gen_simple_return_pop_internal (popc)); 12155 DONE; 12156 } 12157}) 12158 12159(define_insn "simple_return_internal" 12160 [(simple_return)] 12161 "reload_completed" 12162 "%!ret" 12163 [(set_attr "length_nobnd" "1") 12164 (set_attr "atom_unit" "jeu") 12165 (set_attr "length_immediate" "0") 12166 (set_attr "modrm" "0")]) 12167 12168;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 12169;; instruction Athlon and K8 have. 12170 12171(define_insn "simple_return_internal_long" 12172 [(simple_return) 12173 (unspec [(const_int 0)] UNSPEC_REP)] 12174 "reload_completed" 12175{ 12176 if (ix86_bnd_prefixed_insn_p (insn)) 12177 return "%!ret"; 12178 12179 return "rep%; ret"; 12180} 12181 [(set_attr "length" "2") 12182 (set_attr "atom_unit" "jeu") 12183 (set_attr "length_immediate" "0") 12184 (set_attr "prefix_rep" "1") 12185 (set_attr "modrm" "0")]) 12186 12187(define_insn "simple_return_pop_internal" 12188 [(simple_return) 12189 (use (match_operand:SI 0 "const_int_operand"))] 12190 "reload_completed" 12191 "%!ret\t%0" 12192 [(set_attr "length_nobnd" "3") 12193 (set_attr "atom_unit" "jeu") 12194 (set_attr "length_immediate" "2") 12195 (set_attr "modrm" "0")]) 12196 12197(define_insn "simple_return_indirect_internal" 12198 [(simple_return) 12199 (use (match_operand:SI 0 "register_operand" "r"))] 12200 "reload_completed" 12201 "%!jmp\t%A0" 12202 [(set_attr "type" "ibr") 12203 (set_attr "length_immediate" "0")]) 12204 12205(define_insn "nop" 12206 [(const_int 0)] 12207 "" 12208 "nop" 12209 [(set_attr "length" "1") 12210 (set_attr "length_immediate" "0") 12211 (set_attr "modrm" "0")]) 12212 12213;; Generate nops. Operand 0 is the number of nops, up to 8. 12214(define_insn "nops" 12215 [(unspec_volatile [(match_operand 0 "const_int_operand")] 12216 UNSPECV_NOPS)] 12217 "reload_completed" 12218{ 12219 int num = INTVAL (operands[0]); 12220 12221 gcc_assert (IN_RANGE (num, 1, 8)); 12222 12223 while (num--) 12224 fputs ("\tnop\n", asm_out_file); 12225 12226 return ""; 12227} 12228 [(set (attr "length") (symbol_ref "INTVAL (operands[0])")) 12229 (set_attr "length_immediate" "0") 12230 (set_attr "modrm" "0")]) 12231 12232;; Pad to 16-byte boundary, max skip in op0. Used to avoid 12233;; branch prediction penalty for the third jump in a 16-byte 12234;; block on K8. 12235 12236(define_insn "pad" 12237 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)] 12238 "" 12239{ 12240#ifdef ASM_OUTPUT_MAX_SKIP_PAD 12241 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); 12242#else 12243 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 12244 The align insn is used to avoid 3 jump instructions in the row to improve 12245 branch prediction and the benefits hardly outweigh the cost of extra 8 12246 nops on the average inserted by full alignment pseudo operation. */ 12247#endif 12248 return ""; 12249} 12250 [(set_attr "length" "16")]) 12251 12252(define_expand "prologue" 12253 [(const_int 0)] 12254 "" 12255 "ix86_expand_prologue (); DONE;") 12256 12257(define_insn "set_got" 12258 [(set (match_operand:SI 0 "register_operand" "=r") 12259 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 12260 (clobber (reg:CC FLAGS_REG))] 12261 "!TARGET_64BIT" 12262 "* return output_set_got (operands[0], NULL_RTX);" 12263 [(set_attr "type" "multi") 12264 (set_attr "length" "12")]) 12265 12266(define_insn "set_got_labelled" 12267 [(set (match_operand:SI 0 "register_operand" "=r") 12268 (unspec:SI [(label_ref (match_operand 1))] 12269 UNSPEC_SET_GOT)) 12270 (clobber (reg:CC FLAGS_REG))] 12271 "!TARGET_64BIT" 12272 "* return output_set_got (operands[0], operands[1]);" 12273 [(set_attr "type" "multi") 12274 (set_attr "length" "12")]) 12275 12276(define_insn "set_got_rex64" 12277 [(set (match_operand:DI 0 "register_operand" "=r") 12278 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 12279 "TARGET_64BIT" 12280 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" 12281 [(set_attr "type" "lea") 12282 (set_attr "length_address" "4") 12283 (set_attr "mode" "DI")]) 12284 12285(define_insn "set_rip_rex64" 12286 [(set (match_operand:DI 0 "register_operand" "=r") 12287 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))] 12288 "TARGET_64BIT" 12289 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" 12290 [(set_attr "type" "lea") 12291 (set_attr "length_address" "4") 12292 (set_attr "mode" "DI")]) 12293 12294(define_insn "set_got_offset_rex64" 12295 [(set (match_operand:DI 0 "register_operand" "=r") 12296 (unspec:DI 12297 [(label_ref (match_operand 1))] 12298 UNSPEC_SET_GOT_OFFSET))] 12299 "TARGET_LP64" 12300 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" 12301 [(set_attr "type" "imov") 12302 (set_attr "length_immediate" "0") 12303 (set_attr "length_address" "8") 12304 (set_attr "mode" "DI")]) 12305 12306(define_expand "epilogue" 12307 [(const_int 0)] 12308 "" 12309 "ix86_expand_epilogue (1); DONE;") 12310 12311(define_expand "sibcall_epilogue" 12312 [(const_int 0)] 12313 "" 12314 "ix86_expand_epilogue (0); DONE;") 12315 12316(define_expand "eh_return" 12317 [(use (match_operand 0 "register_operand"))] 12318 "" 12319{ 12320 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 12321 12322 /* Tricky bit: we write the address of the handler to which we will 12323 be returning into someone else's stack frame, one word below the 12324 stack address we wish to restore. */ 12325 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 12326 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD); 12327 tmp = gen_rtx_MEM (Pmode, tmp); 12328 emit_move_insn (tmp, ra); 12329 12330 emit_jump_insn (gen_eh_return_internal ()); 12331 emit_barrier (); 12332 DONE; 12333}) 12334 12335(define_insn_and_split "eh_return_internal" 12336 [(eh_return)] 12337 "" 12338 "#" 12339 "epilogue_completed" 12340 [(const_int 0)] 12341 "ix86_expand_epilogue (2); DONE;") 12342 12343(define_insn "leave" 12344 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 12345 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 12346 (clobber (mem:BLK (scratch)))] 12347 "!TARGET_64BIT" 12348 "leave" 12349 [(set_attr "type" "leave")]) 12350 12351(define_insn "leave_rex64" 12352 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 12353 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 12354 (clobber (mem:BLK (scratch)))] 12355 "TARGET_64BIT" 12356 "leave" 12357 [(set_attr "type" "leave")]) 12358 12359;; Handle -fsplit-stack. 12360 12361(define_expand "split_stack_prologue" 12362 [(const_int 0)] 12363 "" 12364{ 12365 ix86_expand_split_stack_prologue (); 12366 DONE; 12367}) 12368 12369;; In order to support the call/return predictor, we use a return 12370;; instruction which the middle-end doesn't see. 12371(define_insn "split_stack_return" 12372 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] 12373 UNSPECV_SPLIT_STACK_RETURN)] 12374 "" 12375{ 12376 if (operands[0] == const0_rtx) 12377 return "ret"; 12378 else 12379 return "ret\t%0"; 12380} 12381 [(set_attr "atom_unit" "jeu") 12382 (set_attr "modrm" "0") 12383 (set (attr "length") 12384 (if_then_else (match_operand:SI 0 "const0_operand") 12385 (const_int 1) 12386 (const_int 3))) 12387 (set (attr "length_immediate") 12388 (if_then_else (match_operand:SI 0 "const0_operand") 12389 (const_int 0) 12390 (const_int 2)))]) 12391 12392;; If there are operand 0 bytes available on the stack, jump to 12393;; operand 1. 12394 12395(define_expand "split_stack_space_check" 12396 [(set (pc) (if_then_else 12397 (ltu (minus (reg SP_REG) 12398 (match_operand 0 "register_operand")) 12399 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 12400 (label_ref (match_operand 1)) 12401 (pc)))] 12402 "" 12403{ 12404 rtx reg, size, limit; 12405 12406 reg = gen_reg_rtx (Pmode); 12407 size = force_reg (Pmode, operands[0]); 12408 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size)); 12409 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), 12410 UNSPEC_STACK_CHECK); 12411 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit)); 12412 ix86_expand_branch (GEU, reg, limit, operands[1]); 12413 12414 DONE; 12415}) 12416 12417;; Bit manipulation instructions. 12418 12419(define_expand "ffs<mode>2" 12420 [(set (match_dup 2) (const_int -1)) 12421 (parallel [(set (match_dup 3) (match_dup 4)) 12422 (set (match_operand:SWI48 0 "register_operand") 12423 (ctz:SWI48 12424 (match_operand:SWI48 1 "nonimmediate_operand")))]) 12425 (set (match_dup 0) (if_then_else:SWI48 12426 (eq (match_dup 3) (const_int 0)) 12427 (match_dup 2) 12428 (match_dup 0))) 12429 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) 12430 (clobber (reg:CC FLAGS_REG))])] 12431 "" 12432{ 12433 machine_mode flags_mode; 12434 12435 if (<MODE>mode == SImode && !TARGET_CMOVE) 12436 { 12437 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); 12438 DONE; 12439 } 12440 12441 flags_mode 12442 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode; 12443 12444 operands[2] = gen_reg_rtx (<MODE>mode); 12445 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG); 12446 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 12447}) 12448 12449(define_insn_and_split "ffssi2_no_cmove" 12450 [(set (match_operand:SI 0 "register_operand" "=r") 12451 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 12452 (clobber (match_scratch:SI 2 "=&q")) 12453 (clobber (reg:CC FLAGS_REG))] 12454 "!TARGET_CMOVE" 12455 "#" 12456 "&& reload_completed" 12457 [(parallel [(set (match_dup 4) (match_dup 5)) 12458 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 12459 (set (strict_low_part (match_dup 3)) 12460 (eq:QI (match_dup 4) (const_int 0))) 12461 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 12462 (clobber (reg:CC FLAGS_REG))]) 12463 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 12464 (clobber (reg:CC FLAGS_REG))]) 12465 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 12466 (clobber (reg:CC FLAGS_REG))])] 12467{ 12468 machine_mode flags_mode 12469 = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode; 12470 12471 operands[3] = gen_lowpart (QImode, operands[2]); 12472 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG); 12473 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 12474 12475 ix86_expand_clear (operands[2]); 12476}) 12477 12478(define_insn "*tzcnt<mode>_1" 12479 [(set (reg:CCC FLAGS_REG) 12480 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12481 (const_int 0))) 12482 (set (match_operand:SWI48 0 "register_operand" "=r") 12483 (ctz:SWI48 (match_dup 1)))] 12484 "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI" 12485 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 12486 [(set_attr "type" "alu1") 12487 (set_attr "prefix_0f" "1") 12488 (set_attr "prefix_rep" "1") 12489 (set_attr "btver2_decode" "double") 12490 (set_attr "mode" "<MODE>")]) 12491 12492(define_insn "*bsf<mode>_1" 12493 [(set (reg:CCZ FLAGS_REG) 12494 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12495 (const_int 0))) 12496 (set (match_operand:SWI48 0 "register_operand" "=r") 12497 (ctz:SWI48 (match_dup 1)))] 12498 "" 12499 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" 12500 [(set_attr "type" "alu1") 12501 (set_attr "prefix_0f" "1") 12502 (set_attr "btver2_decode" "double") 12503 (set_attr "mode" "<MODE>")]) 12504 12505(define_expand "ctz<mode>2" 12506 [(parallel 12507 [(set (match_operand:SWI248 0 "register_operand") 12508 (ctz:SWI248 12509 (match_operand:SWI248 1 "nonimmediate_operand"))) 12510 (clobber (reg:CC FLAGS_REG))])]) 12511 12512; False dependency happens when destination is only updated by tzcnt, 12513; lzcnt or popcnt. There is no false dependency when destination is 12514; also used in source. 12515(define_insn_and_split "*ctz<mode>2_falsedep_1" 12516 [(set (match_operand:SWI48 0 "register_operand" "=r") 12517 (ctz:SWI48 12518 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 12519 (clobber (reg:CC FLAGS_REG))] 12520 "(TARGET_BMI || TARGET_GENERIC) 12521 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" 12522 "#" 12523 "&& reload_completed" 12524 [(parallel 12525 [(set (match_dup 0) 12526 (ctz:SWI48 (match_dup 1))) 12527 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 12528 (clobber (reg:CC FLAGS_REG))])] 12529{ 12530 if (!reg_mentioned_p (operands[0], operands[1])) 12531 ix86_expand_clear (operands[0]); 12532}) 12533 12534(define_insn "*ctz<mode>2_falsedep" 12535 [(set (match_operand:SWI48 0 "register_operand" "=r") 12536 (ctz:SWI48 12537 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 12538 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 12539 UNSPEC_INSN_FALSE_DEP) 12540 (clobber (reg:CC FLAGS_REG))] 12541 "" 12542{ 12543 if (TARGET_BMI) 12544 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12545 else if (TARGET_GENERIC) 12546 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 12547 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 12548 else 12549 gcc_unreachable (); 12550} 12551 [(set_attr "type" "alu1") 12552 (set_attr "prefix_0f" "1") 12553 (set_attr "prefix_rep" "1") 12554 (set_attr "mode" "<MODE>")]) 12555 12556(define_insn "*ctz<mode>2" 12557 [(set (match_operand:SWI248 0 "register_operand" "=r") 12558 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12559 (clobber (reg:CC FLAGS_REG))] 12560 "" 12561{ 12562 if (TARGET_BMI) 12563 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 12564 else if (optimize_function_for_size_p (cfun)) 12565 ; 12566 else if (TARGET_GENERIC) 12567 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 12568 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 12569 12570 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 12571} 12572 [(set_attr "type" "alu1") 12573 (set_attr "prefix_0f" "1") 12574 (set (attr "prefix_rep") 12575 (if_then_else 12576 (ior (match_test "TARGET_BMI") 12577 (and (not (match_test "optimize_function_for_size_p (cfun)")) 12578 (match_test "TARGET_GENERIC"))) 12579 (const_string "1") 12580 (const_string "0"))) 12581 (set_attr "mode" "<MODE>")]) 12582 12583(define_expand "clz<mode>2" 12584 [(parallel 12585 [(set (match_operand:SWI248 0 "register_operand") 12586 (minus:SWI248 12587 (match_dup 2) 12588 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")))) 12589 (clobber (reg:CC FLAGS_REG))]) 12590 (parallel 12591 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2))) 12592 (clobber (reg:CC FLAGS_REG))])] 12593 "" 12594{ 12595 if (TARGET_LZCNT) 12596 { 12597 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1])); 12598 DONE; 12599 } 12600 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 12601}) 12602 12603(define_expand "clz<mode>2_lzcnt" 12604 [(parallel 12605 [(set (match_operand:SWI248 0 "register_operand") 12606 (clz:SWI248 12607 (match_operand:SWI248 1 "nonimmediate_operand"))) 12608 (clobber (reg:CC FLAGS_REG))])] 12609 "TARGET_LZCNT") 12610 12611(define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1" 12612 [(set (match_operand:SWI48 0 "register_operand" "=r") 12613 (clz:SWI48 12614 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 12615 (clobber (reg:CC FLAGS_REG))] 12616 "TARGET_LZCNT 12617 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" 12618 "#" 12619 "&& reload_completed" 12620 [(parallel 12621 [(set (match_dup 0) 12622 (clz:SWI48 (match_dup 1))) 12623 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 12624 (clobber (reg:CC FLAGS_REG))])] 12625{ 12626 if (!reg_mentioned_p (operands[0], operands[1])) 12627 ix86_expand_clear (operands[0]); 12628}) 12629 12630(define_insn "*clz<mode>2_lzcnt_falsedep" 12631 [(set (match_operand:SWI48 0 "register_operand" "=r") 12632 (clz:SWI48 12633 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 12634 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 12635 UNSPEC_INSN_FALSE_DEP) 12636 (clobber (reg:CC FLAGS_REG))] 12637 "TARGET_LZCNT" 12638 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 12639 [(set_attr "prefix_rep" "1") 12640 (set_attr "type" "bitmanip") 12641 (set_attr "mode" "<MODE>")]) 12642 12643(define_insn "*clz<mode>2_lzcnt" 12644 [(set (match_operand:SWI248 0 "register_operand" "=r") 12645 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 12646 (clobber (reg:CC FLAGS_REG))] 12647 "TARGET_LZCNT" 12648 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 12649 [(set_attr "prefix_rep" "1") 12650 (set_attr "type" "bitmanip") 12651 (set_attr "mode" "<MODE>")]) 12652 12653;; BMI instructions. 12654(define_insn "*bmi_andn_<mode>" 12655 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 12656 (and:SWI48 12657 (not:SWI48 12658 (match_operand:SWI48 1 "register_operand" "r,r")) 12659 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))) 12660 (clobber (reg:CC FLAGS_REG))] 12661 "TARGET_BMI" 12662 "andn\t{%2, %1, %0|%0, %1, %2}" 12663 [(set_attr "type" "bitmanip") 12664 (set_attr "btver2_decode" "direct, double") 12665 (set_attr "mode" "<MODE>")]) 12666 12667(define_insn "bmi_bextr_<mode>" 12668 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 12669 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 12670 (match_operand:SWI48 2 "register_operand" "r,r")] 12671 UNSPEC_BEXTR)) 12672 (clobber (reg:CC FLAGS_REG))] 12673 "TARGET_BMI" 12674 "bextr\t{%2, %1, %0|%0, %1, %2}" 12675 [(set_attr "type" "bitmanip") 12676 (set_attr "btver2_decode" "direct, double") 12677 (set_attr "mode" "<MODE>")]) 12678 12679(define_insn "*bmi_blsi_<mode>" 12680 [(set (match_operand:SWI48 0 "register_operand" "=r") 12681 (and:SWI48 12682 (neg:SWI48 12683 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 12684 (match_dup 1))) 12685 (clobber (reg:CC FLAGS_REG))] 12686 "TARGET_BMI" 12687 "blsi\t{%1, %0|%0, %1}" 12688 [(set_attr "type" "bitmanip") 12689 (set_attr "btver2_decode" "double") 12690 (set_attr "mode" "<MODE>")]) 12691 12692(define_insn "*bmi_blsmsk_<mode>" 12693 [(set (match_operand:SWI48 0 "register_operand" "=r") 12694 (xor:SWI48 12695 (plus:SWI48 12696 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12697 (const_int -1)) 12698 (match_dup 1))) 12699 (clobber (reg:CC FLAGS_REG))] 12700 "TARGET_BMI" 12701 "blsmsk\t{%1, %0|%0, %1}" 12702 [(set_attr "type" "bitmanip") 12703 (set_attr "btver2_decode" "double") 12704 (set_attr "mode" "<MODE>")]) 12705 12706(define_insn "*bmi_blsr_<mode>" 12707 [(set (match_operand:SWI48 0 "register_operand" "=r") 12708 (and:SWI48 12709 (plus:SWI48 12710 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12711 (const_int -1)) 12712 (match_dup 1))) 12713 (clobber (reg:CC FLAGS_REG))] 12714 "TARGET_BMI" 12715 "blsr\t{%1, %0|%0, %1}" 12716 [(set_attr "type" "bitmanip") 12717 (set_attr "btver2_decode" "double") 12718 (set_attr "mode" "<MODE>")]) 12719 12720;; BMI2 instructions. 12721(define_expand "bmi2_bzhi_<mode>3" 12722 [(parallel 12723 [(set (match_operand:SWI48 0 "register_operand") 12724 (zero_extract:SWI48 12725 (match_operand:SWI48 1 "nonimmediate_operand") 12726 (umin:SWI48 12727 (and:SWI48 (match_operand:SWI48 2 "register_operand") 12728 (const_int 255)) 12729 (match_dup 3)) 12730 (const_int 0))) 12731 (clobber (reg:CC FLAGS_REG))])] 12732 "TARGET_BMI2" 12733 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);") 12734 12735(define_insn "*bmi2_bzhi_<mode>3" 12736 [(set (match_operand:SWI48 0 "register_operand" "=r") 12737 (zero_extract:SWI48 12738 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12739 (umin:SWI48 12740 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r") 12741 (const_int 255)) 12742 (match_operand:SWI48 3 "const_int_operand" "n")) 12743 (const_int 0))) 12744 (clobber (reg:CC FLAGS_REG))] 12745 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 12746 "bzhi\t{%2, %1, %0|%0, %1, %2}" 12747 [(set_attr "type" "bitmanip") 12748 (set_attr "prefix" "vex") 12749 (set_attr "mode" "<MODE>")]) 12750 12751(define_mode_attr k [(SI "k") (DI "q")]) 12752(define_insn "*bmi2_bzhi_<mode>3_1" 12753 [(set (match_operand:SWI48 0 "register_operand" "=r") 12754 (zero_extract:SWI48 12755 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12756 (umin:SWI48 12757 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r")) 12758 (match_operand:SWI48 3 "const_int_operand" "n")) 12759 (const_int 0))) 12760 (clobber (reg:CC FLAGS_REG))] 12761 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 12762 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 12763 [(set_attr "type" "bitmanip") 12764 (set_attr "prefix" "vex") 12765 (set_attr "mode" "<MODE>")]) 12766 12767(define_insn "bmi2_pdep_<mode>3" 12768 [(set (match_operand:SWI48 0 "register_operand" "=r") 12769 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12770 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12771 UNSPEC_PDEP))] 12772 "TARGET_BMI2" 12773 "pdep\t{%2, %1, %0|%0, %1, %2}" 12774 [(set_attr "type" "bitmanip") 12775 (set_attr "prefix" "vex") 12776 (set_attr "mode" "<MODE>")]) 12777 12778(define_insn "bmi2_pext_<mode>3" 12779 [(set (match_operand:SWI48 0 "register_operand" "=r") 12780 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 12781 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 12782 UNSPEC_PEXT))] 12783 "TARGET_BMI2" 12784 "pext\t{%2, %1, %0|%0, %1, %2}" 12785 [(set_attr "type" "bitmanip") 12786 (set_attr "prefix" "vex") 12787 (set_attr "mode" "<MODE>")]) 12788 12789;; TBM instructions. 12790(define_insn "tbm_bextri_<mode>" 12791 [(set (match_operand:SWI48 0 "register_operand" "=r") 12792 (zero_extract:SWI48 12793 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12794 (match_operand:SWI48 2 "const_0_to_255_operand" "n") 12795 (match_operand:SWI48 3 "const_0_to_255_operand" "n"))) 12796 (clobber (reg:CC FLAGS_REG))] 12797 "TARGET_TBM" 12798{ 12799 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); 12800 return "bextr\t{%2, %1, %0|%0, %1, %2}"; 12801} 12802 [(set_attr "type" "bitmanip") 12803 (set_attr "mode" "<MODE>")]) 12804 12805(define_insn "*tbm_blcfill_<mode>" 12806 [(set (match_operand:SWI48 0 "register_operand" "=r") 12807 (and:SWI48 12808 (plus:SWI48 12809 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12810 (const_int 1)) 12811 (match_dup 1))) 12812 (clobber (reg:CC FLAGS_REG))] 12813 "TARGET_TBM" 12814 "blcfill\t{%1, %0|%0, %1}" 12815 [(set_attr "type" "bitmanip") 12816 (set_attr "mode" "<MODE>")]) 12817 12818(define_insn "*tbm_blci_<mode>" 12819 [(set (match_operand:SWI48 0 "register_operand" "=r") 12820 (ior:SWI48 12821 (not:SWI48 12822 (plus:SWI48 12823 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12824 (const_int 1))) 12825 (match_dup 1))) 12826 (clobber (reg:CC FLAGS_REG))] 12827 "TARGET_TBM" 12828 "blci\t{%1, %0|%0, %1}" 12829 [(set_attr "type" "bitmanip") 12830 (set_attr "mode" "<MODE>")]) 12831 12832(define_insn "*tbm_blcic_<mode>" 12833 [(set (match_operand:SWI48 0 "register_operand" "=r") 12834 (and:SWI48 12835 (plus:SWI48 12836 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12837 (const_int 1)) 12838 (not:SWI48 12839 (match_dup 1)))) 12840 (clobber (reg:CC FLAGS_REG))] 12841 "TARGET_TBM" 12842 "blcic\t{%1, %0|%0, %1}" 12843 [(set_attr "type" "bitmanip") 12844 (set_attr "mode" "<MODE>")]) 12845 12846(define_insn "*tbm_blcmsk_<mode>" 12847 [(set (match_operand:SWI48 0 "register_operand" "=r") 12848 (xor:SWI48 12849 (plus:SWI48 12850 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12851 (const_int 1)) 12852 (match_dup 1))) 12853 (clobber (reg:CC FLAGS_REG))] 12854 "TARGET_TBM" 12855 "blcmsk\t{%1, %0|%0, %1}" 12856 [(set_attr "type" "bitmanip") 12857 (set_attr "mode" "<MODE>")]) 12858 12859(define_insn "*tbm_blcs_<mode>" 12860 [(set (match_operand:SWI48 0 "register_operand" "=r") 12861 (ior:SWI48 12862 (plus:SWI48 12863 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12864 (const_int 1)) 12865 (match_dup 1))) 12866 (clobber (reg:CC FLAGS_REG))] 12867 "TARGET_TBM" 12868 "blcs\t{%1, %0|%0, %1}" 12869 [(set_attr "type" "bitmanip") 12870 (set_attr "mode" "<MODE>")]) 12871 12872(define_insn "*tbm_blsfill_<mode>" 12873 [(set (match_operand:SWI48 0 "register_operand" "=r") 12874 (ior:SWI48 12875 (plus:SWI48 12876 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12877 (const_int -1)) 12878 (match_dup 1))) 12879 (clobber (reg:CC FLAGS_REG))] 12880 "TARGET_TBM" 12881 "blsfill\t{%1, %0|%0, %1}" 12882 [(set_attr "type" "bitmanip") 12883 (set_attr "mode" "<MODE>")]) 12884 12885(define_insn "*tbm_blsic_<mode>" 12886 [(set (match_operand:SWI48 0 "register_operand" "=r") 12887 (ior:SWI48 12888 (plus:SWI48 12889 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12890 (const_int -1)) 12891 (not:SWI48 12892 (match_dup 1)))) 12893 (clobber (reg:CC FLAGS_REG))] 12894 "TARGET_TBM" 12895 "blsic\t{%1, %0|%0, %1}" 12896 [(set_attr "type" "bitmanip") 12897 (set_attr "mode" "<MODE>")]) 12898 12899(define_insn "*tbm_t1mskc_<mode>" 12900 [(set (match_operand:SWI48 0 "register_operand" "=r") 12901 (ior:SWI48 12902 (plus:SWI48 12903 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12904 (const_int 1)) 12905 (not:SWI48 12906 (match_dup 1)))) 12907 (clobber (reg:CC FLAGS_REG))] 12908 "TARGET_TBM" 12909 "t1mskc\t{%1, %0|%0, %1}" 12910 [(set_attr "type" "bitmanip") 12911 (set_attr "mode" "<MODE>")]) 12912 12913(define_insn "*tbm_tzmsk_<mode>" 12914 [(set (match_operand:SWI48 0 "register_operand" "=r") 12915 (and:SWI48 12916 (plus:SWI48 12917 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 12918 (const_int -1)) 12919 (not:SWI48 12920 (match_dup 1)))) 12921 (clobber (reg:CC FLAGS_REG))] 12922 "TARGET_TBM" 12923 "tzmsk\t{%1, %0|%0, %1}" 12924 [(set_attr "type" "bitmanip") 12925 (set_attr "mode" "<MODE>")]) 12926 12927(define_insn "bsr_rex64" 12928 [(set (match_operand:DI 0 "register_operand" "=r") 12929 (minus:DI (const_int 63) 12930 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))) 12931 (clobber (reg:CC FLAGS_REG))] 12932 "TARGET_64BIT" 12933 "bsr{q}\t{%1, %0|%0, %1}" 12934 [(set_attr "type" "alu1") 12935 (set_attr "prefix_0f" "1") 12936 (set_attr "mode" "DI")]) 12937 12938(define_insn "bsr" 12939 [(set (match_operand:SI 0 "register_operand" "=r") 12940 (minus:SI (const_int 31) 12941 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))) 12942 (clobber (reg:CC FLAGS_REG))] 12943 "" 12944 "bsr{l}\t{%1, %0|%0, %1}" 12945 [(set_attr "type" "alu1") 12946 (set_attr "prefix_0f" "1") 12947 (set_attr "mode" "SI")]) 12948 12949(define_insn "*bsrhi" 12950 [(set (match_operand:HI 0 "register_operand" "=r") 12951 (minus:HI (const_int 15) 12952 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))) 12953 (clobber (reg:CC FLAGS_REG))] 12954 "" 12955 "bsr{w}\t{%1, %0|%0, %1}" 12956 [(set_attr "type" "alu1") 12957 (set_attr "prefix_0f" "1") 12958 (set_attr "mode" "HI")]) 12959 12960(define_expand "popcount<mode>2" 12961 [(parallel 12962 [(set (match_operand:SWI248 0 "register_operand") 12963 (popcount:SWI248 12964 (match_operand:SWI248 1 "nonimmediate_operand"))) 12965 (clobber (reg:CC FLAGS_REG))])] 12966 "TARGET_POPCNT") 12967 12968(define_insn_and_split "*popcount<mode>2_falsedep_1" 12969 [(set (match_operand:SWI48 0 "register_operand" "=r") 12970 (popcount:SWI48 12971 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 12972 (clobber (reg:CC FLAGS_REG))] 12973 "TARGET_POPCNT 12974 && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)" 12975 "#" 12976 "&& reload_completed" 12977 [(parallel 12978 [(set (match_dup 0) 12979 (popcount:SWI48 (match_dup 1))) 12980 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 12981 (clobber (reg:CC FLAGS_REG))])] 12982{ 12983 if (!reg_mentioned_p (operands[0], operands[1])) 12984 ix86_expand_clear (operands[0]); 12985}) 12986 12987(define_insn "*popcount<mode>2_falsedep" 12988 [(set (match_operand:SWI48 0 "register_operand" "=r") 12989 (popcount:SWI48 12990 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 12991 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 12992 UNSPEC_INSN_FALSE_DEP) 12993 (clobber (reg:CC FLAGS_REG))] 12994 "TARGET_POPCNT" 12995{ 12996#if TARGET_MACHO 12997 return "popcnt\t{%1, %0|%0, %1}"; 12998#else 12999 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13000#endif 13001} 13002 [(set_attr "prefix_rep" "1") 13003 (set_attr "type" "bitmanip") 13004 (set_attr "mode" "<MODE>")]) 13005 13006(define_insn "*popcount<mode>2" 13007 [(set (match_operand:SWI248 0 "register_operand" "=r") 13008 (popcount:SWI248 13009 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))) 13010 (clobber (reg:CC FLAGS_REG))] 13011 "TARGET_POPCNT" 13012{ 13013#if TARGET_MACHO 13014 return "popcnt\t{%1, %0|%0, %1}"; 13015#else 13016 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13017#endif 13018} 13019 [(set_attr "prefix_rep" "1") 13020 (set_attr "type" "bitmanip") 13021 (set_attr "mode" "<MODE>")]) 13022 13023(define_expand "bswapdi2" 13024 [(set (match_operand:DI 0 "register_operand") 13025 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))] 13026 "TARGET_64BIT" 13027{ 13028 if (!TARGET_MOVBE) 13029 operands[1] = force_reg (DImode, operands[1]); 13030}) 13031 13032(define_expand "bswapsi2" 13033 [(set (match_operand:SI 0 "register_operand") 13034 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))] 13035 "" 13036{ 13037 if (TARGET_MOVBE) 13038 ; 13039 else if (TARGET_BSWAP) 13040 operands[1] = force_reg (SImode, operands[1]); 13041 else 13042 { 13043 rtx x = operands[0]; 13044 13045 emit_move_insn (x, operands[1]); 13046 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 13047 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 13048 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 13049 DONE; 13050 } 13051}) 13052 13053(define_insn "*bswap<mode>2_movbe" 13054 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") 13055 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] 13056 "TARGET_MOVBE 13057 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 13058 "@ 13059 bswap\t%0 13060 movbe\t{%1, %0|%0, %1} 13061 movbe\t{%1, %0|%0, %1}" 13062 [(set_attr "type" "bitmanip,imov,imov") 13063 (set_attr "modrm" "0,1,1") 13064 (set_attr "prefix_0f" "*,1,1") 13065 (set_attr "prefix_extra" "*,1,1") 13066 (set_attr "mode" "<MODE>")]) 13067 13068(define_insn "*bswap<mode>2" 13069 [(set (match_operand:SWI48 0 "register_operand" "=r") 13070 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] 13071 "TARGET_BSWAP" 13072 "bswap\t%0" 13073 [(set_attr "type" "bitmanip") 13074 (set_attr "modrm" "0") 13075 (set_attr "mode" "<MODE>")]) 13076 13077(define_insn "*bswaphi_lowpart_1" 13078 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) 13079 (bswap:HI (match_dup 0))) 13080 (clobber (reg:CC FLAGS_REG))] 13081 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)" 13082 "@ 13083 xchg{b}\t{%h0, %b0|%b0, %h0} 13084 rol{w}\t{$8, %0|%0, 8}" 13085 [(set_attr "length" "2,4") 13086 (set_attr "mode" "QI,HI")]) 13087 13088(define_insn "bswaphi_lowpart" 13089 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r")) 13090 (bswap:HI (match_dup 0))) 13091 (clobber (reg:CC FLAGS_REG))] 13092 "" 13093 "rol{w}\t{$8, %0|%0, 8}" 13094 [(set_attr "length" "4") 13095 (set_attr "mode" "HI")]) 13096 13097(define_expand "paritydi2" 13098 [(set (match_operand:DI 0 "register_operand") 13099 (parity:DI (match_operand:DI 1 "register_operand")))] 13100 "! TARGET_POPCNT" 13101{ 13102 rtx scratch = gen_reg_rtx (QImode); 13103 rtx cond; 13104 13105 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, 13106 NULL_RTX, operands[1])); 13107 13108 cond = gen_rtx_fmt_ee (ORDERED, QImode, 13109 gen_rtx_REG (CCmode, FLAGS_REG), 13110 const0_rtx); 13111 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); 13112 13113 if (TARGET_64BIT) 13114 emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); 13115 else 13116 { 13117 rtx tmp = gen_reg_rtx (SImode); 13118 13119 emit_insn (gen_zero_extendqisi2 (tmp, scratch)); 13120 emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); 13121 } 13122 DONE; 13123}) 13124 13125(define_expand "paritysi2" 13126 [(set (match_operand:SI 0 "register_operand") 13127 (parity:SI (match_operand:SI 1 "register_operand")))] 13128 "! TARGET_POPCNT" 13129{ 13130 rtx scratch = gen_reg_rtx (QImode); 13131 rtx cond; 13132 13133 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); 13134 13135 cond = gen_rtx_fmt_ee (ORDERED, QImode, 13136 gen_rtx_REG (CCmode, FLAGS_REG), 13137 const0_rtx); 13138 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); 13139 13140 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 13141 DONE; 13142}) 13143 13144(define_insn_and_split "paritydi2_cmp" 13145 [(set (reg:CC FLAGS_REG) 13146 (unspec:CC [(match_operand:DI 3 "register_operand" "0")] 13147 UNSPEC_PARITY)) 13148 (clobber (match_scratch:DI 0 "=r")) 13149 (clobber (match_scratch:SI 1 "=&r")) 13150 (clobber (match_scratch:HI 2 "=Q"))] 13151 "! TARGET_POPCNT" 13152 "#" 13153 "&& reload_completed" 13154 [(parallel 13155 [(set (match_dup 1) 13156 (xor:SI (match_dup 1) (match_dup 4))) 13157 (clobber (reg:CC FLAGS_REG))]) 13158 (parallel 13159 [(set (reg:CC FLAGS_REG) 13160 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 13161 (clobber (match_dup 1)) 13162 (clobber (match_dup 2))])] 13163{ 13164 operands[4] = gen_lowpart (SImode, operands[3]); 13165 13166 if (TARGET_64BIT) 13167 { 13168 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); 13169 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); 13170 } 13171 else 13172 operands[1] = gen_highpart (SImode, operands[3]); 13173}) 13174 13175(define_insn_and_split "paritysi2_cmp" 13176 [(set (reg:CC FLAGS_REG) 13177 (unspec:CC [(match_operand:SI 2 "register_operand" "0")] 13178 UNSPEC_PARITY)) 13179 (clobber (match_scratch:SI 0 "=r")) 13180 (clobber (match_scratch:HI 1 "=&Q"))] 13181 "! TARGET_POPCNT" 13182 "#" 13183 "&& reload_completed" 13184 [(parallel 13185 [(set (match_dup 1) 13186 (xor:HI (match_dup 1) (match_dup 3))) 13187 (clobber (reg:CC FLAGS_REG))]) 13188 (parallel 13189 [(set (reg:CC FLAGS_REG) 13190 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 13191 (clobber (match_dup 1))])] 13192{ 13193 operands[3] = gen_lowpart (HImode, operands[2]); 13194 13195 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); 13196 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); 13197}) 13198 13199(define_insn "*parityhi2_cmp" 13200 [(set (reg:CC FLAGS_REG) 13201 (unspec:CC [(match_operand:HI 1 "register_operand" "0")] 13202 UNSPEC_PARITY)) 13203 (clobber (match_scratch:HI 0 "=Q"))] 13204 "! TARGET_POPCNT" 13205 "xor{b}\t{%h0, %b0|%b0, %h0}" 13206 [(set_attr "length" "2") 13207 (set_attr "mode" "HI")]) 13208 13209 13210;; Thread-local storage patterns for ELF. 13211;; 13212;; Note that these code sequences must appear exactly as shown 13213;; in order to allow linker relaxation. 13214 13215(define_insn "*tls_global_dynamic_32_gnu" 13216 [(set (match_operand:SI 0 "register_operand" "=a") 13217 (unspec:SI 13218 [(match_operand:SI 1 "register_operand" "b") 13219 (match_operand 2 "tls_symbolic_operand") 13220 (match_operand 3 "constant_call_address_operand" "Bz") 13221 (reg:SI SP_REG)] 13222 UNSPEC_TLS_GD)) 13223 (clobber (match_scratch:SI 4 "=d")) 13224 (clobber (match_scratch:SI 5 "=c")) 13225 (clobber (reg:CC FLAGS_REG))] 13226 "!TARGET_64BIT && TARGET_GNU_TLS" 13227{ 13228 output_asm_insn 13229 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); 13230 if (TARGET_SUN_TLS) 13231#ifdef HAVE_AS_IX86_TLSGDPLT 13232 return "call\t%a2@tlsgdplt"; 13233#else 13234 return "call\t%p3@plt"; 13235#endif 13236 return "call\t%P3"; 13237} 13238 [(set_attr "type" "multi") 13239 (set_attr "length" "12")]) 13240 13241(define_expand "tls_global_dynamic_32" 13242 [(parallel 13243 [(set (match_operand:SI 0 "register_operand") 13244 (unspec:SI [(match_operand:SI 2 "register_operand") 13245 (match_operand 1 "tls_symbolic_operand") 13246 (match_operand 3 "constant_call_address_operand") 13247 (reg:SI SP_REG)] 13248 UNSPEC_TLS_GD)) 13249 (clobber (match_scratch:SI 4)) 13250 (clobber (match_scratch:SI 5)) 13251 (clobber (reg:CC FLAGS_REG))])] 13252 "" 13253 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 13254 13255(define_insn "*tls_global_dynamic_64_<mode>" 13256 [(set (match_operand:P 0 "register_operand" "=a") 13257 (call:P 13258 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz")) 13259 (match_operand 3))) 13260 (unspec:P [(match_operand 1 "tls_symbolic_operand") 13261 (reg:P SP_REG)] 13262 UNSPEC_TLS_GD)] 13263 "TARGET_64BIT" 13264{ 13265 if (!TARGET_X32) 13266 fputs (ASM_BYTE "0x66\n", asm_out_file); 13267 output_asm_insn 13268 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 13269 fputs (ASM_SHORT "0x6666\n", asm_out_file); 13270 fputs ("\trex64\n", asm_out_file); 13271 if (TARGET_SUN_TLS) 13272 return "call\t%p2@plt"; 13273 return "call\t%P2"; 13274} 13275 [(set_attr "type" "multi") 13276 (set (attr "length") 13277 (symbol_ref "TARGET_X32 ? 15 : 16"))]) 13278 13279(define_insn "*tls_global_dynamic_64_largepic" 13280 [(set (match_operand:DI 0 "register_operand" "=a") 13281 (call:DI 13282 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b") 13283 (match_operand:DI 3 "immediate_operand" "i"))) 13284 (match_operand 4))) 13285 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 13286 (reg:DI SP_REG)] 13287 UNSPEC_TLS_GD)] 13288 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 13289 && GET_CODE (operands[3]) == CONST 13290 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC 13291 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF" 13292{ 13293 output_asm_insn 13294 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 13295 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands); 13296 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands); 13297 return "call\t{*%%rax|rax}"; 13298} 13299 [(set_attr "type" "multi") 13300 (set_attr "length" "22")]) 13301 13302(define_expand "tls_global_dynamic_64_<mode>" 13303 [(parallel 13304 [(set (match_operand:P 0 "register_operand") 13305 (call:P 13306 (mem:QI (match_operand 2)) 13307 (const_int 0))) 13308 (unspec:P [(match_operand 1 "tls_symbolic_operand") 13309 (reg:P SP_REG)] 13310 UNSPEC_TLS_GD)])] 13311 "TARGET_64BIT" 13312 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 13313 13314(define_insn "*tls_local_dynamic_base_32_gnu" 13315 [(set (match_operand:SI 0 "register_operand" "=a") 13316 (unspec:SI 13317 [(match_operand:SI 1 "register_operand" "b") 13318 (match_operand 2 "constant_call_address_operand" "Bz") 13319 (reg:SI SP_REG)] 13320 UNSPEC_TLS_LD_BASE)) 13321 (clobber (match_scratch:SI 3 "=d")) 13322 (clobber (match_scratch:SI 4 "=c")) 13323 (clobber (reg:CC FLAGS_REG))] 13324 "!TARGET_64BIT && TARGET_GNU_TLS" 13325{ 13326 output_asm_insn 13327 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); 13328 if (TARGET_SUN_TLS) 13329 { 13330 if (HAVE_AS_IX86_TLSLDMPLT) 13331 return "call\t%&@tlsldmplt"; 13332 else 13333 return "call\t%p2@plt"; 13334 } 13335 return "call\t%P2"; 13336} 13337 [(set_attr "type" "multi") 13338 (set_attr "length" "11")]) 13339 13340(define_expand "tls_local_dynamic_base_32" 13341 [(parallel 13342 [(set (match_operand:SI 0 "register_operand") 13343 (unspec:SI 13344 [(match_operand:SI 1 "register_operand") 13345 (match_operand 2 "constant_call_address_operand") 13346 (reg:SI SP_REG)] 13347 UNSPEC_TLS_LD_BASE)) 13348 (clobber (match_scratch:SI 3)) 13349 (clobber (match_scratch:SI 4)) 13350 (clobber (reg:CC FLAGS_REG))])] 13351 "" 13352 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 13353 13354(define_insn "*tls_local_dynamic_base_64_<mode>" 13355 [(set (match_operand:P 0 "register_operand" "=a") 13356 (call:P 13357 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz")) 13358 (match_operand 2))) 13359 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)] 13360 "TARGET_64BIT" 13361{ 13362 output_asm_insn 13363 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 13364 if (TARGET_SUN_TLS) 13365 return "call\t%p1@plt"; 13366 return "call\t%P1"; 13367} 13368 [(set_attr "type" "multi") 13369 (set_attr "length" "12")]) 13370 13371(define_insn "*tls_local_dynamic_base_64_largepic" 13372 [(set (match_operand:DI 0 "register_operand" "=a") 13373 (call:DI 13374 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b") 13375 (match_operand:DI 2 "immediate_operand" "i"))) 13376 (match_operand 3))) 13377 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)] 13378 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 13379 && GET_CODE (operands[2]) == CONST 13380 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC 13381 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF" 13382{ 13383 output_asm_insn 13384 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 13385 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands); 13386 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands); 13387 return "call\t{*%%rax|rax}"; 13388} 13389 [(set_attr "type" "multi") 13390 (set_attr "length" "22")]) 13391 13392(define_expand "tls_local_dynamic_base_64_<mode>" 13393 [(parallel 13394 [(set (match_operand:P 0 "register_operand") 13395 (call:P 13396 (mem:QI (match_operand 1)) 13397 (const_int 0))) 13398 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])] 13399 "TARGET_64BIT" 13400 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 13401 13402;; Local dynamic of a single variable is a lose. Show combine how 13403;; to convert that back to global dynamic. 13404 13405(define_insn_and_split "*tls_local_dynamic_32_once" 13406 [(set (match_operand:SI 0 "register_operand" "=a") 13407 (plus:SI 13408 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 13409 (match_operand 2 "constant_call_address_operand" "Bz") 13410 (reg:SI SP_REG)] 13411 UNSPEC_TLS_LD_BASE) 13412 (const:SI (unspec:SI 13413 [(match_operand 3 "tls_symbolic_operand")] 13414 UNSPEC_DTPOFF)))) 13415 (clobber (match_scratch:SI 4 "=d")) 13416 (clobber (match_scratch:SI 5 "=c")) 13417 (clobber (reg:CC FLAGS_REG))] 13418 "" 13419 "#" 13420 "" 13421 [(parallel 13422 [(set (match_dup 0) 13423 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2) 13424 (reg:SI SP_REG)] 13425 UNSPEC_TLS_GD)) 13426 (clobber (match_dup 4)) 13427 (clobber (match_dup 5)) 13428 (clobber (reg:CC FLAGS_REG))])]) 13429 13430;; Segment register for the thread base ptr load 13431(define_mode_attr tp_seg [(SI "gs") (DI "fs")]) 13432 13433;; Load and add the thread base pointer from %<tp_seg>:0. 13434(define_insn "*load_tp_x32" 13435 [(set (match_operand:SI 0 "register_operand" "=r") 13436 (unspec:SI [(const_int 0)] UNSPEC_TP))] 13437 "TARGET_X32" 13438 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" 13439 [(set_attr "type" "imov") 13440 (set_attr "modrm" "0") 13441 (set_attr "length" "7") 13442 (set_attr "memory" "load") 13443 (set_attr "imm_disp" "false")]) 13444 13445(define_insn "*load_tp_x32_zext" 13446 [(set (match_operand:DI 0 "register_operand" "=r") 13447 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))] 13448 "TARGET_X32" 13449 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" 13450 [(set_attr "type" "imov") 13451 (set_attr "modrm" "0") 13452 (set_attr "length" "7") 13453 (set_attr "memory" "load") 13454 (set_attr "imm_disp" "false")]) 13455 13456(define_insn "*load_tp_<mode>" 13457 [(set (match_operand:P 0 "register_operand" "=r") 13458 (unspec:P [(const_int 0)] UNSPEC_TP))] 13459 "!TARGET_X32" 13460 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}" 13461 [(set_attr "type" "imov") 13462 (set_attr "modrm" "0") 13463 (set_attr "length" "7") 13464 (set_attr "memory" "load") 13465 (set_attr "imm_disp" "false")]) 13466 13467(define_insn "*add_tp_x32" 13468 [(set (match_operand:SI 0 "register_operand" "=r") 13469 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 13470 (match_operand:SI 1 "register_operand" "0"))) 13471 (clobber (reg:CC FLAGS_REG))] 13472 "TARGET_X32" 13473 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}" 13474 [(set_attr "type" "alu") 13475 (set_attr "modrm" "0") 13476 (set_attr "length" "7") 13477 (set_attr "memory" "load") 13478 (set_attr "imm_disp" "false")]) 13479 13480(define_insn "*add_tp_x32_zext" 13481 [(set (match_operand:DI 0 "register_operand" "=r") 13482 (zero_extend:DI 13483 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 13484 (match_operand:SI 1 "register_operand" "0")))) 13485 (clobber (reg:CC FLAGS_REG))] 13486 "TARGET_X32" 13487 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}" 13488 [(set_attr "type" "alu") 13489 (set_attr "modrm" "0") 13490 (set_attr "length" "7") 13491 (set_attr "memory" "load") 13492 (set_attr "imm_disp" "false")]) 13493 13494(define_insn "*add_tp_<mode>" 13495 [(set (match_operand:P 0 "register_operand" "=r") 13496 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP) 13497 (match_operand:P 1 "register_operand" "0"))) 13498 (clobber (reg:CC FLAGS_REG))] 13499 "!TARGET_X32" 13500 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}" 13501 [(set_attr "type" "alu") 13502 (set_attr "modrm" "0") 13503 (set_attr "length" "7") 13504 (set_attr "memory" "load") 13505 (set_attr "imm_disp" "false")]) 13506 13507;; The Sun linker took the AMD64 TLS spec literally and can only handle 13508;; %rax as destination of the initial executable code sequence. 13509(define_insn "tls_initial_exec_64_sun" 13510 [(set (match_operand:DI 0 "register_operand" "=a") 13511 (unspec:DI 13512 [(match_operand 1 "tls_symbolic_operand")] 13513 UNSPEC_TLS_IE_SUN)) 13514 (clobber (reg:CC FLAGS_REG))] 13515 "TARGET_64BIT && TARGET_SUN_TLS" 13516{ 13517 output_asm_insn 13518 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); 13519 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; 13520} 13521 [(set_attr "type" "multi")]) 13522 13523;; GNU2 TLS patterns can be split. 13524 13525(define_expand "tls_dynamic_gnu2_32" 13526 [(set (match_dup 3) 13527 (plus:SI (match_operand:SI 2 "register_operand") 13528 (const:SI 13529 (unspec:SI [(match_operand 1 "tls_symbolic_operand")] 13530 UNSPEC_TLSDESC)))) 13531 (parallel 13532 [(set (match_operand:SI 0 "register_operand") 13533 (unspec:SI [(match_dup 1) (match_dup 3) 13534 (match_dup 2) (reg:SI SP_REG)] 13535 UNSPEC_TLSDESC)) 13536 (clobber (reg:CC FLAGS_REG))])] 13537 "!TARGET_64BIT && TARGET_GNU2_TLS" 13538{ 13539 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 13540 ix86_tls_descriptor_calls_expanded_in_cfun = true; 13541}) 13542 13543(define_insn "*tls_dynamic_gnu2_lea_32" 13544 [(set (match_operand:SI 0 "register_operand" "=r") 13545 (plus:SI (match_operand:SI 1 "register_operand" "b") 13546 (const:SI 13547 (unspec:SI [(match_operand 2 "tls_symbolic_operand")] 13548 UNSPEC_TLSDESC))))] 13549 "!TARGET_64BIT && TARGET_GNU2_TLS" 13550 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" 13551 [(set_attr "type" "lea") 13552 (set_attr "mode" "SI") 13553 (set_attr "length" "6") 13554 (set_attr "length_address" "4")]) 13555 13556(define_insn "*tls_dynamic_gnu2_call_32" 13557 [(set (match_operand:SI 0 "register_operand" "=a") 13558 (unspec:SI [(match_operand 1 "tls_symbolic_operand") 13559 (match_operand:SI 2 "register_operand" "0") 13560 ;; we have to make sure %ebx still points to the GOT 13561 (match_operand:SI 3 "register_operand" "b") 13562 (reg:SI SP_REG)] 13563 UNSPEC_TLSDESC)) 13564 (clobber (reg:CC FLAGS_REG))] 13565 "!TARGET_64BIT && TARGET_GNU2_TLS" 13566 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 13567 [(set_attr "type" "call") 13568 (set_attr "length" "2") 13569 (set_attr "length_address" "0")]) 13570 13571(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 13572 [(set (match_operand:SI 0 "register_operand" "=&a") 13573 (plus:SI 13574 (unspec:SI [(match_operand 3 "tls_modbase_operand") 13575 (match_operand:SI 4) 13576 (match_operand:SI 2 "register_operand" "b") 13577 (reg:SI SP_REG)] 13578 UNSPEC_TLSDESC) 13579 (const:SI (unspec:SI 13580 [(match_operand 1 "tls_symbolic_operand")] 13581 UNSPEC_DTPOFF)))) 13582 (clobber (reg:CC FLAGS_REG))] 13583 "!TARGET_64BIT && TARGET_GNU2_TLS" 13584 "#" 13585 "" 13586 [(set (match_dup 0) (match_dup 5))] 13587{ 13588 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 13589 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 13590}) 13591 13592(define_expand "tls_dynamic_gnu2_64" 13593 [(set (match_dup 2) 13594 (unspec:DI [(match_operand 1 "tls_symbolic_operand")] 13595 UNSPEC_TLSDESC)) 13596 (parallel 13597 [(set (match_operand:DI 0 "register_operand") 13598 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)] 13599 UNSPEC_TLSDESC)) 13600 (clobber (reg:CC FLAGS_REG))])] 13601 "TARGET_64BIT && TARGET_GNU2_TLS" 13602{ 13603 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 13604 ix86_tls_descriptor_calls_expanded_in_cfun = true; 13605}) 13606 13607(define_insn "*tls_dynamic_gnu2_lea_64" 13608 [(set (match_operand:DI 0 "register_operand" "=r") 13609 (unspec:DI [(match_operand 1 "tls_symbolic_operand")] 13610 UNSPEC_TLSDESC))] 13611 "TARGET_64BIT && TARGET_GNU2_TLS" 13612 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" 13613 [(set_attr "type" "lea") 13614 (set_attr "mode" "DI") 13615 (set_attr "length" "7") 13616 (set_attr "length_address" "4")]) 13617 13618(define_insn "*tls_dynamic_gnu2_call_64" 13619 [(set (match_operand:DI 0 "register_operand" "=a") 13620 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 13621 (match_operand:DI 2 "register_operand" "0") 13622 (reg:DI SP_REG)] 13623 UNSPEC_TLSDESC)) 13624 (clobber (reg:CC FLAGS_REG))] 13625 "TARGET_64BIT && TARGET_GNU2_TLS" 13626 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 13627 [(set_attr "type" "call") 13628 (set_attr "length" "2") 13629 (set_attr "length_address" "0")]) 13630 13631(define_insn_and_split "*tls_dynamic_gnu2_combine_64" 13632 [(set (match_operand:DI 0 "register_operand" "=&a") 13633 (plus:DI 13634 (unspec:DI [(match_operand 2 "tls_modbase_operand") 13635 (match_operand:DI 3) 13636 (reg:DI SP_REG)] 13637 UNSPEC_TLSDESC) 13638 (const:DI (unspec:DI 13639 [(match_operand 1 "tls_symbolic_operand")] 13640 UNSPEC_DTPOFF)))) 13641 (clobber (reg:CC FLAGS_REG))] 13642 "TARGET_64BIT && TARGET_GNU2_TLS" 13643 "#" 13644 "" 13645 [(set (match_dup 0) (match_dup 4))] 13646{ 13647 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 13648 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1])); 13649}) 13650 13651;; These patterns match the binary 387 instructions for addM3, subM3, 13652;; mulM3 and divM3. There are three patterns for each of DFmode and 13653;; SFmode. The first is the normal insn, the second the same insn but 13654;; with one operand a conversion, and the third the same insn but with 13655;; the other operand a conversion. The conversion may be SFmode or 13656;; SImode if the target mode DFmode, but only SImode if the target mode 13657;; is SFmode. 13658 13659;; Gcc is slightly more smart about handling normal two address instructions 13660;; so use special patterns for add and mull. 13661 13662(define_insn "*fop_<mode>_comm_mixed" 13663 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x") 13664 (match_operator:MODEF 3 "binary_fp_operator" 13665 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x") 13666 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))] 13667 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 13668 && COMMUTATIVE_ARITH_P (operands[3]) 13669 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13670 "* return output_387_binary_op (insn, operands);" 13671 [(set (attr "type") 13672 (if_then_else (eq_attr "alternative" "1,2") 13673 (if_then_else (match_operand:MODEF 3 "mult_operator") 13674 (const_string "ssemul") 13675 (const_string "sseadd")) 13676 (if_then_else (match_operand:MODEF 3 "mult_operator") 13677 (const_string "fmul") 13678 (const_string "fop")))) 13679 (set_attr "isa" "*,noavx,avx") 13680 (set_attr "prefix" "orig,orig,vex") 13681 (set_attr "mode" "<MODE>")]) 13682 13683(define_insn "*fop_<mode>_comm_sse" 13684 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 13685 (match_operator:MODEF 3 "binary_fp_operator" 13686 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v") 13687 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))] 13688 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13689 && COMMUTATIVE_ARITH_P (operands[3]) 13690 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13691 "* return output_387_binary_op (insn, operands);" 13692 [(set (attr "type") 13693 (if_then_else (match_operand:MODEF 3 "mult_operator") 13694 (const_string "ssemul") 13695 (const_string "sseadd"))) 13696 (set_attr "isa" "noavx,avx") 13697 (set_attr "prefix" "orig,vex") 13698 (set_attr "mode" "<MODE>")]) 13699 13700(define_insn "*fop_<mode>_comm_i387" 13701 [(set (match_operand:MODEF 0 "register_operand" "=f") 13702 (match_operator:MODEF 3 "binary_fp_operator" 13703 [(match_operand:MODEF 1 "nonimmediate_operand" "%0") 13704 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))] 13705 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) 13706 && COMMUTATIVE_ARITH_P (operands[3]) 13707 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13708 "* return output_387_binary_op (insn, operands);" 13709 [(set (attr "type") 13710 (if_then_else (match_operand:MODEF 3 "mult_operator") 13711 (const_string "fmul") 13712 (const_string "fop"))) 13713 (set_attr "mode" "<MODE>")]) 13714 13715(define_insn "*fop_<mode>_1_mixed" 13716 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x") 13717 (match_operator:MODEF 3 "binary_fp_operator" 13718 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x") 13719 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))] 13720 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387 13721 && !COMMUTATIVE_ARITH_P (operands[3]) 13722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13723 "* return output_387_binary_op (insn, operands);" 13724 [(set (attr "type") 13725 (cond [(and (eq_attr "alternative" "2,3") 13726 (match_operand:MODEF 3 "mult_operator")) 13727 (const_string "ssemul") 13728 (and (eq_attr "alternative" "2,3") 13729 (match_operand:MODEF 3 "div_operator")) 13730 (const_string "ssediv") 13731 (eq_attr "alternative" "2,3") 13732 (const_string "sseadd") 13733 (match_operand:MODEF 3 "mult_operator") 13734 (const_string "fmul") 13735 (match_operand:MODEF 3 "div_operator") 13736 (const_string "fdiv") 13737 ] 13738 (const_string "fop"))) 13739 (set_attr "isa" "*,*,noavx,avx") 13740 (set_attr "prefix" "orig,orig,orig,vex") 13741 (set_attr "mode" "<MODE>")]) 13742 13743(define_insn "*rcpsf2_sse" 13744 [(set (match_operand:SF 0 "register_operand" "=x") 13745 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 13746 UNSPEC_RCP))] 13747 "TARGET_SSE_MATH" 13748 "%vrcpss\t{%1, %d0|%d0, %1}" 13749 [(set_attr "type" "sse") 13750 (set_attr "atom_sse_attr" "rcp") 13751 (set_attr "btver2_sse_attr" "rcp") 13752 (set_attr "prefix" "maybe_vex") 13753 (set_attr "mode" "SF")]) 13754 13755(define_insn "*fop_<mode>_1_sse" 13756 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 13757 (match_operator:MODEF 3 "binary_fp_operator" 13758 [(match_operand:MODEF 1 "register_operand" "0,x") 13759 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 13760 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 13761 && !COMMUTATIVE_ARITH_P (operands[3])" 13762 "* return output_387_binary_op (insn, operands);" 13763 [(set (attr "type") 13764 (cond [(match_operand:MODEF 3 "mult_operator") 13765 (const_string "ssemul") 13766 (match_operand:MODEF 3 "div_operator") 13767 (const_string "ssediv") 13768 ] 13769 (const_string "sseadd"))) 13770 (set_attr "isa" "noavx,avx") 13771 (set_attr "prefix" "orig,vex") 13772 (set_attr "mode" "<MODE>")]) 13773 13774;; This pattern is not fully shadowed by the pattern above. 13775(define_insn "*fop_<mode>_1_i387" 13776 [(set (match_operand:MODEF 0 "register_operand" "=f,f") 13777 (match_operator:MODEF 3 "binary_fp_operator" 13778 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm") 13779 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))] 13780 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode) 13781 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 13782 && !COMMUTATIVE_ARITH_P (operands[3]) 13783 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13784 "* return output_387_binary_op (insn, operands);" 13785 [(set (attr "type") 13786 (cond [(match_operand:MODEF 3 "mult_operator") 13787 (const_string "fmul") 13788 (match_operand:MODEF 3 "div_operator") 13789 (const_string "fdiv") 13790 ] 13791 (const_string "fop"))) 13792 (set_attr "mode" "<MODE>")]) 13793 13794;; ??? Add SSE splitters for these! 13795(define_insn "*fop_<MODEF:mode>_2_i387" 13796 [(set (match_operand:MODEF 0 "register_operand" "=f") 13797 (match_operator:MODEF 3 "binary_fp_operator" 13798 [(float:MODEF 13799 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 13800 (match_operand:MODEF 2 "register_operand" "0")]))] 13801 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 13802 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 13803 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 13804 || optimize_function_for_size_p (cfun))" 13805 { return output_387_binary_op (insn, operands); } 13806 [(set (attr "type") 13807 (cond [(match_operand:MODEF 3 "mult_operator") 13808 (const_string "fmul") 13809 (match_operand:MODEF 3 "div_operator") 13810 (const_string "fdiv") 13811 ] 13812 (const_string "fop"))) 13813 (set_attr "fp_int_src" "true") 13814 (set_attr "mode" "<SWI24:MODE>")]) 13815 13816(define_insn "*fop_<MODEF:mode>_3_i387" 13817 [(set (match_operand:MODEF 0 "register_operand" "=f") 13818 (match_operator:MODEF 3 "binary_fp_operator" 13819 [(match_operand:MODEF 1 "register_operand" "0") 13820 (float:MODEF 13821 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 13822 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode) 13823 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 13824 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 13825 || optimize_function_for_size_p (cfun))" 13826 { return output_387_binary_op (insn, operands); } 13827 [(set (attr "type") 13828 (cond [(match_operand:MODEF 3 "mult_operator") 13829 (const_string "fmul") 13830 (match_operand:MODEF 3 "div_operator") 13831 (const_string "fdiv") 13832 ] 13833 (const_string "fop"))) 13834 (set_attr "fp_int_src" "true") 13835 (set_attr "mode" "<MODE>")]) 13836 13837(define_insn "*fop_df_4_i387" 13838 [(set (match_operand:DF 0 "register_operand" "=f,f") 13839 (match_operator:DF 3 "binary_fp_operator" 13840 [(float_extend:DF 13841 (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 13842 (match_operand:DF 2 "register_operand" "0,f")]))] 13843 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13844 && !(TARGET_SSE2 && TARGET_SSE_MATH) 13845 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 13846 "* return output_387_binary_op (insn, operands);" 13847 [(set (attr "type") 13848 (cond [(match_operand:DF 3 "mult_operator") 13849 (const_string "fmul") 13850 (match_operand:DF 3 "div_operator") 13851 (const_string "fdiv") 13852 ] 13853 (const_string "fop"))) 13854 (set_attr "mode" "SF")]) 13855 13856(define_insn "*fop_df_5_i387" 13857 [(set (match_operand:DF 0 "register_operand" "=f,f") 13858 (match_operator:DF 3 "binary_fp_operator" 13859 [(match_operand:DF 1 "register_operand" "0,f") 13860 (float_extend:DF 13861 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 13862 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13863 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 13864 "* return output_387_binary_op (insn, operands);" 13865 [(set (attr "type") 13866 (cond [(match_operand:DF 3 "mult_operator") 13867 (const_string "fmul") 13868 (match_operand:DF 3 "div_operator") 13869 (const_string "fdiv") 13870 ] 13871 (const_string "fop"))) 13872 (set_attr "mode" "SF")]) 13873 13874(define_insn "*fop_df_6_i387" 13875 [(set (match_operand:DF 0 "register_operand" "=f,f") 13876 (match_operator:DF 3 "binary_fp_operator" 13877 [(float_extend:DF 13878 (match_operand:SF 1 "register_operand" "0,f")) 13879 (float_extend:DF 13880 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 13881 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 13882 && !(TARGET_SSE2 && TARGET_SSE_MATH)" 13883 "* return output_387_binary_op (insn, operands);" 13884 [(set (attr "type") 13885 (cond [(match_operand:DF 3 "mult_operator") 13886 (const_string "fmul") 13887 (match_operand:DF 3 "div_operator") 13888 (const_string "fdiv") 13889 ] 13890 (const_string "fop"))) 13891 (set_attr "mode" "SF")]) 13892 13893(define_insn "*fop_xf_comm_i387" 13894 [(set (match_operand:XF 0 "register_operand" "=f") 13895 (match_operator:XF 3 "binary_fp_operator" 13896 [(match_operand:XF 1 "register_operand" "%0") 13897 (match_operand:XF 2 "register_operand" "f")]))] 13898 "TARGET_80387 13899 && COMMUTATIVE_ARITH_P (operands[3])" 13900 "* return output_387_binary_op (insn, operands);" 13901 [(set (attr "type") 13902 (if_then_else (match_operand:XF 3 "mult_operator") 13903 (const_string "fmul") 13904 (const_string "fop"))) 13905 (set_attr "mode" "XF")]) 13906 13907(define_insn "*fop_xf_1_i387" 13908 [(set (match_operand:XF 0 "register_operand" "=f,f") 13909 (match_operator:XF 3 "binary_fp_operator" 13910 [(match_operand:XF 1 "register_operand" "0,f") 13911 (match_operand:XF 2 "register_operand" "f,0")]))] 13912 "TARGET_80387 13913 && !COMMUTATIVE_ARITH_P (operands[3])" 13914 "* return output_387_binary_op (insn, operands);" 13915 [(set (attr "type") 13916 (cond [(match_operand:XF 3 "mult_operator") 13917 (const_string "fmul") 13918 (match_operand:XF 3 "div_operator") 13919 (const_string "fdiv") 13920 ] 13921 (const_string "fop"))) 13922 (set_attr "mode" "XF")]) 13923 13924(define_insn "*fop_xf_2_i387" 13925 [(set (match_operand:XF 0 "register_operand" "=f") 13926 (match_operator:XF 3 "binary_fp_operator" 13927 [(float:XF 13928 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 13929 (match_operand:XF 2 "register_operand" "0")]))] 13930 "TARGET_80387 13931 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13932 { return output_387_binary_op (insn, operands); } 13933 [(set (attr "type") 13934 (cond [(match_operand:XF 3 "mult_operator") 13935 (const_string "fmul") 13936 (match_operand:XF 3 "div_operator") 13937 (const_string "fdiv") 13938 ] 13939 (const_string "fop"))) 13940 (set_attr "fp_int_src" "true") 13941 (set_attr "mode" "<MODE>")]) 13942 13943(define_insn "*fop_xf_3_i387" 13944 [(set (match_operand:XF 0 "register_operand" "=f") 13945 (match_operator:XF 3 "binary_fp_operator" 13946 [(match_operand:XF 1 "register_operand" "0") 13947 (float:XF 13948 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 13949 "TARGET_80387 13950 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))" 13951 { return output_387_binary_op (insn, operands); } 13952 [(set (attr "type") 13953 (cond [(match_operand:XF 3 "mult_operator") 13954 (const_string "fmul") 13955 (match_operand:XF 3 "div_operator") 13956 (const_string "fdiv") 13957 ] 13958 (const_string "fop"))) 13959 (set_attr "fp_int_src" "true") 13960 (set_attr "mode" "<MODE>")]) 13961 13962(define_insn "*fop_xf_4_i387" 13963 [(set (match_operand:XF 0 "register_operand" "=f,f") 13964 (match_operator:XF 3 "binary_fp_operator" 13965 [(float_extend:XF 13966 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) 13967 (match_operand:XF 2 "register_operand" "0,f")]))] 13968 "TARGET_80387" 13969 "* return output_387_binary_op (insn, operands);" 13970 [(set (attr "type") 13971 (cond [(match_operand:XF 3 "mult_operator") 13972 (const_string "fmul") 13973 (match_operand:XF 3 "div_operator") 13974 (const_string "fdiv") 13975 ] 13976 (const_string "fop"))) 13977 (set_attr "mode" "<MODE>")]) 13978 13979(define_insn "*fop_xf_5_i387" 13980 [(set (match_operand:XF 0 "register_operand" "=f,f") 13981 (match_operator:XF 3 "binary_fp_operator" 13982 [(match_operand:XF 1 "register_operand" "0,f") 13983 (float_extend:XF 13984 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 13985 "TARGET_80387" 13986 "* return output_387_binary_op (insn, operands);" 13987 [(set (attr "type") 13988 (cond [(match_operand:XF 3 "mult_operator") 13989 (const_string "fmul") 13990 (match_operand:XF 3 "div_operator") 13991 (const_string "fdiv") 13992 ] 13993 (const_string "fop"))) 13994 (set_attr "mode" "<MODE>")]) 13995 13996(define_insn "*fop_xf_6_i387" 13997 [(set (match_operand:XF 0 "register_operand" "=f,f") 13998 (match_operator:XF 3 "binary_fp_operator" 13999 [(float_extend:XF 14000 (match_operand:MODEF 1 "register_operand" "0,f")) 14001 (float_extend:XF 14002 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 14003 "TARGET_80387" 14004 "* return output_387_binary_op (insn, operands);" 14005 [(set (attr "type") 14006 (cond [(match_operand:XF 3 "mult_operator") 14007 (const_string "fmul") 14008 (match_operand:XF 3 "div_operator") 14009 (const_string "fdiv") 14010 ] 14011 (const_string "fop"))) 14012 (set_attr "mode" "<MODE>")]) 14013 14014;; FPU special functions. 14015 14016;; This pattern implements a no-op XFmode truncation for 14017;; all fancy i386 XFmode math functions. 14018 14019(define_insn "truncxf<mode>2_i387_noop_unspec" 14020 [(set (match_operand:MODEF 0 "register_operand" "=f") 14021 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] 14022 UNSPEC_TRUNC_NOOP))] 14023 "TARGET_USE_FANCY_MATH_387" 14024 "* return output_387_reg_move (insn, operands);" 14025 [(set_attr "type" "fmov") 14026 (set_attr "mode" "<MODE>")]) 14027 14028(define_insn "sqrtxf2" 14029 [(set (match_operand:XF 0 "register_operand" "=f") 14030 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 14031 "TARGET_USE_FANCY_MATH_387" 14032 "fsqrt" 14033 [(set_attr "type" "fpspc") 14034 (set_attr "mode" "XF") 14035 (set_attr "athlon_decode" "direct") 14036 (set_attr "amdfam10_decode" "direct") 14037 (set_attr "bdver1_decode" "direct")]) 14038 14039(define_insn "sqrt_extend<mode>xf2_i387" 14040 [(set (match_operand:XF 0 "register_operand" "=f") 14041 (sqrt:XF 14042 (float_extend:XF 14043 (match_operand:MODEF 1 "register_operand" "0"))))] 14044 "TARGET_USE_FANCY_MATH_387" 14045 "fsqrt" 14046 [(set_attr "type" "fpspc") 14047 (set_attr "mode" "XF") 14048 (set_attr "athlon_decode" "direct") 14049 (set_attr "amdfam10_decode" "direct") 14050 (set_attr "bdver1_decode" "direct")]) 14051 14052(define_insn "*rsqrtsf2_sse" 14053 [(set (match_operand:SF 0 "register_operand" "=x") 14054 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")] 14055 UNSPEC_RSQRT))] 14056 "TARGET_SSE_MATH" 14057 "%vrsqrtss\t{%1, %d0|%d0, %1}" 14058 [(set_attr "type" "sse") 14059 (set_attr "atom_sse_attr" "rcp") 14060 (set_attr "btver2_sse_attr" "rcp") 14061 (set_attr "prefix" "maybe_vex") 14062 (set_attr "mode" "SF")]) 14063 14064(define_expand "rsqrtsf2" 14065 [(set (match_operand:SF 0 "register_operand") 14066 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")] 14067 UNSPEC_RSQRT))] 14068 "TARGET_SSE_MATH" 14069{ 14070 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); 14071 DONE; 14072}) 14073 14074(define_insn "*sqrt<mode>2_sse" 14075 [(set (match_operand:MODEF 0 "register_operand" "=x") 14076 (sqrt:MODEF 14077 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))] 14078 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 14079 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}" 14080 [(set_attr "type" "sse") 14081 (set_attr "atom_sse_attr" "sqrt") 14082 (set_attr "btver2_sse_attr" "sqrt") 14083 (set_attr "prefix" "maybe_vex") 14084 (set_attr "mode" "<MODE>") 14085 (set_attr "athlon_decode" "*") 14086 (set_attr "amdfam10_decode" "*") 14087 (set_attr "bdver1_decode" "*")]) 14088 14089(define_expand "sqrt<mode>2" 14090 [(set (match_operand:MODEF 0 "register_operand") 14091 (sqrt:MODEF 14092 (match_operand:MODEF 1 "nonimmediate_operand")))] 14093 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) 14094 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 14095{ 14096 if (<MODE>mode == SFmode 14097 && TARGET_SSE_MATH 14098 && TARGET_RECIP_SQRT 14099 && !optimize_function_for_size_p (cfun) 14100 && flag_finite_math_only && !flag_trapping_math 14101 && flag_unsafe_math_optimizations) 14102 { 14103 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); 14104 DONE; 14105 } 14106 14107 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 14108 { 14109 rtx op0 = gen_reg_rtx (XFmode); 14110 rtx op1 = force_reg (<MODE>mode, operands[1]); 14111 14112 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1)); 14113 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 14114 DONE; 14115 } 14116}) 14117 14118(define_insn "fpremxf4_i387" 14119 [(set (match_operand:XF 0 "register_operand" "=f") 14120 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 14121 (match_operand:XF 3 "register_operand" "1")] 14122 UNSPEC_FPREM_F)) 14123 (set (match_operand:XF 1 "register_operand" "=u") 14124 (unspec:XF [(match_dup 2) (match_dup 3)] 14125 UNSPEC_FPREM_U)) 14126 (set (reg:CCFP FPSR_REG) 14127 (unspec:CCFP [(match_dup 2) (match_dup 3)] 14128 UNSPEC_C2_FLAG))] 14129 "TARGET_USE_FANCY_MATH_387 14130 && flag_finite_math_only" 14131 "fprem" 14132 [(set_attr "type" "fpspc") 14133 (set_attr "mode" "XF")]) 14134 14135(define_expand "fmodxf3" 14136 [(use (match_operand:XF 0 "register_operand")) 14137 (use (match_operand:XF 1 "general_operand")) 14138 (use (match_operand:XF 2 "general_operand"))] 14139 "TARGET_USE_FANCY_MATH_387 14140 && flag_finite_math_only" 14141{ 14142 rtx_code_label *label = gen_label_rtx (); 14143 14144 rtx op1 = gen_reg_rtx (XFmode); 14145 rtx op2 = gen_reg_rtx (XFmode); 14146 14147 emit_move_insn (op2, operands[2]); 14148 emit_move_insn (op1, operands[1]); 14149 14150 emit_label (label); 14151 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 14152 ix86_emit_fp_unordered_jump (label); 14153 LABEL_NUSES (label) = 1; 14154 14155 emit_move_insn (operands[0], op1); 14156 DONE; 14157}) 14158 14159(define_expand "fmod<mode>3" 14160 [(use (match_operand:MODEF 0 "register_operand")) 14161 (use (match_operand:MODEF 1 "general_operand")) 14162 (use (match_operand:MODEF 2 "general_operand"))] 14163 "TARGET_USE_FANCY_MATH_387 14164 && flag_finite_math_only" 14165{ 14166 rtx (*gen_truncxf) (rtx, rtx); 14167 14168 rtx_code_label *label = gen_label_rtx (); 14169 14170 rtx op1 = gen_reg_rtx (XFmode); 14171 rtx op2 = gen_reg_rtx (XFmode); 14172 14173 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 14174 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14175 14176 emit_label (label); 14177 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 14178 ix86_emit_fp_unordered_jump (label); 14179 LABEL_NUSES (label) = 1; 14180 14181 /* Truncate the result properly for strict SSE math. */ 14182 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14183 && !TARGET_MIX_SSE_I387) 14184 gen_truncxf = gen_truncxf<mode>2; 14185 else 14186 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 14187 14188 emit_insn (gen_truncxf (operands[0], op1)); 14189 DONE; 14190}) 14191 14192(define_insn "fprem1xf4_i387" 14193 [(set (match_operand:XF 0 "register_operand" "=f") 14194 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 14195 (match_operand:XF 3 "register_operand" "1")] 14196 UNSPEC_FPREM1_F)) 14197 (set (match_operand:XF 1 "register_operand" "=u") 14198 (unspec:XF [(match_dup 2) (match_dup 3)] 14199 UNSPEC_FPREM1_U)) 14200 (set (reg:CCFP FPSR_REG) 14201 (unspec:CCFP [(match_dup 2) (match_dup 3)] 14202 UNSPEC_C2_FLAG))] 14203 "TARGET_USE_FANCY_MATH_387 14204 && flag_finite_math_only" 14205 "fprem1" 14206 [(set_attr "type" "fpspc") 14207 (set_attr "mode" "XF")]) 14208 14209(define_expand "remainderxf3" 14210 [(use (match_operand:XF 0 "register_operand")) 14211 (use (match_operand:XF 1 "general_operand")) 14212 (use (match_operand:XF 2 "general_operand"))] 14213 "TARGET_USE_FANCY_MATH_387 14214 && flag_finite_math_only" 14215{ 14216 rtx_code_label *label = gen_label_rtx (); 14217 14218 rtx op1 = gen_reg_rtx (XFmode); 14219 rtx op2 = gen_reg_rtx (XFmode); 14220 14221 emit_move_insn (op2, operands[2]); 14222 emit_move_insn (op1, operands[1]); 14223 14224 emit_label (label); 14225 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 14226 ix86_emit_fp_unordered_jump (label); 14227 LABEL_NUSES (label) = 1; 14228 14229 emit_move_insn (operands[0], op1); 14230 DONE; 14231}) 14232 14233(define_expand "remainder<mode>3" 14234 [(use (match_operand:MODEF 0 "register_operand")) 14235 (use (match_operand:MODEF 1 "general_operand")) 14236 (use (match_operand:MODEF 2 "general_operand"))] 14237 "TARGET_USE_FANCY_MATH_387 14238 && flag_finite_math_only" 14239{ 14240 rtx (*gen_truncxf) (rtx, rtx); 14241 14242 rtx_code_label *label = gen_label_rtx (); 14243 14244 rtx op1 = gen_reg_rtx (XFmode); 14245 rtx op2 = gen_reg_rtx (XFmode); 14246 14247 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 14248 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14249 14250 emit_label (label); 14251 14252 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 14253 ix86_emit_fp_unordered_jump (label); 14254 LABEL_NUSES (label) = 1; 14255 14256 /* Truncate the result properly for strict SSE math. */ 14257 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 14258 && !TARGET_MIX_SSE_I387) 14259 gen_truncxf = gen_truncxf<mode>2; 14260 else 14261 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 14262 14263 emit_insn (gen_truncxf (operands[0], op1)); 14264 DONE; 14265}) 14266 14267(define_int_iterator SINCOS 14268 [UNSPEC_SIN 14269 UNSPEC_COS]) 14270 14271(define_int_attr sincos 14272 [(UNSPEC_SIN "sin") 14273 (UNSPEC_COS "cos")]) 14274 14275(define_insn "*<sincos>xf2_i387" 14276 [(set (match_operand:XF 0 "register_operand" "=f") 14277 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14278 SINCOS))] 14279 "TARGET_USE_FANCY_MATH_387 14280 && flag_unsafe_math_optimizations" 14281 "f<sincos>" 14282 [(set_attr "type" "fpspc") 14283 (set_attr "mode" "XF")]) 14284 14285(define_insn "*<sincos>_extend<mode>xf2_i387" 14286 [(set (match_operand:XF 0 "register_operand" "=f") 14287 (unspec:XF [(float_extend:XF 14288 (match_operand:MODEF 1 "register_operand" "0"))] 14289 SINCOS))] 14290 "TARGET_USE_FANCY_MATH_387 14291 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14292 || TARGET_MIX_SSE_I387) 14293 && flag_unsafe_math_optimizations" 14294 "f<sincos>" 14295 [(set_attr "type" "fpspc") 14296 (set_attr "mode" "XF")]) 14297 14298;; When sincos pattern is defined, sin and cos builtin functions will be 14299;; expanded to sincos pattern with one of its outputs left unused. 14300;; CSE pass will figure out if two sincos patterns can be combined, 14301;; otherwise sincos pattern will be split back to sin or cos pattern, 14302;; depending on the unused output. 14303 14304(define_insn "sincosxf3" 14305 [(set (match_operand:XF 0 "register_operand" "=f") 14306 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 14307 UNSPEC_SINCOS_COS)) 14308 (set (match_operand:XF 1 "register_operand" "=u") 14309 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 14310 "TARGET_USE_FANCY_MATH_387 14311 && flag_unsafe_math_optimizations" 14312 "fsincos" 14313 [(set_attr "type" "fpspc") 14314 (set_attr "mode" "XF")]) 14315 14316(define_split 14317 [(set (match_operand:XF 0 "register_operand") 14318 (unspec:XF [(match_operand:XF 2 "register_operand")] 14319 UNSPEC_SINCOS_COS)) 14320 (set (match_operand:XF 1 "register_operand") 14321 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 14322 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 14323 && can_create_pseudo_p ()" 14324 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]) 14325 14326(define_split 14327 [(set (match_operand:XF 0 "register_operand") 14328 (unspec:XF [(match_operand:XF 2 "register_operand")] 14329 UNSPEC_SINCOS_COS)) 14330 (set (match_operand:XF 1 "register_operand") 14331 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 14332 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 14333 && can_create_pseudo_p ()" 14334 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]) 14335 14336(define_insn "sincos_extend<mode>xf3_i387" 14337 [(set (match_operand:XF 0 "register_operand" "=f") 14338 (unspec:XF [(float_extend:XF 14339 (match_operand:MODEF 2 "register_operand" "0"))] 14340 UNSPEC_SINCOS_COS)) 14341 (set (match_operand:XF 1 "register_operand" "=u") 14342 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 14343 "TARGET_USE_FANCY_MATH_387 14344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14345 || TARGET_MIX_SSE_I387) 14346 && flag_unsafe_math_optimizations" 14347 "fsincos" 14348 [(set_attr "type" "fpspc") 14349 (set_attr "mode" "XF")]) 14350 14351(define_split 14352 [(set (match_operand:XF 0 "register_operand") 14353 (unspec:XF [(float_extend:XF 14354 (match_operand:MODEF 2 "register_operand"))] 14355 UNSPEC_SINCOS_COS)) 14356 (set (match_operand:XF 1 "register_operand") 14357 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 14358 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0])) 14359 && can_create_pseudo_p ()" 14360 [(set (match_dup 1) 14361 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]) 14362 14363(define_split 14364 [(set (match_operand:XF 0 "register_operand") 14365 (unspec:XF [(float_extend:XF 14366 (match_operand:MODEF 2 "register_operand"))] 14367 UNSPEC_SINCOS_COS)) 14368 (set (match_operand:XF 1 "register_operand") 14369 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))] 14370 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1])) 14371 && can_create_pseudo_p ()" 14372 [(set (match_dup 0) 14373 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]) 14374 14375(define_expand "sincos<mode>3" 14376 [(use (match_operand:MODEF 0 "register_operand")) 14377 (use (match_operand:MODEF 1 "register_operand")) 14378 (use (match_operand:MODEF 2 "register_operand"))] 14379 "TARGET_USE_FANCY_MATH_387 14380 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14381 || TARGET_MIX_SSE_I387) 14382 && flag_unsafe_math_optimizations" 14383{ 14384 rtx op0 = gen_reg_rtx (XFmode); 14385 rtx op1 = gen_reg_rtx (XFmode); 14386 14387 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2])); 14388 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14389 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1)); 14390 DONE; 14391}) 14392 14393(define_insn "fptanxf4_i387" 14394 [(set (match_operand:XF 0 "register_operand" "=f") 14395 (match_operand:XF 3 "const_double_operand" "F")) 14396 (set (match_operand:XF 1 "register_operand" "=u") 14397 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 14398 UNSPEC_TAN))] 14399 "TARGET_USE_FANCY_MATH_387 14400 && flag_unsafe_math_optimizations 14401 && standard_80387_constant_p (operands[3]) == 2" 14402 "fptan" 14403 [(set_attr "type" "fpspc") 14404 (set_attr "mode" "XF")]) 14405 14406(define_insn "fptan_extend<mode>xf4_i387" 14407 [(set (match_operand:MODEF 0 "register_operand" "=f") 14408 (match_operand:MODEF 3 "const_double_operand" "F")) 14409 (set (match_operand:XF 1 "register_operand" "=u") 14410 (unspec:XF [(float_extend:XF 14411 (match_operand:MODEF 2 "register_operand" "0"))] 14412 UNSPEC_TAN))] 14413 "TARGET_USE_FANCY_MATH_387 14414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14415 || TARGET_MIX_SSE_I387) 14416 && flag_unsafe_math_optimizations 14417 && standard_80387_constant_p (operands[3]) == 2" 14418 "fptan" 14419 [(set_attr "type" "fpspc") 14420 (set_attr "mode" "XF")]) 14421 14422(define_expand "tanxf2" 14423 [(use (match_operand:XF 0 "register_operand")) 14424 (use (match_operand:XF 1 "register_operand"))] 14425 "TARGET_USE_FANCY_MATH_387 14426 && flag_unsafe_math_optimizations" 14427{ 14428 rtx one = gen_reg_rtx (XFmode); 14429 rtx op2 = CONST1_RTX (XFmode); /* fld1 */ 14430 14431 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2)); 14432 DONE; 14433}) 14434 14435(define_expand "tan<mode>2" 14436 [(use (match_operand:MODEF 0 "register_operand")) 14437 (use (match_operand:MODEF 1 "register_operand"))] 14438 "TARGET_USE_FANCY_MATH_387 14439 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14440 || TARGET_MIX_SSE_I387) 14441 && flag_unsafe_math_optimizations" 14442{ 14443 rtx op0 = gen_reg_rtx (XFmode); 14444 14445 rtx one = gen_reg_rtx (<MODE>mode); 14446 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */ 14447 14448 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0, 14449 operands[1], op2)); 14450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14451 DONE; 14452}) 14453 14454(define_insn "*fpatanxf3_i387" 14455 [(set (match_operand:XF 0 "register_operand" "=f") 14456 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 14457 (match_operand:XF 2 "register_operand" "u")] 14458 UNSPEC_FPATAN)) 14459 (clobber (match_scratch:XF 3 "=2"))] 14460 "TARGET_USE_FANCY_MATH_387 14461 && flag_unsafe_math_optimizations" 14462 "fpatan" 14463 [(set_attr "type" "fpspc") 14464 (set_attr "mode" "XF")]) 14465 14466(define_insn "fpatan_extend<mode>xf3_i387" 14467 [(set (match_operand:XF 0 "register_operand" "=f") 14468 (unspec:XF [(float_extend:XF 14469 (match_operand:MODEF 1 "register_operand" "0")) 14470 (float_extend:XF 14471 (match_operand:MODEF 2 "register_operand" "u"))] 14472 UNSPEC_FPATAN)) 14473 (clobber (match_scratch:XF 3 "=2"))] 14474 "TARGET_USE_FANCY_MATH_387 14475 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14476 || TARGET_MIX_SSE_I387) 14477 && flag_unsafe_math_optimizations" 14478 "fpatan" 14479 [(set_attr "type" "fpspc") 14480 (set_attr "mode" "XF")]) 14481 14482(define_expand "atan2xf3" 14483 [(parallel [(set (match_operand:XF 0 "register_operand") 14484 (unspec:XF [(match_operand:XF 2 "register_operand") 14485 (match_operand:XF 1 "register_operand")] 14486 UNSPEC_FPATAN)) 14487 (clobber (match_scratch:XF 3))])] 14488 "TARGET_USE_FANCY_MATH_387 14489 && flag_unsafe_math_optimizations") 14490 14491(define_expand "atan2<mode>3" 14492 [(use (match_operand:MODEF 0 "register_operand")) 14493 (use (match_operand:MODEF 1 "register_operand")) 14494 (use (match_operand:MODEF 2 "register_operand"))] 14495 "TARGET_USE_FANCY_MATH_387 14496 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14497 || TARGET_MIX_SSE_I387) 14498 && flag_unsafe_math_optimizations" 14499{ 14500 rtx op0 = gen_reg_rtx (XFmode); 14501 14502 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1])); 14503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14504 DONE; 14505}) 14506 14507(define_expand "atanxf2" 14508 [(parallel [(set (match_operand:XF 0 "register_operand") 14509 (unspec:XF [(match_dup 2) 14510 (match_operand:XF 1 "register_operand")] 14511 UNSPEC_FPATAN)) 14512 (clobber (match_scratch:XF 3))])] 14513 "TARGET_USE_FANCY_MATH_387 14514 && flag_unsafe_math_optimizations" 14515{ 14516 operands[2] = gen_reg_rtx (XFmode); 14517 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 14518}) 14519 14520(define_expand "atan<mode>2" 14521 [(use (match_operand:MODEF 0 "register_operand")) 14522 (use (match_operand:MODEF 1 "register_operand"))] 14523 "TARGET_USE_FANCY_MATH_387 14524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14525 || TARGET_MIX_SSE_I387) 14526 && flag_unsafe_math_optimizations" 14527{ 14528 rtx op0 = gen_reg_rtx (XFmode); 14529 14530 rtx op2 = gen_reg_rtx (<MODE>mode); 14531 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */ 14532 14533 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1])); 14534 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14535 DONE; 14536}) 14537 14538(define_expand "asinxf2" 14539 [(set (match_dup 2) 14540 (mult:XF (match_operand:XF 1 "register_operand") 14541 (match_dup 1))) 14542 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 14543 (set (match_dup 5) (sqrt:XF (match_dup 4))) 14544 (parallel [(set (match_operand:XF 0 "register_operand") 14545 (unspec:XF [(match_dup 5) (match_dup 1)] 14546 UNSPEC_FPATAN)) 14547 (clobber (match_scratch:XF 6))])] 14548 "TARGET_USE_FANCY_MATH_387 14549 && flag_unsafe_math_optimizations" 14550{ 14551 int i; 14552 14553 if (optimize_insn_for_size_p ()) 14554 FAIL; 14555 14556 for (i = 2; i < 6; i++) 14557 operands[i] = gen_reg_rtx (XFmode); 14558 14559 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 14560}) 14561 14562(define_expand "asin<mode>2" 14563 [(use (match_operand:MODEF 0 "register_operand")) 14564 (use (match_operand:MODEF 1 "general_operand"))] 14565 "TARGET_USE_FANCY_MATH_387 14566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14567 || TARGET_MIX_SSE_I387) 14568 && flag_unsafe_math_optimizations" 14569{ 14570 rtx op0 = gen_reg_rtx (XFmode); 14571 rtx op1 = gen_reg_rtx (XFmode); 14572 14573 if (optimize_insn_for_size_p ()) 14574 FAIL; 14575 14576 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14577 emit_insn (gen_asinxf2 (op0, op1)); 14578 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14579 DONE; 14580}) 14581 14582(define_expand "acosxf2" 14583 [(set (match_dup 2) 14584 (mult:XF (match_operand:XF 1 "register_operand") 14585 (match_dup 1))) 14586 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 14587 (set (match_dup 5) (sqrt:XF (match_dup 4))) 14588 (parallel [(set (match_operand:XF 0 "register_operand") 14589 (unspec:XF [(match_dup 1) (match_dup 5)] 14590 UNSPEC_FPATAN)) 14591 (clobber (match_scratch:XF 6))])] 14592 "TARGET_USE_FANCY_MATH_387 14593 && flag_unsafe_math_optimizations" 14594{ 14595 int i; 14596 14597 if (optimize_insn_for_size_p ()) 14598 FAIL; 14599 14600 for (i = 2; i < 6; i++) 14601 operands[i] = gen_reg_rtx (XFmode); 14602 14603 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */ 14604}) 14605 14606(define_expand "acos<mode>2" 14607 [(use (match_operand:MODEF 0 "register_operand")) 14608 (use (match_operand:MODEF 1 "general_operand"))] 14609 "TARGET_USE_FANCY_MATH_387 14610 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14611 || TARGET_MIX_SSE_I387) 14612 && flag_unsafe_math_optimizations" 14613{ 14614 rtx op0 = gen_reg_rtx (XFmode); 14615 rtx op1 = gen_reg_rtx (XFmode); 14616 14617 if (optimize_insn_for_size_p ()) 14618 FAIL; 14619 14620 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14621 emit_insn (gen_acosxf2 (op0, op1)); 14622 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14623 DONE; 14624}) 14625 14626(define_insn "fyl2xxf3_i387" 14627 [(set (match_operand:XF 0 "register_operand" "=f") 14628 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 14629 (match_operand:XF 2 "register_operand" "u")] 14630 UNSPEC_FYL2X)) 14631 (clobber (match_scratch:XF 3 "=2"))] 14632 "TARGET_USE_FANCY_MATH_387 14633 && flag_unsafe_math_optimizations" 14634 "fyl2x" 14635 [(set_attr "type" "fpspc") 14636 (set_attr "mode" "XF")]) 14637 14638(define_insn "fyl2x_extend<mode>xf3_i387" 14639 [(set (match_operand:XF 0 "register_operand" "=f") 14640 (unspec:XF [(float_extend:XF 14641 (match_operand:MODEF 1 "register_operand" "0")) 14642 (match_operand:XF 2 "register_operand" "u")] 14643 UNSPEC_FYL2X)) 14644 (clobber (match_scratch:XF 3 "=2"))] 14645 "TARGET_USE_FANCY_MATH_387 14646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14647 || TARGET_MIX_SSE_I387) 14648 && flag_unsafe_math_optimizations" 14649 "fyl2x" 14650 [(set_attr "type" "fpspc") 14651 (set_attr "mode" "XF")]) 14652 14653(define_expand "logxf2" 14654 [(parallel [(set (match_operand:XF 0 "register_operand") 14655 (unspec:XF [(match_operand:XF 1 "register_operand") 14656 (match_dup 2)] UNSPEC_FYL2X)) 14657 (clobber (match_scratch:XF 3))])] 14658 "TARGET_USE_FANCY_MATH_387 14659 && flag_unsafe_math_optimizations" 14660{ 14661 operands[2] = gen_reg_rtx (XFmode); 14662 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */ 14663}) 14664 14665(define_expand "log<mode>2" 14666 [(use (match_operand:MODEF 0 "register_operand")) 14667 (use (match_operand:MODEF 1 "register_operand"))] 14668 "TARGET_USE_FANCY_MATH_387 14669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14670 || TARGET_MIX_SSE_I387) 14671 && flag_unsafe_math_optimizations" 14672{ 14673 rtx op0 = gen_reg_rtx (XFmode); 14674 14675 rtx op2 = gen_reg_rtx (XFmode); 14676 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */ 14677 14678 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14679 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14680 DONE; 14681}) 14682 14683(define_expand "log10xf2" 14684 [(parallel [(set (match_operand:XF 0 "register_operand") 14685 (unspec:XF [(match_operand:XF 1 "register_operand") 14686 (match_dup 2)] UNSPEC_FYL2X)) 14687 (clobber (match_scratch:XF 3))])] 14688 "TARGET_USE_FANCY_MATH_387 14689 && flag_unsafe_math_optimizations" 14690{ 14691 operands[2] = gen_reg_rtx (XFmode); 14692 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */ 14693}) 14694 14695(define_expand "log10<mode>2" 14696 [(use (match_operand:MODEF 0 "register_operand")) 14697 (use (match_operand:MODEF 1 "register_operand"))] 14698 "TARGET_USE_FANCY_MATH_387 14699 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14700 || TARGET_MIX_SSE_I387) 14701 && flag_unsafe_math_optimizations" 14702{ 14703 rtx op0 = gen_reg_rtx (XFmode); 14704 14705 rtx op2 = gen_reg_rtx (XFmode); 14706 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */ 14707 14708 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14709 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14710 DONE; 14711}) 14712 14713(define_expand "log2xf2" 14714 [(parallel [(set (match_operand:XF 0 "register_operand") 14715 (unspec:XF [(match_operand:XF 1 "register_operand") 14716 (match_dup 2)] UNSPEC_FYL2X)) 14717 (clobber (match_scratch:XF 3))])] 14718 "TARGET_USE_FANCY_MATH_387 14719 && flag_unsafe_math_optimizations" 14720{ 14721 operands[2] = gen_reg_rtx (XFmode); 14722 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */ 14723}) 14724 14725(define_expand "log2<mode>2" 14726 [(use (match_operand:MODEF 0 "register_operand")) 14727 (use (match_operand:MODEF 1 "register_operand"))] 14728 "TARGET_USE_FANCY_MATH_387 14729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14730 || TARGET_MIX_SSE_I387) 14731 && flag_unsafe_math_optimizations" 14732{ 14733 rtx op0 = gen_reg_rtx (XFmode); 14734 14735 rtx op2 = gen_reg_rtx (XFmode); 14736 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 14737 14738 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2)); 14739 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14740 DONE; 14741}) 14742 14743(define_insn "fyl2xp1xf3_i387" 14744 [(set (match_operand:XF 0 "register_operand" "=f") 14745 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 14746 (match_operand:XF 2 "register_operand" "u")] 14747 UNSPEC_FYL2XP1)) 14748 (clobber (match_scratch:XF 3 "=2"))] 14749 "TARGET_USE_FANCY_MATH_387 14750 && flag_unsafe_math_optimizations" 14751 "fyl2xp1" 14752 [(set_attr "type" "fpspc") 14753 (set_attr "mode" "XF")]) 14754 14755(define_insn "fyl2xp1_extend<mode>xf3_i387" 14756 [(set (match_operand:XF 0 "register_operand" "=f") 14757 (unspec:XF [(float_extend:XF 14758 (match_operand:MODEF 1 "register_operand" "0")) 14759 (match_operand:XF 2 "register_operand" "u")] 14760 UNSPEC_FYL2XP1)) 14761 (clobber (match_scratch:XF 3 "=2"))] 14762 "TARGET_USE_FANCY_MATH_387 14763 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14764 || TARGET_MIX_SSE_I387) 14765 && flag_unsafe_math_optimizations" 14766 "fyl2xp1" 14767 [(set_attr "type" "fpspc") 14768 (set_attr "mode" "XF")]) 14769 14770(define_expand "log1pxf2" 14771 [(use (match_operand:XF 0 "register_operand")) 14772 (use (match_operand:XF 1 "register_operand"))] 14773 "TARGET_USE_FANCY_MATH_387 14774 && flag_unsafe_math_optimizations" 14775{ 14776 if (optimize_insn_for_size_p ()) 14777 FAIL; 14778 14779 ix86_emit_i387_log1p (operands[0], operands[1]); 14780 DONE; 14781}) 14782 14783(define_expand "log1p<mode>2" 14784 [(use (match_operand:MODEF 0 "register_operand")) 14785 (use (match_operand:MODEF 1 "register_operand"))] 14786 "TARGET_USE_FANCY_MATH_387 14787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14788 || TARGET_MIX_SSE_I387) 14789 && flag_unsafe_math_optimizations" 14790{ 14791 rtx op0; 14792 14793 if (optimize_insn_for_size_p ()) 14794 FAIL; 14795 14796 op0 = gen_reg_rtx (XFmode); 14797 14798 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]); 14799 14800 ix86_emit_i387_log1p (op0, operands[1]); 14801 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14802 DONE; 14803}) 14804 14805(define_insn "fxtractxf3_i387" 14806 [(set (match_operand:XF 0 "register_operand" "=f") 14807 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 14808 UNSPEC_XTRACT_FRACT)) 14809 (set (match_operand:XF 1 "register_operand" "=u") 14810 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 14811 "TARGET_USE_FANCY_MATH_387 14812 && flag_unsafe_math_optimizations" 14813 "fxtract" 14814 [(set_attr "type" "fpspc") 14815 (set_attr "mode" "XF")]) 14816 14817(define_insn "fxtract_extend<mode>xf3_i387" 14818 [(set (match_operand:XF 0 "register_operand" "=f") 14819 (unspec:XF [(float_extend:XF 14820 (match_operand:MODEF 2 "register_operand" "0"))] 14821 UNSPEC_XTRACT_FRACT)) 14822 (set (match_operand:XF 1 "register_operand" "=u") 14823 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))] 14824 "TARGET_USE_FANCY_MATH_387 14825 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14826 || TARGET_MIX_SSE_I387) 14827 && flag_unsafe_math_optimizations" 14828 "fxtract" 14829 [(set_attr "type" "fpspc") 14830 (set_attr "mode" "XF")]) 14831 14832(define_expand "logbxf2" 14833 [(parallel [(set (match_dup 2) 14834 (unspec:XF [(match_operand:XF 1 "register_operand")] 14835 UNSPEC_XTRACT_FRACT)) 14836 (set (match_operand:XF 0 "register_operand") 14837 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 14838 "TARGET_USE_FANCY_MATH_387 14839 && flag_unsafe_math_optimizations" 14840 "operands[2] = gen_reg_rtx (XFmode);") 14841 14842(define_expand "logb<mode>2" 14843 [(use (match_operand:MODEF 0 "register_operand")) 14844 (use (match_operand:MODEF 1 "register_operand"))] 14845 "TARGET_USE_FANCY_MATH_387 14846 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14847 || TARGET_MIX_SSE_I387) 14848 && flag_unsafe_math_optimizations" 14849{ 14850 rtx op0 = gen_reg_rtx (XFmode); 14851 rtx op1 = gen_reg_rtx (XFmode); 14852 14853 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14854 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1)); 14855 DONE; 14856}) 14857 14858(define_expand "ilogbxf2" 14859 [(use (match_operand:SI 0 "register_operand")) 14860 (use (match_operand:XF 1 "register_operand"))] 14861 "TARGET_USE_FANCY_MATH_387 14862 && flag_unsafe_math_optimizations" 14863{ 14864 rtx op0, op1; 14865 14866 if (optimize_insn_for_size_p ()) 14867 FAIL; 14868 14869 op0 = gen_reg_rtx (XFmode); 14870 op1 = gen_reg_rtx (XFmode); 14871 14872 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); 14873 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 14874 DONE; 14875}) 14876 14877(define_expand "ilogb<mode>2" 14878 [(use (match_operand:SI 0 "register_operand")) 14879 (use (match_operand:MODEF 1 "register_operand"))] 14880 "TARGET_USE_FANCY_MATH_387 14881 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14882 || TARGET_MIX_SSE_I387) 14883 && flag_unsafe_math_optimizations" 14884{ 14885 rtx op0, op1; 14886 14887 if (optimize_insn_for_size_p ()) 14888 FAIL; 14889 14890 op0 = gen_reg_rtx (XFmode); 14891 op1 = gen_reg_rtx (XFmode); 14892 14893 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 14894 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 14895 DONE; 14896}) 14897 14898(define_insn "*f2xm1xf2_i387" 14899 [(set (match_operand:XF 0 "register_operand" "=f") 14900 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 14901 UNSPEC_F2XM1))] 14902 "TARGET_USE_FANCY_MATH_387 14903 && flag_unsafe_math_optimizations" 14904 "f2xm1" 14905 [(set_attr "type" "fpspc") 14906 (set_attr "mode" "XF")]) 14907 14908(define_insn "fscalexf4_i387" 14909 [(set (match_operand:XF 0 "register_operand" "=f") 14910 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 14911 (match_operand:XF 3 "register_operand" "1")] 14912 UNSPEC_FSCALE_FRACT)) 14913 (set (match_operand:XF 1 "register_operand" "=u") 14914 (unspec:XF [(match_dup 2) (match_dup 3)] 14915 UNSPEC_FSCALE_EXP))] 14916 "TARGET_USE_FANCY_MATH_387 14917 && flag_unsafe_math_optimizations" 14918 "fscale" 14919 [(set_attr "type" "fpspc") 14920 (set_attr "mode" "XF")]) 14921 14922(define_expand "expNcorexf3" 14923 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 14924 (match_operand:XF 2 "register_operand"))) 14925 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 14926 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 14927 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 14928 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 14929 (parallel [(set (match_operand:XF 0 "register_operand") 14930 (unspec:XF [(match_dup 8) (match_dup 4)] 14931 UNSPEC_FSCALE_FRACT)) 14932 (set (match_dup 9) 14933 (unspec:XF [(match_dup 8) (match_dup 4)] 14934 UNSPEC_FSCALE_EXP))])] 14935 "TARGET_USE_FANCY_MATH_387 14936 && flag_unsafe_math_optimizations" 14937{ 14938 int i; 14939 14940 if (optimize_insn_for_size_p ()) 14941 FAIL; 14942 14943 for (i = 3; i < 10; i++) 14944 operands[i] = gen_reg_rtx (XFmode); 14945 14946 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */ 14947}) 14948 14949(define_expand "expxf2" 14950 [(use (match_operand:XF 0 "register_operand")) 14951 (use (match_operand:XF 1 "register_operand"))] 14952 "TARGET_USE_FANCY_MATH_387 14953 && flag_unsafe_math_optimizations" 14954{ 14955 rtx op2; 14956 14957 if (optimize_insn_for_size_p ()) 14958 FAIL; 14959 14960 op2 = gen_reg_rtx (XFmode); 14961 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */ 14962 14963 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 14964 DONE; 14965}) 14966 14967(define_expand "exp<mode>2" 14968 [(use (match_operand:MODEF 0 "register_operand")) 14969 (use (match_operand:MODEF 1 "general_operand"))] 14970 "TARGET_USE_FANCY_MATH_387 14971 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 14972 || TARGET_MIX_SSE_I387) 14973 && flag_unsafe_math_optimizations" 14974{ 14975 rtx op0, op1; 14976 14977 if (optimize_insn_for_size_p ()) 14978 FAIL; 14979 14980 op0 = gen_reg_rtx (XFmode); 14981 op1 = gen_reg_rtx (XFmode); 14982 14983 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 14984 emit_insn (gen_expxf2 (op0, op1)); 14985 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 14986 DONE; 14987}) 14988 14989(define_expand "exp10xf2" 14990 [(use (match_operand:XF 0 "register_operand")) 14991 (use (match_operand:XF 1 "register_operand"))] 14992 "TARGET_USE_FANCY_MATH_387 14993 && flag_unsafe_math_optimizations" 14994{ 14995 rtx op2; 14996 14997 if (optimize_insn_for_size_p ()) 14998 FAIL; 14999 15000 op2 = gen_reg_rtx (XFmode); 15001 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */ 15002 15003 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 15004 DONE; 15005}) 15006 15007(define_expand "exp10<mode>2" 15008 [(use (match_operand:MODEF 0 "register_operand")) 15009 (use (match_operand:MODEF 1 "general_operand"))] 15010 "TARGET_USE_FANCY_MATH_387 15011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15012 || TARGET_MIX_SSE_I387) 15013 && flag_unsafe_math_optimizations" 15014{ 15015 rtx op0, op1; 15016 15017 if (optimize_insn_for_size_p ()) 15018 FAIL; 15019 15020 op0 = gen_reg_rtx (XFmode); 15021 op1 = gen_reg_rtx (XFmode); 15022 15023 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15024 emit_insn (gen_exp10xf2 (op0, op1)); 15025 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15026 DONE; 15027}) 15028 15029(define_expand "exp2xf2" 15030 [(use (match_operand:XF 0 "register_operand")) 15031 (use (match_operand:XF 1 "register_operand"))] 15032 "TARGET_USE_FANCY_MATH_387 15033 && flag_unsafe_math_optimizations" 15034{ 15035 rtx op2; 15036 15037 if (optimize_insn_for_size_p ()) 15038 FAIL; 15039 15040 op2 = gen_reg_rtx (XFmode); 15041 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */ 15042 15043 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 15044 DONE; 15045}) 15046 15047(define_expand "exp2<mode>2" 15048 [(use (match_operand:MODEF 0 "register_operand")) 15049 (use (match_operand:MODEF 1 "general_operand"))] 15050 "TARGET_USE_FANCY_MATH_387 15051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15052 || TARGET_MIX_SSE_I387) 15053 && flag_unsafe_math_optimizations" 15054{ 15055 rtx op0, op1; 15056 15057 if (optimize_insn_for_size_p ()) 15058 FAIL; 15059 15060 op0 = gen_reg_rtx (XFmode); 15061 op1 = gen_reg_rtx (XFmode); 15062 15063 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15064 emit_insn (gen_exp2xf2 (op0, op1)); 15065 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15066 DONE; 15067}) 15068 15069(define_expand "expm1xf2" 15070 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 15071 (match_dup 2))) 15072 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 15073 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 15074 (set (match_dup 9) (float_extend:XF (match_dup 13))) 15075 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 15076 (parallel [(set (match_dup 7) 15077 (unspec:XF [(match_dup 6) (match_dup 4)] 15078 UNSPEC_FSCALE_FRACT)) 15079 (set (match_dup 8) 15080 (unspec:XF [(match_dup 6) (match_dup 4)] 15081 UNSPEC_FSCALE_EXP))]) 15082 (parallel [(set (match_dup 10) 15083 (unspec:XF [(match_dup 9) (match_dup 8)] 15084 UNSPEC_FSCALE_FRACT)) 15085 (set (match_dup 11) 15086 (unspec:XF [(match_dup 9) (match_dup 8)] 15087 UNSPEC_FSCALE_EXP))]) 15088 (set (match_dup 12) (minus:XF (match_dup 10) 15089 (float_extend:XF (match_dup 13)))) 15090 (set (match_operand:XF 0 "register_operand") 15091 (plus:XF (match_dup 12) (match_dup 7)))] 15092 "TARGET_USE_FANCY_MATH_387 15093 && flag_unsafe_math_optimizations" 15094{ 15095 int i; 15096 15097 if (optimize_insn_for_size_p ()) 15098 FAIL; 15099 15100 for (i = 2; i < 13; i++) 15101 operands[i] = gen_reg_rtx (XFmode); 15102 15103 operands[13] 15104 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */ 15105 15106 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ 15107}) 15108 15109(define_expand "expm1<mode>2" 15110 [(use (match_operand:MODEF 0 "register_operand")) 15111 (use (match_operand:MODEF 1 "general_operand"))] 15112 "TARGET_USE_FANCY_MATH_387 15113 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15114 || TARGET_MIX_SSE_I387) 15115 && flag_unsafe_math_optimizations" 15116{ 15117 rtx op0, op1; 15118 15119 if (optimize_insn_for_size_p ()) 15120 FAIL; 15121 15122 op0 = gen_reg_rtx (XFmode); 15123 op1 = gen_reg_rtx (XFmode); 15124 15125 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15126 emit_insn (gen_expm1xf2 (op0, op1)); 15127 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15128 DONE; 15129}) 15130 15131(define_expand "ldexpxf3" 15132 [(match_operand:XF 0 "register_operand") 15133 (match_operand:XF 1 "register_operand") 15134 (match_operand:SI 2 "register_operand")] 15135 "TARGET_USE_FANCY_MATH_387 15136 && flag_unsafe_math_optimizations" 15137{ 15138 rtx tmp1, tmp2; 15139 if (optimize_insn_for_size_p ()) 15140 FAIL; 15141 15142 tmp1 = gen_reg_rtx (XFmode); 15143 tmp2 = gen_reg_rtx (XFmode); 15144 15145 emit_insn (gen_floatsixf2 (tmp1, operands[2])); 15146 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2, 15147 operands[1], tmp1)); 15148 DONE; 15149}) 15150 15151(define_expand "ldexp<mode>3" 15152 [(use (match_operand:MODEF 0 "register_operand")) 15153 (use (match_operand:MODEF 1 "general_operand")) 15154 (use (match_operand:SI 2 "register_operand"))] 15155 "TARGET_USE_FANCY_MATH_387 15156 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15157 || TARGET_MIX_SSE_I387) 15158 && flag_unsafe_math_optimizations" 15159{ 15160 rtx op0, op1; 15161 15162 if (optimize_insn_for_size_p ()) 15163 FAIL; 15164 15165 op0 = gen_reg_rtx (XFmode); 15166 op1 = gen_reg_rtx (XFmode); 15167 15168 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15169 emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); 15170 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15171 DONE; 15172}) 15173 15174(define_expand "scalbxf3" 15175 [(parallel [(set (match_operand:XF 0 " register_operand") 15176 (unspec:XF [(match_operand:XF 1 "register_operand") 15177 (match_operand:XF 2 "register_operand")] 15178 UNSPEC_FSCALE_FRACT)) 15179 (set (match_dup 3) 15180 (unspec:XF [(match_dup 1) (match_dup 2)] 15181 UNSPEC_FSCALE_EXP))])] 15182 "TARGET_USE_FANCY_MATH_387 15183 && flag_unsafe_math_optimizations" 15184{ 15185 if (optimize_insn_for_size_p ()) 15186 FAIL; 15187 15188 operands[3] = gen_reg_rtx (XFmode); 15189}) 15190 15191(define_expand "scalb<mode>3" 15192 [(use (match_operand:MODEF 0 "register_operand")) 15193 (use (match_operand:MODEF 1 "general_operand")) 15194 (use (match_operand:MODEF 2 "general_operand"))] 15195 "TARGET_USE_FANCY_MATH_387 15196 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15197 || TARGET_MIX_SSE_I387) 15198 && flag_unsafe_math_optimizations" 15199{ 15200 rtx op0, op1, op2; 15201 15202 if (optimize_insn_for_size_p ()) 15203 FAIL; 15204 15205 op0 = gen_reg_rtx (XFmode); 15206 op1 = gen_reg_rtx (XFmode); 15207 op2 = gen_reg_rtx (XFmode); 15208 15209 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15210 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15211 emit_insn (gen_scalbxf3 (op0, op1, op2)); 15212 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15213 DONE; 15214}) 15215 15216(define_expand "significandxf2" 15217 [(parallel [(set (match_operand:XF 0 "register_operand") 15218 (unspec:XF [(match_operand:XF 1 "register_operand")] 15219 UNSPEC_XTRACT_FRACT)) 15220 (set (match_dup 2) 15221 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 15222 "TARGET_USE_FANCY_MATH_387 15223 && flag_unsafe_math_optimizations" 15224 "operands[2] = gen_reg_rtx (XFmode);") 15225 15226(define_expand "significand<mode>2" 15227 [(use (match_operand:MODEF 0 "register_operand")) 15228 (use (match_operand:MODEF 1 "register_operand"))] 15229 "TARGET_USE_FANCY_MATH_387 15230 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15231 || TARGET_MIX_SSE_I387) 15232 && flag_unsafe_math_optimizations" 15233{ 15234 rtx op0 = gen_reg_rtx (XFmode); 15235 rtx op1 = gen_reg_rtx (XFmode); 15236 15237 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1])); 15238 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15239 DONE; 15240}) 15241 15242 15243(define_insn "sse4_1_round<mode>2" 15244 [(set (match_operand:MODEF 0 "register_operand" "=x") 15245 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x") 15246 (match_operand:SI 2 "const_0_to_15_operand" "n")] 15247 UNSPEC_ROUND))] 15248 "TARGET_ROUND" 15249 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}" 15250 [(set_attr "type" "ssecvt") 15251 (set_attr "prefix_extra" "1") 15252 (set_attr "prefix" "maybe_vex") 15253 (set_attr "mode" "<MODE>")]) 15254 15255(define_insn "rintxf2" 15256 [(set (match_operand:XF 0 "register_operand" "=f") 15257 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15258 UNSPEC_FRNDINT))] 15259 "TARGET_USE_FANCY_MATH_387 15260 && flag_unsafe_math_optimizations" 15261 "frndint" 15262 [(set_attr "type" "fpspc") 15263 (set_attr "mode" "XF")]) 15264 15265(define_expand "rint<mode>2" 15266 [(use (match_operand:MODEF 0 "register_operand")) 15267 (use (match_operand:MODEF 1 "register_operand"))] 15268 "(TARGET_USE_FANCY_MATH_387 15269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15270 || TARGET_MIX_SSE_I387) 15271 && flag_unsafe_math_optimizations) 15272 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15273 && !flag_trapping_math)" 15274{ 15275 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15276 && !flag_trapping_math) 15277 { 15278 if (TARGET_ROUND) 15279 emit_insn (gen_sse4_1_round<mode>2 15280 (operands[0], operands[1], GEN_INT (ROUND_MXCSR))); 15281 else if (optimize_insn_for_size_p ()) 15282 FAIL; 15283 else 15284 ix86_expand_rint (operands[0], operands[1]); 15285 } 15286 else 15287 { 15288 rtx op0 = gen_reg_rtx (XFmode); 15289 rtx op1 = gen_reg_rtx (XFmode); 15290 15291 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15292 emit_insn (gen_rintxf2 (op0, op1)); 15293 15294 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15295 } 15296 DONE; 15297}) 15298 15299(define_expand "round<mode>2" 15300 [(match_operand:X87MODEF 0 "register_operand") 15301 (match_operand:X87MODEF 1 "nonimmediate_operand")] 15302 "(TARGET_USE_FANCY_MATH_387 15303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15304 || TARGET_MIX_SSE_I387) 15305 && flag_unsafe_math_optimizations) 15306 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15307 && !flag_trapping_math && !flag_rounding_math)" 15308{ 15309 if (optimize_insn_for_size_p ()) 15310 FAIL; 15311 15312 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15313 && !flag_trapping_math && !flag_rounding_math) 15314 { 15315 if (TARGET_ROUND) 15316 { 15317 operands[1] = force_reg (<MODE>mode, operands[1]); 15318 ix86_expand_round_sse4 (operands[0], operands[1]); 15319 } 15320 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 15321 ix86_expand_round (operands[0], operands[1]); 15322 else 15323 ix86_expand_rounddf_32 (operands[0], operands[1]); 15324 } 15325 else 15326 { 15327 operands[1] = force_reg (<MODE>mode, operands[1]); 15328 ix86_emit_i387_round (operands[0], operands[1]); 15329 } 15330 DONE; 15331}) 15332 15333(define_insn_and_split "*fistdi2_1" 15334 [(set (match_operand:DI 0 "nonimmediate_operand") 15335 (unspec:DI [(match_operand:XF 1 "register_operand")] 15336 UNSPEC_FIST))] 15337 "TARGET_USE_FANCY_MATH_387 15338 && can_create_pseudo_p ()" 15339 "#" 15340 "&& 1" 15341 [(const_int 0)] 15342{ 15343 if (memory_operand (operands[0], VOIDmode)) 15344 emit_insn (gen_fistdi2 (operands[0], operands[1])); 15345 else 15346 { 15347 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP); 15348 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1], 15349 operands[2])); 15350 } 15351 DONE; 15352} 15353 [(set_attr "type" "fpspc") 15354 (set_attr "mode" "DI")]) 15355 15356(define_insn "fistdi2" 15357 [(set (match_operand:DI 0 "memory_operand" "=m") 15358 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 15359 UNSPEC_FIST)) 15360 (clobber (match_scratch:XF 2 "=&1f"))] 15361 "TARGET_USE_FANCY_MATH_387" 15362 "* return output_fix_trunc (insn, operands, false);" 15363 [(set_attr "type" "fpspc") 15364 (set_attr "mode" "DI")]) 15365 15366(define_insn "fistdi2_with_temp" 15367 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 15368 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 15369 UNSPEC_FIST)) 15370 (clobber (match_operand:DI 2 "memory_operand" "=X,m")) 15371 (clobber (match_scratch:XF 3 "=&1f,&1f"))] 15372 "TARGET_USE_FANCY_MATH_387" 15373 "#" 15374 [(set_attr "type" "fpspc") 15375 (set_attr "mode" "DI")]) 15376 15377(define_split 15378 [(set (match_operand:DI 0 "register_operand") 15379 (unspec:DI [(match_operand:XF 1 "register_operand")] 15380 UNSPEC_FIST)) 15381 (clobber (match_operand:DI 2 "memory_operand")) 15382 (clobber (match_scratch 3))] 15383 "reload_completed" 15384 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 15385 (clobber (match_dup 3))]) 15386 (set (match_dup 0) (match_dup 2))]) 15387 15388(define_split 15389 [(set (match_operand:DI 0 "memory_operand") 15390 (unspec:DI [(match_operand:XF 1 "register_operand")] 15391 UNSPEC_FIST)) 15392 (clobber (match_operand:DI 2 "memory_operand")) 15393 (clobber (match_scratch 3))] 15394 "reload_completed" 15395 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST)) 15396 (clobber (match_dup 3))])]) 15397 15398(define_insn_and_split "*fist<mode>2_1" 15399 [(set (match_operand:SWI24 0 "register_operand") 15400 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 15401 UNSPEC_FIST))] 15402 "TARGET_USE_FANCY_MATH_387 15403 && can_create_pseudo_p ()" 15404 "#" 15405 "&& 1" 15406 [(const_int 0)] 15407{ 15408 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 15409 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1], 15410 operands[2])); 15411 DONE; 15412} 15413 [(set_attr "type" "fpspc") 15414 (set_attr "mode" "<MODE>")]) 15415 15416(define_insn "fist<mode>2" 15417 [(set (match_operand:SWI24 0 "memory_operand" "=m") 15418 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15419 UNSPEC_FIST))] 15420 "TARGET_USE_FANCY_MATH_387" 15421 "* return output_fix_trunc (insn, operands, false);" 15422 [(set_attr "type" "fpspc") 15423 (set_attr "mode" "<MODE>")]) 15424 15425(define_insn "fist<mode>2_with_temp" 15426 [(set (match_operand:SWI24 0 "register_operand" "=r") 15427 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15428 UNSPEC_FIST)) 15429 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))] 15430 "TARGET_USE_FANCY_MATH_387" 15431 "#" 15432 [(set_attr "type" "fpspc") 15433 (set_attr "mode" "<MODE>")]) 15434 15435(define_split 15436 [(set (match_operand:SWI24 0 "register_operand") 15437 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 15438 UNSPEC_FIST)) 15439 (clobber (match_operand:SWI24 2 "memory_operand"))] 15440 "reload_completed" 15441 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST)) 15442 (set (match_dup 0) (match_dup 2))]) 15443 15444(define_split 15445 [(set (match_operand:SWI24 0 "memory_operand") 15446 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 15447 UNSPEC_FIST)) 15448 (clobber (match_operand:SWI24 2 "memory_operand"))] 15449 "reload_completed" 15450 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))]) 15451 15452(define_expand "lrintxf<mode>2" 15453 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 15454 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 15455 UNSPEC_FIST))] 15456 "TARGET_USE_FANCY_MATH_387") 15457 15458(define_expand "lrint<MODEF:mode><SWI48:mode>2" 15459 [(set (match_operand:SWI48 0 "nonimmediate_operand") 15460 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 15461 UNSPEC_FIX_NOTRUNC))] 15462 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH") 15463 15464(define_expand "lround<X87MODEF:mode><SWI248x:mode>2" 15465 [(match_operand:SWI248x 0 "nonimmediate_operand") 15466 (match_operand:X87MODEF 1 "register_operand")] 15467 "(TARGET_USE_FANCY_MATH_387 15468 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 15469 || TARGET_MIX_SSE_I387) 15470 && flag_unsafe_math_optimizations) 15471 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 15472 && <SWI248x:MODE>mode != HImode 15473 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 15474 && !flag_trapping_math && !flag_rounding_math)" 15475{ 15476 if (optimize_insn_for_size_p ()) 15477 FAIL; 15478 15479 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 15480 && <SWI248x:MODE>mode != HImode 15481 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 15482 && !flag_trapping_math && !flag_rounding_math) 15483 ix86_expand_lround (operands[0], operands[1]); 15484 else 15485 ix86_emit_i387_round (operands[0], operands[1]); 15486 DONE; 15487}) 15488 15489(define_int_iterator FRNDINT_ROUNDING 15490 [UNSPEC_FRNDINT_FLOOR 15491 UNSPEC_FRNDINT_CEIL 15492 UNSPEC_FRNDINT_TRUNC]) 15493 15494(define_int_iterator FIST_ROUNDING 15495 [UNSPEC_FIST_FLOOR 15496 UNSPEC_FIST_CEIL]) 15497 15498;; Base name for define_insn 15499(define_int_attr rounding_insn 15500 [(UNSPEC_FRNDINT_FLOOR "floor") 15501 (UNSPEC_FRNDINT_CEIL "ceil") 15502 (UNSPEC_FRNDINT_TRUNC "btrunc") 15503 (UNSPEC_FIST_FLOOR "floor") 15504 (UNSPEC_FIST_CEIL "ceil")]) 15505 15506(define_int_attr rounding 15507 [(UNSPEC_FRNDINT_FLOOR "floor") 15508 (UNSPEC_FRNDINT_CEIL "ceil") 15509 (UNSPEC_FRNDINT_TRUNC "trunc") 15510 (UNSPEC_FIST_FLOOR "floor") 15511 (UNSPEC_FIST_CEIL "ceil")]) 15512 15513(define_int_attr ROUNDING 15514 [(UNSPEC_FRNDINT_FLOOR "FLOOR") 15515 (UNSPEC_FRNDINT_CEIL "CEIL") 15516 (UNSPEC_FRNDINT_TRUNC "TRUNC") 15517 (UNSPEC_FIST_FLOOR "FLOOR") 15518 (UNSPEC_FIST_CEIL "CEIL")]) 15519 15520;; Rounding mode control word calculation could clobber FLAGS_REG. 15521(define_insn_and_split "frndintxf2_<rounding>" 15522 [(set (match_operand:XF 0 "register_operand") 15523 (unspec:XF [(match_operand:XF 1 "register_operand")] 15524 FRNDINT_ROUNDING)) 15525 (clobber (reg:CC FLAGS_REG))] 15526 "TARGET_USE_FANCY_MATH_387 15527 && flag_unsafe_math_optimizations 15528 && can_create_pseudo_p ()" 15529 "#" 15530 "&& 1" 15531 [(const_int 0)] 15532{ 15533 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 15534 15535 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15536 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 15537 15538 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1], 15539 operands[2], operands[3])); 15540 DONE; 15541} 15542 [(set_attr "type" "frndint") 15543 (set_attr "i387_cw" "<rounding>") 15544 (set_attr "mode" "XF")]) 15545 15546(define_insn "frndintxf2_<rounding>_i387" 15547 [(set (match_operand:XF 0 "register_operand" "=f") 15548 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15549 FRNDINT_ROUNDING)) 15550 (use (match_operand:HI 2 "memory_operand" "m")) 15551 (use (match_operand:HI 3 "memory_operand" "m"))] 15552 "TARGET_USE_FANCY_MATH_387 15553 && flag_unsafe_math_optimizations" 15554 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 15555 [(set_attr "type" "frndint") 15556 (set_attr "i387_cw" "<rounding>") 15557 (set_attr "mode" "XF")]) 15558 15559(define_expand "<rounding_insn>xf2" 15560 [(parallel [(set (match_operand:XF 0 "register_operand") 15561 (unspec:XF [(match_operand:XF 1 "register_operand")] 15562 FRNDINT_ROUNDING)) 15563 (clobber (reg:CC FLAGS_REG))])] 15564 "TARGET_USE_FANCY_MATH_387 15565 && flag_unsafe_math_optimizations 15566 && !optimize_insn_for_size_p ()") 15567 15568(define_expand "<rounding_insn><mode>2" 15569 [(parallel [(set (match_operand:MODEF 0 "register_operand") 15570 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")] 15571 FRNDINT_ROUNDING)) 15572 (clobber (reg:CC FLAGS_REG))])] 15573 "(TARGET_USE_FANCY_MATH_387 15574 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15575 || TARGET_MIX_SSE_I387) 15576 && flag_unsafe_math_optimizations) 15577 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15578 && !flag_trapping_math)" 15579{ 15580 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15581 && !flag_trapping_math) 15582 { 15583 if (TARGET_ROUND) 15584 emit_insn (gen_sse4_1_round<mode>2 15585 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>))); 15586 else if (optimize_insn_for_size_p ()) 15587 FAIL; 15588 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 15589 { 15590 if (ROUND_<ROUNDING> == ROUND_FLOOR) 15591 ix86_expand_floorceil (operands[0], operands[1], true); 15592 else if (ROUND_<ROUNDING> == ROUND_CEIL) 15593 ix86_expand_floorceil (operands[0], operands[1], false); 15594 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 15595 ix86_expand_trunc (operands[0], operands[1]); 15596 else 15597 gcc_unreachable (); 15598 } 15599 else 15600 { 15601 if (ROUND_<ROUNDING> == ROUND_FLOOR) 15602 ix86_expand_floorceildf_32 (operands[0], operands[1], true); 15603 else if (ROUND_<ROUNDING> == ROUND_CEIL) 15604 ix86_expand_floorceildf_32 (operands[0], operands[1], false); 15605 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 15606 ix86_expand_truncdf_32 (operands[0], operands[1]); 15607 else 15608 gcc_unreachable (); 15609 } 15610 } 15611 else 15612 { 15613 rtx op0, op1; 15614 15615 if (optimize_insn_for_size_p ()) 15616 FAIL; 15617 15618 op0 = gen_reg_rtx (XFmode); 15619 op1 = gen_reg_rtx (XFmode); 15620 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15621 emit_insn (gen_frndintxf2_<rounding> (op0, op1)); 15622 15623 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15624 } 15625 DONE; 15626}) 15627 15628;; Rounding mode control word calculation could clobber FLAGS_REG. 15629(define_insn_and_split "frndintxf2_mask_pm" 15630 [(set (match_operand:XF 0 "register_operand") 15631 (unspec:XF [(match_operand:XF 1 "register_operand")] 15632 UNSPEC_FRNDINT_MASK_PM)) 15633 (clobber (reg:CC FLAGS_REG))] 15634 "TARGET_USE_FANCY_MATH_387 15635 && flag_unsafe_math_optimizations 15636 && can_create_pseudo_p ()" 15637 "#" 15638 "&& 1" 15639 [(const_int 0)] 15640{ 15641 ix86_optimize_mode_switching[I387_MASK_PM] = 1; 15642 15643 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15644 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); 15645 15646 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], 15647 operands[2], operands[3])); 15648 DONE; 15649} 15650 [(set_attr "type" "frndint") 15651 (set_attr "i387_cw" "mask_pm") 15652 (set_attr "mode" "XF")]) 15653 15654(define_insn "frndintxf2_mask_pm_i387" 15655 [(set (match_operand:XF 0 "register_operand" "=f") 15656 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15657 UNSPEC_FRNDINT_MASK_PM)) 15658 (use (match_operand:HI 2 "memory_operand" "m")) 15659 (use (match_operand:HI 3 "memory_operand" "m"))] 15660 "TARGET_USE_FANCY_MATH_387 15661 && flag_unsafe_math_optimizations" 15662 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" 15663 [(set_attr "type" "frndint") 15664 (set_attr "i387_cw" "mask_pm") 15665 (set_attr "mode" "XF")]) 15666 15667(define_expand "nearbyintxf2" 15668 [(parallel [(set (match_operand:XF 0 "register_operand") 15669 (unspec:XF [(match_operand:XF 1 "register_operand")] 15670 UNSPEC_FRNDINT_MASK_PM)) 15671 (clobber (reg:CC FLAGS_REG))])] 15672 "TARGET_USE_FANCY_MATH_387 15673 && flag_unsafe_math_optimizations") 15674 15675(define_expand "nearbyint<mode>2" 15676 [(use (match_operand:MODEF 0 "register_operand")) 15677 (use (match_operand:MODEF 1 "register_operand"))] 15678 "TARGET_USE_FANCY_MATH_387 15679 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15680 || TARGET_MIX_SSE_I387) 15681 && flag_unsafe_math_optimizations" 15682{ 15683 rtx op0 = gen_reg_rtx (XFmode); 15684 rtx op1 = gen_reg_rtx (XFmode); 15685 15686 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15687 emit_insn (gen_frndintxf2_mask_pm (op0, op1)); 15688 15689 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); 15690 DONE; 15691}) 15692 15693;; Rounding mode control word calculation could clobber FLAGS_REG. 15694(define_insn_and_split "*fist<mode>2_<rounding>_1" 15695 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 15696 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 15697 FIST_ROUNDING)) 15698 (clobber (reg:CC FLAGS_REG))] 15699 "TARGET_USE_FANCY_MATH_387 15700 && flag_unsafe_math_optimizations 15701 && can_create_pseudo_p ()" 15702 "#" 15703 "&& 1" 15704 [(const_int 0)] 15705{ 15706 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 15707 15708 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 15709 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 15710 if (memory_operand (operands[0], VOIDmode)) 15711 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1], 15712 operands[2], operands[3])); 15713 else 15714 { 15715 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 15716 emit_insn (gen_fist<mode>2_<rounding>_with_temp 15717 (operands[0], operands[1], operands[2], 15718 operands[3], operands[4])); 15719 } 15720 DONE; 15721} 15722 [(set_attr "type" "fistp") 15723 (set_attr "i387_cw" "<rounding>") 15724 (set_attr "mode" "<MODE>")]) 15725 15726(define_insn "fistdi2_<rounding>" 15727 [(set (match_operand:DI 0 "memory_operand" "=m") 15728 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 15729 FIST_ROUNDING)) 15730 (use (match_operand:HI 2 "memory_operand" "m")) 15731 (use (match_operand:HI 3 "memory_operand" "m")) 15732 (clobber (match_scratch:XF 4 "=&1f"))] 15733 "TARGET_USE_FANCY_MATH_387 15734 && flag_unsafe_math_optimizations" 15735 "* return output_fix_trunc (insn, operands, false);" 15736 [(set_attr "type" "fistp") 15737 (set_attr "i387_cw" "<rounding>") 15738 (set_attr "mode" "DI")]) 15739 15740(define_insn "fistdi2_<rounding>_with_temp" 15741 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") 15742 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] 15743 FIST_ROUNDING)) 15744 (use (match_operand:HI 2 "memory_operand" "m,m")) 15745 (use (match_operand:HI 3 "memory_operand" "m,m")) 15746 (clobber (match_operand:DI 4 "memory_operand" "=X,m")) 15747 (clobber (match_scratch:XF 5 "=&1f,&1f"))] 15748 "TARGET_USE_FANCY_MATH_387 15749 && flag_unsafe_math_optimizations" 15750 "#" 15751 [(set_attr "type" "fistp") 15752 (set_attr "i387_cw" "<rounding>") 15753 (set_attr "mode" "DI")]) 15754 15755(define_split 15756 [(set (match_operand:DI 0 "register_operand") 15757 (unspec:DI [(match_operand:XF 1 "register_operand")] 15758 FIST_ROUNDING)) 15759 (use (match_operand:HI 2 "memory_operand")) 15760 (use (match_operand:HI 3 "memory_operand")) 15761 (clobber (match_operand:DI 4 "memory_operand")) 15762 (clobber (match_scratch 5))] 15763 "reload_completed" 15764 [(parallel [(set (match_dup 4) 15765 (unspec:DI [(match_dup 1)] FIST_ROUNDING)) 15766 (use (match_dup 2)) 15767 (use (match_dup 3)) 15768 (clobber (match_dup 5))]) 15769 (set (match_dup 0) (match_dup 4))]) 15770 15771(define_split 15772 [(set (match_operand:DI 0 "memory_operand") 15773 (unspec:DI [(match_operand:XF 1 "register_operand")] 15774 FIST_ROUNDING)) 15775 (use (match_operand:HI 2 "memory_operand")) 15776 (use (match_operand:HI 3 "memory_operand")) 15777 (clobber (match_operand:DI 4 "memory_operand")) 15778 (clobber (match_scratch 5))] 15779 "reload_completed" 15780 [(parallel [(set (match_dup 0) 15781 (unspec:DI [(match_dup 1)] FIST_ROUNDING)) 15782 (use (match_dup 2)) 15783 (use (match_dup 3)) 15784 (clobber (match_dup 5))])]) 15785 15786(define_insn "fist<mode>2_<rounding>" 15787 [(set (match_operand:SWI24 0 "memory_operand" "=m") 15788 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 15789 FIST_ROUNDING)) 15790 (use (match_operand:HI 2 "memory_operand" "m")) 15791 (use (match_operand:HI 3 "memory_operand" "m"))] 15792 "TARGET_USE_FANCY_MATH_387 15793 && flag_unsafe_math_optimizations" 15794 "* return output_fix_trunc (insn, operands, false);" 15795 [(set_attr "type" "fistp") 15796 (set_attr "i387_cw" "<rounding>") 15797 (set_attr "mode" "<MODE>")]) 15798 15799(define_insn "fist<mode>2_<rounding>_with_temp" 15800 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") 15801 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] 15802 FIST_ROUNDING)) 15803 (use (match_operand:HI 2 "memory_operand" "m,m")) 15804 (use (match_operand:HI 3 "memory_operand" "m,m")) 15805 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] 15806 "TARGET_USE_FANCY_MATH_387 15807 && flag_unsafe_math_optimizations" 15808 "#" 15809 [(set_attr "type" "fistp") 15810 (set_attr "i387_cw" "<rounding>") 15811 (set_attr "mode" "<MODE>")]) 15812 15813(define_split 15814 [(set (match_operand:SWI24 0 "register_operand") 15815 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 15816 FIST_ROUNDING)) 15817 (use (match_operand:HI 2 "memory_operand")) 15818 (use (match_operand:HI 3 "memory_operand")) 15819 (clobber (match_operand:SWI24 4 "memory_operand"))] 15820 "reload_completed" 15821 [(parallel [(set (match_dup 4) 15822 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) 15823 (use (match_dup 2)) 15824 (use (match_dup 3))]) 15825 (set (match_dup 0) (match_dup 4))]) 15826 15827(define_split 15828 [(set (match_operand:SWI24 0 "memory_operand") 15829 (unspec:SWI24 [(match_operand:XF 1 "register_operand")] 15830 FIST_ROUNDING)) 15831 (use (match_operand:HI 2 "memory_operand")) 15832 (use (match_operand:HI 3 "memory_operand")) 15833 (clobber (match_operand:SWI24 4 "memory_operand"))] 15834 "reload_completed" 15835 [(parallel [(set (match_dup 0) 15836 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) 15837 (use (match_dup 2)) 15838 (use (match_dup 3))])]) 15839 15840(define_expand "l<rounding_insn>xf<mode>2" 15841 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand") 15842 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 15843 FIST_ROUNDING)) 15844 (clobber (reg:CC FLAGS_REG))])] 15845 "TARGET_USE_FANCY_MATH_387 15846 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 15847 && flag_unsafe_math_optimizations") 15848 15849(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2" 15850 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand") 15851 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 15852 FIST_ROUNDING)) 15853 (clobber (reg:CC FLAGS_REG))])] 15854 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 15855 && !flag_trapping_math" 15856{ 15857 if (TARGET_64BIT && optimize_insn_for_size_p ()) 15858 FAIL; 15859 15860 if (ROUND_<ROUNDING> == ROUND_FLOOR) 15861 ix86_expand_lfloorceil (operands[0], operands[1], true); 15862 else if (ROUND_<ROUNDING> == ROUND_CEIL) 15863 ix86_expand_lfloorceil (operands[0], operands[1], false); 15864 else 15865 gcc_unreachable (); 15866 15867 DONE; 15868}) 15869 15870(define_insn "fxam<mode>2_i387" 15871 [(set (match_operand:HI 0 "register_operand" "=a") 15872 (unspec:HI 15873 [(match_operand:X87MODEF 1 "register_operand" "f")] 15874 UNSPEC_FXAM))] 15875 "TARGET_USE_FANCY_MATH_387" 15876 "fxam\n\tfnstsw\t%0" 15877 [(set_attr "type" "multi") 15878 (set_attr "length" "4") 15879 (set_attr "unit" "i387") 15880 (set_attr "mode" "<MODE>")]) 15881 15882(define_insn_and_split "fxam<mode>2_i387_with_temp" 15883 [(set (match_operand:HI 0 "register_operand") 15884 (unspec:HI 15885 [(match_operand:MODEF 1 "memory_operand")] 15886 UNSPEC_FXAM_MEM))] 15887 "TARGET_USE_FANCY_MATH_387 15888 && can_create_pseudo_p ()" 15889 "#" 15890 "&& 1" 15891 [(set (match_dup 2)(match_dup 1)) 15892 (set (match_dup 0) 15893 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))] 15894{ 15895 operands[2] = gen_reg_rtx (<MODE>mode); 15896 15897 MEM_VOLATILE_P (operands[1]) = 1; 15898} 15899 [(set_attr "type" "multi") 15900 (set_attr "unit" "i387") 15901 (set_attr "mode" "<MODE>")]) 15902 15903(define_expand "isinfxf2" 15904 [(use (match_operand:SI 0 "register_operand")) 15905 (use (match_operand:XF 1 "register_operand"))] 15906 "TARGET_USE_FANCY_MATH_387 15907 && ix86_libc_has_function (function_c99_misc)" 15908{ 15909 rtx mask = GEN_INT (0x45); 15910 rtx val = GEN_INT (0x05); 15911 15912 rtx cond; 15913 15914 rtx scratch = gen_reg_rtx (HImode); 15915 rtx res = gen_reg_rtx (QImode); 15916 15917 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 15918 15919 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); 15920 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 15921 cond = gen_rtx_fmt_ee (EQ, QImode, 15922 gen_rtx_REG (CCmode, FLAGS_REG), 15923 const0_rtx); 15924 emit_insn (gen_rtx_SET (VOIDmode, res, cond)); 15925 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 15926 DONE; 15927}) 15928 15929(define_expand "isinf<mode>2" 15930 [(use (match_operand:SI 0 "register_operand")) 15931 (use (match_operand:MODEF 1 "nonimmediate_operand"))] 15932 "TARGET_USE_FANCY_MATH_387 15933 && ix86_libc_has_function (function_c99_misc) 15934 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 15935{ 15936 rtx mask = GEN_INT (0x45); 15937 rtx val = GEN_INT (0x05); 15938 15939 rtx cond; 15940 15941 rtx scratch = gen_reg_rtx (HImode); 15942 rtx res = gen_reg_rtx (QImode); 15943 15944 /* Remove excess precision by forcing value through memory. */ 15945 if (memory_operand (operands[1], VOIDmode)) 15946 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1])); 15947 else 15948 { 15949 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP); 15950 15951 emit_move_insn (temp, operands[1]); 15952 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp)); 15953 } 15954 15955 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask)); 15956 emit_insn (gen_cmpqi_ext_3 (scratch, val)); 15957 cond = gen_rtx_fmt_ee (EQ, QImode, 15958 gen_rtx_REG (CCmode, FLAGS_REG), 15959 const0_rtx); 15960 emit_insn (gen_rtx_SET (VOIDmode, res, cond)); 15961 emit_insn (gen_zero_extendqisi2 (operands[0], res)); 15962 DONE; 15963}) 15964 15965(define_expand "signbitxf2" 15966 [(use (match_operand:SI 0 "register_operand")) 15967 (use (match_operand:XF 1 "register_operand"))] 15968 "TARGET_USE_FANCY_MATH_387" 15969{ 15970 rtx scratch = gen_reg_rtx (HImode); 15971 15972 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 15973 emit_insn (gen_andsi3 (operands[0], 15974 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 15975 DONE; 15976}) 15977 15978(define_insn "movmsk_df" 15979 [(set (match_operand:SI 0 "register_operand" "=r") 15980 (unspec:SI 15981 [(match_operand:DF 1 "register_operand" "x")] 15982 UNSPEC_MOVMSK))] 15983 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH" 15984 "%vmovmskpd\t{%1, %0|%0, %1}" 15985 [(set_attr "type" "ssemov") 15986 (set_attr "prefix" "maybe_vex") 15987 (set_attr "mode" "DF")]) 15988 15989;; Use movmskpd in SSE mode to avoid store forwarding stall 15990;; for 32bit targets and movq+shrq sequence for 64bit targets. 15991(define_expand "signbitdf2" 15992 [(use (match_operand:SI 0 "register_operand")) 15993 (use (match_operand:DF 1 "register_operand"))] 15994 "TARGET_USE_FANCY_MATH_387 15995 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15996{ 15997 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH) 15998 { 15999 emit_insn (gen_movmsk_df (operands[0], operands[1])); 16000 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx)); 16001 } 16002 else 16003 { 16004 rtx scratch = gen_reg_rtx (HImode); 16005 16006 emit_insn (gen_fxamdf2_i387 (scratch, operands[1])); 16007 emit_insn (gen_andsi3 (operands[0], 16008 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 16009 } 16010 DONE; 16011}) 16012 16013(define_expand "signbitsf2" 16014 [(use (match_operand:SI 0 "register_operand")) 16015 (use (match_operand:SF 1 "register_operand"))] 16016 "TARGET_USE_FANCY_MATH_387 16017 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)" 16018{ 16019 rtx scratch = gen_reg_rtx (HImode); 16020 16021 emit_insn (gen_fxamsf2_i387 (scratch, operands[1])); 16022 emit_insn (gen_andsi3 (operands[0], 16023 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 16024 DONE; 16025}) 16026 16027;; Block operation instructions 16028 16029(define_insn "cld" 16030 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] 16031 "" 16032 "cld" 16033 [(set_attr "length" "1") 16034 (set_attr "length_immediate" "0") 16035 (set_attr "modrm" "0")]) 16036 16037(define_expand "movmem<mode>" 16038 [(use (match_operand:BLK 0 "memory_operand")) 16039 (use (match_operand:BLK 1 "memory_operand")) 16040 (use (match_operand:SWI48 2 "nonmemory_operand")) 16041 (use (match_operand:SWI48 3 "const_int_operand")) 16042 (use (match_operand:SI 4 "const_int_operand")) 16043 (use (match_operand:SI 5 "const_int_operand")) 16044 (use (match_operand:SI 6 "")) 16045 (use (match_operand:SI 7 "")) 16046 (use (match_operand:SI 8 ""))] 16047 "" 16048{ 16049 if (ix86_expand_set_or_movmem (operands[0], operands[1], 16050 operands[2], NULL, operands[3], 16051 operands[4], operands[5], 16052 operands[6], operands[7], 16053 operands[8], false)) 16054 DONE; 16055 else 16056 FAIL; 16057}) 16058 16059;; Most CPUs don't like single string operations 16060;; Handle this case here to simplify previous expander. 16061 16062(define_expand "strmov" 16063 [(set (match_dup 4) (match_operand 3 "memory_operand")) 16064 (set (match_operand 1 "memory_operand") (match_dup 4)) 16065 (parallel [(set (match_operand 0 "register_operand") (match_dup 5)) 16066 (clobber (reg:CC FLAGS_REG))]) 16067 (parallel [(set (match_operand 2 "register_operand") (match_dup 6)) 16068 (clobber (reg:CC FLAGS_REG))])] 16069 "" 16070{ 16071 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 16072 16073 /* If .md ever supports :P for Pmode, these can be directly 16074 in the pattern above. */ 16075 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 16076 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 16077 16078 /* Can't use this if the user has appropriated esi or edi. */ 16079 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 16080 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])) 16081 { 16082 emit_insn (gen_strmov_singleop (operands[0], operands[1], 16083 operands[2], operands[3], 16084 operands[5], operands[6])); 16085 DONE; 16086 } 16087 16088 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 16089}) 16090 16091(define_expand "strmov_singleop" 16092 [(parallel [(set (match_operand 1 "memory_operand") 16093 (match_operand 3 "memory_operand")) 16094 (set (match_operand 0 "register_operand") 16095 (match_operand 4)) 16096 (set (match_operand 2 "register_operand") 16097 (match_operand 5))])] 16098 "" 16099 "ix86_current_function_needs_cld = 1;") 16100 16101(define_insn "*strmovdi_rex_1" 16102 [(set (mem:DI (match_operand:P 2 "register_operand" "0")) 16103 (mem:DI (match_operand:P 3 "register_operand" "1"))) 16104 (set (match_operand:P 0 "register_operand" "=D") 16105 (plus:P (match_dup 2) 16106 (const_int 8))) 16107 (set (match_operand:P 1 "register_operand" "=S") 16108 (plus:P (match_dup 3) 16109 (const_int 8)))] 16110 "TARGET_64BIT 16111 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16112 "%^movsq" 16113 [(set_attr "type" "str") 16114 (set_attr "memory" "both") 16115 (set_attr "mode" "DI")]) 16116 16117(define_insn "*strmovsi_1" 16118 [(set (mem:SI (match_operand:P 2 "register_operand" "0")) 16119 (mem:SI (match_operand:P 3 "register_operand" "1"))) 16120 (set (match_operand:P 0 "register_operand" "=D") 16121 (plus:P (match_dup 2) 16122 (const_int 4))) 16123 (set (match_operand:P 1 "register_operand" "=S") 16124 (plus:P (match_dup 3) 16125 (const_int 4)))] 16126 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16127 "%^movs{l|d}" 16128 [(set_attr "type" "str") 16129 (set_attr "memory" "both") 16130 (set_attr "mode" "SI")]) 16131 16132(define_insn "*strmovhi_1" 16133 [(set (mem:HI (match_operand:P 2 "register_operand" "0")) 16134 (mem:HI (match_operand:P 3 "register_operand" "1"))) 16135 (set (match_operand:P 0 "register_operand" "=D") 16136 (plus:P (match_dup 2) 16137 (const_int 2))) 16138 (set (match_operand:P 1 "register_operand" "=S") 16139 (plus:P (match_dup 3) 16140 (const_int 2)))] 16141 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16142 "%^movsw" 16143 [(set_attr "type" "str") 16144 (set_attr "memory" "both") 16145 (set_attr "mode" "HI")]) 16146 16147(define_insn "*strmovqi_1" 16148 [(set (mem:QI (match_operand:P 2 "register_operand" "0")) 16149 (mem:QI (match_operand:P 3 "register_operand" "1"))) 16150 (set (match_operand:P 0 "register_operand" "=D") 16151 (plus:P (match_dup 2) 16152 (const_int 1))) 16153 (set (match_operand:P 1 "register_operand" "=S") 16154 (plus:P (match_dup 3) 16155 (const_int 1)))] 16156 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16157 "%^movsb" 16158 [(set_attr "type" "str") 16159 (set_attr "memory" "both") 16160 (set (attr "prefix_rex") 16161 (if_then_else 16162 (match_test "<P:MODE>mode == DImode") 16163 (const_string "0") 16164 (const_string "*"))) 16165 (set_attr "mode" "QI")]) 16166 16167(define_expand "rep_mov" 16168 [(parallel [(set (match_operand 4 "register_operand") (const_int 0)) 16169 (set (match_operand 0 "register_operand") 16170 (match_operand 5)) 16171 (set (match_operand 2 "register_operand") 16172 (match_operand 6)) 16173 (set (match_operand 1 "memory_operand") 16174 (match_operand 3 "memory_operand")) 16175 (use (match_dup 4))])] 16176 "" 16177 "ix86_current_function_needs_cld = 1;") 16178 16179(define_insn "*rep_movdi_rex64" 16180 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 16181 (set (match_operand:P 0 "register_operand" "=D") 16182 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 16183 (const_int 3)) 16184 (match_operand:P 3 "register_operand" "0"))) 16185 (set (match_operand:P 1 "register_operand" "=S") 16186 (plus:P (ashift:P (match_dup 5) (const_int 3)) 16187 (match_operand:P 4 "register_operand" "1"))) 16188 (set (mem:BLK (match_dup 3)) 16189 (mem:BLK (match_dup 4))) 16190 (use (match_dup 5))] 16191 "TARGET_64BIT 16192 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16193 "%^rep{%;} movsq" 16194 [(set_attr "type" "str") 16195 (set_attr "prefix_rep" "1") 16196 (set_attr "memory" "both") 16197 (set_attr "mode" "DI")]) 16198 16199(define_insn "*rep_movsi" 16200 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 16201 (set (match_operand:P 0 "register_operand" "=D") 16202 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 16203 (const_int 2)) 16204 (match_operand:P 3 "register_operand" "0"))) 16205 (set (match_operand:P 1 "register_operand" "=S") 16206 (plus:P (ashift:P (match_dup 5) (const_int 2)) 16207 (match_operand:P 4 "register_operand" "1"))) 16208 (set (mem:BLK (match_dup 3)) 16209 (mem:BLK (match_dup 4))) 16210 (use (match_dup 5))] 16211 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16212 "%^rep{%;} movs{l|d}" 16213 [(set_attr "type" "str") 16214 (set_attr "prefix_rep" "1") 16215 (set_attr "memory" "both") 16216 (set_attr "mode" "SI")]) 16217 16218(define_insn "*rep_movqi" 16219 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 16220 (set (match_operand:P 0 "register_operand" "=D") 16221 (plus:P (match_operand:P 3 "register_operand" "0") 16222 (match_operand:P 5 "register_operand" "2"))) 16223 (set (match_operand:P 1 "register_operand" "=S") 16224 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5))) 16225 (set (mem:BLK (match_dup 3)) 16226 (mem:BLK (match_dup 4))) 16227 (use (match_dup 5))] 16228 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16229 "%^rep{%;} movsb" 16230 [(set_attr "type" "str") 16231 (set_attr "prefix_rep" "1") 16232 (set_attr "memory" "both") 16233 (set_attr "mode" "QI")]) 16234 16235(define_expand "setmem<mode>" 16236 [(use (match_operand:BLK 0 "memory_operand")) 16237 (use (match_operand:SWI48 1 "nonmemory_operand")) 16238 (use (match_operand:QI 2 "nonmemory_operand")) 16239 (use (match_operand 3 "const_int_operand")) 16240 (use (match_operand:SI 4 "const_int_operand")) 16241 (use (match_operand:SI 5 "const_int_operand")) 16242 (use (match_operand:SI 6 "")) 16243 (use (match_operand:SI 7 "")) 16244 (use (match_operand:SI 8 ""))] 16245 "" 16246{ 16247 if (ix86_expand_set_or_movmem (operands[0], NULL, 16248 operands[1], operands[2], 16249 operands[3], operands[4], 16250 operands[5], operands[6], 16251 operands[7], operands[8], true)) 16252 DONE; 16253 else 16254 FAIL; 16255}) 16256 16257;; Most CPUs don't like single string operations 16258;; Handle this case here to simplify previous expander. 16259 16260(define_expand "strset" 16261 [(set (match_operand 1 "memory_operand") 16262 (match_operand 2 "register_operand")) 16263 (parallel [(set (match_operand 0 "register_operand") 16264 (match_dup 3)) 16265 (clobber (reg:CC FLAGS_REG))])] 16266 "" 16267{ 16268 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 16269 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 16270 16271 /* If .md ever supports :P for Pmode, this can be directly 16272 in the pattern above. */ 16273 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 16274 GEN_INT (GET_MODE_SIZE (GET_MODE 16275 (operands[2])))); 16276 /* Can't use this if the user has appropriated eax or edi. */ 16277 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 16278 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])) 16279 { 16280 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 16281 operands[3])); 16282 DONE; 16283 } 16284}) 16285 16286(define_expand "strset_singleop" 16287 [(parallel [(set (match_operand 1 "memory_operand") 16288 (match_operand 2 "register_operand")) 16289 (set (match_operand 0 "register_operand") 16290 (match_operand 3)) 16291 (unspec [(const_int 0)] UNSPEC_STOS)])] 16292 "" 16293 "ix86_current_function_needs_cld = 1;") 16294 16295(define_insn "*strsetdi_rex_1" 16296 [(set (mem:DI (match_operand:P 1 "register_operand" "0")) 16297 (match_operand:DI 2 "register_operand" "a")) 16298 (set (match_operand:P 0 "register_operand" "=D") 16299 (plus:P (match_dup 1) 16300 (const_int 8))) 16301 (unspec [(const_int 0)] UNSPEC_STOS)] 16302 "TARGET_64BIT 16303 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 16304 "%^stosq" 16305 [(set_attr "type" "str") 16306 (set_attr "memory" "store") 16307 (set_attr "mode" "DI")]) 16308 16309(define_insn "*strsetsi_1" 16310 [(set (mem:SI (match_operand:P 1 "register_operand" "0")) 16311 (match_operand:SI 2 "register_operand" "a")) 16312 (set (match_operand:P 0 "register_operand" "=D") 16313 (plus:P (match_dup 1) 16314 (const_int 4))) 16315 (unspec [(const_int 0)] UNSPEC_STOS)] 16316 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 16317 "%^stos{l|d}" 16318 [(set_attr "type" "str") 16319 (set_attr "memory" "store") 16320 (set_attr "mode" "SI")]) 16321 16322(define_insn "*strsethi_1" 16323 [(set (mem:HI (match_operand:P 1 "register_operand" "0")) 16324 (match_operand:HI 2 "register_operand" "a")) 16325 (set (match_operand:P 0 "register_operand" "=D") 16326 (plus:P (match_dup 1) 16327 (const_int 2))) 16328 (unspec [(const_int 0)] UNSPEC_STOS)] 16329 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 16330 "%^stosw" 16331 [(set_attr "type" "str") 16332 (set_attr "memory" "store") 16333 (set_attr "mode" "HI")]) 16334 16335(define_insn "*strsetqi_1" 16336 [(set (mem:QI (match_operand:P 1 "register_operand" "0")) 16337 (match_operand:QI 2 "register_operand" "a")) 16338 (set (match_operand:P 0 "register_operand" "=D") 16339 (plus:P (match_dup 1) 16340 (const_int 1))) 16341 (unspec [(const_int 0)] UNSPEC_STOS)] 16342 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])" 16343 "%^stosb" 16344 [(set_attr "type" "str") 16345 (set_attr "memory" "store") 16346 (set (attr "prefix_rex") 16347 (if_then_else 16348 (match_test "<P:MODE>mode == DImode") 16349 (const_string "0") 16350 (const_string "*"))) 16351 (set_attr "mode" "QI")]) 16352 16353(define_expand "rep_stos" 16354 [(parallel [(set (match_operand 1 "register_operand") (const_int 0)) 16355 (set (match_operand 0 "register_operand") 16356 (match_operand 4)) 16357 (set (match_operand 2 "memory_operand") (const_int 0)) 16358 (use (match_operand 3 "register_operand")) 16359 (use (match_dup 1))])] 16360 "" 16361 "ix86_current_function_needs_cld = 1;") 16362 16363(define_insn "*rep_stosdi_rex64" 16364 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 16365 (set (match_operand:P 0 "register_operand" "=D") 16366 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 16367 (const_int 3)) 16368 (match_operand:P 3 "register_operand" "0"))) 16369 (set (mem:BLK (match_dup 3)) 16370 (const_int 0)) 16371 (use (match_operand:DI 2 "register_operand" "a")) 16372 (use (match_dup 4))] 16373 "TARGET_64BIT 16374 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16375 "%^rep{%;} stosq" 16376 [(set_attr "type" "str") 16377 (set_attr "prefix_rep" "1") 16378 (set_attr "memory" "store") 16379 (set_attr "mode" "DI")]) 16380 16381(define_insn "*rep_stossi" 16382 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 16383 (set (match_operand:P 0 "register_operand" "=D") 16384 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 16385 (const_int 2)) 16386 (match_operand:P 3 "register_operand" "0"))) 16387 (set (mem:BLK (match_dup 3)) 16388 (const_int 0)) 16389 (use (match_operand:SI 2 "register_operand" "a")) 16390 (use (match_dup 4))] 16391 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16392 "%^rep{%;} stos{l|d}" 16393 [(set_attr "type" "str") 16394 (set_attr "prefix_rep" "1") 16395 (set_attr "memory" "store") 16396 (set_attr "mode" "SI")]) 16397 16398(define_insn "*rep_stosqi" 16399 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 16400 (set (match_operand:P 0 "register_operand" "=D") 16401 (plus:P (match_operand:P 3 "register_operand" "0") 16402 (match_operand:P 4 "register_operand" "1"))) 16403 (set (mem:BLK (match_dup 3)) 16404 (const_int 0)) 16405 (use (match_operand:QI 2 "register_operand" "a")) 16406 (use (match_dup 4))] 16407 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16408 "%^rep{%;} stosb" 16409 [(set_attr "type" "str") 16410 (set_attr "prefix_rep" "1") 16411 (set_attr "memory" "store") 16412 (set (attr "prefix_rex") 16413 (if_then_else 16414 (match_test "<P:MODE>mode == DImode") 16415 (const_string "0") 16416 (const_string "*"))) 16417 (set_attr "mode" "QI")]) 16418 16419(define_expand "cmpstrnsi" 16420 [(set (match_operand:SI 0 "register_operand") 16421 (compare:SI (match_operand:BLK 1 "general_operand") 16422 (match_operand:BLK 2 "general_operand"))) 16423 (use (match_operand 3 "general_operand")) 16424 (use (match_operand 4 "immediate_operand"))] 16425 "" 16426{ 16427 rtx addr1, addr2, out, outlow, count, countreg, align; 16428 16429 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) 16430 FAIL; 16431 16432 /* Can't use this if the user has appropriated ecx, esi or edi. */ 16433 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 16434 FAIL; 16435 16436 out = operands[0]; 16437 if (!REG_P (out)) 16438 out = gen_reg_rtx (SImode); 16439 16440 addr1 = copy_addr_to_reg (XEXP (operands[1], 0)); 16441 addr2 = copy_addr_to_reg (XEXP (operands[2], 0)); 16442 if (addr1 != XEXP (operands[1], 0)) 16443 operands[1] = replace_equiv_address_nv (operands[1], addr1); 16444 if (addr2 != XEXP (operands[2], 0)) 16445 operands[2] = replace_equiv_address_nv (operands[2], addr2); 16446 16447 count = operands[3]; 16448 countreg = ix86_zero_extend_to_Pmode (count); 16449 16450 /* %%% Iff we are testing strict equality, we can use known alignment 16451 to good advantage. This may be possible with combine, particularly 16452 once cc0 is dead. */ 16453 align = operands[4]; 16454 16455 if (CONST_INT_P (count)) 16456 { 16457 if (INTVAL (count) == 0) 16458 { 16459 emit_move_insn (operands[0], const0_rtx); 16460 DONE; 16461 } 16462 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 16463 operands[1], operands[2])); 16464 } 16465 else 16466 { 16467 rtx (*gen_cmp) (rtx, rtx); 16468 16469 gen_cmp = (TARGET_64BIT 16470 ? gen_cmpdi_1 : gen_cmpsi_1); 16471 16472 emit_insn (gen_cmp (countreg, countreg)); 16473 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 16474 operands[1], operands[2])); 16475 } 16476 16477 outlow = gen_lowpart (QImode, out); 16478 emit_insn (gen_cmpintqi (outlow)); 16479 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow)); 16480 16481 if (operands[0] != out) 16482 emit_move_insn (operands[0], out); 16483 16484 DONE; 16485}) 16486 16487;; Produce a tri-state integer (-1, 0, 1) from condition codes. 16488 16489(define_expand "cmpintqi" 16490 [(set (match_dup 1) 16491 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16492 (set (match_dup 2) 16493 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16494 (parallel [(set (match_operand:QI 0 "register_operand") 16495 (minus:QI (match_dup 1) 16496 (match_dup 2))) 16497 (clobber (reg:CC FLAGS_REG))])] 16498 "" 16499{ 16500 operands[1] = gen_reg_rtx (QImode); 16501 operands[2] = gen_reg_rtx (QImode); 16502}) 16503 16504;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 16505;; zero. Emit extra code to make sure that a zero-length compare is EQ. 16506 16507(define_expand "cmpstrnqi_nz_1" 16508 [(parallel [(set (reg:CC FLAGS_REG) 16509 (compare:CC (match_operand 4 "memory_operand") 16510 (match_operand 5 "memory_operand"))) 16511 (use (match_operand 2 "register_operand")) 16512 (use (match_operand:SI 3 "immediate_operand")) 16513 (clobber (match_operand 0 "register_operand")) 16514 (clobber (match_operand 1 "register_operand")) 16515 (clobber (match_dup 2))])] 16516 "" 16517 "ix86_current_function_needs_cld = 1;") 16518 16519(define_insn "*cmpstrnqi_nz_1" 16520 [(set (reg:CC FLAGS_REG) 16521 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 16522 (mem:BLK (match_operand:P 5 "register_operand" "1")))) 16523 (use (match_operand:P 6 "register_operand" "2")) 16524 (use (match_operand:SI 3 "immediate_operand" "i")) 16525 (clobber (match_operand:P 0 "register_operand" "=S")) 16526 (clobber (match_operand:P 1 "register_operand" "=D")) 16527 (clobber (match_operand:P 2 "register_operand" "=c"))] 16528 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16529 "%^repz{%;} cmpsb" 16530 [(set_attr "type" "str") 16531 (set_attr "mode" "QI") 16532 (set (attr "prefix_rex") 16533 (if_then_else 16534 (match_test "<P:MODE>mode == DImode") 16535 (const_string "0") 16536 (const_string "*"))) 16537 (set_attr "prefix_rep" "1")]) 16538 16539;; The same, but the count is not known to not be zero. 16540 16541(define_expand "cmpstrnqi_1" 16542 [(parallel [(set (reg:CC FLAGS_REG) 16543 (if_then_else:CC (ne (match_operand 2 "register_operand") 16544 (const_int 0)) 16545 (compare:CC (match_operand 4 "memory_operand") 16546 (match_operand 5 "memory_operand")) 16547 (const_int 0))) 16548 (use (match_operand:SI 3 "immediate_operand")) 16549 (use (reg:CC FLAGS_REG)) 16550 (clobber (match_operand 0 "register_operand")) 16551 (clobber (match_operand 1 "register_operand")) 16552 (clobber (match_dup 2))])] 16553 "" 16554 "ix86_current_function_needs_cld = 1;") 16555 16556(define_insn "*cmpstrnqi_1" 16557 [(set (reg:CC FLAGS_REG) 16558 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2") 16559 (const_int 0)) 16560 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 16561 (mem:BLK (match_operand:P 5 "register_operand" "1"))) 16562 (const_int 0))) 16563 (use (match_operand:SI 3 "immediate_operand" "i")) 16564 (use (reg:CC FLAGS_REG)) 16565 (clobber (match_operand:P 0 "register_operand" "=S")) 16566 (clobber (match_operand:P 1 "register_operand" "=D")) 16567 (clobber (match_operand:P 2 "register_operand" "=c"))] 16568 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])" 16569 "%^repz{%;} cmpsb" 16570 [(set_attr "type" "str") 16571 (set_attr "mode" "QI") 16572 (set (attr "prefix_rex") 16573 (if_then_else 16574 (match_test "<P:MODE>mode == DImode") 16575 (const_string "0") 16576 (const_string "*"))) 16577 (set_attr "prefix_rep" "1")]) 16578 16579(define_expand "strlen<mode>" 16580 [(set (match_operand:P 0 "register_operand") 16581 (unspec:P [(match_operand:BLK 1 "general_operand") 16582 (match_operand:QI 2 "immediate_operand") 16583 (match_operand 3 "immediate_operand")] 16584 UNSPEC_SCAS))] 16585 "" 16586{ 16587 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 16588 DONE; 16589 else 16590 FAIL; 16591}) 16592 16593(define_expand "strlenqi_1" 16594 [(parallel [(set (match_operand 0 "register_operand") 16595 (match_operand 2)) 16596 (clobber (match_operand 1 "register_operand")) 16597 (clobber (reg:CC FLAGS_REG))])] 16598 "" 16599 "ix86_current_function_needs_cld = 1;") 16600 16601(define_insn "*strlenqi_1" 16602 [(set (match_operand:P 0 "register_operand" "=&c") 16603 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1")) 16604 (match_operand:QI 2 "register_operand" "a") 16605 (match_operand:P 3 "immediate_operand" "i") 16606 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS)) 16607 (clobber (match_operand:P 1 "register_operand" "=D")) 16608 (clobber (reg:CC FLAGS_REG))] 16609 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])" 16610 "%^repnz{%;} scasb" 16611 [(set_attr "type" "str") 16612 (set_attr "mode" "QI") 16613 (set (attr "prefix_rex") 16614 (if_then_else 16615 (match_test "<P:MODE>mode == DImode") 16616 (const_string "0") 16617 (const_string "*"))) 16618 (set_attr "prefix_rep" "1")]) 16619 16620;; Peephole optimizations to clean up after cmpstrn*. This should be 16621;; handled in combine, but it is not currently up to the task. 16622;; When used for their truth value, the cmpstrn* expanders generate 16623;; code like this: 16624;; 16625;; repz cmpsb 16626;; seta %al 16627;; setb %dl 16628;; cmpb %al, %dl 16629;; jcc label 16630;; 16631;; The intermediate three instructions are unnecessary. 16632 16633;; This one handles cmpstrn*_nz_1... 16634(define_peephole2 16635 [(parallel[ 16636 (set (reg:CC FLAGS_REG) 16637 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 16638 (mem:BLK (match_operand 5 "register_operand")))) 16639 (use (match_operand 6 "register_operand")) 16640 (use (match_operand:SI 3 "immediate_operand")) 16641 (clobber (match_operand 0 "register_operand")) 16642 (clobber (match_operand 1 "register_operand")) 16643 (clobber (match_operand 2 "register_operand"))]) 16644 (set (match_operand:QI 7 "register_operand") 16645 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16646 (set (match_operand:QI 8 "register_operand") 16647 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16648 (set (reg FLAGS_REG) 16649 (compare (match_dup 7) (match_dup 8))) 16650 ] 16651 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 16652 [(parallel[ 16653 (set (reg:CC FLAGS_REG) 16654 (compare:CC (mem:BLK (match_dup 4)) 16655 (mem:BLK (match_dup 5)))) 16656 (use (match_dup 6)) 16657 (use (match_dup 3)) 16658 (clobber (match_dup 0)) 16659 (clobber (match_dup 1)) 16660 (clobber (match_dup 2))])]) 16661 16662;; ...and this one handles cmpstrn*_1. 16663(define_peephole2 16664 [(parallel[ 16665 (set (reg:CC FLAGS_REG) 16666 (if_then_else:CC (ne (match_operand 6 "register_operand") 16667 (const_int 0)) 16668 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 16669 (mem:BLK (match_operand 5 "register_operand"))) 16670 (const_int 0))) 16671 (use (match_operand:SI 3 "immediate_operand")) 16672 (use (reg:CC FLAGS_REG)) 16673 (clobber (match_operand 0 "register_operand")) 16674 (clobber (match_operand 1 "register_operand")) 16675 (clobber (match_operand 2 "register_operand"))]) 16676 (set (match_operand:QI 7 "register_operand") 16677 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 16678 (set (match_operand:QI 8 "register_operand") 16679 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 16680 (set (reg FLAGS_REG) 16681 (compare (match_dup 7) (match_dup 8))) 16682 ] 16683 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 16684 [(parallel[ 16685 (set (reg:CC FLAGS_REG) 16686 (if_then_else:CC (ne (match_dup 6) 16687 (const_int 0)) 16688 (compare:CC (mem:BLK (match_dup 4)) 16689 (mem:BLK (match_dup 5))) 16690 (const_int 0))) 16691 (use (match_dup 3)) 16692 (use (reg:CC FLAGS_REG)) 16693 (clobber (match_dup 0)) 16694 (clobber (match_dup 1)) 16695 (clobber (match_dup 2))])]) 16696 16697;; Conditional move instructions. 16698 16699(define_expand "mov<mode>cc" 16700 [(set (match_operand:SWIM 0 "register_operand") 16701 (if_then_else:SWIM (match_operand 1 "comparison_operator") 16702 (match_operand:SWIM 2 "<general_operand>") 16703 (match_operand:SWIM 3 "<general_operand>")))] 16704 "" 16705 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") 16706 16707;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 16708;; the register first winds up with `sbbl $0,reg', which is also weird. 16709;; So just document what we're doing explicitly. 16710 16711(define_expand "x86_mov<mode>cc_0_m1" 16712 [(parallel 16713 [(set (match_operand:SWI48 0 "register_operand") 16714 (if_then_else:SWI48 16715 (match_operator:SWI48 2 "ix86_carry_flag_operator" 16716 [(match_operand 1 "flags_reg_operand") 16717 (const_int 0)]) 16718 (const_int -1) 16719 (const_int 0))) 16720 (clobber (reg:CC FLAGS_REG))])]) 16721 16722(define_insn "*x86_mov<mode>cc_0_m1" 16723 [(set (match_operand:SWI48 0 "register_operand" "=r") 16724 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16725 [(reg FLAGS_REG) (const_int 0)]) 16726 (const_int -1) 16727 (const_int 0))) 16728 (clobber (reg:CC FLAGS_REG))] 16729 "" 16730 "sbb{<imodesuffix>}\t%0, %0" 16731 ; Since we don't have the proper number of operands for an alu insn, 16732 ; fill in all the blanks. 16733 [(set_attr "type" "alu") 16734 (set_attr "use_carry" "1") 16735 (set_attr "pent_pair" "pu") 16736 (set_attr "memory" "none") 16737 (set_attr "imm_disp" "false") 16738 (set_attr "mode" "<MODE>") 16739 (set_attr "length_immediate" "0")]) 16740 16741(define_insn "*x86_mov<mode>cc_0_m1_se" 16742 [(set (match_operand:SWI48 0 "register_operand" "=r") 16743 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16744 [(reg FLAGS_REG) (const_int 0)]) 16745 (const_int 1) 16746 (const_int 0))) 16747 (clobber (reg:CC FLAGS_REG))] 16748 "" 16749 "sbb{<imodesuffix>}\t%0, %0" 16750 [(set_attr "type" "alu") 16751 (set_attr "use_carry" "1") 16752 (set_attr "pent_pair" "pu") 16753 (set_attr "memory" "none") 16754 (set_attr "imm_disp" "false") 16755 (set_attr "mode" "<MODE>") 16756 (set_attr "length_immediate" "0")]) 16757 16758(define_insn "*x86_mov<mode>cc_0_m1_neg" 16759 [(set (match_operand:SWI48 0 "register_operand" "=r") 16760 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator" 16761 [(reg FLAGS_REG) (const_int 0)]))) 16762 (clobber (reg:CC FLAGS_REG))] 16763 "" 16764 "sbb{<imodesuffix>}\t%0, %0" 16765 [(set_attr "type" "alu") 16766 (set_attr "use_carry" "1") 16767 (set_attr "pent_pair" "pu") 16768 (set_attr "memory" "none") 16769 (set_attr "imm_disp" "false") 16770 (set_attr "mode" "<MODE>") 16771 (set_attr "length_immediate" "0")]) 16772 16773(define_insn "*mov<mode>cc_noc" 16774 [(set (match_operand:SWI248 0 "register_operand" "=r,r") 16775 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 16776 [(reg FLAGS_REG) (const_int 0)]) 16777 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0") 16778 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))] 16779 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16780 "@ 16781 cmov%O2%C1\t{%2, %0|%0, %2} 16782 cmov%O2%c1\t{%3, %0|%0, %3}" 16783 [(set_attr "type" "icmov") 16784 (set_attr "mode" "<MODE>")]) 16785 16786;; Don't do conditional moves with memory inputs. This splitter helps 16787;; register starved x86_32 by forcing inputs into registers before reload. 16788(define_split 16789 [(set (match_operand:SWI248 0 "register_operand") 16790 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 16791 [(reg FLAGS_REG) (const_int 0)]) 16792 (match_operand:SWI248 2 "nonimmediate_operand") 16793 (match_operand:SWI248 3 "nonimmediate_operand")))] 16794 "!TARGET_64BIT && TARGET_CMOVE 16795 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 16796 && (MEM_P (operands[2]) || MEM_P (operands[3])) 16797 && can_create_pseudo_p () 16798 && optimize_insn_for_speed_p ()" 16799 [(set (match_dup 0) 16800 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 16801{ 16802 if (MEM_P (operands[2])) 16803 operands[2] = force_reg (<MODE>mode, operands[2]); 16804 if (MEM_P (operands[3])) 16805 operands[3] = force_reg (<MODE>mode, operands[3]); 16806}) 16807 16808(define_insn "*movqicc_noc" 16809 [(set (match_operand:QI 0 "register_operand" "=r,r") 16810 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 16811 [(reg FLAGS_REG) (const_int 0)]) 16812 (match_operand:QI 2 "register_operand" "r,0") 16813 (match_operand:QI 3 "register_operand" "0,r")))] 16814 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 16815 "#" 16816 [(set_attr "type" "icmov") 16817 (set_attr "mode" "QI")]) 16818 16819(define_split 16820 [(set (match_operand:SWI12 0 "register_operand") 16821 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator" 16822 [(reg FLAGS_REG) (const_int 0)]) 16823 (match_operand:SWI12 2 "register_operand") 16824 (match_operand:SWI12 3 "register_operand")))] 16825 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL 16826 && reload_completed" 16827 [(set (match_dup 0) 16828 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 16829{ 16830 operands[0] = gen_lowpart (SImode, operands[0]); 16831 operands[2] = gen_lowpart (SImode, operands[2]); 16832 operands[3] = gen_lowpart (SImode, operands[3]); 16833}) 16834 16835;; Don't do conditional moves with memory inputs 16836(define_peephole2 16837 [(match_scratch:SWI248 2 "r") 16838 (set (match_operand:SWI248 0 "register_operand") 16839 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 16840 [(reg FLAGS_REG) (const_int 0)]) 16841 (match_dup 0) 16842 (match_operand:SWI248 3 "memory_operand")))] 16843 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 16844 && optimize_insn_for_speed_p ()" 16845 [(set (match_dup 2) (match_dup 3)) 16846 (set (match_dup 0) 16847 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))]) 16848 16849(define_peephole2 16850 [(match_scratch:SWI248 2 "r") 16851 (set (match_operand:SWI248 0 "register_operand") 16852 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 16853 [(reg FLAGS_REG) (const_int 0)]) 16854 (match_operand:SWI248 3 "memory_operand") 16855 (match_dup 0)))] 16856 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 16857 && optimize_insn_for_speed_p ()" 16858 [(set (match_dup 2) (match_dup 3)) 16859 (set (match_dup 0) 16860 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))]) 16861 16862(define_expand "mov<mode>cc" 16863 [(set (match_operand:X87MODEF 0 "register_operand") 16864 (if_then_else:X87MODEF 16865 (match_operand 1 "comparison_operator") 16866 (match_operand:X87MODEF 2 "register_operand") 16867 (match_operand:X87MODEF 3 "register_operand")))] 16868 "(TARGET_80387 && TARGET_CMOVE) 16869 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 16870 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;") 16871 16872(define_insn "*movxfcc_1" 16873 [(set (match_operand:XF 0 "register_operand" "=f,f") 16874 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 16875 [(reg FLAGS_REG) (const_int 0)]) 16876 (match_operand:XF 2 "register_operand" "f,0") 16877 (match_operand:XF 3 "register_operand" "0,f")))] 16878 "TARGET_80387 && TARGET_CMOVE" 16879 "@ 16880 fcmov%F1\t{%2, %0|%0, %2} 16881 fcmov%f1\t{%3, %0|%0, %3}" 16882 [(set_attr "type" "fcmov") 16883 (set_attr "mode" "XF")]) 16884 16885(define_insn "*movdfcc_1" 16886 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r") 16887 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 16888 [(reg FLAGS_REG) (const_int 0)]) 16889 (match_operand:DF 2 "nonimmediate_operand" 16890 "f ,0,rm,0 ,rm,0") 16891 (match_operand:DF 3 "nonimmediate_operand" 16892 "0 ,f,0 ,rm,0, rm")))] 16893 "TARGET_80387 && TARGET_CMOVE 16894 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16895 "@ 16896 fcmov%F1\t{%2, %0|%0, %2} 16897 fcmov%f1\t{%3, %0|%0, %3} 16898 # 16899 # 16900 cmov%O2%C1\t{%2, %0|%0, %2} 16901 cmov%O2%c1\t{%3, %0|%0, %3}" 16902 [(set_attr "isa" "*,*,nox64,nox64,x64,x64") 16903 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov") 16904 (set_attr "mode" "DF,DF,DI,DI,DI,DI")]) 16905 16906(define_split 16907 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand") 16908 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 16909 [(reg FLAGS_REG) (const_int 0)]) 16910 (match_operand:DF 2 "nonimmediate_operand") 16911 (match_operand:DF 3 "nonimmediate_operand")))] 16912 "!TARGET_64BIT && reload_completed" 16913 [(set (match_dup 2) 16914 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5))) 16915 (set (match_dup 3) 16916 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))] 16917{ 16918 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]); 16919 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]); 16920}) 16921 16922(define_insn "*movsfcc_1_387" 16923 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 16924 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 16925 [(reg FLAGS_REG) (const_int 0)]) 16926 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 16927 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 16928 "TARGET_80387 && TARGET_CMOVE 16929 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 16930 "@ 16931 fcmov%F1\t{%2, %0|%0, %2} 16932 fcmov%f1\t{%3, %0|%0, %3} 16933 cmov%O2%C1\t{%2, %0|%0, %2} 16934 cmov%O2%c1\t{%3, %0|%0, %3}" 16935 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 16936 (set_attr "mode" "SF,SF,SI,SI")]) 16937 16938;; Don't do conditional moves with memory inputs. This splitter helps 16939;; register starved x86_32 by forcing inputs into registers before reload. 16940(define_split 16941 [(set (match_operand:MODEF 0 "register_operand") 16942 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator" 16943 [(reg FLAGS_REG) (const_int 0)]) 16944 (match_operand:MODEF 2 "nonimmediate_operand") 16945 (match_operand:MODEF 3 "nonimmediate_operand")))] 16946 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 16947 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 16948 && (MEM_P (operands[2]) || MEM_P (operands[3])) 16949 && can_create_pseudo_p () 16950 && optimize_insn_for_speed_p ()" 16951 [(set (match_dup 0) 16952 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 16953{ 16954 if (MEM_P (operands[2])) 16955 operands[2] = force_reg (<MODE>mode, operands[2]); 16956 if (MEM_P (operands[3])) 16957 operands[3] = force_reg (<MODE>mode, operands[3]); 16958}) 16959 16960;; Don't do conditional moves with memory inputs 16961(define_peephole2 16962 [(match_scratch:MODEF 2 "r") 16963 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand") 16964 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator" 16965 [(reg FLAGS_REG) (const_int 0)]) 16966 (match_dup 0) 16967 (match_operand:MODEF 3 "memory_operand")))] 16968 "(<MODE>mode != DFmode || TARGET_64BIT) 16969 && TARGET_80387 && TARGET_CMOVE 16970 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 16971 && optimize_insn_for_speed_p ()" 16972 [(set (match_dup 2) (match_dup 3)) 16973 (set (match_dup 0) 16974 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))]) 16975 16976(define_peephole2 16977 [(match_scratch:MODEF 2 "r") 16978 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand") 16979 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator" 16980 [(reg FLAGS_REG) (const_int 0)]) 16981 (match_operand:MODEF 3 "memory_operand") 16982 (match_dup 0)))] 16983 "(<MODE>mode != DFmode || TARGET_64BIT) 16984 && TARGET_80387 && TARGET_CMOVE 16985 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 16986 && optimize_insn_for_speed_p ()" 16987 [(set (match_dup 2) (match_dup 3)) 16988 (set (match_dup 0) 16989 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))]) 16990 16991;; All moves in XOP pcmov instructions are 128 bits and hence we restrict 16992;; the scalar versions to have only XMM registers as operands. 16993 16994;; XOP conditional move 16995(define_insn "*xop_pcmov_<mode>" 16996 [(set (match_operand:MODEF 0 "register_operand" "=x") 16997 (if_then_else:MODEF 16998 (match_operand:MODEF 1 "register_operand" "x") 16999 (match_operand:MODEF 2 "register_operand" "x") 17000 (match_operand:MODEF 3 "register_operand" "x")))] 17001 "TARGET_XOP" 17002 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}" 17003 [(set_attr "type" "sse4arg")]) 17004 17005;; These versions of the min/max patterns are intentionally ignorant of 17006;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 17007;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 17008;; are undefined in this condition, we're certain this is correct. 17009 17010(define_insn "<code><mode>3" 17011 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 17012 (smaxmin:MODEF 17013 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v") 17014 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))] 17015 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 17016 "@ 17017 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2} 17018 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 17019 [(set_attr "isa" "noavx,avx") 17020 (set_attr "prefix" "orig,vex") 17021 (set_attr "type" "sseadd") 17022 (set_attr "mode" "<MODE>")]) 17023 17024;; These versions of the min/max patterns implement exactly the operations 17025;; min = (op1 < op2 ? op1 : op2) 17026;; max = (!(op1 < op2) ? op1 : op2) 17027;; Their operands are not commutative, and thus they may be used in the 17028;; presence of -0.0 and NaN. 17029 17030(define_int_iterator IEEE_MAXMIN 17031 [UNSPEC_IEEE_MAX 17032 UNSPEC_IEEE_MIN]) 17033 17034(define_int_attr ieee_maxmin 17035 [(UNSPEC_IEEE_MAX "max") 17036 (UNSPEC_IEEE_MIN "min")]) 17037 17038(define_insn "*ieee_s<ieee_maxmin><mode>3" 17039 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 17040 (unspec:MODEF 17041 [(match_operand:MODEF 1 "register_operand" "0,x") 17042 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")] 17043 IEEE_MAXMIN))] 17044 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 17045 "@ 17046 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2} 17047 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 17048 [(set_attr "isa" "noavx,avx") 17049 (set_attr "prefix" "orig,vex") 17050 (set_attr "type" "sseadd") 17051 (set_attr "mode" "<MODE>")]) 17052 17053;; Make two stack loads independent: 17054;; fld aa fld aa 17055;; fld %st(0) -> fld bb 17056;; fmul bb fmul %st(1), %st 17057;; 17058;; Actually we only match the last two instructions for simplicity. 17059(define_peephole2 17060 [(set (match_operand 0 "fp_register_operand") 17061 (match_operand 1 "fp_register_operand")) 17062 (set (match_dup 0) 17063 (match_operator 2 "binary_fp_operator" 17064 [(match_dup 0) 17065 (match_operand 3 "memory_operand")]))] 17066 "REGNO (operands[0]) != REGNO (operands[1])" 17067 [(set (match_dup 0) (match_dup 3)) 17068 (set (match_dup 0) (match_dup 4))] 17069 17070 ;; The % modifier is not operational anymore in peephole2's, so we have to 17071 ;; swap the operands manually in the case of addition and multiplication. 17072{ 17073 rtx op0, op1; 17074 17075 if (COMMUTATIVE_ARITH_P (operands[2])) 17076 op0 = operands[0], op1 = operands[1]; 17077 else 17078 op0 = operands[1], op1 = operands[0]; 17079 17080 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), 17081 GET_MODE (operands[2]), 17082 op0, op1); 17083}) 17084 17085;; Conditional addition patterns 17086(define_expand "add<mode>cc" 17087 [(match_operand:SWI 0 "register_operand") 17088 (match_operand 1 "ordered_comparison_operator") 17089 (match_operand:SWI 2 "register_operand") 17090 (match_operand:SWI 3 "const_int_operand")] 17091 "" 17092 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;") 17093 17094;; Misc patterns (?) 17095 17096;; This pattern exists to put a dependency on all ebp-based memory accesses. 17097;; Otherwise there will be nothing to keep 17098;; 17099;; [(set (reg ebp) (reg esp))] 17100;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 17101;; (clobber (eflags)] 17102;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 17103;; 17104;; in proper program order. 17105 17106(define_insn "pro_epilogue_adjust_stack_<mode>_add" 17107 [(set (match_operand:P 0 "register_operand" "=r,r") 17108 (plus:P (match_operand:P 1 "register_operand" "0,r") 17109 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>"))) 17110 (clobber (reg:CC FLAGS_REG)) 17111 (clobber (mem:BLK (scratch)))] 17112 "" 17113{ 17114 switch (get_attr_type (insn)) 17115 { 17116 case TYPE_IMOV: 17117 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 17118 17119 case TYPE_ALU: 17120 gcc_assert (rtx_equal_p (operands[0], operands[1])); 17121 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 17122 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 17123 17124 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 17125 17126 default: 17127 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 17128 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}"; 17129 } 17130} 17131 [(set (attr "type") 17132 (cond [(and (eq_attr "alternative" "0") 17133 (not (match_test "TARGET_OPT_AGU"))) 17134 (const_string "alu") 17135 (match_operand:<MODE> 2 "const0_operand") 17136 (const_string "imov") 17137 ] 17138 (const_string "lea"))) 17139 (set (attr "length_immediate") 17140 (cond [(eq_attr "type" "imov") 17141 (const_string "0") 17142 (and (eq_attr "type" "alu") 17143 (match_operand 2 "const128_operand")) 17144 (const_string "1") 17145 ] 17146 (const_string "*"))) 17147 (set_attr "mode" "<MODE>")]) 17148 17149(define_insn "pro_epilogue_adjust_stack_<mode>_sub" 17150 [(set (match_operand:P 0 "register_operand" "=r") 17151 (minus:P (match_operand:P 1 "register_operand" "0") 17152 (match_operand:P 2 "register_operand" "r"))) 17153 (clobber (reg:CC FLAGS_REG)) 17154 (clobber (mem:BLK (scratch)))] 17155 "" 17156 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 17157 [(set_attr "type" "alu") 17158 (set_attr "mode" "<MODE>")]) 17159 17160(define_insn "allocate_stack_worker_probe_<mode>" 17161 [(set (match_operand:P 0 "register_operand" "=a") 17162 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 17163 UNSPECV_STACK_PROBE)) 17164 (clobber (reg:CC FLAGS_REG))] 17165 "ix86_target_stack_probe ()" 17166 "call\t___chkstk_ms" 17167 [(set_attr "type" "multi") 17168 (set_attr "length" "5")]) 17169 17170(define_expand "allocate_stack" 17171 [(match_operand 0 "register_operand") 17172 (match_operand 1 "general_operand")] 17173 "ix86_target_stack_probe ()" 17174{ 17175 rtx x; 17176 17177#ifndef CHECK_STACK_LIMIT 17178#define CHECK_STACK_LIMIT 0 17179#endif 17180 17181 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1]) 17182 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 17183 x = operands[1]; 17184 else 17185 { 17186 rtx (*insn) (rtx, rtx); 17187 17188 x = copy_to_mode_reg (Pmode, operands[1]); 17189 17190 insn = (TARGET_64BIT 17191 ? gen_allocate_stack_worker_probe_di 17192 : gen_allocate_stack_worker_probe_si); 17193 17194 emit_insn (insn (x, x)); 17195 } 17196 17197 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x, 17198 stack_pointer_rtx, 0, OPTAB_DIRECT); 17199 17200 if (x != stack_pointer_rtx) 17201 emit_move_insn (stack_pointer_rtx, x); 17202 17203 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 17204 DONE; 17205}) 17206 17207;; Use IOR for stack probes, this is shorter. 17208(define_expand "probe_stack" 17209 [(match_operand 0 "memory_operand")] 17210 "" 17211{ 17212 rtx (*gen_ior3) (rtx, rtx, rtx); 17213 17214 gen_ior3 = (GET_MODE (operands[0]) == DImode 17215 ? gen_iordi3 : gen_iorsi3); 17216 17217 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx)); 17218 DONE; 17219}) 17220 17221(define_insn "adjust_stack_and_probe<mode>" 17222 [(set (match_operand:P 0 "register_operand" "=r") 17223 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 17224 UNSPECV_PROBE_STACK_RANGE)) 17225 (set (reg:P SP_REG) 17226 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n"))) 17227 (clobber (reg:CC FLAGS_REG)) 17228 (clobber (mem:BLK (scratch)))] 17229 "" 17230 "* return output_adjust_stack_and_probe (operands[0]);" 17231 [(set_attr "type" "multi")]) 17232 17233(define_insn "probe_stack_range<mode>" 17234 [(set (match_operand:P 0 "register_operand" "=r") 17235 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 17236 (match_operand:P 2 "const_int_operand" "n")] 17237 UNSPECV_PROBE_STACK_RANGE)) 17238 (clobber (reg:CC FLAGS_REG))] 17239 "" 17240 "* return output_probe_stack_range (operands[0], operands[2]);" 17241 [(set_attr "type" "multi")]) 17242 17243(define_expand "builtin_setjmp_receiver" 17244 [(label_ref (match_operand 0))] 17245 "!TARGET_64BIT && flag_pic" 17246{ 17247#if TARGET_MACHO 17248 if (TARGET_MACHO) 17249 { 17250 rtx xops[3]; 17251 rtx_code_label *label_rtx = gen_label_rtx (); 17252 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 17253 xops[0] = xops[1] = pic_offset_table_rtx; 17254 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx)); 17255 ix86_expand_binary_operator (MINUS, SImode, xops); 17256 } 17257 else 17258#endif 17259 emit_insn (gen_set_got (pic_offset_table_rtx)); 17260 DONE; 17261}) 17262 17263;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 17264;; Do not split instructions with mask registers. 17265(define_split 17266 [(set (match_operand 0 "general_reg_operand") 17267 (match_operator 3 "promotable_binary_operator" 17268 [(match_operand 1 "general_reg_operand") 17269 (match_operand 2 "aligned_operand")])) 17270 (clobber (reg:CC FLAGS_REG))] 17271 "! TARGET_PARTIAL_REG_STALL && reload_completed 17272 && ((GET_MODE (operands[0]) == HImode 17273 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX) 17274 /* ??? next two lines just !satisfies_constraint_K (...) */ 17275 || !CONST_INT_P (operands[2]) 17276 || satisfies_constraint_K (operands[2]))) 17277 || (GET_MODE (operands[0]) == QImode 17278 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))" 17279 [(parallel [(set (match_dup 0) 17280 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 17281 (clobber (reg:CC FLAGS_REG))])] 17282{ 17283 operands[0] = gen_lowpart (SImode, operands[0]); 17284 operands[1] = gen_lowpart (SImode, operands[1]); 17285 if (GET_CODE (operands[3]) != ASHIFT) 17286 operands[2] = gen_lowpart (SImode, operands[2]); 17287 operands[3] = shallow_copy_rtx (operands[3]); 17288 PUT_MODE (operands[3], SImode); 17289}) 17290 17291; Promote the QImode tests, as i386 has encoding of the AND 17292; instruction with 32-bit sign-extended immediate and thus the 17293; instruction size is unchanged, except in the %eax case for 17294; which it is increased by one byte, hence the ! optimize_size. 17295(define_split 17296 [(set (match_operand 0 "flags_reg_operand") 17297 (match_operator 2 "compare_operator" 17298 [(and (match_operand 3 "aligned_operand") 17299 (match_operand 4 "const_int_operand")) 17300 (const_int 0)])) 17301 (set (match_operand 1 "register_operand") 17302 (and (match_dup 3) (match_dup 4)))] 17303 "! TARGET_PARTIAL_REG_STALL && reload_completed 17304 && optimize_insn_for_speed_p () 17305 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 17306 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode)) 17307 /* Ensure that the operand will remain sign-extended immediate. */ 17308 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)" 17309 [(parallel [(set (match_dup 0) 17310 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 17311 (const_int 0)])) 17312 (set (match_dup 1) 17313 (and:SI (match_dup 3) (match_dup 4)))])] 17314{ 17315 operands[4] 17316 = gen_int_mode (INTVAL (operands[4]) 17317 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 17318 operands[1] = gen_lowpart (SImode, operands[1]); 17319 operands[3] = gen_lowpart (SImode, operands[3]); 17320}) 17321 17322; Don't promote the QImode tests, as i386 doesn't have encoding of 17323; the TEST instruction with 32-bit sign-extended immediate and thus 17324; the instruction size would at least double, which is not what we 17325; want even with ! optimize_size. 17326(define_split 17327 [(set (match_operand 0 "flags_reg_operand") 17328 (match_operator 1 "compare_operator" 17329 [(and (match_operand:HI 2 "aligned_operand") 17330 (match_operand:HI 3 "const_int_operand")) 17331 (const_int 0)]))] 17332 "! TARGET_PARTIAL_REG_STALL && reload_completed 17333 && ! TARGET_FAST_PREFIX 17334 && optimize_insn_for_speed_p () 17335 /* Ensure that the operand will remain sign-extended immediate. */ 17336 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)" 17337 [(set (match_dup 0) 17338 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 17339 (const_int 0)]))] 17340{ 17341 operands[3] 17342 = gen_int_mode (INTVAL (operands[3]) 17343 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 17344 operands[2] = gen_lowpart (SImode, operands[2]); 17345}) 17346 17347(define_split 17348 [(set (match_operand 0 "register_operand") 17349 (neg (match_operand 1 "register_operand"))) 17350 (clobber (reg:CC FLAGS_REG))] 17351 "! TARGET_PARTIAL_REG_STALL && reload_completed 17352 && (GET_MODE (operands[0]) == HImode 17353 || (GET_MODE (operands[0]) == QImode 17354 && (TARGET_PROMOTE_QImode 17355 || optimize_insn_for_size_p ())))" 17356 [(parallel [(set (match_dup 0) 17357 (neg:SI (match_dup 1))) 17358 (clobber (reg:CC FLAGS_REG))])] 17359{ 17360 operands[0] = gen_lowpart (SImode, operands[0]); 17361 operands[1] = gen_lowpart (SImode, operands[1]); 17362}) 17363 17364;; Do not split instructions with mask regs. 17365(define_split 17366 [(set (match_operand 0 "general_reg_operand") 17367 (not (match_operand 1 "general_reg_operand")))] 17368 "! TARGET_PARTIAL_REG_STALL && reload_completed 17369 && (GET_MODE (operands[0]) == HImode 17370 || (GET_MODE (operands[0]) == QImode 17371 && (TARGET_PROMOTE_QImode 17372 || optimize_insn_for_size_p ())))" 17373 [(set (match_dup 0) 17374 (not:SI (match_dup 1)))] 17375{ 17376 operands[0] = gen_lowpart (SImode, operands[0]); 17377 operands[1] = gen_lowpart (SImode, operands[1]); 17378}) 17379 17380;; RTL Peephole optimizations, run before sched2. These primarily look to 17381;; transform a complex memory operation into two memory to register operations. 17382 17383;; Don't push memory operands 17384(define_peephole2 17385 [(set (match_operand:SWI 0 "push_operand") 17386 (match_operand:SWI 1 "memory_operand")) 17387 (match_scratch:SWI 2 "<r>")] 17388 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 17389 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 17390 [(set (match_dup 2) (match_dup 1)) 17391 (set (match_dup 0) (match_dup 2))]) 17392 17393;; We need to handle SFmode only, because DFmode and XFmode are split to 17394;; SImode pushes. 17395(define_peephole2 17396 [(set (match_operand:SF 0 "push_operand") 17397 (match_operand:SF 1 "memory_operand")) 17398 (match_scratch:SF 2 "r")] 17399 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 17400 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 17401 [(set (match_dup 2) (match_dup 1)) 17402 (set (match_dup 0) (match_dup 2))]) 17403 17404;; Don't move an immediate directly to memory when the instruction 17405;; gets too big, or if LCP stalls are a problem for 16-bit moves. 17406(define_peephole2 17407 [(match_scratch:SWI124 1 "<r>") 17408 (set (match_operand:SWI124 0 "memory_operand") 17409 (const_int 0))] 17410 "optimize_insn_for_speed_p () 17411 && ((<MODE>mode == HImode 17412 && TARGET_LCP_STALL) 17413 || (!TARGET_USE_MOV0 17414 && TARGET_SPLIT_LONG_MOVES 17415 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn)) 17416 && peep2_regno_dead_p (0, FLAGS_REG)" 17417 [(parallel [(set (match_dup 2) (const_int 0)) 17418 (clobber (reg:CC FLAGS_REG))]) 17419 (set (match_dup 0) (match_dup 1))] 17420 "operands[2] = gen_lowpart (SImode, operands[1]);") 17421 17422(define_peephole2 17423 [(match_scratch:SWI124 2 "<r>") 17424 (set (match_operand:SWI124 0 "memory_operand") 17425 (match_operand:SWI124 1 "immediate_operand"))] 17426 "optimize_insn_for_speed_p () 17427 && ((<MODE>mode == HImode 17428 && TARGET_LCP_STALL) 17429 || (TARGET_SPLIT_LONG_MOVES 17430 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))" 17431 [(set (match_dup 2) (match_dup 1)) 17432 (set (match_dup 0) (match_dup 2))]) 17433 17434;; Don't compare memory with zero, load and use a test instead. 17435(define_peephole2 17436 [(set (match_operand 0 "flags_reg_operand") 17437 (match_operator 1 "compare_operator" 17438 [(match_operand:SI 2 "memory_operand") 17439 (const_int 0)])) 17440 (match_scratch:SI 3 "r")] 17441 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)" 17442 [(set (match_dup 3) (match_dup 2)) 17443 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]) 17444 17445;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 17446;; Don't split NOTs with a displacement operand, because resulting XOR 17447;; will not be pairable anyway. 17448;; 17449;; On AMD K6, NOT is vector decoded with memory operand that cannot be 17450;; represented using a modRM byte. The XOR replacement is long decoded, 17451;; so this split helps here as well. 17452;; 17453;; Note: Can't do this as a regular split because we can't get proper 17454;; lifetime information then. 17455 17456(define_peephole2 17457 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand") 17458 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))] 17459 "optimize_insn_for_speed_p () 17460 && ((TARGET_NOT_UNPAIRABLE 17461 && (!MEM_P (operands[0]) 17462 || !memory_displacement_operand (operands[0], <MODE>mode))) 17463 || (TARGET_NOT_VECTORMODE 17464 && long_memory_operand (operands[0], <MODE>mode))) 17465 && peep2_regno_dead_p (0, FLAGS_REG)" 17466 [(parallel [(set (match_dup 0) 17467 (xor:SWI124 (match_dup 1) (const_int -1))) 17468 (clobber (reg:CC FLAGS_REG))])]) 17469 17470;; Non pairable "test imm, reg" instructions can be translated to 17471;; "and imm, reg" if reg dies. The "and" form is also shorter (one 17472;; byte opcode instead of two, have a short form for byte operands), 17473;; so do it for other CPUs as well. Given that the value was dead, 17474;; this should not create any new dependencies. Pass on the sub-word 17475;; versions if we're concerned about partial register stalls. 17476 17477(define_peephole2 17478 [(set (match_operand 0 "flags_reg_operand") 17479 (match_operator 1 "compare_operator" 17480 [(and:SI (match_operand:SI 2 "register_operand") 17481 (match_operand:SI 3 "immediate_operand")) 17482 (const_int 0)]))] 17483 "ix86_match_ccmode (insn, CCNOmode) 17484 && (true_regnum (operands[2]) != AX_REG 17485 || satisfies_constraint_K (operands[3])) 17486 && peep2_reg_dead_p (1, operands[2])" 17487 [(parallel 17488 [(set (match_dup 0) 17489 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 17490 (const_int 0)])) 17491 (set (match_dup 2) 17492 (and:SI (match_dup 2) (match_dup 3)))])]) 17493 17494;; We don't need to handle HImode case, because it will be promoted to SImode 17495;; on ! TARGET_PARTIAL_REG_STALL 17496 17497(define_peephole2 17498 [(set (match_operand 0 "flags_reg_operand") 17499 (match_operator 1 "compare_operator" 17500 [(and:QI (match_operand:QI 2 "register_operand") 17501 (match_operand:QI 3 "immediate_operand")) 17502 (const_int 0)]))] 17503 "! TARGET_PARTIAL_REG_STALL 17504 && ix86_match_ccmode (insn, CCNOmode) 17505 && true_regnum (operands[2]) != AX_REG 17506 && peep2_reg_dead_p (1, operands[2])" 17507 [(parallel 17508 [(set (match_dup 0) 17509 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 17510 (const_int 0)])) 17511 (set (match_dup 2) 17512 (and:QI (match_dup 2) (match_dup 3)))])]) 17513 17514(define_peephole2 17515 [(set (match_operand 0 "flags_reg_operand") 17516 (match_operator 1 "compare_operator" 17517 [(and:SI 17518 (zero_extract:SI 17519 (match_operand 2 "ext_register_operand") 17520 (const_int 8) 17521 (const_int 8)) 17522 (match_operand 3 "const_int_operand")) 17523 (const_int 0)]))] 17524 "! TARGET_PARTIAL_REG_STALL 17525 && ix86_match_ccmode (insn, CCNOmode) 17526 && true_regnum (operands[2]) != AX_REG 17527 && peep2_reg_dead_p (1, operands[2])" 17528 [(parallel [(set (match_dup 0) 17529 (match_op_dup 1 17530 [(and:SI 17531 (zero_extract:SI 17532 (match_dup 2) 17533 (const_int 8) 17534 (const_int 8)) 17535 (match_dup 3)) 17536 (const_int 0)])) 17537 (set (zero_extract:SI (match_dup 2) 17538 (const_int 8) 17539 (const_int 8)) 17540 (and:SI 17541 (zero_extract:SI 17542 (match_dup 2) 17543 (const_int 8) 17544 (const_int 8)) 17545 (match_dup 3)))])]) 17546 17547;; Don't do logical operations with memory inputs. 17548(define_peephole2 17549 [(match_scratch:SI 2 "r") 17550 (parallel [(set (match_operand:SI 0 "register_operand") 17551 (match_operator:SI 3 "arith_or_logical_operator" 17552 [(match_dup 0) 17553 (match_operand:SI 1 "memory_operand")])) 17554 (clobber (reg:CC FLAGS_REG))])] 17555 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 17556 [(set (match_dup 2) (match_dup 1)) 17557 (parallel [(set (match_dup 0) 17558 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 17559 (clobber (reg:CC FLAGS_REG))])]) 17560 17561(define_peephole2 17562 [(match_scratch:SI 2 "r") 17563 (parallel [(set (match_operand:SI 0 "register_operand") 17564 (match_operator:SI 3 "arith_or_logical_operator" 17565 [(match_operand:SI 1 "memory_operand") 17566 (match_dup 0)])) 17567 (clobber (reg:CC FLAGS_REG))])] 17568 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 17569 [(set (match_dup 2) (match_dup 1)) 17570 (parallel [(set (match_dup 0) 17571 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 17572 (clobber (reg:CC FLAGS_REG))])]) 17573 17574;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address 17575;; refers to the destination of the load! 17576 17577(define_peephole2 17578 [(set (match_operand:SI 0 "register_operand") 17579 (match_operand:SI 1 "register_operand")) 17580 (parallel [(set (match_dup 0) 17581 (match_operator:SI 3 "commutative_operator" 17582 [(match_dup 0) 17583 (match_operand:SI 2 "memory_operand")])) 17584 (clobber (reg:CC FLAGS_REG))])] 17585 "REGNO (operands[0]) != REGNO (operands[1]) 17586 && GENERAL_REGNO_P (REGNO (operands[0])) 17587 && GENERAL_REGNO_P (REGNO (operands[1]))" 17588 [(set (match_dup 0) (match_dup 4)) 17589 (parallel [(set (match_dup 0) 17590 (match_op_dup 3 [(match_dup 0) (match_dup 1)])) 17591 (clobber (reg:CC FLAGS_REG))])] 17592 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);") 17593 17594(define_peephole2 17595 [(set (match_operand 0 "register_operand") 17596 (match_operand 1 "register_operand")) 17597 (set (match_dup 0) 17598 (match_operator 3 "commutative_operator" 17599 [(match_dup 0) 17600 (match_operand 2 "memory_operand")]))] 17601 "REGNO (operands[0]) != REGNO (operands[1]) 17602 && ((MMX_REGNO_P (REGNO (operands[0])) 17603 && MMX_REGNO_P (REGNO (operands[1]))) 17604 || (SSE_REGNO_P (REGNO (operands[0])) 17605 && SSE_REGNO_P (REGNO (operands[1]))))" 17606 [(set (match_dup 0) (match_dup 2)) 17607 (set (match_dup 0) 17608 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 17609 17610; Don't do logical operations with memory outputs 17611; 17612; These two don't make sense for PPro/PII -- we're expanding a 4-uop 17613; instruction into two 1-uop insns plus a 2-uop insn. That last has 17614; the same decoder scheduling characteristics as the original. 17615 17616(define_peephole2 17617 [(match_scratch:SI 2 "r") 17618 (parallel [(set (match_operand:SI 0 "memory_operand") 17619 (match_operator:SI 3 "arith_or_logical_operator" 17620 [(match_dup 0) 17621 (match_operand:SI 1 "nonmemory_operand")])) 17622 (clobber (reg:CC FLAGS_REG))])] 17623 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17624 /* Do not split stack checking probes. */ 17625 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx" 17626 [(set (match_dup 2) (match_dup 0)) 17627 (parallel [(set (match_dup 2) 17628 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 17629 (clobber (reg:CC FLAGS_REG))]) 17630 (set (match_dup 0) (match_dup 2))]) 17631 17632(define_peephole2 17633 [(match_scratch:SI 2 "r") 17634 (parallel [(set (match_operand:SI 0 "memory_operand") 17635 (match_operator:SI 3 "arith_or_logical_operator" 17636 [(match_operand:SI 1 "nonmemory_operand") 17637 (match_dup 0)])) 17638 (clobber (reg:CC FLAGS_REG))])] 17639 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17640 /* Do not split stack checking probes. */ 17641 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx" 17642 [(set (match_dup 2) (match_dup 0)) 17643 (parallel [(set (match_dup 2) 17644 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 17645 (clobber (reg:CC FLAGS_REG))]) 17646 (set (match_dup 0) (match_dup 2))]) 17647 17648;; Attempt to use arith or logical operations with memory outputs with 17649;; setting of flags. 17650(define_peephole2 17651 [(set (match_operand:SWI 0 "register_operand") 17652 (match_operand:SWI 1 "memory_operand")) 17653 (parallel [(set (match_dup 0) 17654 (match_operator:SWI 3 "plusminuslogic_operator" 17655 [(match_dup 0) 17656 (match_operand:SWI 2 "<nonmemory_operand>")])) 17657 (clobber (reg:CC FLAGS_REG))]) 17658 (set (match_dup 1) (match_dup 0)) 17659 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17660 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17661 && peep2_reg_dead_p (4, operands[0]) 17662 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17663 && !reg_overlap_mentioned_p (operands[0], operands[2]) 17664 && (<MODE>mode != QImode 17665 || immediate_operand (operands[2], QImode) 17666 || q_regs_operand (operands[2], QImode)) 17667 && ix86_match_ccmode (peep2_next_insn (3), 17668 (GET_CODE (operands[3]) == PLUS 17669 || GET_CODE (operands[3]) == MINUS) 17670 ? CCGOCmode : CCNOmode)" 17671 [(parallel [(set (match_dup 4) (match_dup 5)) 17672 (set (match_dup 1) (match_op_dup 3 [(match_dup 1) 17673 (match_dup 2)]))])] 17674{ 17675 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 17676 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17677 copy_rtx (operands[1]), 17678 copy_rtx (operands[2])); 17679 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), 17680 operands[5], const0_rtx); 17681}) 17682 17683(define_peephole2 17684 [(parallel [(set (match_operand:SWI 0 "register_operand") 17685 (match_operator:SWI 2 "plusminuslogic_operator" 17686 [(match_dup 0) 17687 (match_operand:SWI 1 "memory_operand")])) 17688 (clobber (reg:CC FLAGS_REG))]) 17689 (set (match_dup 1) (match_dup 0)) 17690 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17691 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17692 && GET_CODE (operands[2]) != MINUS 17693 && peep2_reg_dead_p (3, operands[0]) 17694 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17695 && ix86_match_ccmode (peep2_next_insn (2), 17696 GET_CODE (operands[2]) == PLUS 17697 ? CCGOCmode : CCNOmode)" 17698 [(parallel [(set (match_dup 3) (match_dup 4)) 17699 (set (match_dup 1) (match_op_dup 2 [(match_dup 1) 17700 (match_dup 0)]))])] 17701{ 17702 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); 17703 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode, 17704 copy_rtx (operands[1]), 17705 copy_rtx (operands[0])); 17706 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]), 17707 operands[4], const0_rtx); 17708}) 17709 17710(define_peephole2 17711 [(set (match_operand:SWI12 0 "register_operand") 17712 (match_operand:SWI12 1 "memory_operand")) 17713 (parallel [(set (match_operand:SI 4 "register_operand") 17714 (match_operator:SI 3 "plusminuslogic_operator" 17715 [(match_dup 4) 17716 (match_operand:SI 2 "nonmemory_operand")])) 17717 (clobber (reg:CC FLAGS_REG))]) 17718 (set (match_dup 1) (match_dup 0)) 17719 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 17720 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 17721 && REG_P (operands[0]) && REG_P (operands[4]) 17722 && REGNO (operands[0]) == REGNO (operands[4]) 17723 && peep2_reg_dead_p (4, operands[0]) 17724 && (<MODE>mode != QImode 17725 || immediate_operand (operands[2], SImode) 17726 || q_regs_operand (operands[2], SImode)) 17727 && !reg_overlap_mentioned_p (operands[0], operands[1]) 17728 && !reg_overlap_mentioned_p (operands[0], operands[2]) 17729 && ix86_match_ccmode (peep2_next_insn (3), 17730 (GET_CODE (operands[3]) == PLUS 17731 || GET_CODE (operands[3]) == MINUS) 17732 ? CCGOCmode : CCNOmode)" 17733 [(parallel [(set (match_dup 4) (match_dup 5)) 17734 (set (match_dup 1) (match_dup 6))])] 17735{ 17736 operands[2] = gen_lowpart (<MODE>mode, operands[2]); 17737 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 17738 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17739 copy_rtx (operands[1]), operands[2]); 17740 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]), 17741 operands[5], const0_rtx); 17742 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 17743 copy_rtx (operands[1]), 17744 copy_rtx (operands[2])); 17745}) 17746 17747;; Attempt to always use XOR for zeroing registers. 17748(define_peephole2 17749 [(set (match_operand 0 "register_operand") 17750 (match_operand 1 "const0_operand"))] 17751 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 17752 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 17753 && GENERAL_REGNO_P (REGNO (operands[0])) 17754 && peep2_regno_dead_p (0, FLAGS_REG)" 17755 [(parallel [(set (match_dup 0) (const_int 0)) 17756 (clobber (reg:CC FLAGS_REG))])] 17757 "operands[0] = gen_lowpart (word_mode, operands[0]);") 17758 17759(define_peephole2 17760 [(set (strict_low_part (match_operand 0 "register_operand")) 17761 (const_int 0))] 17762 "(GET_MODE (operands[0]) == QImode 17763 || GET_MODE (operands[0]) == HImode) 17764 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 17765 && peep2_regno_dead_p (0, FLAGS_REG)" 17766 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 17767 (clobber (reg:CC FLAGS_REG))])]) 17768 17769;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg. 17770(define_peephole2 17771 [(set (match_operand:SWI248 0 "register_operand") 17772 (const_int -1))] 17773 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR) 17774 && GENERAL_REGNO_P (REGNO (operands[0])) 17775 && peep2_regno_dead_p (0, FLAGS_REG)" 17776 [(parallel [(set (match_dup 0) (const_int -1)) 17777 (clobber (reg:CC FLAGS_REG))])] 17778{ 17779 if (<MODE_SIZE> < GET_MODE_SIZE (SImode)) 17780 operands[0] = gen_lowpart (SImode, operands[0]); 17781}) 17782 17783;; Attempt to convert simple lea to add/shift. 17784;; These can be created by move expanders. 17785;; Disable PLUS peepholes on TARGET_OPT_AGU, since all 17786;; relevant lea instructions were already split. 17787 17788(define_peephole2 17789 [(set (match_operand:SWI48 0 "register_operand") 17790 (plus:SWI48 (match_dup 0) 17791 (match_operand:SWI48 1 "<nonmemory_operand>")))] 17792 "!TARGET_OPT_AGU 17793 && peep2_regno_dead_p (0, FLAGS_REG)" 17794 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 17795 (clobber (reg:CC FLAGS_REG))])]) 17796 17797(define_peephole2 17798 [(set (match_operand:SWI48 0 "register_operand") 17799 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>") 17800 (match_dup 0)))] 17801 "!TARGET_OPT_AGU 17802 && peep2_regno_dead_p (0, FLAGS_REG)" 17803 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 17804 (clobber (reg:CC FLAGS_REG))])]) 17805 17806(define_peephole2 17807 [(set (match_operand:DI 0 "register_operand") 17808 (zero_extend:DI 17809 (plus:SI (match_operand:SI 1 "register_operand") 17810 (match_operand:SI 2 "nonmemory_operand"))))] 17811 "TARGET_64BIT && !TARGET_OPT_AGU 17812 && REGNO (operands[0]) == REGNO (operands[1]) 17813 && peep2_regno_dead_p (0, FLAGS_REG)" 17814 [(parallel [(set (match_dup 0) 17815 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))) 17816 (clobber (reg:CC FLAGS_REG))])]) 17817 17818(define_peephole2 17819 [(set (match_operand:DI 0 "register_operand") 17820 (zero_extend:DI 17821 (plus:SI (match_operand:SI 1 "nonmemory_operand") 17822 (match_operand:SI 2 "register_operand"))))] 17823 "TARGET_64BIT && !TARGET_OPT_AGU 17824 && REGNO (operands[0]) == REGNO (operands[2]) 17825 && peep2_regno_dead_p (0, FLAGS_REG)" 17826 [(parallel [(set (match_dup 0) 17827 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1)))) 17828 (clobber (reg:CC FLAGS_REG))])]) 17829 17830(define_peephole2 17831 [(set (match_operand:SWI48 0 "register_operand") 17832 (mult:SWI48 (match_dup 0) 17833 (match_operand:SWI48 1 "const_int_operand")))] 17834 "exact_log2 (INTVAL (operands[1])) >= 0 17835 && peep2_regno_dead_p (0, FLAGS_REG)" 17836 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1))) 17837 (clobber (reg:CC FLAGS_REG))])] 17838 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 17839 17840(define_peephole2 17841 [(set (match_operand:DI 0 "register_operand") 17842 (zero_extend:DI 17843 (mult:SI (match_operand:SI 1 "register_operand") 17844 (match_operand:SI 2 "const_int_operand"))))] 17845 "TARGET_64BIT 17846 && exact_log2 (INTVAL (operands[2])) >= 0 17847 && REGNO (operands[0]) == REGNO (operands[1]) 17848 && peep2_regno_dead_p (0, FLAGS_REG)" 17849 [(parallel [(set (match_dup 0) 17850 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2)))) 17851 (clobber (reg:CC FLAGS_REG))])] 17852 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 17853 17854;; The ESP adjustments can be done by the push and pop instructions. Resulting 17855;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes. 17856;; On many CPUs it is also faster, since special hardware to avoid esp 17857;; dependencies is present. 17858 17859;; While some of these conversions may be done using splitters, we use 17860;; peepholes in order to allow combine_stack_adjustments pass to see 17861;; nonobfuscated RTL. 17862 17863;; Convert prologue esp subtractions to push. 17864;; We need register to push. In order to keep verify_flow_info happy we have 17865;; two choices 17866;; - use scratch and clobber it in order to avoid dependencies 17867;; - use already live register 17868;; We can't use the second way right now, since there is no reliable way how to 17869;; verify that given register is live. First choice will also most likely in 17870;; fewer dependencies. On the place of esp adjustments it is very likely that 17871;; call clobbered registers are dead. We may want to use base pointer as an 17872;; alternative when no register is available later. 17873 17874(define_peephole2 17875 [(match_scratch:W 1 "r") 17876 (parallel [(set (reg:P SP_REG) 17877 (plus:P (reg:P SP_REG) 17878 (match_operand:P 0 "const_int_operand"))) 17879 (clobber (reg:CC FLAGS_REG)) 17880 (clobber (mem:BLK (scratch)))])] 17881 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 17882 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)" 17883 [(clobber (match_dup 1)) 17884 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17885 (clobber (mem:BLK (scratch)))])]) 17886 17887(define_peephole2 17888 [(match_scratch:W 1 "r") 17889 (parallel [(set (reg:P SP_REG) 17890 (plus:P (reg:P SP_REG) 17891 (match_operand:P 0 "const_int_operand"))) 17892 (clobber (reg:CC FLAGS_REG)) 17893 (clobber (mem:BLK (scratch)))])] 17894 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 17895 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)" 17896 [(clobber (match_dup 1)) 17897 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17898 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17899 (clobber (mem:BLK (scratch)))])]) 17900 17901;; Convert esp subtractions to push. 17902(define_peephole2 17903 [(match_scratch:W 1 "r") 17904 (parallel [(set (reg:P SP_REG) 17905 (plus:P (reg:P SP_REG) 17906 (match_operand:P 0 "const_int_operand"))) 17907 (clobber (reg:CC FLAGS_REG))])] 17908 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 17909 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)" 17910 [(clobber (match_dup 1)) 17911 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 17912 17913(define_peephole2 17914 [(match_scratch:W 1 "r") 17915 (parallel [(set (reg:P SP_REG) 17916 (plus:P (reg:P SP_REG) 17917 (match_operand:P 0 "const_int_operand"))) 17918 (clobber (reg:CC FLAGS_REG))])] 17919 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 17920 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)" 17921 [(clobber (match_dup 1)) 17922 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 17923 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 17924 17925;; Convert epilogue deallocator to pop. 17926(define_peephole2 17927 [(match_scratch:W 1 "r") 17928 (parallel [(set (reg:P SP_REG) 17929 (plus:P (reg:P SP_REG) 17930 (match_operand:P 0 "const_int_operand"))) 17931 (clobber (reg:CC FLAGS_REG)) 17932 (clobber (mem:BLK (scratch)))])] 17933 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ()) 17934 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 17935 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 17936 (clobber (mem:BLK (scratch)))])]) 17937 17938;; Two pops case is tricky, since pop causes dependency 17939;; on destination register. We use two registers if available. 17940(define_peephole2 17941 [(match_scratch:W 1 "r") 17942 (match_scratch:W 2 "r") 17943 (parallel [(set (reg:P SP_REG) 17944 (plus:P (reg:P SP_REG) 17945 (match_operand:P 0 "const_int_operand"))) 17946 (clobber (reg:CC FLAGS_REG)) 17947 (clobber (mem:BLK (scratch)))])] 17948 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ()) 17949 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 17950 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 17951 (clobber (mem:BLK (scratch)))]) 17952 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 17953 17954(define_peephole2 17955 [(match_scratch:W 1 "r") 17956 (parallel [(set (reg:P SP_REG) 17957 (plus:P (reg:P SP_REG) 17958 (match_operand:P 0 "const_int_operand"))) 17959 (clobber (reg:CC FLAGS_REG)) 17960 (clobber (mem:BLK (scratch)))])] 17961 "optimize_insn_for_size_p () 17962 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 17963 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 17964 (clobber (mem:BLK (scratch)))]) 17965 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 17966 17967;; Convert esp additions to pop. 17968(define_peephole2 17969 [(match_scratch:W 1 "r") 17970 (parallel [(set (reg:P SP_REG) 17971 (plus:P (reg:P SP_REG) 17972 (match_operand:P 0 "const_int_operand"))) 17973 (clobber (reg:CC FLAGS_REG))])] 17974 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 17975 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 17976 17977;; Two pops case is tricky, since pop causes dependency 17978;; on destination register. We use two registers if available. 17979(define_peephole2 17980 [(match_scratch:W 1 "r") 17981 (match_scratch:W 2 "r") 17982 (parallel [(set (reg:P SP_REG) 17983 (plus:P (reg:P SP_REG) 17984 (match_operand:P 0 "const_int_operand"))) 17985 (clobber (reg:CC FLAGS_REG))])] 17986 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 17987 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 17988 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 17989 17990(define_peephole2 17991 [(match_scratch:W 1 "r") 17992 (parallel [(set (reg:P SP_REG) 17993 (plus:P (reg:P SP_REG) 17994 (match_operand:P 0 "const_int_operand"))) 17995 (clobber (reg:CC FLAGS_REG))])] 17996 "optimize_insn_for_size_p () 17997 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 17998 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 17999 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 18000 18001;; Convert compares with 1 to shorter inc/dec operations when CF is not 18002;; required and register dies. Similarly for 128 to -128. 18003(define_peephole2 18004 [(set (match_operand 0 "flags_reg_operand") 18005 (match_operator 1 "compare_operator" 18006 [(match_operand 2 "register_operand") 18007 (match_operand 3 "const_int_operand")]))] 18008 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ()) 18009 && incdec_operand (operands[3], GET_MODE (operands[3]))) 18010 || (!TARGET_FUSE_CMP_AND_BRANCH 18011 && INTVAL (operands[3]) == 128)) 18012 && ix86_match_ccmode (insn, CCGCmode) 18013 && peep2_reg_dead_p (1, operands[2])" 18014 [(parallel [(set (match_dup 0) 18015 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 18016 (clobber (match_dup 2))])]) 18017 18018;; Convert imul by three, five and nine into lea 18019(define_peephole2 18020 [(parallel 18021 [(set (match_operand:SWI48 0 "register_operand") 18022 (mult:SWI48 (match_operand:SWI48 1 "register_operand") 18023 (match_operand:SWI48 2 "const359_operand"))) 18024 (clobber (reg:CC FLAGS_REG))])] 18025 "!TARGET_PARTIAL_REG_STALL 18026 || <MODE>mode == SImode 18027 || optimize_function_for_size_p (cfun)" 18028 [(set (match_dup 0) 18029 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2)) 18030 (match_dup 1)))] 18031 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 18032 18033(define_peephole2 18034 [(parallel 18035 [(set (match_operand:SWI48 0 "register_operand") 18036 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 18037 (match_operand:SWI48 2 "const359_operand"))) 18038 (clobber (reg:CC FLAGS_REG))])] 18039 "optimize_insn_for_speed_p () 18040 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)" 18041 [(set (match_dup 0) (match_dup 1)) 18042 (set (match_dup 0) 18043 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2)) 18044 (match_dup 0)))] 18045 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 18046 18047;; imul $32bit_imm, mem, reg is vector decoded, while 18048;; imul $32bit_imm, reg, reg is direct decoded. 18049(define_peephole2 18050 [(match_scratch:SWI48 3 "r") 18051 (parallel [(set (match_operand:SWI48 0 "register_operand") 18052 (mult:SWI48 (match_operand:SWI48 1 "memory_operand") 18053 (match_operand:SWI48 2 "immediate_operand"))) 18054 (clobber (reg:CC FLAGS_REG))])] 18055 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 18056 && !satisfies_constraint_K (operands[2])" 18057 [(set (match_dup 3) (match_dup 1)) 18058 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2))) 18059 (clobber (reg:CC FLAGS_REG))])]) 18060 18061(define_peephole2 18062 [(match_scratch:SI 3 "r") 18063 (parallel [(set (match_operand:DI 0 "register_operand") 18064 (zero_extend:DI 18065 (mult:SI (match_operand:SI 1 "memory_operand") 18066 (match_operand:SI 2 "immediate_operand")))) 18067 (clobber (reg:CC FLAGS_REG))])] 18068 "TARGET_64BIT 18069 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 18070 && !satisfies_constraint_K (operands[2])" 18071 [(set (match_dup 3) (match_dup 1)) 18072 (parallel [(set (match_dup 0) 18073 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 18074 (clobber (reg:CC FLAGS_REG))])]) 18075 18076;; imul $8/16bit_imm, regmem, reg is vector decoded. 18077;; Convert it into imul reg, reg 18078;; It would be better to force assembler to encode instruction using long 18079;; immediate, but there is apparently no way to do so. 18080(define_peephole2 18081 [(parallel [(set (match_operand:SWI248 0 "register_operand") 18082 (mult:SWI248 18083 (match_operand:SWI248 1 "nonimmediate_operand") 18084 (match_operand:SWI248 2 "const_int_operand"))) 18085 (clobber (reg:CC FLAGS_REG))]) 18086 (match_scratch:SWI248 3 "r")] 18087 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () 18088 && satisfies_constraint_K (operands[2])" 18089 [(set (match_dup 3) (match_dup 2)) 18090 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3))) 18091 (clobber (reg:CC FLAGS_REG))])] 18092{ 18093 if (!rtx_equal_p (operands[0], operands[1])) 18094 emit_move_insn (operands[0], operands[1]); 18095}) 18096 18097;; After splitting up read-modify operations, array accesses with memory 18098;; operands might end up in form: 18099;; sall $2, %eax 18100;; movl 4(%esp), %edx 18101;; addl %edx, %eax 18102;; instead of pre-splitting: 18103;; sall $2, %eax 18104;; addl 4(%esp), %eax 18105;; Turn it into: 18106;; movl 4(%esp), %edx 18107;; leal (%edx,%eax,4), %eax 18108 18109(define_peephole2 18110 [(match_scratch:W 5 "r") 18111 (parallel [(set (match_operand 0 "register_operand") 18112 (ashift (match_operand 1 "register_operand") 18113 (match_operand 2 "const_int_operand"))) 18114 (clobber (reg:CC FLAGS_REG))]) 18115 (parallel [(set (match_operand 3 "register_operand") 18116 (plus (match_dup 0) 18117 (match_operand 4 "x86_64_general_operand"))) 18118 (clobber (reg:CC FLAGS_REG))])] 18119 "IN_RANGE (INTVAL (operands[2]), 1, 3) 18120 /* Validate MODE for lea. */ 18121 && ((!TARGET_PARTIAL_REG_STALL 18122 && (GET_MODE (operands[0]) == QImode 18123 || GET_MODE (operands[0]) == HImode)) 18124 || GET_MODE (operands[0]) == SImode 18125 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 18126 && (rtx_equal_p (operands[0], operands[3]) 18127 || peep2_reg_dead_p (2, operands[0])) 18128 /* We reorder load and the shift. */ 18129 && !reg_overlap_mentioned_p (operands[0], operands[4])" 18130 [(set (match_dup 5) (match_dup 4)) 18131 (set (match_dup 0) (match_dup 1))] 18132{ 18133 machine_mode op1mode = GET_MODE (operands[1]); 18134 machine_mode mode = op1mode == DImode ? DImode : SImode; 18135 int scale = 1 << INTVAL (operands[2]); 18136 rtx index = gen_lowpart (word_mode, operands[1]); 18137 rtx base = gen_lowpart (word_mode, operands[5]); 18138 rtx dest = gen_lowpart (mode, operands[3]); 18139 18140 operands[1] = gen_rtx_PLUS (word_mode, base, 18141 gen_rtx_MULT (word_mode, index, GEN_INT (scale))); 18142 if (mode != word_mode) 18143 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 18144 18145 operands[5] = base; 18146 if (op1mode != word_mode) 18147 operands[5] = gen_lowpart (op1mode, operands[5]); 18148 18149 operands[0] = dest; 18150}) 18151 18152;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 18153;; That, however, is usually mapped by the OS to SIGSEGV, which is often 18154;; caught for use by garbage collectors and the like. Using an insn that 18155;; maps to SIGILL makes it more likely the program will rightfully die. 18156;; Keeping with tradition, "6" is in honor of #UD. 18157(define_insn "trap" 18158 [(trap_if (const_int 1) (const_int 6))] 18159 "" 18160{ 18161#ifdef HAVE_AS_IX86_UD2 18162 return "ud2"; 18163#else 18164 return ASM_SHORT "0x0b0f"; 18165#endif 18166} 18167 [(set_attr "length" "2")]) 18168 18169(define_expand "prefetch" 18170 [(prefetch (match_operand 0 "address_operand") 18171 (match_operand:SI 1 "const_int_operand") 18172 (match_operand:SI 2 "const_int_operand"))] 18173 "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1" 18174{ 18175 bool write = INTVAL (operands[1]) != 0; 18176 int locality = INTVAL (operands[2]); 18177 18178 gcc_assert (IN_RANGE (locality, 0, 3)); 18179 18180 /* Use 3dNOW prefetch in case we are asking for write prefetch not 18181 supported by SSE counterpart or the SSE prefetch is not available 18182 (K6 machines). Otherwise use SSE prefetch as it allows specifying 18183 of locality. */ 18184 if (TARGET_PREFETCHWT1 && write && locality <= 2) 18185 operands[2] = const2_rtx; 18186 else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE)) 18187 operands[2] = GEN_INT (3); 18188 else 18189 operands[1] = const0_rtx; 18190}) 18191 18192(define_insn "*prefetch_sse" 18193 [(prefetch (match_operand 0 "address_operand" "p") 18194 (const_int 0) 18195 (match_operand:SI 1 "const_int_operand"))] 18196 "TARGET_PREFETCH_SSE" 18197{ 18198 static const char * const patterns[4] = { 18199 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 18200 }; 18201 18202 int locality = INTVAL (operands[1]); 18203 gcc_assert (IN_RANGE (locality, 0, 3)); 18204 18205 return patterns[locality]; 18206} 18207 [(set_attr "type" "sse") 18208 (set_attr "atom_sse_attr" "prefetch") 18209 (set (attr "length_address") 18210 (symbol_ref "memory_address_length (operands[0], false)")) 18211 (set_attr "memory" "none")]) 18212 18213(define_insn "*prefetch_3dnow" 18214 [(prefetch (match_operand 0 "address_operand" "p") 18215 (match_operand:SI 1 "const_int_operand" "n") 18216 (const_int 3))] 18217 "TARGET_PRFCHW" 18218{ 18219 if (INTVAL (operands[1]) == 0) 18220 return "prefetch\t%a0"; 18221 else 18222 return "prefetchw\t%a0"; 18223} 18224 [(set_attr "type" "mmx") 18225 (set (attr "length_address") 18226 (symbol_ref "memory_address_length (operands[0], false)")) 18227 (set_attr "memory" "none")]) 18228 18229(define_insn "*prefetch_prefetchwt1" 18230 [(prefetch (match_operand 0 "address_operand" "p") 18231 (const_int 1) 18232 (const_int 2))] 18233 "TARGET_PREFETCHWT1" 18234 "prefetchwt1\t%a0"; 18235 [(set_attr "type" "sse") 18236 (set (attr "length_address") 18237 (symbol_ref "memory_address_length (operands[0], false)")) 18238 (set_attr "memory" "none")]) 18239 18240(define_expand "stack_protect_set" 18241 [(match_operand 0 "memory_operand") 18242 (match_operand 1 "memory_operand")] 18243 "TARGET_SSP_TLS_GUARD" 18244{ 18245 rtx (*insn)(rtx, rtx); 18246 18247#ifdef TARGET_THREAD_SSP_OFFSET 18248 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET); 18249 insn = (TARGET_LP64 18250 ? gen_stack_tls_protect_set_di 18251 : gen_stack_tls_protect_set_si); 18252#else 18253 insn = (TARGET_LP64 18254 ? gen_stack_protect_set_di 18255 : gen_stack_protect_set_si); 18256#endif 18257 18258 emit_insn (insn (operands[0], operands[1])); 18259 DONE; 18260}) 18261 18262(define_insn "stack_protect_set_<mode>" 18263 [(set (match_operand:PTR 0 "memory_operand" "=m") 18264 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] 18265 UNSPEC_SP_SET)) 18266 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 18267 (clobber (reg:CC FLAGS_REG))] 18268 "TARGET_SSP_TLS_GUARD" 18269 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 18270 [(set_attr "type" "multi")]) 18271 18272(define_insn "stack_tls_protect_set_<mode>" 18273 [(set (match_operand:PTR 0 "memory_operand" "=m") 18274 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")] 18275 UNSPEC_SP_TLS_SET)) 18276 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 18277 (clobber (reg:CC FLAGS_REG))] 18278 "" 18279 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2" 18280 [(set_attr "type" "multi")]) 18281 18282(define_expand "stack_protect_test" 18283 [(match_operand 0 "memory_operand") 18284 (match_operand 1 "memory_operand") 18285 (match_operand 2)] 18286 "TARGET_SSP_TLS_GUARD" 18287{ 18288 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 18289 18290 rtx (*insn)(rtx, rtx, rtx); 18291 18292#ifdef TARGET_THREAD_SSP_OFFSET 18293 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET); 18294 insn = (TARGET_LP64 18295 ? gen_stack_tls_protect_test_di 18296 : gen_stack_tls_protect_test_si); 18297#else 18298 insn = (TARGET_LP64 18299 ? gen_stack_protect_test_di 18300 : gen_stack_protect_test_si); 18301#endif 18302 18303 emit_insn (insn (flags, operands[0], operands[1])); 18304 18305 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx), 18306 flags, const0_rtx, operands[2])); 18307 DONE; 18308}) 18309 18310(define_insn "stack_protect_test_<mode>" 18311 [(set (match_operand:CCZ 0 "flags_reg_operand") 18312 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 18313 (match_operand:PTR 2 "memory_operand" "m")] 18314 UNSPEC_SP_TEST)) 18315 (clobber (match_scratch:PTR 3 "=&r"))] 18316 "TARGET_SSP_TLS_GUARD" 18317 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}" 18318 [(set_attr "type" "multi")]) 18319 18320(define_insn "stack_tls_protect_test_<mode>" 18321 [(set (match_operand:CCZ 0 "flags_reg_operand") 18322 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 18323 (match_operand:PTR 2 "const_int_operand" "i")] 18324 UNSPEC_SP_TLS_TEST)) 18325 (clobber (match_scratch:PTR 3 "=r"))] 18326 "" 18327 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}" 18328 [(set_attr "type" "multi")]) 18329 18330(define_insn "sse4_2_crc32<mode>" 18331 [(set (match_operand:SI 0 "register_operand" "=r") 18332 (unspec:SI 18333 [(match_operand:SI 1 "register_operand" "0") 18334 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")] 18335 UNSPEC_CRC32))] 18336 "TARGET_SSE4_2 || TARGET_CRC32" 18337 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}" 18338 [(set_attr "type" "sselog1") 18339 (set_attr "prefix_rep" "1") 18340 (set_attr "prefix_extra" "1") 18341 (set (attr "prefix_data16") 18342 (if_then_else (match_operand:HI 2) 18343 (const_string "1") 18344 (const_string "*"))) 18345 (set (attr "prefix_rex") 18346 (if_then_else (match_operand:QI 2 "ext_QIreg_operand") 18347 (const_string "1") 18348 (const_string "*"))) 18349 (set_attr "mode" "SI")]) 18350 18351(define_insn "sse4_2_crc32di" 18352 [(set (match_operand:DI 0 "register_operand" "=r") 18353 (unspec:DI 18354 [(match_operand:DI 1 "register_operand" "0") 18355 (match_operand:DI 2 "nonimmediate_operand" "rm")] 18356 UNSPEC_CRC32))] 18357 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)" 18358 "crc32{q}\t{%2, %0|%0, %2}" 18359 [(set_attr "type" "sselog1") 18360 (set_attr "prefix_rep" "1") 18361 (set_attr "prefix_extra" "1") 18362 (set_attr "mode" "DI")]) 18363 18364(define_insn "rdpmc" 18365 [(set (match_operand:DI 0 "register_operand" "=A") 18366 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 18367 UNSPECV_RDPMC))] 18368 "!TARGET_64BIT" 18369 "rdpmc" 18370 [(set_attr "type" "other") 18371 (set_attr "length" "2")]) 18372 18373(define_insn "rdpmc_rex64" 18374 [(set (match_operand:DI 0 "register_operand" "=a") 18375 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 18376 UNSPECV_RDPMC)) 18377 (set (match_operand:DI 1 "register_operand" "=d") 18378 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))] 18379 "TARGET_64BIT" 18380 "rdpmc" 18381 [(set_attr "type" "other") 18382 (set_attr "length" "2")]) 18383 18384(define_insn "rdtsc" 18385 [(set (match_operand:DI 0 "register_operand" "=A") 18386 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 18387 "!TARGET_64BIT" 18388 "rdtsc" 18389 [(set_attr "type" "other") 18390 (set_attr "length" "2")]) 18391 18392(define_insn "rdtsc_rex64" 18393 [(set (match_operand:DI 0 "register_operand" "=a") 18394 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC)) 18395 (set (match_operand:DI 1 "register_operand" "=d") 18396 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 18397 "TARGET_64BIT" 18398 "rdtsc" 18399 [(set_attr "type" "other") 18400 (set_attr "length" "2")]) 18401 18402(define_insn "rdtscp" 18403 [(set (match_operand:DI 0 "register_operand" "=A") 18404 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 18405 (set (match_operand:SI 1 "register_operand" "=c") 18406 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 18407 "!TARGET_64BIT" 18408 "rdtscp" 18409 [(set_attr "type" "other") 18410 (set_attr "length" "3")]) 18411 18412(define_insn "rdtscp_rex64" 18413 [(set (match_operand:DI 0 "register_operand" "=a") 18414 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 18415 (set (match_operand:DI 1 "register_operand" "=d") 18416 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 18417 (set (match_operand:SI 2 "register_operand" "=c") 18418 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 18419 "TARGET_64BIT" 18420 "rdtscp" 18421 [(set_attr "type" "other") 18422 (set_attr "length" "3")]) 18423 18424;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18425;; 18426;; FXSR, XSAVE and XSAVEOPT instructions 18427;; 18428;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18429 18430(define_insn "fxsave" 18431 [(set (match_operand:BLK 0 "memory_operand" "=m") 18432 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))] 18433 "TARGET_FXSR" 18434 "fxsave\t%0" 18435 [(set_attr "type" "other") 18436 (set_attr "memory" "store") 18437 (set (attr "length") 18438 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 18439 18440(define_insn "fxsave64" 18441 [(set (match_operand:BLK 0 "memory_operand" "=m") 18442 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))] 18443 "TARGET_64BIT && TARGET_FXSR" 18444 "fxsave64\t%0" 18445 [(set_attr "type" "other") 18446 (set_attr "memory" "store") 18447 (set (attr "length") 18448 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 18449 18450(define_insn "fxrstor" 18451 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 18452 UNSPECV_FXRSTOR)] 18453 "TARGET_FXSR" 18454 "fxrstor\t%0" 18455 [(set_attr "type" "other") 18456 (set_attr "memory" "load") 18457 (set (attr "length") 18458 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 18459 18460(define_insn "fxrstor64" 18461 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 18462 UNSPECV_FXRSTOR64)] 18463 "TARGET_64BIT && TARGET_FXSR" 18464 "fxrstor64\t%0" 18465 [(set_attr "type" "other") 18466 (set_attr "memory" "load") 18467 (set (attr "length") 18468 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 18469 18470(define_int_iterator ANY_XSAVE 18471 [UNSPECV_XSAVE 18472 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT") 18473 (UNSPECV_XSAVEC "TARGET_XSAVEC") 18474 (UNSPECV_XSAVES "TARGET_XSAVES")]) 18475 18476(define_int_iterator ANY_XSAVE64 18477 [UNSPECV_XSAVE64 18478 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT") 18479 (UNSPECV_XSAVEC64 "TARGET_XSAVEC") 18480 (UNSPECV_XSAVES64 "TARGET_XSAVES")]) 18481 18482(define_int_attr xsave 18483 [(UNSPECV_XSAVE "xsave") 18484 (UNSPECV_XSAVE64 "xsave64") 18485 (UNSPECV_XSAVEOPT "xsaveopt") 18486 (UNSPECV_XSAVEOPT64 "xsaveopt64") 18487 (UNSPECV_XSAVEC "xsavec") 18488 (UNSPECV_XSAVEC64 "xsavec64") 18489 (UNSPECV_XSAVES "xsaves") 18490 (UNSPECV_XSAVES64 "xsaves64")]) 18491 18492(define_int_iterator ANY_XRSTOR 18493 [UNSPECV_XRSTOR 18494 (UNSPECV_XRSTORS "TARGET_XSAVES")]) 18495 18496(define_int_iterator ANY_XRSTOR64 18497 [UNSPECV_XRSTOR64 18498 (UNSPECV_XRSTORS64 "TARGET_XSAVES")]) 18499 18500(define_int_attr xrstor 18501 [(UNSPECV_XRSTOR "xrstor") 18502 (UNSPECV_XRSTOR64 "xrstor") 18503 (UNSPECV_XRSTORS "xrstors") 18504 (UNSPECV_XRSTORS64 "xrstors")]) 18505 18506(define_insn "<xsave>" 18507 [(set (match_operand:BLK 0 "memory_operand" "=m") 18508 (unspec_volatile:BLK 18509 [(match_operand:DI 1 "register_operand" "A")] 18510 ANY_XSAVE))] 18511 "!TARGET_64BIT && TARGET_XSAVE" 18512 "<xsave>\t%0" 18513 [(set_attr "type" "other") 18514 (set_attr "memory" "store") 18515 (set (attr "length") 18516 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 18517 18518(define_insn "<xsave>_rex64" 18519 [(set (match_operand:BLK 0 "memory_operand" "=m") 18520 (unspec_volatile:BLK 18521 [(match_operand:SI 1 "register_operand" "a") 18522 (match_operand:SI 2 "register_operand" "d")] 18523 ANY_XSAVE))] 18524 "TARGET_64BIT && TARGET_XSAVE" 18525 "<xsave>\t%0" 18526 [(set_attr "type" "other") 18527 (set_attr "memory" "store") 18528 (set (attr "length") 18529 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 18530 18531(define_insn "<xsave>" 18532 [(set (match_operand:BLK 0 "memory_operand" "=m") 18533 (unspec_volatile:BLK 18534 [(match_operand:SI 1 "register_operand" "a") 18535 (match_operand:SI 2 "register_operand" "d")] 18536 ANY_XSAVE64))] 18537 "TARGET_64BIT && TARGET_XSAVE" 18538 "<xsave>\t%0" 18539 [(set_attr "type" "other") 18540 (set_attr "memory" "store") 18541 (set (attr "length") 18542 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 18543 18544(define_insn "<xrstor>" 18545 [(unspec_volatile:BLK 18546 [(match_operand:BLK 0 "memory_operand" "m") 18547 (match_operand:DI 1 "register_operand" "A")] 18548 ANY_XRSTOR)] 18549 "!TARGET_64BIT && TARGET_XSAVE" 18550 "<xrstor>\t%0" 18551 [(set_attr "type" "other") 18552 (set_attr "memory" "load") 18553 (set (attr "length") 18554 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 18555 18556(define_insn "<xrstor>_rex64" 18557 [(unspec_volatile:BLK 18558 [(match_operand:BLK 0 "memory_operand" "m") 18559 (match_operand:SI 1 "register_operand" "a") 18560 (match_operand:SI 2 "register_operand" "d")] 18561 ANY_XRSTOR)] 18562 "TARGET_64BIT && TARGET_XSAVE" 18563 "<xrstor>\t%0" 18564 [(set_attr "type" "other") 18565 (set_attr "memory" "load") 18566 (set (attr "length") 18567 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 18568 18569(define_insn "<xrstor>64" 18570 [(unspec_volatile:BLK 18571 [(match_operand:BLK 0 "memory_operand" "m") 18572 (match_operand:SI 1 "register_operand" "a") 18573 (match_operand:SI 2 "register_operand" "d")] 18574 ANY_XRSTOR64)] 18575 "TARGET_64BIT && TARGET_XSAVE" 18576 "<xrstor>64\t%0" 18577 [(set_attr "type" "other") 18578 (set_attr "memory" "load") 18579 (set (attr "length") 18580 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 18581 18582;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18583;; 18584;; Floating-point instructions for atomic compound assignments 18585;; 18586;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18587 18588; Clobber all floating-point registers on environment save and restore 18589; to ensure that the TOS value saved at fnstenv is valid after fldenv. 18590(define_insn "fnstenv" 18591 [(set (match_operand:BLK 0 "memory_operand" "=m") 18592 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV)) 18593 (clobber (reg:HI FPCR_REG)) 18594 (clobber (reg:XF ST0_REG)) 18595 (clobber (reg:XF ST1_REG)) 18596 (clobber (reg:XF ST2_REG)) 18597 (clobber (reg:XF ST3_REG)) 18598 (clobber (reg:XF ST4_REG)) 18599 (clobber (reg:XF ST5_REG)) 18600 (clobber (reg:XF ST6_REG)) 18601 (clobber (reg:XF ST7_REG))] 18602 "TARGET_80387" 18603 "fnstenv\t%0" 18604 [(set_attr "type" "other") 18605 (set_attr "memory" "store") 18606 (set (attr "length") 18607 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 18608 18609(define_insn "fldenv" 18610 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 18611 UNSPECV_FLDENV) 18612 (clobber (reg:CCFP FPSR_REG)) 18613 (clobber (reg:HI FPCR_REG)) 18614 (clobber (reg:XF ST0_REG)) 18615 (clobber (reg:XF ST1_REG)) 18616 (clobber (reg:XF ST2_REG)) 18617 (clobber (reg:XF ST3_REG)) 18618 (clobber (reg:XF ST4_REG)) 18619 (clobber (reg:XF ST5_REG)) 18620 (clobber (reg:XF ST6_REG)) 18621 (clobber (reg:XF ST7_REG))] 18622 "TARGET_80387" 18623 "fldenv\t%0" 18624 [(set_attr "type" "other") 18625 (set_attr "memory" "load") 18626 (set (attr "length") 18627 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 18628 18629(define_insn "fnstsw" 18630 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m") 18631 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))] 18632 "TARGET_80387" 18633 "fnstsw\t%0" 18634 [(set_attr "type" "other,other") 18635 (set_attr "memory" "none,store") 18636 (set (attr "length") 18637 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 18638 18639(define_insn "fnclex" 18640 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)] 18641 "TARGET_80387" 18642 "fnclex" 18643 [(set_attr "type" "other") 18644 (set_attr "memory" "none") 18645 (set_attr "length" "2")]) 18646 18647;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18648;; 18649;; LWP instructions 18650;; 18651;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 18652 18653(define_expand "lwp_llwpcb" 18654 [(unspec_volatile [(match_operand 0 "register_operand" "r")] 18655 UNSPECV_LLWP_INTRINSIC)] 18656 "TARGET_LWP") 18657 18658(define_insn "*lwp_llwpcb<mode>1" 18659 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 18660 UNSPECV_LLWP_INTRINSIC)] 18661 "TARGET_LWP" 18662 "llwpcb\t%0" 18663 [(set_attr "type" "lwp") 18664 (set_attr "mode" "<MODE>") 18665 (set_attr "length" "5")]) 18666 18667(define_expand "lwp_slwpcb" 18668 [(set (match_operand 0 "register_operand" "=r") 18669 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 18670 "TARGET_LWP" 18671{ 18672 rtx (*insn)(rtx); 18673 18674 insn = (Pmode == DImode 18675 ? gen_lwp_slwpcbdi 18676 : gen_lwp_slwpcbsi); 18677 18678 emit_insn (insn (operands[0])); 18679 DONE; 18680}) 18681 18682(define_insn "lwp_slwpcb<mode>" 18683 [(set (match_operand:P 0 "register_operand" "=r") 18684 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 18685 "TARGET_LWP" 18686 "slwpcb\t%0" 18687 [(set_attr "type" "lwp") 18688 (set_attr "mode" "<MODE>") 18689 (set_attr "length" "5")]) 18690 18691(define_expand "lwp_lwpval<mode>3" 18692 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r") 18693 (match_operand:SI 2 "nonimmediate_operand" "rm") 18694 (match_operand:SI 3 "const_int_operand" "i")] 18695 UNSPECV_LWPVAL_INTRINSIC)] 18696 "TARGET_LWP" 18697 ;; Avoid unused variable warning. 18698 "(void) operands[0];") 18699 18700(define_insn "*lwp_lwpval<mode>3_1" 18701 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") 18702 (match_operand:SI 1 "nonimmediate_operand" "rm") 18703 (match_operand:SI 2 "const_int_operand" "i")] 18704 UNSPECV_LWPVAL_INTRINSIC)] 18705 "TARGET_LWP" 18706 "lwpval\t{%2, %1, %0|%0, %1, %2}" 18707 [(set_attr "type" "lwp") 18708 (set_attr "mode" "<MODE>") 18709 (set (attr "length") 18710 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 18711 18712(define_expand "lwp_lwpins<mode>3" 18713 [(set (reg:CCC FLAGS_REG) 18714 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r") 18715 (match_operand:SI 2 "nonimmediate_operand" "rm") 18716 (match_operand:SI 3 "const_int_operand" "i")] 18717 UNSPECV_LWPINS_INTRINSIC)) 18718 (set (match_operand:QI 0 "nonimmediate_operand" "=qm") 18719 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] 18720 "TARGET_LWP") 18721 18722(define_insn "*lwp_lwpins<mode>3_1" 18723 [(set (reg:CCC FLAGS_REG) 18724 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r") 18725 (match_operand:SI 1 "nonimmediate_operand" "rm") 18726 (match_operand:SI 2 "const_int_operand" "i")] 18727 UNSPECV_LWPINS_INTRINSIC))] 18728 "TARGET_LWP" 18729 "lwpins\t{%2, %1, %0|%0, %1, %2}" 18730 [(set_attr "type" "lwp") 18731 (set_attr "mode" "<MODE>") 18732 (set (attr "length") 18733 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 18734 18735(define_int_iterator RDFSGSBASE 18736 [UNSPECV_RDFSBASE 18737 UNSPECV_RDGSBASE]) 18738 18739(define_int_iterator WRFSGSBASE 18740 [UNSPECV_WRFSBASE 18741 UNSPECV_WRGSBASE]) 18742 18743(define_int_attr fsgs 18744 [(UNSPECV_RDFSBASE "fs") 18745 (UNSPECV_RDGSBASE "gs") 18746 (UNSPECV_WRFSBASE "fs") 18747 (UNSPECV_WRGSBASE "gs")]) 18748 18749(define_insn "rd<fsgs>base<mode>" 18750 [(set (match_operand:SWI48 0 "register_operand" "=r") 18751 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))] 18752 "TARGET_64BIT && TARGET_FSGSBASE" 18753 "rd<fsgs>base\t%0" 18754 [(set_attr "type" "other") 18755 (set_attr "prefix_extra" "2")]) 18756 18757(define_insn "wr<fsgs>base<mode>" 18758 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 18759 WRFSGSBASE)] 18760 "TARGET_64BIT && TARGET_FSGSBASE" 18761 "wr<fsgs>base\t%0" 18762 [(set_attr "type" "other") 18763 (set_attr "prefix_extra" "2")]) 18764 18765(define_insn "rdrand<mode>_1" 18766 [(set (match_operand:SWI248 0 "register_operand" "=r") 18767 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND)) 18768 (set (reg:CCC FLAGS_REG) 18769 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))] 18770 "TARGET_RDRND" 18771 "rdrand\t%0" 18772 [(set_attr "type" "other") 18773 (set_attr "prefix_extra" "1")]) 18774 18775(define_insn "rdseed<mode>_1" 18776 [(set (match_operand:SWI248 0 "register_operand" "=r") 18777 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED)) 18778 (set (reg:CCC FLAGS_REG) 18779 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))] 18780 "TARGET_RDSEED" 18781 "rdseed\t%0" 18782 [(set_attr "type" "other") 18783 (set_attr "prefix_extra" "1")]) 18784 18785(define_expand "pause" 18786 [(set (match_dup 0) 18787 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 18788 "" 18789{ 18790 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 18791 MEM_VOLATILE_P (operands[0]) = 1; 18792}) 18793 18794;; Use "rep; nop", instead of "pause", to support older assemblers. 18795;; They have the same encoding. 18796(define_insn "*pause" 18797 [(set (match_operand:BLK 0) 18798 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 18799 "" 18800 "rep%; nop" 18801 [(set_attr "length" "2") 18802 (set_attr "memory" "unknown")]) 18803 18804(define_expand "xbegin" 18805 [(set (match_operand:SI 0 "register_operand") 18806 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))] 18807 "TARGET_RTM" 18808{ 18809 rtx_code_label *label = gen_label_rtx (); 18810 18811 /* xbegin is emitted as jump_insn, so reload won't be able 18812 to reload its operand. Force the value into AX hard register. */ 18813 rtx ax_reg = gen_rtx_REG (SImode, AX_REG); 18814 emit_move_insn (ax_reg, constm1_rtx); 18815 18816 emit_jump_insn (gen_xbegin_1 (ax_reg, label)); 18817 18818 emit_label (label); 18819 LABEL_NUSES (label) = 1; 18820 18821 emit_move_insn (operands[0], ax_reg); 18822 18823 DONE; 18824}) 18825 18826(define_insn "xbegin_1" 18827 [(set (pc) 18828 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT) 18829 (const_int 0)) 18830 (label_ref (match_operand 1)) 18831 (pc))) 18832 (set (match_operand:SI 0 "register_operand" "+a") 18833 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))] 18834 "TARGET_RTM" 18835 "xbegin\t%l1" 18836 [(set_attr "type" "other") 18837 (set_attr "length" "6")]) 18838 18839(define_insn "xend" 18840 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)] 18841 "TARGET_RTM" 18842 "xend" 18843 [(set_attr "type" "other") 18844 (set_attr "length" "3")]) 18845 18846(define_insn "xabort" 18847 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")] 18848 UNSPECV_XABORT)] 18849 "TARGET_RTM" 18850 "xabort\t%0" 18851 [(set_attr "type" "other") 18852 (set_attr "length" "3")]) 18853 18854(define_expand "xtest" 18855 [(set (match_operand:QI 0 "register_operand") 18856 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))] 18857 "TARGET_RTM" 18858{ 18859 emit_insn (gen_xtest_1 ()); 18860 18861 ix86_expand_setcc (operands[0], NE, 18862 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 18863 DONE; 18864}) 18865 18866(define_insn "xtest_1" 18867 [(set (reg:CCZ FLAGS_REG) 18868 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))] 18869 "TARGET_RTM" 18870 "xtest" 18871 [(set_attr "type" "other") 18872 (set_attr "length" "3")]) 18873 18874(define_insn "pcommit" 18875 [(unspec_volatile [(const_int 0)] UNSPECV_PCOMMIT)] 18876 "TARGET_PCOMMIT" 18877 "pcommit" 18878 [(set_attr "type" "other") 18879 (set_attr "length" "4")]) 18880 18881(define_insn "clwb" 18882 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 18883 UNSPECV_CLWB)] 18884 "TARGET_CLWB" 18885 "clwb\t%a0" 18886 [(set_attr "type" "sse") 18887 (set_attr "atom_sse_attr" "fence") 18888 (set_attr "memory" "unknown")]) 18889 18890(define_insn "clflushopt" 18891 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 18892 UNSPECV_CLFLUSHOPT)] 18893 "TARGET_CLFLUSHOPT" 18894 "clflushopt\t%a0" 18895 [(set_attr "type" "sse") 18896 (set_attr "atom_sse_attr" "fence") 18897 (set_attr "memory" "unknown")]) 18898 18899;; MONITORX and MWAITX 18900(define_insn "mwaitx" 18901 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c") 18902 (match_operand:SI 1 "register_operand" "a") 18903 (match_operand:SI 2 "register_operand" "b")] 18904 UNSPECV_MWAITX)] 18905 "TARGET_MWAITX" 18906;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used. 18907;; Since 32bit register operands are implicitly zero extended to 64bit, 18908;; we only need to set up 32bit registers. 18909 "mwaitx" 18910 [(set_attr "length" "3")]) 18911 18912(define_insn "monitorx_<mode>" 18913 [(unspec_volatile [(match_operand:P 0 "register_operand" "a") 18914 (match_operand:SI 1 "register_operand" "c") 18915 (match_operand:SI 2 "register_operand" "d")] 18916 UNSPECV_MONITORX)] 18917 "TARGET_MWAITX" 18918;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in 18919;; RCX and RDX are used. Since 32bit register operands are implicitly 18920;; zero extended to 64bit, we only need to set up 32bit registers. 18921 "%^monitorx" 18922 [(set (attr "length") 18923 (symbol_ref ("(Pmode != word_mode) + 3")))]) 18924 18925;; MPX instructions 18926 18927(define_expand "<mode>_mk" 18928 [(set (match_operand:BND 0 "register_operand") 18929 (unspec:BND 18930 [(mem:<bnd_ptr> 18931 (match_par_dup 3 18932 [(match_operand:<bnd_ptr> 1 "register_operand") 18933 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))] 18934 UNSPEC_BNDMK))] 18935 "TARGET_MPX" 18936{ 18937 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], 18938 operands[2]), 18939 UNSPEC_BNDMK_ADDR); 18940}) 18941 18942(define_insn "*<mode>_mk" 18943 [(set (match_operand:BND 0 "register_operand" "=w") 18944 (unspec:BND 18945 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 18946 [(unspec:<bnd_ptr> 18947 [(match_operand:<bnd_ptr> 1 "register_operand" "r") 18948 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")] 18949 UNSPEC_BNDMK_ADDR)])] 18950 UNSPEC_BNDMK))] 18951 "TARGET_MPX" 18952 "bndmk\t{%3, %0|%0, %3}" 18953 [(set_attr "type" "mpxmk")]) 18954 18955(define_expand "mov<mode>" 18956 [(set (match_operand:BND 0 "general_operand") 18957 (match_operand:BND 1 "general_operand"))] 18958 "TARGET_MPX" 18959{ 18960 ix86_expand_move (<MODE>mode, operands);DONE; 18961}) 18962 18963(define_insn "*mov<mode>_internal_mpx" 18964 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m") 18965 (match_operand:BND 1 "general_operand" "wm,w"))] 18966 "TARGET_MPX" 18967 "bndmov\t{%1, %0|%0, %1}" 18968 [(set_attr "type" "mpxmov")]) 18969 18970(define_expand "<mode>_<bndcheck>" 18971 [(parallel [(unspec [(match_operand:BND 0 "register_operand") 18972 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK) 18973 (set (match_dup 2) 18974 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])] 18975 "TARGET_MPX" 18976{ 18977 operands[2] = gen_rtx_MEM (BLKmode, operands[1]); 18978 MEM_VOLATILE_P (operands[2]) = 1; 18979}) 18980 18981(define_insn "*<mode>_<bndcheck>" 18982 [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w") 18983 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK) 18984 (set (match_operand:BLK 2 "bnd_mem_operator") 18985 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])] 18986 "TARGET_MPX" 18987 "bnd<bndcheck>\t{%a1, %0|%0, %a1}" 18988 [(set_attr "type" "mpxchk")]) 18989 18990(define_expand "<mode>_ldx" 18991 [(parallel [(set:BND (match_operand:BND 0 "register_operand") 18992 (unspec:BND 18993 [(mem:<bnd_ptr> 18994 (match_par_dup 3 18995 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand") 18996 (match_operand:<bnd_ptr> 2 "register_operand")]))] 18997 UNSPEC_BNDLDX)) 18998 (use (mem:BLK (match_dup 1)))])] 18999 "TARGET_MPX" 19000{ 19001 /* Avoid registers which connot be used as index. */ 19002 if (!index_register_operand (operands[2], Pmode)) 19003 { 19004 rtx temp = gen_reg_rtx (Pmode); 19005 emit_move_insn (temp, operands[2]); 19006 operands[2] = temp; 19007 } 19008 19009 /* If it was a register originally then it may have 19010 mode other than Pmode. We need to extend in such 19011 case because bndldx may work only with Pmode regs. */ 19012 if (GET_MODE (operands[2]) != Pmode) 19013 operands[2] = ix86_zero_extend_to_Pmode (operands[2]); 19014 19015 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1], 19016 operands[2]), 19017 UNSPEC_BNDLDX_ADDR); 19018}) 19019 19020(define_insn "*<mode>_ldx" 19021 [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w") 19022 (unspec:BND 19023 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 19024 [(unspec:<bnd_ptr> 19025 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti") 19026 (match_operand:<bnd_ptr> 2 "register_operand" "l")] 19027 UNSPEC_BNDLDX_ADDR)])] 19028 UNSPEC_BNDLDX)) 19029 (use (mem:BLK (match_dup 1)))])] 19030 "TARGET_MPX" 19031 "bndldx\t{%3, %0|%0, %3}" 19032 [(set_attr "type" "mpxld")]) 19033 19034(define_expand "<mode>_stx" 19035 [(parallel [(unspec [(mem:<bnd_ptr> 19036 (match_par_dup 3 19037 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand") 19038 (match_operand:<bnd_ptr> 1 "register_operand")])) 19039 (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX) 19040 (set (match_dup 4) 19041 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])] 19042 "TARGET_MPX" 19043{ 19044 /* Avoid registers which connot be used as index. */ 19045 if (!index_register_operand (operands[1], Pmode)) 19046 { 19047 rtx temp = gen_reg_rtx (Pmode); 19048 emit_move_insn (temp, operands[1]); 19049 operands[1] = temp; 19050 } 19051 19052 /* If it was a register originally then it may have 19053 mode other than Pmode. We need to extend in such 19054 case because bndstx may work only with Pmode regs. */ 19055 if (GET_MODE (operands[1]) != Pmode) 19056 operands[1] = ix86_zero_extend_to_Pmode (operands[1]); 19057 19058 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0], 19059 operands[1]), 19060 UNSPEC_BNDLDX_ADDR); 19061 operands[4] = gen_rtx_MEM (BLKmode, operands[0]); 19062 MEM_VOLATILE_P (operands[4]) = 1; 19063}) 19064 19065(define_insn "*<mode>_stx" 19066 [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator" 19067 [(unspec:<bnd_ptr> 19068 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti") 19069 (match_operand:<bnd_ptr> 1 "register_operand" "l")] 19070 UNSPEC_BNDLDX_ADDR)]) 19071 (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX) 19072 (set (match_operand:BLK 4 "bnd_mem_operator") 19073 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])] 19074 "TARGET_MPX" 19075 "bndstx\t{%2, %3|%3, %2}" 19076 [(set_attr "type" "mpxst")]) 19077 19078(define_insn "move_size_reloc_<mode>" 19079 [(set (match_operand:SWI48 0 "register_operand" "=r") 19080 (unspec:SWI48 19081 [(match_operand:SWI48 1 "symbol_operand")] 19082 UNSPEC_SIZEOF))] 19083 "TARGET_MPX" 19084{ 19085 if (x86_64_immediate_size_operand (operands[1], VOIDmode)) 19086 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}"; 19087 else 19088 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}"; 19089} 19090 [(set_attr "type" "imov") 19091 (set_attr "mode" "<MODE>")]) 19092 19093(include "mmx.md") 19094(include "sse.md") 19095(include "sync.md") 19096