1157184Sache;; GCC machine description for IA-32 and x86-64. 2157184Sache;; Copyright (C) 1988-2020 Free Software Foundation, Inc. 3157184Sache;; Mostly by William Schelter. 4157184Sache;; x86_64 support added by Jan Hubicka 5157184Sache;; 6157184Sache;; This file is part of GCC. 7157184Sache;; 8157184Sache;; GCC is free software; you can redistribute it and/or modify 9157184Sache;; it under the terms of the GNU General Public License as published by 10157184Sache;; the Free Software Foundation; either version 3, or (at your option) 11157184Sache;; any later version. 12157184Sache;; 13157184Sache;; GCC is distributed in the hope that it will be useful, 14157184Sache;; but WITHOUT ANY WARRANTY; without even the implied warranty of 15157184Sache;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16157184Sache;; GNU General Public License for more details. 17157184Sache;; 18157184Sache;; You should have received a copy of the GNU General Public License 19157184Sache;; along with GCC; see the file COPYING3. If not see 20157184Sache;; <http://www.gnu.org/licenses/>. */ 21157184Sache;; 22157184Sache;; The original PO technology requires these to be ordered by speed, 23157184Sache;; so that assigner will pick the fastest. 24157184Sache;; 25157184Sache;; See file "rtl.def" for documentation on define_insn, match_*, et. al. 26157184Sache;; 27157184Sache;; The special asm out single letter directives following a '%' are: 28157184Sache;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand. 29157184Sache;; C -- print opcode suffix for set/cmov insn. 30157184Sache;; c -- like C, but print reversed condition 31157184Sache;; F,f -- likewise, but for floating-point. 32157184Sache;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.", 33157184Sache;; otherwise nothing 34157184Sache;; R -- print the prefix for register names. 35157184Sache;; z -- print the opcode suffix for the size of the current operand. 36157184Sache;; Z -- likewise, with special suffixes for x87 instructions. 37157184Sache;; * -- print a star (in certain assembler syntax) 38157184Sache;; A -- print an absolute memory reference. 39157184Sache;; E -- print address with DImode register names if TARGET_64BIT. 40157184Sache;; w -- print the operand as if it's a "word" (HImode) even if it isn't. 41157184Sache;; s -- print a shift double count, followed by the assemblers argument 42157184Sache;; delimiter. 43157184Sache;; b -- print the QImode name of the register for the indicated operand. 44157184Sache;; %b0 would print %al if operands[0] is reg 0. 45157184Sache;; w -- likewise, print the HImode name of the register. 46157184Sache;; k -- likewise, print the SImode name of the register. 47157184Sache;; q -- likewise, print the DImode name of the register. 48157184Sache;; x -- likewise, print the V4SFmode name of the register. 49157184Sache;; t -- likewise, print the V8SFmode name of the register. 50157184Sache;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh. 51157184Sache;; y -- print "st(0)" instead of "st" as a register. 52157184Sache;; d -- print duplicated register operand for AVX instruction. 53157184Sache;; D -- print condition for SSE cmp instruction. 54157184Sache;; P -- if PIC, print an @PLT suffix. 55157184Sache;; p -- print raw symbol name. 56157184Sache;; X -- don't print any sort of PIC '@' suffix for a symbol. 57157184Sache;; & -- print some in-use local-dynamic symbol name. 58157184Sache;; H -- print a memory address offset by 8; used for sse high-parts 59157184Sache;; K -- print HLE lock prefix 60157184Sache;; Y -- print condition for XOP pcom* instruction. 61157184Sache;; + -- print a branch hint as 'cs' or 'ds' prefix 62157184Sache;; ; -- print a semicolon (after prefixes due to bug in older gas). 63157184Sache;; ~ -- print "i" if TARGET_AVX2, "f" otherwise. 64157184Sache;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode 65157184Sache;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required. 66157184Sache 67157184Sache(define_c_enum "unspec" [ 68157184Sache ;; Relocation specifiers 69157184Sache UNSPEC_GOT 70157184Sache UNSPEC_GOTOFF 71157184Sache UNSPEC_GOTPCREL 72157184Sache UNSPEC_GOTTPOFF 73157184Sache UNSPEC_TPOFF 74157184Sache UNSPEC_NTPOFF 75157184Sache UNSPEC_DTPOFF 76157184Sache UNSPEC_GOTNTPOFF 77157184Sache UNSPEC_INDNTPOFF 78157184Sache UNSPEC_PLTOFF 79157184Sache UNSPEC_MACHOPIC_OFFSET 80157184Sache UNSPEC_PCREL 81157184Sache UNSPEC_SIZEOF 82157184Sache 83157184Sache ;; Prologue support 84157184Sache UNSPEC_STACK_ALLOC 85157184Sache UNSPEC_SET_GOT 86157184Sache UNSPEC_SET_RIP 87157184Sache UNSPEC_SET_GOT_OFFSET 88157184Sache UNSPEC_MEMORY_BLOCKAGE 89157184Sache UNSPEC_PROBE_STACK 90157184Sache 91157184Sache ;; TLS support 92157184Sache UNSPEC_TP 93157184Sache UNSPEC_TLS_GD 94157184Sache UNSPEC_TLS_LD_BASE 95157184Sache UNSPEC_TLSDESC 96157184Sache UNSPEC_TLS_IE_SUN 97157184Sache 98157184Sache ;; Other random patterns 99157184Sache UNSPEC_SCAS 100157184Sache UNSPEC_FNSTSW 101157184Sache UNSPEC_SAHF 102157184Sache UNSPEC_NOTRAP 103157184Sache UNSPEC_PARITY 104157184Sache UNSPEC_FSTCW 105157184Sache UNSPEC_REP 106157184Sache UNSPEC_LD_MPIC ; load_macho_picbase 107157184Sache UNSPEC_TRUNC_NOOP 108157184Sache UNSPEC_DIV_ALREADY_SPLIT 109157184Sache UNSPEC_PAUSE 110157184Sache UNSPEC_LEA_ADDR 111157184Sache UNSPEC_XBEGIN_ABORT 112157184Sache UNSPEC_STOS 113157184Sache UNSPEC_PEEPSIB 114157184Sache UNSPEC_INSN_FALSE_DEP 115157184Sache UNSPEC_SBB 116157184Sache 117157184Sache ;; For SSE/MMX support: 118157184Sache UNSPEC_FIX_NOTRUNC 119157184Sache UNSPEC_MASKMOV 120157184Sache UNSPEC_MOVMSK 121157184Sache UNSPEC_RCP 122157184Sache UNSPEC_RSQRT 123157184Sache UNSPEC_PSADBW 124157184Sache 125157184Sache ;; Generic math support 126157184Sache UNSPEC_COPYSIGN 127157184Sache UNSPEC_XORSIGN 128157184Sache UNSPEC_IEEE_MIN ; not commutative 129157184Sache UNSPEC_IEEE_MAX ; not commutative 130157184Sache 131157184Sache ;; x87 Floating point 132157184Sache UNSPEC_SIN 133157184Sache UNSPEC_COS 134157184Sache UNSPEC_FPATAN 135157184Sache UNSPEC_FYL2X 136157184Sache UNSPEC_FYL2XP1 137157184Sache UNSPEC_FRNDINT 138157184Sache UNSPEC_FIST 139157184Sache UNSPEC_F2XM1 140157184Sache UNSPEC_TAN 141157184Sache UNSPEC_FXAM 142157184Sache 143157184Sache ;; x87 Rounding 144157184Sache UNSPEC_FRNDINT_ROUNDEVEN 145157184Sache UNSPEC_FRNDINT_FLOOR 146157184Sache UNSPEC_FRNDINT_CEIL 147157184Sache UNSPEC_FRNDINT_TRUNC 148157184Sache UNSPEC_FIST_FLOOR 149157184Sache UNSPEC_FIST_CEIL 150157184Sache 151157184Sache ;; x87 Double output FP 152157184Sache UNSPEC_SINCOS_COS 153157184Sache UNSPEC_SINCOS_SIN 154157184Sache UNSPEC_XTRACT_FRACT 155157184Sache UNSPEC_XTRACT_EXP 156157184Sache UNSPEC_FSCALE_FRACT 157157184Sache UNSPEC_FSCALE_EXP 158157184Sache UNSPEC_FPREM_F 159157184Sache UNSPEC_FPREM_U 160157184Sache UNSPEC_FPREM1_F 161157184Sache UNSPEC_FPREM1_U 162157184Sache 163157184Sache UNSPEC_C2_FLAG 164157184Sache UNSPEC_FXAM_MEM 165157184Sache 166157184Sache ;; SSP patterns 167157184Sache UNSPEC_SP_SET 168157184Sache UNSPEC_SP_TEST 169157184Sache 170157184Sache ;; For ROUND support 171157184Sache UNSPEC_ROUND 172157184Sache 173157184Sache ;; For CRC32 support 174157184Sache UNSPEC_CRC32 175157184Sache 176157184Sache ;; For LZCNT suppoprt 177157184Sache UNSPEC_LZCNT 178157184Sache 179157184Sache ;; For BMI support 180157184Sache UNSPEC_TZCNT 181157184Sache UNSPEC_BEXTR 182157184Sache 183157184Sache ;; For BMI2 support 184157184Sache UNSPEC_PDEP 185157184Sache UNSPEC_PEXT 186157184Sache 187157184Sache ;; IRET support 188157184Sache UNSPEC_INTERRUPT_RETURN 189157184Sache 190157184Sache ;; For MOVDIRI and MOVDIR64B support 191157184Sache UNSPEC_MOVDIRI 192157184Sache UNSPEC_MOVDIR64B 193157184Sache]) 194157184Sache 195157184Sache(define_c_enum "unspecv" [ 196157184Sache UNSPECV_UD2 197157184Sache UNSPECV_BLOCKAGE 198157184Sache UNSPECV_STACK_PROBE 199157184Sache UNSPECV_PROBE_STACK_RANGE 200157184Sache UNSPECV_ALIGN 201157184Sache UNSPECV_PROLOGUE_USE 202157184Sache UNSPECV_SPLIT_STACK_RETURN 203157184Sache UNSPECV_CLD 204157184Sache UNSPECV_NOPS 205157184Sache UNSPECV_RDTSC 206157184Sache UNSPECV_RDTSCP 207157184Sache UNSPECV_RDPMC 208157184Sache UNSPECV_LLWP_INTRINSIC 209157184Sache UNSPECV_SLWP_INTRINSIC 210157184Sache UNSPECV_LWPVAL_INTRINSIC 211157184Sache UNSPECV_LWPINS_INTRINSIC 212157184Sache UNSPECV_RDFSBASE 213157184Sache UNSPECV_RDGSBASE 214157184Sache UNSPECV_WRFSBASE 215157184Sache UNSPECV_WRGSBASE 216157184Sache UNSPECV_FXSAVE 217157184Sache UNSPECV_FXRSTOR 218157184Sache UNSPECV_FXSAVE64 219157184Sache UNSPECV_FXRSTOR64 220157184Sache UNSPECV_XSAVE 221157184Sache UNSPECV_XRSTOR 222157184Sache UNSPECV_XSAVE64 223157184Sache UNSPECV_XRSTOR64 224157184Sache UNSPECV_XSAVEOPT 225157184Sache UNSPECV_XSAVEOPT64 226157184Sache UNSPECV_XSAVES 227157184Sache UNSPECV_XRSTORS 228157184Sache UNSPECV_XSAVES64 229157184Sache UNSPECV_XRSTORS64 230157184Sache UNSPECV_XSAVEC 231157184Sache UNSPECV_XSAVEC64 232157184Sache UNSPECV_XGETBV 233157184Sache UNSPECV_XSETBV 234157184Sache UNSPECV_WBINVD 235157184Sache UNSPECV_WBNOINVD 236157184Sache 237157184Sache ;; For atomic compound assignments. 238157184Sache UNSPECV_FNSTENV 239157184Sache UNSPECV_FLDENV 240157184Sache UNSPECV_FNSTSW 241157184Sache UNSPECV_FNCLEX 242157184Sache 243157184Sache ;; For RDRAND support 244157184Sache UNSPECV_RDRAND 245157184Sache 246157184Sache ;; For RDSEED support 247157184Sache UNSPECV_RDSEED 248157184Sache 249157184Sache ;; For RTM support 250157184Sache UNSPECV_XBEGIN 251157184Sache UNSPECV_XEND 252157184Sache UNSPECV_XABORT 253157184Sache UNSPECV_XTEST 254157184Sache 255157184Sache UNSPECV_NLGR 256157184Sache 257157184Sache ;; For CLWB support 258157184Sache UNSPECV_CLWB 259157184Sache 260157184Sache ;; For CLFLUSHOPT support 261157184Sache UNSPECV_CLFLUSHOPT 262157184Sache 263157184Sache ;; For MONITORX and MWAITX support 264157184Sache UNSPECV_MONITORX 265157184Sache UNSPECV_MWAITX 266157184Sache 267157184Sache ;; For CLZERO support 268157184Sache UNSPECV_CLZERO 269157184Sache 270157184Sache ;; For RDPKRU and WRPKRU support 271157184Sache UNSPECV_PKU 272157184Sache 273157184Sache ;; For RDPID support 274157184Sache UNSPECV_RDPID 275157184Sache 276157184Sache ;; For CET support 277157184Sache UNSPECV_NOP_ENDBR 278157184Sache UNSPECV_NOP_RDSSP 279157184Sache UNSPECV_INCSSP 280157184Sache UNSPECV_SAVEPREVSSP 281157184Sache UNSPECV_RSTORSSP 282157184Sache UNSPECV_WRSS 283157184Sache UNSPECV_WRUSS 284157184Sache UNSPECV_SETSSBSY 285157184Sache UNSPECV_CLRSSBSY 286157184Sache 287157184Sache ;; For WAITPKG support 288157184Sache UNSPECV_UMWAIT 289157184Sache UNSPECV_UMONITOR 290157184Sache UNSPECV_TPAUSE 291157184Sache 292157184Sache ;; For CLDEMOTE support 293157184Sache UNSPECV_CLDEMOTE 294157184Sache 295157184Sache ;; For Speculation Barrier support 296157184Sache UNSPECV_SPECULATION_BARRIER 297157184Sache 298157184Sache UNSPECV_PTWRITE 299157184Sache 300157184Sache ;; For ENQCMD and ENQCMDS support 301157184Sache UNSPECV_ENQCMD 302157184Sache UNSPECV_ENQCMDS 303157184Sache]) 304157184Sache 305157184Sache;; Constants to represent rounding modes in the ROUND instruction 306157184Sache(define_constants 307157184Sache [(ROUND_ROUNDEVEN 0x0) 308157184Sache (ROUND_FLOOR 0x1) 309157184Sache (ROUND_CEIL 0x2) 310157184Sache (ROUND_TRUNC 0x3) 311157184Sache (ROUND_MXCSR 0x4) 312157184Sache (ROUND_NO_EXC 0x8) 313157184Sache ]) 314157184Sache 315157184Sache;; Constants to represent AVX512F embeded rounding 316157184Sache(define_constants 317157184Sache [(ROUND_NEAREST_INT 0) 318157184Sache (ROUND_NEG_INF 1) 319157184Sache (ROUND_POS_INF 2) 320157184Sache (ROUND_ZERO 3) 321157184Sache (NO_ROUND 4) 322157184Sache (ROUND_SAE 8) 323157184Sache ]) 324157184Sache 325157184Sache;; Constants to represent pcomtrue/pcomfalse variants 326157184Sache(define_constants 327157184Sache [(PCOM_FALSE 0) 328157184Sache (PCOM_TRUE 1) 329157184Sache (COM_FALSE_S 2) 330157184Sache (COM_FALSE_P 3) 331157184Sache (COM_TRUE_S 4) 332157184Sache (COM_TRUE_P 5) 333157184Sache ]) 334157184Sache 335157184Sache;; Constants used in the XOP pperm instruction 336157184Sache(define_constants 337157184Sache [(PPERM_SRC 0x00) /* copy source */ 338157184Sache (PPERM_INVERT 0x20) /* invert source */ 339157184Sache (PPERM_REVERSE 0x40) /* bit reverse source */ 340157184Sache (PPERM_REV_INV 0x60) /* bit reverse & invert src */ 341157184Sache (PPERM_ZERO 0x80) /* all 0's */ 342157184Sache (PPERM_ONES 0xa0) /* all 1's */ 343157184Sache (PPERM_SIGN 0xc0) /* propagate sign bit */ 344157184Sache (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */ 345157184Sache (PPERM_SRC1 0x00) /* use first source byte */ 346157184Sache (PPERM_SRC2 0x10) /* use second source byte */ 347157184Sache ]) 348157184Sache 349157184Sache;; Registers by name. 350157184Sache(define_constants 351157184Sache [(AX_REG 0) 352157184Sache (DX_REG 1) 353157184Sache (CX_REG 2) 354157184Sache (BX_REG 3) 355157184Sache (SI_REG 4) 356157184Sache (DI_REG 5) 357157184Sache (BP_REG 6) 358157184Sache (SP_REG 7) 359157184Sache (ST0_REG 8) 360157184Sache (ST1_REG 9) 361157184Sache (ST2_REG 10) 362157184Sache (ST3_REG 11) 363157184Sache (ST4_REG 12) 364157184Sache (ST5_REG 13) 365157184Sache (ST6_REG 14) 366157184Sache (ST7_REG 15) 367157184Sache (ARGP_REG 16) 368157184Sache (FLAGS_REG 17) 369157184Sache (FPSR_REG 18) 370157184Sache (FRAME_REG 19) 371157184Sache (XMM0_REG 20) 372157184Sache (XMM1_REG 21) 373157184Sache (XMM2_REG 22) 374157184Sache (XMM3_REG 23) 375157184Sache (XMM4_REG 24) 376157184Sache (XMM5_REG 25) 377157184Sache (XMM6_REG 26) 378157184Sache (XMM7_REG 27) 379157184Sache (MM0_REG 28) 380157184Sache (MM1_REG 29) 381157184Sache (MM2_REG 30) 382157184Sache (MM3_REG 31) 383157184Sache (MM4_REG 32) 384157184Sache (MM5_REG 33) 385157184Sache (MM6_REG 34) 386157184Sache (MM7_REG 35) 387157184Sache (R8_REG 36) 388157184Sache (R9_REG 37) 389157184Sache (R10_REG 38) 390157184Sache (R11_REG 39) 391157184Sache (R12_REG 40) 392157184Sache (R13_REG 41) 393157184Sache (R14_REG 42) 394157184Sache (R15_REG 43) 395157184Sache (XMM8_REG 44) 396157184Sache (XMM9_REG 45) 397157184Sache (XMM10_REG 46) 398157184Sache (XMM11_REG 47) 399157184Sache (XMM12_REG 48) 400157184Sache (XMM13_REG 49) 401157184Sache (XMM14_REG 50) 402157184Sache (XMM15_REG 51) 403157184Sache (XMM16_REG 52) 404157184Sache (XMM17_REG 53) 405157184Sache (XMM18_REG 54) 406157184Sache (XMM19_REG 55) 407157184Sache (XMM20_REG 56) 408157184Sache (XMM21_REG 57) 409157184Sache (XMM22_REG 58) 410157184Sache (XMM23_REG 59) 411157184Sache (XMM24_REG 60) 412157184Sache (XMM25_REG 61) 413157184Sache (XMM26_REG 62) 414157184Sache (XMM27_REG 63) 415157184Sache (XMM28_REG 64) 416157184Sache (XMM29_REG 65) 417157184Sache (XMM30_REG 66) 418157184Sache (XMM31_REG 67) 419157184Sache (MASK0_REG 68) 420157184Sache (MASK1_REG 69) 421157184Sache (MASK2_REG 70) 422157184Sache (MASK3_REG 71) 423157184Sache (MASK4_REG 72) 424157184Sache (MASK5_REG 73) 425157184Sache (MASK6_REG 74) 426157184Sache (MASK7_REG 75) 427157184Sache (FIRST_PSEUDO_REG 76) 428157184Sache ]) 429157184Sache 430157184Sache;; Insns whose names begin with "x86_" are emitted by gen_FOO calls 431157184Sache;; from i386.c. 432157184Sache 433157184Sache;; In C guard expressions, put expressions which may be compile-time 434157184Sache;; constants first. This allows for better optimization. For 435157184Sache;; example, write "TARGET_64BIT && reload_completed", not 436157184Sache;; "reload_completed && TARGET_64BIT". 437157184Sache 438157184Sache 439;; Processor type. 440(define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem, 441 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3, 442 bdver4,btver2,znver1,znver2,znver3" 443 (const (symbol_ref "ix86_schedule"))) 444 445;; A basic instruction type. Refinements due to arguments to be 446;; provided in other attributes. 447(define_attr "type" 448 "other,multi, 449 alu,alu1,negnot,imov,imovx,lea, 450 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1, 451 imul,imulx,idiv,icmp,test,ibr,setcc,icmov, 452 push,pop,call,callv,leave, 453 str,bitmanip, 454 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp, 455 fxch,fistp,fisttp,frndint, 456 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1, 457 ssemul,sseimul,ssediv,sselog,sselog1, 458 sseishft,sseishft1,ssecmp,ssecomi, 459 ssecvt,ssecvt1,sseicvt,sseins, 460 sseshuf,sseshuf1,ssemuladd,sse4arg, 461 lwp,mskmov,msklog, 462 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft" 463 (const_string "other")) 464 465;; Main data type used by the insn 466(define_attr "mode" 467 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF, 468 V2DF,V2SF,V1DF,V8DF" 469 (const_string "unknown")) 470 471;; The CPU unit operations uses. 472(define_attr "unit" "integer,i387,sse,mmx,unknown" 473 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp, 474 fxch,fistp,fisttp,frndint") 475 (const_string "i387") 476 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1, 477 ssemul,sseimul,ssediv,sselog,sselog1, 478 sseishft,sseishft1,ssecmp,ssecomi, 479 ssecvt,ssecvt1,sseicvt,sseins, 480 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov") 481 (const_string "sse") 482 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft") 483 (const_string "mmx") 484 (eq_attr "type" "other") 485 (const_string "unknown")] 486 (const_string "integer"))) 487 488;; The (bounding maximum) length of an instruction immediate. 489(define_attr "length_immediate" "" 490 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave, 491 bitmanip,imulx,msklog,mskmov") 492 (const_int 0) 493 (eq_attr "unit" "i387,sse,mmx") 494 (const_int 0) 495 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1, 496 rotate,rotatex,rotate1,imul,icmp,push,pop") 497 (symbol_ref "ix86_attr_length_immediate_default (insn, true)") 498 (eq_attr "type" "imov,test") 499 (symbol_ref "ix86_attr_length_immediate_default (insn, false)") 500 (eq_attr "type" "call") 501 (if_then_else (match_operand 0 "constant_call_address_operand") 502 (const_int 4) 503 (const_int 0)) 504 (eq_attr "type" "callv") 505 (if_then_else (match_operand 1 "constant_call_address_operand") 506 (const_int 4) 507 (const_int 0)) 508 ;; We don't know the size before shorten_branches. Expect 509 ;; the instruction to fit for better scheduling. 510 (eq_attr "type" "ibr") 511 (const_int 1) 512 ] 513 (symbol_ref "/* Update immediate_length and other attributes! */ 514 gcc_unreachable (),1"))) 515 516;; The (bounding maximum) length of an instruction address. 517(define_attr "length_address" "" 518 (cond [(eq_attr "type" "str,other,multi,fxch") 519 (const_int 0) 520 (and (eq_attr "type" "call") 521 (match_operand 0 "constant_call_address_operand")) 522 (const_int 0) 523 (and (eq_attr "type" "callv") 524 (match_operand 1 "constant_call_address_operand")) 525 (const_int 0) 526 ] 527 (symbol_ref "ix86_attr_length_address_default (insn)"))) 528 529;; Set when length prefix is used. 530(define_attr "prefix_data16" "" 531 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 532 (const_int 0) 533 (eq_attr "mode" "HI") 534 (const_int 1) 535 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI")) 536 (const_int 1) 537 ] 538 (const_int 0))) 539 540;; Set when string REP prefix is used. 541(define_attr "prefix_rep" "" 542 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1") 543 (const_int 0) 544 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF")) 545 (const_int 1) 546 ] 547 (const_int 0))) 548 549;; Set when 0f opcode prefix is used. 550(define_attr "prefix_0f" "" 551 (if_then_else 552 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov") 553 (eq_attr "unit" "sse,mmx")) 554 (const_int 1) 555 (const_int 0))) 556 557;; Set when REX opcode prefix is used. 558(define_attr "prefix_rex" "" 559 (cond [(not (match_test "TARGET_64BIT")) 560 (const_int 0) 561 (and (eq_attr "mode" "DI") 562 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr") 563 (eq_attr "unit" "!mmx"))) 564 (const_int 1) 565 (and (eq_attr "mode" "QI") 566 (match_test "x86_extended_QIreg_mentioned_p (insn)")) 567 (const_int 1) 568 (match_test "x86_extended_reg_mentioned_p (insn)") 569 (const_int 1) 570 (and (eq_attr "type" "imovx") 571 (match_operand:QI 1 "ext_QIreg_operand")) 572 (const_int 1) 573 ] 574 (const_int 0))) 575 576;; There are also additional prefixes in 3DNOW, SSSE3. 577;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte, 578;; sseiadd1,ssecvt1 to 0f7a with no DREX byte. 579;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a. 580(define_attr "prefix_extra" "" 581 (cond [(eq_attr "type" "ssemuladd,sse4arg") 582 (const_int 2) 583 (eq_attr "type" "sseiadd1,ssecvt1") 584 (const_int 1) 585 ] 586 (const_int 0))) 587 588;; Prefix used: original, VEX or maybe VEX. 589(define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex" 590 (cond [(eq_attr "mode" "OI,V8SF,V4DF") 591 (const_string "vex") 592 (eq_attr "mode" "XI,V16SF,V8DF") 593 (const_string "evex") 594 ] 595 (const_string "orig"))) 596 597;; VEX W bit is used. 598(define_attr "prefix_vex_w" "" (const_int 0)) 599 600;; The length of VEX prefix 601;; Only instructions with 0f prefix can have 2 byte VEX prefix, 602;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is 603;; still prefix_0f 1, with prefix_extra 1. 604(define_attr "length_vex" "" 605 (if_then_else (and (eq_attr "prefix_0f" "1") 606 (eq_attr "prefix_extra" "0")) 607 (if_then_else (eq_attr "prefix_vex_w" "1") 608 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)") 609 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)")) 610 (if_then_else (eq_attr "prefix_vex_w" "1") 611 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)") 612 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)")))) 613 614;; 4-bytes evex prefix and 1 byte opcode. 615(define_attr "length_evex" "" (const_int 5)) 616 617;; Set when modrm byte is used. 618(define_attr "modrm" "" 619 (cond [(eq_attr "type" "str,leave") 620 (const_int 0) 621 (eq_attr "unit" "i387") 622 (const_int 0) 623 (and (eq_attr "type" "incdec") 624 (and (not (match_test "TARGET_64BIT")) 625 (ior (match_operand:SI 1 "register_operand") 626 (match_operand:HI 1 "register_operand")))) 627 (const_int 0) 628 (and (eq_attr "type" "push") 629 (not (match_operand 1 "memory_operand"))) 630 (const_int 0) 631 (and (eq_attr "type" "pop") 632 (not (match_operand 0 "memory_operand"))) 633 (const_int 0) 634 (and (eq_attr "type" "imov") 635 (and (not (eq_attr "mode" "DI")) 636 (ior (and (match_operand 0 "register_operand") 637 (match_operand 1 "immediate_operand")) 638 (ior (and (match_operand 0 "ax_reg_operand") 639 (match_operand 1 "memory_displacement_only_operand")) 640 (and (match_operand 0 "memory_displacement_only_operand") 641 (match_operand 1 "ax_reg_operand")))))) 642 (const_int 0) 643 (and (eq_attr "type" "call") 644 (match_operand 0 "constant_call_address_operand")) 645 (const_int 0) 646 (and (eq_attr "type" "callv") 647 (match_operand 1 "constant_call_address_operand")) 648 (const_int 0) 649 (and (eq_attr "type" "alu,alu1,icmp,test") 650 (match_operand 0 "ax_reg_operand")) 651 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))") 652 ] 653 (const_int 1))) 654 655;; The (bounding maximum) length of an instruction in bytes. 656;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences. 657;; Later we may want to split them and compute proper length as for 658;; other insns. 659(define_attr "length" "" 660 (cond [(eq_attr "type" "other,multi,fistp,frndint") 661 (const_int 16) 662 (eq_attr "type" "fcmp") 663 (const_int 4) 664 (eq_attr "unit" "i387") 665 (plus (const_int 2) 666 (plus (attr "prefix_data16") 667 (attr "length_address"))) 668 (ior (eq_attr "prefix" "evex") 669 (and (ior (eq_attr "prefix" "maybe_evex") 670 (eq_attr "prefix" "maybe_vex")) 671 (match_test "TARGET_AVX512F"))) 672 (plus (attr "length_evex") 673 (plus (attr "length_immediate") 674 (plus (attr "modrm") 675 (attr "length_address")))) 676 (ior (eq_attr "prefix" "vex") 677 (and (ior (eq_attr "prefix" "maybe_vex") 678 (eq_attr "prefix" "maybe_evex")) 679 (match_test "TARGET_AVX"))) 680 (plus (attr "length_vex") 681 (plus (attr "length_immediate") 682 (plus (attr "modrm") 683 (attr "length_address"))))] 684 (plus (plus (attr "modrm") 685 (plus (attr "prefix_0f") 686 (plus (attr "prefix_rex") 687 (plus (attr "prefix_extra") 688 (const_int 1))))) 689 (plus (attr "prefix_rep") 690 (plus (attr "prefix_data16") 691 (plus (attr "length_immediate") 692 (attr "length_address"))))))) 693 694;; The `memory' attribute is `none' if no memory is referenced, `load' or 695;; `store' if there is a simple memory reference therein, or `unknown' 696;; if the instruction is complex. 697 698(define_attr "memory" "none,load,store,both,unknown" 699 (cond [(eq_attr "type" "other,multi,str,lwp") 700 (const_string "unknown") 701 (eq_attr "type" "lea,fcmov,fpspc") 702 (const_string "none") 703 (eq_attr "type" "fistp,leave") 704 (const_string "both") 705 (eq_attr "type" "frndint") 706 (const_string "load") 707 (eq_attr "type" "push") 708 (if_then_else (match_operand 1 "memory_operand") 709 (const_string "both") 710 (const_string "store")) 711 (eq_attr "type" "pop") 712 (if_then_else (match_operand 0 "memory_operand") 713 (const_string "both") 714 (const_string "load")) 715 (eq_attr "type" "setcc") 716 (if_then_else (match_operand 0 "memory_operand") 717 (const_string "store") 718 (const_string "none")) 719 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp") 720 (if_then_else (ior (match_operand 0 "memory_operand") 721 (match_operand 1 "memory_operand")) 722 (const_string "load") 723 (const_string "none")) 724 (eq_attr "type" "ibr") 725 (if_then_else (match_operand 0 "memory_operand") 726 (const_string "load") 727 (const_string "none")) 728 (eq_attr "type" "call") 729 (if_then_else (match_operand 0 "constant_call_address_operand") 730 (const_string "none") 731 (const_string "load")) 732 (eq_attr "type" "callv") 733 (if_then_else (match_operand 1 "constant_call_address_operand") 734 (const_string "none") 735 (const_string "load")) 736 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1") 737 (match_operand 1 "memory_operand")) 738 (const_string "both") 739 (and (match_operand 0 "memory_operand") 740 (match_operand 1 "memory_operand")) 741 (const_string "both") 742 (match_operand 0 "memory_operand") 743 (const_string "store") 744 (match_operand 1 "memory_operand") 745 (const_string "load") 746 (and (eq_attr "type" 747 "!alu1,negnot,ishift1,rotate1, 748 imov,imovx,icmp,test,bitmanip, 749 fmov,fcmp,fsgn, 750 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt, 751 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1, 752 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog") 753 (match_operand 2 "memory_operand")) 754 (const_string "load") 755 (and (eq_attr "type" "icmov,ssemuladd,sse4arg") 756 (match_operand 3 "memory_operand")) 757 (const_string "load") 758 ] 759 (const_string "none"))) 760 761;; Indicates if an instruction has both an immediate and a displacement. 762 763(define_attr "imm_disp" "false,true,unknown" 764 (cond [(eq_attr "type" "other,multi") 765 (const_string "unknown") 766 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1") 767 (and (match_operand 0 "memory_displacement_operand") 768 (match_operand 1 "immediate_operand"))) 769 (const_string "true") 770 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv") 771 (and (match_operand 0 "memory_displacement_operand") 772 (match_operand 2 "immediate_operand"))) 773 (const_string "true") 774 ] 775 (const_string "false"))) 776 777;; Indicates if an FP operation has an integer source. 778 779(define_attr "fp_int_src" "false,true" 780 (const_string "false")) 781 782;; Defines rounding mode of an FP operation. 783 784(define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any" 785 (const_string "any")) 786 787;; Define attribute to indicate AVX insns with partial XMM register update. 788(define_attr "avx_partial_xmm_update" "false,true" 789 (const_string "false")) 790 791;; Define attribute to classify add/sub insns that consumes carry flag (CF) 792(define_attr "use_carry" "0,1" (const_string "0")) 793 794;; Define attribute to indicate unaligned ssemov insns 795(define_attr "movu" "0,1" (const_string "0")) 796 797;; Used to control the "enabled" attribute on a per-instruction basis. 798(define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64, 799 sse_noavx,sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx, 800 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f, 801 avx512bw,noavx512bw,avx512dq,noavx512dq, 802 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw" 803 (const_string "base")) 804 805;; Define instruction set of MMX instructions 806(define_attr "mmx_isa" "base,native,sse,sse_noavx,avx" 807 (const_string "base")) 808 809(define_attr "enabled" "" 810 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT") 811 (eq_attr "isa" "x64_sse2") 812 (symbol_ref "TARGET_64BIT && TARGET_SSE2") 813 (eq_attr "isa" "x64_sse4") 814 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1") 815 (eq_attr "isa" "x64_sse4_noavx") 816 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX") 817 (eq_attr "isa" "x64_avx") 818 (symbol_ref "TARGET_64BIT && TARGET_AVX") 819 (eq_attr "isa" "x64_avx512dq") 820 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ") 821 (eq_attr "isa" "x64_avx512bw") 822 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW") 823 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT") 824 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2") 825 (eq_attr "isa" "sse_noavx") 826 (symbol_ref "TARGET_SSE && !TARGET_AVX") 827 (eq_attr "isa" "sse2_noavx") 828 (symbol_ref "TARGET_SSE2 && !TARGET_AVX") 829 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3") 830 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1") 831 (eq_attr "isa" "sse4_noavx") 832 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX") 833 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX") 834 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX") 835 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2") 836 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2") 837 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI") 838 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2") 839 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4") 840 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA") 841 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F") 842 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F") 843 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW") 844 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW") 845 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ") 846 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ") 847 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL") 848 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL") 849 850 (eq_attr "mmx_isa" "native") 851 (symbol_ref "!TARGET_MMX_WITH_SSE") 852 (eq_attr "mmx_isa" "sse") 853 (symbol_ref "TARGET_MMX_WITH_SSE") 854 (eq_attr "mmx_isa" "sse_noavx") 855 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX") 856 (eq_attr "mmx_isa" "avx") 857 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX") 858 ] 859 (const_int 1))) 860 861(define_attr "preferred_for_size" "" (const_int 1)) 862(define_attr "preferred_for_speed" "" (const_int 1)) 863 864;; Describe a user's asm statement. 865(define_asm_attributes 866 [(set_attr "length" "128") 867 (set_attr "type" "multi")]) 868 869(define_code_iterator plusminus [plus minus]) 870 871(define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus]) 872 873(define_code_iterator multdiv [mult div]) 874 875;; Base name for define_insn 876(define_code_attr plusminus_insn 877 [(plus "add") (ss_plus "ssadd") (us_plus "usadd") 878 (minus "sub") (ss_minus "sssub") (us_minus "ussub")]) 879 880;; Base name for insn mnemonic. 881(define_code_attr plusminus_mnemonic 882 [(plus "add") (ss_plus "adds") (us_plus "addus") 883 (minus "sub") (ss_minus "subs") (us_minus "subus")]) 884(define_code_attr multdiv_mnemonic 885 [(mult "mul") (div "div")]) 886 887;; Mark commutative operators as such in constraints. 888(define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%") 889 (minus "") (ss_minus "") (us_minus "")]) 890 891;; Mapping of max and min 892(define_code_iterator maxmin [smax smin umax umin]) 893 894;; Mapping of signed max and min 895(define_code_iterator smaxmin [smax smin]) 896 897;; Mapping of unsigned max and min 898(define_code_iterator umaxmin [umax umin]) 899 900;; Base name for integer and FP insn mnemonic 901(define_code_attr maxmin_int [(smax "maxs") (smin "mins") 902 (umax "maxu") (umin "minu")]) 903(define_code_attr maxmin_float [(smax "max") (smin "min")]) 904 905(define_int_iterator IEEE_MAXMIN 906 [UNSPEC_IEEE_MAX 907 UNSPEC_IEEE_MIN]) 908 909(define_int_attr ieee_maxmin 910 [(UNSPEC_IEEE_MAX "max") 911 (UNSPEC_IEEE_MIN "min")]) 912 913;; Mapping of logic operators 914(define_code_iterator any_logic [and ior xor]) 915(define_code_iterator any_or [ior xor]) 916(define_code_iterator fpint_logic [and xor]) 917 918;; Base name for insn mnemonic. 919(define_code_attr logic [(and "and") (ior "or") (xor "xor")]) 920 921;; Mapping of logic-shift operators 922(define_code_iterator any_lshift [ashift lshiftrt]) 923 924;; Mapping of shift-right operators 925(define_code_iterator any_shiftrt [lshiftrt ashiftrt]) 926 927;; Mapping of all shift operators 928(define_code_iterator any_shift [ashift lshiftrt ashiftrt]) 929 930;; Base name for define_insn 931(define_code_attr shift_insn 932 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")]) 933 934;; Base name for insn mnemonic. 935(define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")]) 936(define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")]) 937 938;; Mapping of rotate operators 939(define_code_iterator any_rotate [rotate rotatert]) 940 941;; Base name for define_insn 942(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")]) 943 944;; Base name for insn mnemonic. 945(define_code_attr rotate [(rotate "rol") (rotatert "ror")]) 946 947;; Mapping of abs neg operators 948(define_code_iterator absneg [abs neg]) 949 950;; Base name for x87 insn mnemonic. 951(define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")]) 952 953;; Used in signed and unsigned widening multiplications. 954(define_code_iterator any_extend [sign_extend zero_extend]) 955 956;; Prefix for insn menmonic. 957(define_code_attr sgnprefix [(sign_extend "i") (zero_extend "") 958 (div "i") (udiv "")]) 959;; Prefix for define_insn 960(define_code_attr s [(sign_extend "s") (zero_extend "u")]) 961(define_code_attr u [(sign_extend "") (zero_extend "u") 962 (div "") (udiv "u")]) 963(define_code_attr u_bool [(sign_extend "false") (zero_extend "true") 964 (div "false") (udiv "true")]) 965 966;; Used in signed and unsigned truncations. 967(define_code_iterator any_truncate [ss_truncate truncate us_truncate]) 968;; Instruction suffix for truncations. 969(define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")]) 970 971;; Used in signed and unsigned fix. 972(define_code_iterator any_fix [fix unsigned_fix]) 973(define_code_attr fixsuffix [(fix "") (unsigned_fix "u")]) 974(define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")]) 975(define_code_attr fixprefix [(fix "s") (unsigned_fix "u")]) 976 977;; Used in signed and unsigned float. 978(define_code_iterator any_float [float unsigned_float]) 979(define_code_attr floatsuffix [(float "") (unsigned_float "u")]) 980(define_code_attr floatunssuffix [(float "") (unsigned_float "uns")]) 981(define_code_attr floatprefix [(float "s") (unsigned_float "u")]) 982 983;; All integer modes. 984(define_mode_iterator SWI1248x [QI HI SI DI]) 985 986;; All integer modes without QImode. 987(define_mode_iterator SWI248x [HI SI DI]) 988 989;; All integer modes without QImode and HImode. 990(define_mode_iterator SWI48x [SI DI]) 991 992;; All integer modes without SImode and DImode. 993(define_mode_iterator SWI12 [QI HI]) 994 995;; All integer modes without DImode. 996(define_mode_iterator SWI124 [QI HI SI]) 997 998;; All integer modes without QImode and DImode. 999(define_mode_iterator SWI24 [HI SI]) 1000 1001;; Single word integer modes. 1002(define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")]) 1003 1004;; Single word integer modes without QImode. 1005(define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")]) 1006 1007;; Single word integer modes without QImode and HImode. 1008(define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")]) 1009 1010;; All math-dependant single and double word integer modes. 1011(define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH") 1012 (HI "TARGET_HIMODE_MATH") 1013 SI DI (TI "TARGET_64BIT")]) 1014 1015;; Math-dependant single word integer modes. 1016(define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH") 1017 (HI "TARGET_HIMODE_MATH") 1018 SI (DI "TARGET_64BIT")]) 1019 1020;; Math-dependant integer modes without DImode. 1021(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH") 1022 (HI "TARGET_HIMODE_MATH") 1023 SI]) 1024 1025;; Math-dependant integer modes with DImode (enabled for 32bit with STV). 1026(define_mode_iterator SWIM1248s 1027 [(QI "TARGET_QIMODE_MATH") 1028 (HI "TARGET_HIMODE_MATH") 1029 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")]) 1030 1031;; Math-dependant single word integer modes without QImode. 1032(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH") 1033 SI (DI "TARGET_64BIT")]) 1034 1035;; Double word integer modes. 1036(define_mode_iterator DWI [(DI "!TARGET_64BIT") 1037 (TI "TARGET_64BIT")]) 1038 1039;; SWI and DWI together. 1040(define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")]) 1041 1042;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not 1043;; compile time constant, it is faster to use <MODE_SIZE> than 1044;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on 1045;; command line options just use GET_MODE_SIZE macro. 1046(define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16") 1047 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)") 1048 (V16QI "16") (V32QI "32") (V64QI "64") 1049 (V8HI "16") (V16HI "32") (V32HI "64") 1050 (V4SI "16") (V8SI "32") (V16SI "64") 1051 (V2DI "16") (V4DI "32") (V8DI "64") 1052 (V1TI "16") (V2TI "32") (V4TI "64") 1053 (V2DF "16") (V4DF "32") (V8DF "64") 1054 (V4SF "16") (V8SF "32") (V16SF "64")]) 1055 1056;; Double word integer modes as mode attribute. 1057(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")]) 1058(define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")]) 1059 1060;; LEA mode corresponding to an integer mode 1061(define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")]) 1062 1063;; Half mode for double word integer modes. 1064(define_mode_iterator DWIH [(SI "!TARGET_64BIT") 1065 (DI "TARGET_64BIT")]) 1066 1067;; Instruction suffix for integer modes. 1068(define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")]) 1069 1070;; Instruction suffix for masks. 1071(define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")]) 1072 1073;; Pointer size prefix for integer modes (Intel asm dialect) 1074(define_mode_attr iptrsize [(QI "BYTE") 1075 (HI "WORD") 1076 (SI "DWORD") 1077 (DI "QWORD")]) 1078 1079;; Register class for integer modes. 1080(define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")]) 1081 1082;; Immediate operand constraint for integer modes. 1083(define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")]) 1084 1085;; General operand constraint for word modes. 1086(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")]) 1087 1088;; Immediate operand constraint for double integer modes. 1089(define_mode_attr di [(SI "nF") (DI "Wd")]) 1090 1091;; Immediate operand constraint for shifts. 1092(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")]) 1093 1094;; Print register name in the specified mode. 1095(define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")]) 1096 1097;; General operand predicate for integer modes. 1098(define_mode_attr general_operand 1099 [(QI "general_operand") 1100 (HI "general_operand") 1101 (SI "x86_64_general_operand") 1102 (DI "x86_64_general_operand") 1103 (TI "x86_64_general_operand")]) 1104 1105;; General operand predicate for integer modes, where for TImode 1106;; we need both words of the operand to be general operands. 1107(define_mode_attr general_hilo_operand 1108 [(QI "general_operand") 1109 (HI "general_operand") 1110 (SI "x86_64_general_operand") 1111 (DI "x86_64_general_operand") 1112 (TI "x86_64_hilo_general_operand")]) 1113 1114;; General sign extend operand predicate for integer modes, 1115;; which disallows VOIDmode operands and thus it is suitable 1116;; for use inside sign_extend. 1117(define_mode_attr general_sext_operand 1118 [(QI "sext_operand") 1119 (HI "sext_operand") 1120 (SI "x86_64_sext_operand") 1121 (DI "x86_64_sext_operand")]) 1122 1123;; General sign/zero extend operand predicate for integer modes. 1124(define_mode_attr general_szext_operand 1125 [(QI "general_operand") 1126 (HI "general_operand") 1127 (SI "x86_64_szext_general_operand") 1128 (DI "x86_64_szext_general_operand")]) 1129 1130(define_mode_attr nonmemory_szext_operand 1131 [(QI "nonmemory_operand") 1132 (HI "nonmemory_operand") 1133 (SI "x86_64_szext_nonmemory_operand") 1134 (DI "x86_64_szext_nonmemory_operand")]) 1135 1136;; Immediate operand predicate for integer modes. 1137(define_mode_attr immediate_operand 1138 [(QI "immediate_operand") 1139 (HI "immediate_operand") 1140 (SI "x86_64_immediate_operand") 1141 (DI "x86_64_immediate_operand")]) 1142 1143;; Nonmemory operand predicate for integer modes. 1144(define_mode_attr nonmemory_operand 1145 [(QI "nonmemory_operand") 1146 (HI "nonmemory_operand") 1147 (SI "x86_64_nonmemory_operand") 1148 (DI "x86_64_nonmemory_operand")]) 1149 1150;; Operand predicate for shifts. 1151(define_mode_attr shift_operand 1152 [(QI "nonimmediate_operand") 1153 (HI "nonimmediate_operand") 1154 (SI "nonimmediate_operand") 1155 (DI "shiftdi_operand") 1156 (TI "register_operand")]) 1157 1158;; Operand predicate for shift argument. 1159(define_mode_attr shift_immediate_operand 1160 [(QI "const_1_to_31_operand") 1161 (HI "const_1_to_31_operand") 1162 (SI "const_1_to_31_operand") 1163 (DI "const_1_to_63_operand")]) 1164 1165;; Input operand predicate for arithmetic left shifts. 1166(define_mode_attr ashl_input_operand 1167 [(QI "nonimmediate_operand") 1168 (HI "nonimmediate_operand") 1169 (SI "nonimmediate_operand") 1170 (DI "ashldi_input_operand") 1171 (TI "reg_or_pm1_operand")]) 1172 1173;; SSE and x87 SFmode and DFmode floating point modes 1174(define_mode_iterator MODEF [SF DF]) 1175 1176;; All x87 floating point modes 1177(define_mode_iterator X87MODEF [SF DF XF]) 1178 1179;; All SSE floating point modes 1180(define_mode_iterator SSEMODEF [SF DF TF]) 1181(define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")]) 1182 1183;; SSE instruction suffix for various modes 1184(define_mode_attr ssemodesuffix 1185 [(SF "ss") (DF "sd") 1186 (V16SF "ps") (V8DF "pd") 1187 (V8SF "ps") (V4DF "pd") 1188 (V4SF "ps") (V2DF "pd") 1189 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q") 1190 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q") 1191 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")]) 1192 1193;; SSE vector suffix for floating point modes 1194(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")]) 1195 1196;; SSE vector mode corresponding to a scalar mode 1197(define_mode_attr ssevecmode 1198 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")]) 1199(define_mode_attr ssevecmodelower 1200 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")]) 1201 1202;; AVX512F vector mode corresponding to a scalar mode 1203(define_mode_attr avx512fvecmode 1204 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")]) 1205 1206;; Instruction suffix for REX 64bit operators. 1207(define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")]) 1208(define_mode_attr rex64namesuffix [(SI "") (DI "q")]) 1209 1210;; This mode iterator allows :P to be used for patterns that operate on 1211;; pointer-sized quantities. Exactly one of the two alternatives will match. 1212(define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) 1213 1214;; This mode iterator allows :W to be used for patterns that operate on 1215;; word_mode sized quantities. 1216(define_mode_iterator W 1217 [(SI "word_mode == SImode") (DI "word_mode == DImode")]) 1218 1219;; This mode iterator allows :PTR to be used for patterns that operate on 1220;; ptr_mode sized quantities. 1221(define_mode_iterator PTR 1222 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")]) 1223 1224;; Scheduling descriptions 1225 1226(include "pentium.md") 1227(include "ppro.md") 1228(include "k6.md") 1229(include "athlon.md") 1230(include "bdver1.md") 1231(include "bdver3.md") 1232(include "btver2.md") 1233(include "znver1.md") 1234(include "geode.md") 1235(include "atom.md") 1236(include "slm.md") 1237(include "glm.md") 1238(include "core2.md") 1239(include "haswell.md") 1240 1241 1242;; Operand and operator predicates and constraints 1243 1244(include "predicates.md") 1245(include "constraints.md") 1246 1247 1248;; Compare and branch/compare and store instructions. 1249 1250(define_expand "cbranch<mode>4" 1251 [(set (reg:CC FLAGS_REG) 1252 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand") 1253 (match_operand:SDWIM 2 "<general_operand>"))) 1254 (set (pc) (if_then_else 1255 (match_operator 0 "ordered_comparison_operator" 1256 [(reg:CC FLAGS_REG) (const_int 0)]) 1257 (label_ref (match_operand 3)) 1258 (pc)))] 1259 "" 1260{ 1261 if (MEM_P (operands[1]) && MEM_P (operands[2])) 1262 operands[1] = force_reg (<MODE>mode, operands[1]); 1263 ix86_expand_branch (GET_CODE (operands[0]), 1264 operands[1], operands[2], operands[3]); 1265 DONE; 1266}) 1267 1268(define_expand "cstore<mode>4" 1269 [(set (reg:CC FLAGS_REG) 1270 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand") 1271 (match_operand:SWIM 3 "<general_operand>"))) 1272 (set (match_operand:QI 0 "register_operand") 1273 (match_operator 1 "ordered_comparison_operator" 1274 [(reg:CC FLAGS_REG) (const_int 0)]))] 1275 "" 1276{ 1277 if (MEM_P (operands[2]) && MEM_P (operands[3])) 1278 operands[2] = force_reg (<MODE>mode, operands[2]); 1279 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1280 operands[2], operands[3]); 1281 DONE; 1282}) 1283 1284(define_expand "@cmp<mode>_1" 1285 [(set (reg:CC FLAGS_REG) 1286 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand") 1287 (match_operand:SWI48 1 "<general_operand>")))]) 1288 1289(define_mode_iterator SWI1248_AVX512BWDQ_64 1290 [(QI "TARGET_AVX512DQ") HI 1291 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")]) 1292 1293(define_insn "*cmp<mode>_ccz_1" 1294 [(set (reg FLAGS_REG) 1295 (compare (match_operand:SWI1248_AVX512BWDQ_64 0 1296 "nonimmediate_operand" "<r>,?m<r>,$k") 1297 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))] 1298 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)" 1299 "@ 1300 test{<imodesuffix>}\t%0, %0 1301 cmp{<imodesuffix>}\t{%1, %0|%0, %1} 1302 kortest<mskmodesuffix>\t%0, %0" 1303 [(set_attr "type" "test,icmp,msklog") 1304 (set_attr "length_immediate" "0,1,*") 1305 (set_attr "prefix" "*,*,vex") 1306 (set_attr "mode" "<MODE>")]) 1307 1308(define_insn "*cmp<mode>_ccno_1" 1309 [(set (reg FLAGS_REG) 1310 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>") 1311 (match_operand:SWI 1 "const0_operand")))] 1312 "ix86_match_ccmode (insn, CCNOmode)" 1313 "@ 1314 test{<imodesuffix>}\t%0, %0 1315 cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1316 [(set_attr "type" "test,icmp") 1317 (set_attr "length_immediate" "0,1") 1318 (set_attr "mode" "<MODE>")]) 1319 1320(define_insn "*cmp<mode>_1" 1321 [(set (reg FLAGS_REG) 1322 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 1323 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))] 1324 "ix86_match_ccmode (insn, CCmode)" 1325 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1326 [(set_attr "type" "icmp") 1327 (set_attr "mode" "<MODE>")]) 1328 1329(define_insn "*cmp<mode>_minus_1" 1330 [(set (reg FLAGS_REG) 1331 (compare 1332 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>") 1333 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")) 1334 (const_int 0)))] 1335 "ix86_match_ccmode (insn, CCGOCmode)" 1336 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}" 1337 [(set_attr "type" "icmp") 1338 (set_attr "mode" "<MODE>")]) 1339 1340(define_insn "*cmpqi_ext_1" 1341 [(set (reg FLAGS_REG) 1342 (compare 1343 (match_operand:QI 0 "nonimmediate_operand" "QBc,m") 1344 (subreg:QI 1345 (zero_extract:SI 1346 (match_operand 1 "ext_register_operand" "Q,Q") 1347 (const_int 8) 1348 (const_int 8)) 0)))] 1349 "ix86_match_ccmode (insn, CCmode)" 1350 "cmp{b}\t{%h1, %0|%0, %h1}" 1351 [(set_attr "isa" "*,nox64") 1352 (set_attr "type" "icmp") 1353 (set_attr "mode" "QI")]) 1354 1355(define_insn "*cmpqi_ext_2" 1356 [(set (reg FLAGS_REG) 1357 (compare 1358 (subreg:QI 1359 (zero_extract:SI 1360 (match_operand 0 "ext_register_operand" "Q") 1361 (const_int 8) 1362 (const_int 8)) 0) 1363 (match_operand:QI 1 "const0_operand")))] 1364 "ix86_match_ccmode (insn, CCNOmode)" 1365 "test{b}\t%h0, %h0" 1366 [(set_attr "type" "test") 1367 (set_attr "length_immediate" "0") 1368 (set_attr "mode" "QI")]) 1369 1370(define_expand "cmpqi_ext_3" 1371 [(set (reg:CC FLAGS_REG) 1372 (compare:CC 1373 (subreg:QI 1374 (zero_extract:SI 1375 (match_operand 0 "ext_register_operand") 1376 (const_int 8) 1377 (const_int 8)) 0) 1378 (match_operand:QI 1 "const_int_operand")))]) 1379 1380(define_insn "*cmpqi_ext_3" 1381 [(set (reg FLAGS_REG) 1382 (compare 1383 (subreg:QI 1384 (zero_extract:SI 1385 (match_operand 0 "ext_register_operand" "Q,Q") 1386 (const_int 8) 1387 (const_int 8)) 0) 1388 (match_operand:QI 1 "general_operand" "QnBc,m")))] 1389 "ix86_match_ccmode (insn, CCmode)" 1390 "cmp{b}\t{%1, %h0|%h0, %1}" 1391 [(set_attr "isa" "*,nox64") 1392 (set_attr "type" "icmp") 1393 (set_attr "mode" "QI")]) 1394 1395(define_insn "*cmpqi_ext_4" 1396 [(set (reg FLAGS_REG) 1397 (compare 1398 (subreg:QI 1399 (zero_extract:SI 1400 (match_operand 0 "ext_register_operand" "Q") 1401 (const_int 8) 1402 (const_int 8)) 0) 1403 (subreg:QI 1404 (zero_extract:SI 1405 (match_operand 1 "ext_register_operand" "Q") 1406 (const_int 8) 1407 (const_int 8)) 0)))] 1408 "ix86_match_ccmode (insn, CCmode)" 1409 "cmp{b}\t{%h1, %h0|%h0, %h1}" 1410 [(set_attr "type" "icmp") 1411 (set_attr "mode" "QI")]) 1412 1413;; These implement float point compares. 1414;; %%% See if we can get away with VOIDmode operands on the actual insns, 1415;; which would allow mix and match FP modes on the compares. Which is what 1416;; the old patterns did, but with many more of them. 1417 1418(define_expand "cbranchxf4" 1419 [(set (reg:CC FLAGS_REG) 1420 (compare:CC (match_operand:XF 1 "nonmemory_operand") 1421 (match_operand:XF 2 "nonmemory_operand"))) 1422 (set (pc) (if_then_else 1423 (match_operator 0 "ix86_fp_comparison_operator" 1424 [(reg:CC FLAGS_REG) 1425 (const_int 0)]) 1426 (label_ref (match_operand 3)) 1427 (pc)))] 1428 "TARGET_80387" 1429{ 1430 ix86_expand_branch (GET_CODE (operands[0]), 1431 operands[1], operands[2], operands[3]); 1432 DONE; 1433}) 1434 1435(define_expand "cstorexf4" 1436 [(set (reg:CC FLAGS_REG) 1437 (compare:CC (match_operand:XF 2 "nonmemory_operand") 1438 (match_operand:XF 3 "nonmemory_operand"))) 1439 (set (match_operand:QI 0 "register_operand") 1440 (match_operator 1 "ix86_fp_comparison_operator" 1441 [(reg:CC FLAGS_REG) 1442 (const_int 0)]))] 1443 "TARGET_80387" 1444{ 1445 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1446 operands[2], operands[3]); 1447 DONE; 1448}) 1449 1450(define_expand "cbranch<mode>4" 1451 [(set (reg:CC FLAGS_REG) 1452 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand") 1453 (match_operand:MODEF 2 "cmp_fp_expander_operand"))) 1454 (set (pc) (if_then_else 1455 (match_operator 0 "ix86_fp_comparison_operator" 1456 [(reg:CC FLAGS_REG) 1457 (const_int 0)]) 1458 (label_ref (match_operand 3)) 1459 (pc)))] 1460 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1461{ 1462 ix86_expand_branch (GET_CODE (operands[0]), 1463 operands[1], operands[2], operands[3]); 1464 DONE; 1465}) 1466 1467(define_expand "cstore<mode>4" 1468 [(set (reg:CC FLAGS_REG) 1469 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand") 1470 (match_operand:MODEF 3 "cmp_fp_expander_operand"))) 1471 (set (match_operand:QI 0 "register_operand") 1472 (match_operator 1 "ix86_fp_comparison_operator" 1473 [(reg:CC FLAGS_REG) 1474 (const_int 0)]))] 1475 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 1476{ 1477 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1478 operands[2], operands[3]); 1479 DONE; 1480}) 1481 1482(define_expand "cbranchcc4" 1483 [(set (pc) (if_then_else 1484 (match_operator 0 "comparison_operator" 1485 [(match_operand 1 "flags_reg_operand") 1486 (match_operand 2 "const0_operand")]) 1487 (label_ref (match_operand 3)) 1488 (pc)))] 1489 "" 1490{ 1491 ix86_expand_branch (GET_CODE (operands[0]), 1492 operands[1], operands[2], operands[3]); 1493 DONE; 1494}) 1495 1496(define_expand "cstorecc4" 1497 [(set (match_operand:QI 0 "register_operand") 1498 (match_operator 1 "comparison_operator" 1499 [(match_operand 2 "flags_reg_operand") 1500 (match_operand 3 "const0_operand")]))] 1501 "" 1502{ 1503 ix86_expand_setcc (operands[0], GET_CODE (operands[1]), 1504 operands[2], operands[3]); 1505 DONE; 1506}) 1507 1508;; FP compares, step 1: 1509;; Set the FP condition codes and move fpsr to ax. 1510 1511;; We may not use "#" to split and emit these 1512;; due to reg-stack pops killing fpsr. 1513 1514(define_insn "*cmpxf_i387" 1515 [(set (match_operand:HI 0 "register_operand" "=a") 1516 (unspec:HI 1517 [(compare:CCFP 1518 (match_operand:XF 1 "register_operand" "f") 1519 (match_operand:XF 2 "reg_or_0_operand" "fC"))] 1520 UNSPEC_FNSTSW))] 1521 "TARGET_80387" 1522 "* return output_fp_compare (insn, operands, false, false);" 1523 [(set_attr "type" "multi") 1524 (set_attr "unit" "i387") 1525 (set_attr "mode" "XF")]) 1526 1527(define_insn "*cmp<mode>_i387" 1528 [(set (match_operand:HI 0 "register_operand" "=a") 1529 (unspec:HI 1530 [(compare:CCFP 1531 (match_operand:MODEF 1 "register_operand" "f") 1532 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))] 1533 UNSPEC_FNSTSW))] 1534 "TARGET_80387" 1535 "* return output_fp_compare (insn, operands, false, false);" 1536 [(set_attr "type" "multi") 1537 (set_attr "unit" "i387") 1538 (set_attr "mode" "<MODE>")]) 1539 1540(define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387" 1541 [(set (match_operand:HI 0 "register_operand" "=a") 1542 (unspec:HI 1543 [(compare:CCFP 1544 (match_operand:X87MODEF 1 "register_operand" "f") 1545 (float:X87MODEF 1546 (match_operand:SWI24 2 "nonimmediate_operand" "m")))] 1547 UNSPEC_FNSTSW))] 1548 "TARGET_80387 1549 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 1550 || optimize_function_for_size_p (cfun))" 1551 "* return output_fp_compare (insn, operands, false, false);" 1552 [(set_attr "type" "multi") 1553 (set_attr "unit" "i387") 1554 (set_attr "fp_int_src" "true") 1555 (set_attr "mode" "<SWI24:MODE>")]) 1556 1557(define_insn "*cmpu<mode>_i387" 1558 [(set (match_operand:HI 0 "register_operand" "=a") 1559 (unspec:HI 1560 [(unspec:CCFP 1561 [(compare:CCFP 1562 (match_operand:X87MODEF 1 "register_operand" "f") 1563 (match_operand:X87MODEF 2 "register_operand" "f"))] 1564 UNSPEC_NOTRAP)] 1565 UNSPEC_FNSTSW))] 1566 "TARGET_80387" 1567 "* return output_fp_compare (insn, operands, false, true);" 1568 [(set_attr "type" "multi") 1569 (set_attr "unit" "i387") 1570 (set_attr "mode" "<MODE>")]) 1571 1572;; FP compares, step 2: 1573;; Get ax into flags, general case. 1574 1575(define_insn "x86_sahf_1" 1576 [(set (reg:CC FLAGS_REG) 1577 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] 1578 UNSPEC_SAHF))] 1579 "TARGET_SAHF" 1580{ 1581#ifndef HAVE_AS_IX86_SAHF 1582 if (TARGET_64BIT) 1583 return ASM_BYTE "0x9e"; 1584 else 1585#endif 1586 return "sahf"; 1587} 1588 [(set_attr "length" "1") 1589 (set_attr "athlon_decode" "vector") 1590 (set_attr "amdfam10_decode" "direct") 1591 (set_attr "bdver1_decode" "direct") 1592 (set_attr "mode" "SI")]) 1593 1594;; Pentium Pro can do both steps in one go. 1595;; (these instructions set flags directly) 1596 1597(define_subst_attr "unord" "unord_subst" "" "u") 1598(define_subst_attr "unordered" "unord_subst" "false" "true") 1599 1600(define_subst "unord_subst" 1601 [(set (match_operand:CCFP 0) 1602 (match_operand:CCFP 1))] 1603 "" 1604 [(set (match_dup 0) 1605 (unspec:CCFP 1606 [(match_dup 1)] 1607 UNSPEC_NOTRAP))]) 1608 1609(define_insn "*cmpi<unord>xf_i387" 1610 [(set (reg:CCFP FLAGS_REG) 1611 (compare:CCFP 1612 (match_operand:XF 0 "register_operand" "f") 1613 (match_operand:XF 1 "register_operand" "f")))] 1614 "TARGET_80387 && TARGET_CMOVE" 1615 "* return output_fp_compare (insn, operands, true, <unordered>);" 1616 [(set_attr "type" "fcmp") 1617 (set_attr "mode" "XF") 1618 (set_attr "athlon_decode" "vector") 1619 (set_attr "amdfam10_decode" "direct") 1620 (set_attr "bdver1_decode" "double") 1621 (set_attr "znver1_decode" "double")]) 1622 1623(define_insn "*cmpi<unord><MODEF:mode>" 1624 [(set (reg:CCFP FLAGS_REG) 1625 (compare:CCFP 1626 (match_operand:MODEF 0 "register_operand" "f,v") 1627 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))] 1628 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH) 1629 || (TARGET_80387 && TARGET_CMOVE)" 1630 "@ 1631 * return output_fp_compare (insn, operands, true, <unordered>); 1632 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}" 1633 [(set_attr "type" "fcmp,ssecomi") 1634 (set_attr "prefix" "orig,maybe_vex") 1635 (set_attr "mode" "<MODEF:MODE>") 1636 (set_attr "prefix_rep" "*,0") 1637 (set (attr "prefix_data16") 1638 (cond [(eq_attr "alternative" "0") 1639 (const_string "*") 1640 (eq_attr "mode" "DF") 1641 (const_string "1") 1642 ] 1643 (const_string "0"))) 1644 (set_attr "athlon_decode" "vector") 1645 (set_attr "amdfam10_decode" "direct") 1646 (set_attr "bdver1_decode" "double") 1647 (set_attr "znver1_decode" "double") 1648 (set (attr "enabled") 1649 (if_then_else 1650 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")) 1651 (if_then_else 1652 (eq_attr "alternative" "0") 1653 (symbol_ref "TARGET_MIX_SSE_I387") 1654 (symbol_ref "true")) 1655 (if_then_else 1656 (eq_attr "alternative" "0") 1657 (symbol_ref "true") 1658 (symbol_ref "false"))))]) 1659 1660;; Push/pop instructions. 1661 1662(define_insn "*push<mode>2" 1663 [(set (match_operand:DWI 0 "push_operand" "=<") 1664 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))] 1665 "" 1666 "#" 1667 [(set_attr "type" "multi") 1668 (set_attr "mode" "<MODE>")]) 1669 1670(define_split 1671 [(set (match_operand:DWI 0 "push_operand") 1672 (match_operand:DWI 1 "general_gr_operand"))] 1673 "reload_completed" 1674 [(const_int 0)] 1675 "ix86_split_long_move (operands); DONE;") 1676 1677(define_insn "*pushdi2_rex64" 1678 [(set (match_operand:DI 0 "push_operand" "=<,!<") 1679 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))] 1680 "TARGET_64BIT" 1681 "@ 1682 push{q}\t%1 1683 #" 1684 [(set_attr "type" "push,multi") 1685 (set_attr "mode" "DI")]) 1686 1687;; Convert impossible pushes of immediate to existing instructions. 1688;; First try to get scratch register and go through it. In case this 1689;; fails, push sign extended lower part first and then overwrite 1690;; upper part by 32bit move. 1691 1692(define_peephole2 1693 [(match_scratch:DI 2 "r") 1694 (set (match_operand:DI 0 "push_operand") 1695 (match_operand:DI 1 "immediate_operand"))] 1696 "TARGET_64BIT 1697 && !symbolic_operand (operands[1], DImode) 1698 && !x86_64_immediate_operand (operands[1], DImode)" 1699 [(set (match_dup 2) (match_dup 1)) 1700 (set (match_dup 0) (match_dup 2))]) 1701 1702(define_split 1703 [(set (match_operand:DI 0 "push_operand") 1704 (match_operand:DI 1 "immediate_operand"))] 1705 "TARGET_64BIT && epilogue_completed 1706 && !symbolic_operand (operands[1], DImode) 1707 && !x86_64_immediate_operand (operands[1], DImode)" 1708 [(set (match_dup 0) (match_dup 1)) 1709 (set (match_dup 2) (match_dup 3))] 1710{ 1711 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]); 1712 1713 operands[1] = gen_lowpart (DImode, operands[2]); 1714 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx, 1715 GEN_INT (4))); 1716}) 1717 1718(define_insn "*pushsi2" 1719 [(set (match_operand:SI 0 "push_operand" "=<") 1720 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))] 1721 "!TARGET_64BIT" 1722 "push{l}\t%1" 1723 [(set_attr "type" "push") 1724 (set_attr "mode" "SI")]) 1725 1726;; emit_push_insn when it calls move_by_pieces requires an insn to 1727;; "push a byte/word". But actually we use pushl, which has the effect 1728;; of rounding the amount pushed up to a word. 1729 1730;; For TARGET_64BIT we always round up to 8 bytes. 1731(define_insn "*push<mode>2_rex64" 1732 [(set (match_operand:SWI124 0 "push_operand" "=X") 1733 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))] 1734 "TARGET_64BIT" 1735 "push{q}\t%q1" 1736 [(set_attr "type" "push") 1737 (set_attr "mode" "DI")]) 1738 1739(define_insn "*push<mode>2" 1740 [(set (match_operand:SWI12 0 "push_operand" "=X") 1741 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))] 1742 "!TARGET_64BIT" 1743 "push{l}\t%k1" 1744 [(set_attr "type" "push") 1745 (set_attr "mode" "SI")]) 1746 1747(define_insn "*push<mode>2_prologue" 1748 [(set (match_operand:W 0 "push_operand" "=<") 1749 (match_operand:W 1 "general_no_elim_operand" "r<i>*m")) 1750 (clobber (mem:BLK (scratch)))] 1751 "" 1752 "push{<imodesuffix>}\t%1" 1753 [(set_attr "type" "push") 1754 (set_attr "mode" "<MODE>")]) 1755 1756(define_insn "*pop<mode>1" 1757 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m") 1758 (match_operand:W 1 "pop_operand" ">"))] 1759 "" 1760 "pop{<imodesuffix>}\t%0" 1761 [(set_attr "type" "pop") 1762 (set_attr "mode" "<MODE>")]) 1763 1764(define_insn "*pop<mode>1_epilogue" 1765 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m") 1766 (match_operand:W 1 "pop_operand" ">")) 1767 (clobber (mem:BLK (scratch)))] 1768 "" 1769 "pop{<imodesuffix>}\t%0" 1770 [(set_attr "type" "pop") 1771 (set_attr "mode" "<MODE>")]) 1772 1773(define_insn "*pushfl<mode>2" 1774 [(set (match_operand:W 0 "push_operand" "=<") 1775 (match_operand:W 1 "flags_reg_operand"))] 1776 "" 1777 "pushf{<imodesuffix>}" 1778 [(set_attr "type" "push") 1779 (set_attr "mode" "<MODE>")]) 1780 1781(define_insn "*popfl<mode>1" 1782 [(set (match_operand:W 0 "flags_reg_operand") 1783 (match_operand:W 1 "pop_operand" ">"))] 1784 "" 1785 "popf{<imodesuffix>}" 1786 [(set_attr "type" "pop") 1787 (set_attr "mode" "<MODE>")]) 1788 1789 1790;; Reload patterns to support multi-word load/store 1791;; with non-offsetable address. 1792(define_expand "reload_noff_store" 1793 [(parallel [(match_operand 0 "memory_operand" "=m") 1794 (match_operand 1 "register_operand" "r") 1795 (match_operand:DI 2 "register_operand" "=&r")])] 1796 "TARGET_64BIT" 1797{ 1798 rtx mem = operands[0]; 1799 rtx addr = XEXP (mem, 0); 1800 1801 emit_move_insn (operands[2], addr); 1802 mem = replace_equiv_address_nv (mem, operands[2]); 1803 1804 emit_insn (gen_rtx_SET (mem, operands[1])); 1805 DONE; 1806}) 1807 1808(define_expand "reload_noff_load" 1809 [(parallel [(match_operand 0 "register_operand" "=r") 1810 (match_operand 1 "memory_operand" "m") 1811 (match_operand:DI 2 "register_operand" "=r")])] 1812 "TARGET_64BIT" 1813{ 1814 rtx mem = operands[1]; 1815 rtx addr = XEXP (mem, 0); 1816 1817 emit_move_insn (operands[2], addr); 1818 mem = replace_equiv_address_nv (mem, operands[2]); 1819 1820 emit_insn (gen_rtx_SET (operands[0], mem)); 1821 DONE; 1822}) 1823 1824;; Move instructions. 1825 1826(define_expand "movxi" 1827 [(set (match_operand:XI 0 "nonimmediate_operand") 1828 (match_operand:XI 1 "general_operand"))] 1829 "TARGET_AVX512F" 1830 "ix86_expand_vector_move (XImode, operands); DONE;") 1831 1832(define_expand "movoi" 1833 [(set (match_operand:OI 0 "nonimmediate_operand") 1834 (match_operand:OI 1 "general_operand"))] 1835 "TARGET_AVX" 1836 "ix86_expand_vector_move (OImode, operands); DONE;") 1837 1838(define_expand "movti" 1839 [(set (match_operand:TI 0 "nonimmediate_operand") 1840 (match_operand:TI 1 "general_operand"))] 1841 "TARGET_64BIT || TARGET_SSE" 1842{ 1843 if (TARGET_64BIT) 1844 ix86_expand_move (TImode, operands); 1845 else 1846 ix86_expand_vector_move (TImode, operands); 1847 DONE; 1848}) 1849 1850;; This expands to what emit_move_complex would generate if we didn't 1851;; have a movti pattern. Having this avoids problems with reload on 1852;; 32-bit targets when SSE is present, but doesn't seem to be harmful 1853;; to have around all the time. 1854(define_expand "movcdi" 1855 [(set (match_operand:CDI 0 "nonimmediate_operand") 1856 (match_operand:CDI 1 "general_operand"))] 1857 "" 1858{ 1859 if (push_operand (operands[0], CDImode)) 1860 emit_move_complex_push (CDImode, operands[0], operands[1]); 1861 else 1862 emit_move_complex_parts (operands[0], operands[1]); 1863 DONE; 1864}) 1865 1866(define_expand "mov<mode>" 1867 [(set (match_operand:SWI1248x 0 "nonimmediate_operand") 1868 (match_operand:SWI1248x 1 "general_operand"))] 1869 "" 1870 "ix86_expand_move (<MODE>mode, operands); DONE;") 1871 1872(define_insn "*mov<mode>_xor" 1873 [(set (match_operand:SWI48 0 "register_operand" "=r") 1874 (match_operand:SWI48 1 "const0_operand")) 1875 (clobber (reg:CC FLAGS_REG))] 1876 "reload_completed" 1877 "xor{l}\t%k0, %k0" 1878 [(set_attr "type" "alu1") 1879 (set_attr "mode" "SI") 1880 (set_attr "length_immediate" "0")]) 1881 1882(define_insn "*mov<mode>_or" 1883 [(set (match_operand:SWI48 0 "register_operand" "=r") 1884 (match_operand:SWI48 1 "constm1_operand")) 1885 (clobber (reg:CC FLAGS_REG))] 1886 "reload_completed" 1887 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 1888 [(set_attr "type" "alu1") 1889 (set_attr "mode" "<MODE>") 1890 (set_attr "length_immediate" "1")]) 1891 1892(define_insn "*movxi_internal_avx512f" 1893 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m") 1894 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))] 1895 "TARGET_AVX512F 1896 && (register_operand (operands[0], XImode) 1897 || register_operand (operands[1], XImode))" 1898{ 1899 switch (get_attr_type (insn)) 1900 { 1901 case TYPE_SSELOG1: 1902 return standard_sse_constant_opcode (insn, operands); 1903 1904 case TYPE_SSEMOV: 1905 return ix86_output_ssemov (insn, operands); 1906 1907 default: 1908 gcc_unreachable (); 1909 } 1910} 1911 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov") 1912 (set_attr "prefix" "evex") 1913 (set_attr "mode" "XI")]) 1914 1915(define_insn "*movoi_internal_avx" 1916 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m") 1917 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))] 1918 "TARGET_AVX 1919 && (register_operand (operands[0], OImode) 1920 || register_operand (operands[1], OImode))" 1921{ 1922 switch (get_attr_type (insn)) 1923 { 1924 case TYPE_SSELOG1: 1925 return standard_sse_constant_opcode (insn, operands); 1926 1927 case TYPE_SSEMOV: 1928 return ix86_output_ssemov (insn, operands); 1929 1930 default: 1931 gcc_unreachable (); 1932 } 1933} 1934 [(set_attr "isa" "*,avx2,*,*") 1935 (set_attr "type" "sselog1,sselog1,ssemov,ssemov") 1936 (set_attr "prefix" "vex") 1937 (set_attr "mode" "OI")]) 1938 1939(define_insn "*movti_internal" 1940 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd") 1941 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))] 1942 "(TARGET_64BIT 1943 && !(MEM_P (operands[0]) && MEM_P (operands[1]))) 1944 || (TARGET_SSE 1945 && nonimmediate_or_sse_const_operand (operands[1], TImode) 1946 && (register_operand (operands[0], TImode) 1947 || register_operand (operands[1], TImode)))" 1948{ 1949 switch (get_attr_type (insn)) 1950 { 1951 case TYPE_MULTI: 1952 return "#"; 1953 1954 case TYPE_SSELOG1: 1955 return standard_sse_constant_opcode (insn, operands); 1956 1957 case TYPE_SSEMOV: 1958 return ix86_output_ssemov (insn, operands); 1959 1960 default: 1961 gcc_unreachable (); 1962 } 1963} 1964 [(set (attr "isa") 1965 (cond [(eq_attr "alternative" "0,1,6,7") 1966 (const_string "x64") 1967 (eq_attr "alternative" "3") 1968 (const_string "sse2") 1969 ] 1970 (const_string "*"))) 1971 (set (attr "type") 1972 (cond [(eq_attr "alternative" "0,1,6,7") 1973 (const_string "multi") 1974 (eq_attr "alternative" "2,3") 1975 (const_string "sselog1") 1976 ] 1977 (const_string "ssemov"))) 1978 (set (attr "prefix") 1979 (if_then_else (eq_attr "type" "sselog1,ssemov") 1980 (const_string "maybe_vex") 1981 (const_string "orig"))) 1982 (set (attr "mode") 1983 (cond [(eq_attr "alternative" "0,1") 1984 (const_string "DI") 1985 (match_test "TARGET_AVX") 1986 (const_string "TI") 1987 (ior (not (match_test "TARGET_SSE2")) 1988 (match_test "optimize_function_for_size_p (cfun)")) 1989 (const_string "V4SF") 1990 (and (eq_attr "alternative" "5") 1991 (match_test "TARGET_SSE_TYPELESS_STORES")) 1992 (const_string "V4SF") 1993 ] 1994 (const_string "TI"))) 1995 (set (attr "preferred_for_speed") 1996 (cond [(eq_attr "alternative" "6") 1997 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 1998 (eq_attr "alternative" "7") 1999 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC") 2000 ] 2001 (symbol_ref "true")))]) 2002 2003(define_split 2004 [(set (match_operand:TI 0 "sse_reg_operand") 2005 (match_operand:TI 1 "general_reg_operand"))] 2006 "TARGET_64BIT && TARGET_SSE4_1 2007 && reload_completed" 2008 [(set (match_dup 2) 2009 (vec_merge:V2DI 2010 (vec_duplicate:V2DI (match_dup 3)) 2011 (match_dup 2) 2012 (const_int 2)))] 2013{ 2014 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode); 2015 operands[3] = gen_highpart (DImode, operands[1]); 2016 2017 emit_move_insn (gen_lowpart (DImode, operands[0]), 2018 gen_lowpart (DImode, operands[1])); 2019}) 2020 2021(define_insn "*movdi_internal" 2022 [(set (match_operand:DI 0 "nonimmediate_operand" 2023 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m,*k") 2024 (match_operand:DI 1 "general_operand" 2025 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k,CBC"))] 2026 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2027{ 2028 switch (get_attr_type (insn)) 2029 { 2030 case TYPE_MSKMOV: 2031 return "kmovq\t{%1, %0|%0, %1}"; 2032 2033 case TYPE_MSKLOG: 2034 if (operands[1] == const0_rtx) 2035 return "kxorq\t%0, %0, %0"; 2036 else if (operands[1] == constm1_rtx) 2037 return "kxnorq\t%0, %0, %0"; 2038 gcc_unreachable (); 2039 2040 case TYPE_MULTI: 2041 return "#"; 2042 2043 case TYPE_MMX: 2044 return "pxor\t%0, %0"; 2045 2046 case TYPE_MMXMOV: 2047 /* Handle broken assemblers that require movd instead of movq. */ 2048 if (!HAVE_AS_IX86_INTERUNIT_MOVQ 2049 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))) 2050 return "movd\t{%1, %0|%0, %1}"; 2051 return "movq\t{%1, %0|%0, %1}"; 2052 2053 case TYPE_SSELOG1: 2054 return standard_sse_constant_opcode (insn, operands); 2055 2056 case TYPE_SSEMOV: 2057 return ix86_output_ssemov (insn, operands); 2058 2059 case TYPE_SSECVT: 2060 if (SSE_REG_P (operands[0])) 2061 return "movq2dq\t{%1, %0|%0, %1}"; 2062 else 2063 return "movdq2q\t{%1, %0|%0, %1}"; 2064 2065 case TYPE_LEA: 2066 return "lea{q}\t{%E1, %0|%0, %E1}"; 2067 2068 case TYPE_IMOV: 2069 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2070 if (get_attr_mode (insn) == MODE_SI) 2071 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2072 else if (which_alternative == 4) 2073 return "movabs{q}\t{%1, %0|%0, %1}"; 2074 else if (ix86_use_lea_for_mov (insn, operands)) 2075 return "lea{q}\t{%E1, %0|%0, %E1}"; 2076 else 2077 return "mov{q}\t{%1, %0|%0, %1}"; 2078 2079 default: 2080 gcc_unreachable (); 2081 } 2082} 2083 [(set (attr "isa") 2084 (cond [(eq_attr "alternative" "0,1,17,18") 2085 (const_string "nox64") 2086 (eq_attr "alternative" "2,3,4,5,10,11,23,25") 2087 (const_string "x64") 2088 (eq_attr "alternative" "19,20") 2089 (const_string "x64_sse2") 2090 (eq_attr "alternative" "21,22") 2091 (const_string "sse2") 2092 ] 2093 (const_string "*"))) 2094 (set (attr "type") 2095 (cond [(eq_attr "alternative" "0,1,17,18") 2096 (const_string "multi") 2097 (eq_attr "alternative" "6") 2098 (const_string "mmx") 2099 (eq_attr "alternative" "7,8,9,10,11") 2100 (const_string "mmxmov") 2101 (eq_attr "alternative" "12") 2102 (const_string "sselog1") 2103 (eq_attr "alternative" "13,14,15,16,19,20") 2104 (const_string "ssemov") 2105 (eq_attr "alternative" "21,22") 2106 (const_string "ssecvt") 2107 (eq_attr "alternative" "23,24,25,26") 2108 (const_string "mskmov") 2109 (eq_attr "alternative" "27") 2110 (const_string "msklog") 2111 (and (match_operand 0 "register_operand") 2112 (match_operand 1 "pic_32bit_operand")) 2113 (const_string "lea") 2114 ] 2115 (const_string "imov"))) 2116 (set (attr "modrm") 2117 (if_then_else 2118 (and (eq_attr "alternative" "4") (eq_attr "type" "imov")) 2119 (const_string "0") 2120 (const_string "*"))) 2121 (set (attr "length_immediate") 2122 (if_then_else 2123 (and (eq_attr "alternative" "4") (eq_attr "type" "imov")) 2124 (const_string "8") 2125 (const_string "*"))) 2126 (set (attr "prefix_rex") 2127 (if_then_else 2128 (eq_attr "alternative" "10,11,19,20") 2129 (const_string "1") 2130 (const_string "*"))) 2131 (set (attr "prefix") 2132 (if_then_else (eq_attr "type" "sselog1,ssemov") 2133 (const_string "maybe_vex") 2134 (const_string "orig"))) 2135 (set (attr "prefix_data16") 2136 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI")) 2137 (const_string "1") 2138 (const_string "*"))) 2139 (set (attr "mode") 2140 (cond [(eq_attr "alternative" "2") 2141 (const_string "SI") 2142 (eq_attr "alternative" "12,13") 2143 (cond [(match_test "TARGET_AVX") 2144 (const_string "TI") 2145 (ior (not (match_test "TARGET_SSE2")) 2146 (match_test "optimize_function_for_size_p (cfun)")) 2147 (const_string "V4SF") 2148 ] 2149 (const_string "TI")) 2150 2151 (and (eq_attr "alternative" "14,15,16") 2152 (not (match_test "TARGET_SSE2"))) 2153 (const_string "V2SF") 2154 ] 2155 (const_string "DI"))) 2156 (set (attr "preferred_for_speed") 2157 (cond [(eq_attr "alternative" "10,17,19") 2158 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 2159 (eq_attr "alternative" "11,18,20") 2160 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC") 2161 ] 2162 (symbol_ref "true"))) 2163 (set (attr "enabled") 2164 (cond [(eq_attr "alternative" "15") 2165 (if_then_else 2166 (match_test "TARGET_STV && TARGET_SSE2") 2167 (symbol_ref "false") 2168 (const_string "*")) 2169 (eq_attr "alternative" "16") 2170 (if_then_else 2171 (match_test "TARGET_STV && TARGET_SSE2") 2172 (symbol_ref "true") 2173 (symbol_ref "false")) 2174 ] 2175 (const_string "*")))]) 2176 2177(define_split 2178 [(set (match_operand:<DWI> 0 "general_reg_operand") 2179 (match_operand:<DWI> 1 "sse_reg_operand"))] 2180 "TARGET_SSE4_1 2181 && reload_completed" 2182 [(set (match_dup 2) 2183 (vec_select:DWIH 2184 (match_dup 3) 2185 (parallel [(const_int 1)])))] 2186{ 2187 operands[2] = gen_highpart (<MODE>mode, operands[0]); 2188 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode); 2189 2190 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), 2191 gen_lowpart (<MODE>mode, operands[1])); 2192}) 2193 2194(define_split 2195 [(set (match_operand:DWI 0 "nonimmediate_gr_operand") 2196 (match_operand:DWI 1 "general_gr_operand"))] 2197 "reload_completed" 2198 [(const_int 0)] 2199 "ix86_split_long_move (operands); DONE;") 2200 2201(define_split 2202 [(set (match_operand:DI 0 "sse_reg_operand") 2203 (match_operand:DI 1 "general_reg_operand"))] 2204 "!TARGET_64BIT && TARGET_SSE4_1 2205 && reload_completed" 2206 [(set (match_dup 2) 2207 (vec_merge:V4SI 2208 (vec_duplicate:V4SI (match_dup 3)) 2209 (match_dup 2) 2210 (const_int 2)))] 2211{ 2212 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode); 2213 operands[3] = gen_highpart (SImode, operands[1]); 2214 2215 emit_move_insn (gen_lowpart (SImode, operands[0]), 2216 gen_lowpart (SImode, operands[1])); 2217}) 2218 2219;; movabsq $0x0012345678000000, %rax is longer 2220;; than movl $0x12345678, %eax; shlq $24, %rax. 2221(define_peephole2 2222 [(set (match_operand:DI 0 "register_operand") 2223 (match_operand:DI 1 "const_int_operand"))] 2224 "TARGET_64BIT 2225 && optimize_insn_for_size_p () 2226 && LEGACY_INT_REG_P (operands[0]) 2227 && !x86_64_immediate_operand (operands[1], DImode) 2228 && !x86_64_zext_immediate_operand (operands[1], DImode) 2229 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1]))) 2230 & ~(HOST_WIDE_INT) 0xffffffff) 2231 && peep2_regno_dead_p (0, FLAGS_REG)" 2232 [(set (match_dup 0) (match_dup 1)) 2233 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2))) 2234 (clobber (reg:CC FLAGS_REG))])] 2235{ 2236 int shift = ctz_hwi (UINTVAL (operands[1])); 2237 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode); 2238 operands[2] = gen_int_mode (shift, QImode); 2239}) 2240 2241(define_insn "*movsi_internal" 2242 [(set (match_operand:SI 0 "nonimmediate_operand" 2243 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k") 2244 (match_operand:SI 1 "general_operand" 2245 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))] 2246 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2247{ 2248 switch (get_attr_type (insn)) 2249 { 2250 case TYPE_SSELOG1: 2251 return standard_sse_constant_opcode (insn, operands); 2252 2253 case TYPE_MSKMOV: 2254 return "kmovd\t{%1, %0|%0, %1}"; 2255 2256 case TYPE_MSKLOG: 2257 if (operands[1] == const0_rtx) 2258 return "kxord\t%0, %0, %0"; 2259 else if (operands[1] == constm1_rtx) 2260 return "kxnord\t%0, %0, %0"; 2261 gcc_unreachable (); 2262 2263 case TYPE_SSEMOV: 2264 return ix86_output_ssemov (insn, operands); 2265 2266 case TYPE_MMX: 2267 return "pxor\t%0, %0"; 2268 2269 case TYPE_MMXMOV: 2270 switch (get_attr_mode (insn)) 2271 { 2272 case MODE_DI: 2273 return "movq\t{%1, %0|%0, %1}"; 2274 case MODE_SI: 2275 return "movd\t{%1, %0|%0, %1}"; 2276 2277 default: 2278 gcc_unreachable (); 2279 } 2280 2281 case TYPE_LEA: 2282 return "lea{l}\t{%E1, %0|%0, %E1}"; 2283 2284 case TYPE_IMOV: 2285 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1])); 2286 if (ix86_use_lea_for_mov (insn, operands)) 2287 return "lea{l}\t{%E1, %0|%0, %E1}"; 2288 else 2289 return "mov{l}\t{%1, %0|%0, %1}"; 2290 2291 default: 2292 gcc_unreachable (); 2293 } 2294} 2295 [(set (attr "isa") 2296 (cond [(eq_attr "alternative" "12,13") 2297 (const_string "sse2") 2298 ] 2299 (const_string "*"))) 2300 (set (attr "type") 2301 (cond [(eq_attr "alternative" "2") 2302 (const_string "mmx") 2303 (eq_attr "alternative" "3,4,5,6,7") 2304 (const_string "mmxmov") 2305 (eq_attr "alternative" "8") 2306 (const_string "sselog1") 2307 (eq_attr "alternative" "9,10,11,12,13") 2308 (const_string "ssemov") 2309 (eq_attr "alternative" "14,15,16") 2310 (const_string "mskmov") 2311 (eq_attr "alternative" "17") 2312 (const_string "msklog") 2313 (and (match_operand 0 "register_operand") 2314 (match_operand 1 "pic_32bit_operand")) 2315 (const_string "lea") 2316 ] 2317 (const_string "imov"))) 2318 (set (attr "prefix") 2319 (if_then_else (eq_attr "type" "sselog1,ssemov") 2320 (const_string "maybe_vex") 2321 (const_string "orig"))) 2322 (set (attr "prefix_data16") 2323 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 2324 (const_string "1") 2325 (const_string "*"))) 2326 (set (attr "mode") 2327 (cond [(eq_attr "alternative" "2,3") 2328 (const_string "DI") 2329 (eq_attr "alternative" "8,9") 2330 (cond [(match_test "TARGET_AVX") 2331 (const_string "TI") 2332 (ior (not (match_test "TARGET_SSE2")) 2333 (match_test "optimize_function_for_size_p (cfun)")) 2334 (const_string "V4SF") 2335 ] 2336 (const_string "TI")) 2337 2338 (and (eq_attr "alternative" "10,11") 2339 (not (match_test "TARGET_SSE2"))) 2340 (const_string "SF") 2341 ] 2342 (const_string "SI"))) 2343 (set (attr "preferred_for_speed") 2344 (cond [(eq_attr "alternative" "6,12") 2345 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 2346 (eq_attr "alternative" "7,13") 2347 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC") 2348 ] 2349 (symbol_ref "true")))]) 2350 2351(define_insn "*movhi_internal" 2352 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k") 2353 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k,CBC"))] 2354 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2355{ 2356 switch (get_attr_type (insn)) 2357 { 2358 case TYPE_IMOVX: 2359 /* movzwl is faster than movw on p2 due to partial word stalls, 2360 though not as fast as an aligned movl. */ 2361 return "movz{wl|x}\t{%1, %k0|%k0, %1}"; 2362 2363 case TYPE_MSKMOV: 2364 switch (which_alternative) 2365 { 2366 case 4: 2367 return "kmovw\t{%k1, %0|%0, %k1}"; 2368 case 6: 2369 return "kmovw\t{%1, %k0|%k0, %1}"; 2370 case 5: 2371 case 7: 2372 return "kmovw\t{%1, %0|%0, %1}"; 2373 default: 2374 gcc_unreachable (); 2375 } 2376 2377 case TYPE_MSKLOG: 2378 if (operands[1] == const0_rtx) 2379 return "kxorw\t%0, %0, %0"; 2380 else if (operands[1] == constm1_rtx) 2381 return "kxnorw\t%0, %0, %0"; 2382 gcc_unreachable (); 2383 2384 default: 2385 if (get_attr_mode (insn) == MODE_SI) 2386 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2387 else 2388 return "mov{w}\t{%1, %0|%0, %1}"; 2389 } 2390} 2391 [(set (attr "type") 2392 (cond [(eq_attr "alternative" "4,5,6,7") 2393 (const_string "mskmov") 2394 (eq_attr "alternative" "8") 2395 (const_string "msklog") 2396 (match_test "optimize_function_for_size_p (cfun)") 2397 (const_string "imov") 2398 (and (eq_attr "alternative" "0") 2399 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2400 (not (match_test "TARGET_HIMODE_MATH")))) 2401 (const_string "imov") 2402 (and (eq_attr "alternative" "1,2") 2403 (match_operand:HI 1 "aligned_operand")) 2404 (const_string "imov") 2405 (and (match_test "TARGET_MOVX") 2406 (eq_attr "alternative" "0,2")) 2407 (const_string "imovx") 2408 ] 2409 (const_string "imov"))) 2410 (set (attr "prefix") 2411 (if_then_else (eq_attr "alternative" "4,5,6,7,8") 2412 (const_string "vex") 2413 (const_string "orig"))) 2414 (set (attr "mode") 2415 (cond [(eq_attr "type" "imovx") 2416 (const_string "SI") 2417 (and (eq_attr "alternative" "1,2") 2418 (match_operand:HI 1 "aligned_operand")) 2419 (const_string "SI") 2420 (and (eq_attr "alternative" "0") 2421 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2422 (not (match_test "TARGET_HIMODE_MATH")))) 2423 (const_string "SI") 2424 ] 2425 (const_string "HI")))]) 2426 2427;; Situation is quite tricky about when to choose full sized (SImode) move 2428;; over QImode moves. For Q_REG -> Q_REG move we use full size only for 2429;; partial register dependency machines (such as AMD Athlon), where QImode 2430;; moves issue extra dependency and for partial register stalls machines 2431;; that don't use QImode patterns (and QImode move cause stall on the next 2432;; instruction). 2433;; 2434;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial 2435;; register stall machines with, where we use QImode instructions, since 2436;; partial register stall can be caused there. Then we use movzx. 2437 2438(define_insn "*movqi_internal" 2439 [(set (match_operand:QI 0 "nonimmediate_operand" 2440 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k") 2441 (match_operand:QI 1 "general_operand" 2442 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))] 2443 "!(MEM_P (operands[0]) && MEM_P (operands[1]))" 2444{ 2445 char buf[128]; 2446 const char *ops; 2447 const char *suffix; 2448 2449 switch (get_attr_type (insn)) 2450 { 2451 case TYPE_IMOVX: 2452 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1])); 2453 return "movz{bl|x}\t{%1, %k0|%k0, %1}"; 2454 2455 case TYPE_MSKMOV: 2456 switch (which_alternative) 2457 { 2458 case 9: 2459 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}"; 2460 break; 2461 case 11: 2462 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}"; 2463 break; 2464 case 12: 2465 case 13: 2466 gcc_assert (TARGET_AVX512DQ); 2467 /* FALLTHRU */ 2468 case 10: 2469 ops = "kmov%s\t{%%1, %%0|%%0, %%1}"; 2470 break; 2471 default: 2472 gcc_unreachable (); 2473 } 2474 2475 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b"; 2476 2477 snprintf (buf, sizeof (buf), ops, suffix); 2478 output_asm_insn (buf, operands); 2479 return ""; 2480 2481 case TYPE_MSKLOG: 2482 if (operands[1] == const0_rtx) 2483 { 2484 if (get_attr_mode (insn) == MODE_HI) 2485 return "kxorw\t%0, %0, %0"; 2486 else 2487 return "kxorb\t%0, %0, %0"; 2488 } 2489 else if (operands[1] == constm1_rtx) 2490 { 2491 gcc_assert (TARGET_AVX512DQ); 2492 return "kxnorb\t%0, %0, %0"; 2493 } 2494 gcc_unreachable (); 2495 2496 default: 2497 if (get_attr_mode (insn) == MODE_SI) 2498 return "mov{l}\t{%k1, %k0|%k0, %k1}"; 2499 else 2500 return "mov{b}\t{%1, %0|%0, %1}"; 2501 } 2502} 2503 [(set (attr "isa") 2504 (cond [(eq_attr "alternative" "1,2") 2505 (const_string "x64") 2506 (eq_attr "alternative" "12,13,15") 2507 (const_string "avx512dq") 2508 ] 2509 (const_string "*"))) 2510 (set (attr "type") 2511 (cond [(eq_attr "alternative" "9,10,11,12,13") 2512 (const_string "mskmov") 2513 (eq_attr "alternative" "14,15") 2514 (const_string "msklog") 2515 (and (eq_attr "alternative" "7") 2516 (not (match_operand:QI 1 "aligned_operand"))) 2517 (const_string "imovx") 2518 (match_test "optimize_function_for_size_p (cfun)") 2519 (const_string "imov") 2520 (and (eq_attr "alternative" "5") 2521 (ior (not (match_test "TARGET_PARTIAL_REG_STALL")) 2522 (not (match_test "TARGET_QIMODE_MATH")))) 2523 (const_string "imov") 2524 (eq_attr "alternative" "5,7") 2525 (const_string "imovx") 2526 (and (match_test "TARGET_MOVX") 2527 (eq_attr "alternative" "4")) 2528 (const_string "imovx") 2529 ] 2530 (const_string "imov"))) 2531 (set (attr "prefix") 2532 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15") 2533 (const_string "vex") 2534 (const_string "orig"))) 2535 (set (attr "mode") 2536 (cond [(eq_attr "alternative" "5,6,7") 2537 (const_string "SI") 2538 (eq_attr "alternative" "8") 2539 (const_string "QI") 2540 (and (eq_attr "alternative" "9,10,11,14") 2541 (not (match_test "TARGET_AVX512DQ"))) 2542 (const_string "HI") 2543 (eq_attr "type" "imovx") 2544 (const_string "SI") 2545 ;; For -Os, 8-bit immediates are always shorter than 32-bit 2546 ;; ones. 2547 (and (eq_attr "type" "imov") 2548 (and (eq_attr "alternative" "3") 2549 (match_test "optimize_function_for_size_p (cfun)"))) 2550 (const_string "QI") 2551 ;; For -Os, movl where one or both operands are NON_Q_REGS 2552 ;; and both are LEGACY_REGS is shorter than movb. 2553 ;; Otherwise movb and movl sizes are the same, so decide purely 2554 ;; based on speed factors. 2555 (and (eq_attr "type" "imov") 2556 (and (eq_attr "alternative" "1") 2557 (match_test "optimize_function_for_size_p (cfun)"))) 2558 (const_string "SI") 2559 (and (eq_attr "type" "imov") 2560 (and (eq_attr "alternative" "0,1,2,3") 2561 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY") 2562 (not (match_test "TARGET_PARTIAL_REG_STALL"))))) 2563 (const_string "SI") 2564 ;; Avoid partial register stalls when not using QImode arithmetic 2565 (and (eq_attr "type" "imov") 2566 (and (eq_attr "alternative" "0,1,2,3") 2567 (and (match_test "TARGET_PARTIAL_REG_STALL") 2568 (not (match_test "TARGET_QIMODE_MATH"))))) 2569 (const_string "SI") 2570 ] 2571 (const_string "QI")))]) 2572 2573;; Stores and loads of ax to arbitrary constant address. 2574;; We fake an second form of instruction to force reload to load address 2575;; into register when rax is not available 2576(define_insn "*movabs<mode>_1" 2577 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r")) 2578 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))] 2579 "TARGET_LP64 && ix86_check_movabs (insn, 0)" 2580{ 2581 /* Recover the full memory rtx. */ 2582 operands[0] = SET_DEST (PATTERN (insn)); 2583 switch (which_alternative) 2584 { 2585 case 0: 2586 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}"; 2587 case 1: 2588 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 2589 default: 2590 gcc_unreachable (); 2591 } 2592} 2593 [(set_attr "type" "imov") 2594 (set_attr "modrm" "0,*") 2595 (set_attr "length_address" "8,0") 2596 (set_attr "length_immediate" "0,*") 2597 (set_attr "memory" "store") 2598 (set_attr "mode" "<MODE>")]) 2599 2600(define_insn "*movabs<mode>_2" 2601 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r") 2602 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))] 2603 "TARGET_LP64 && ix86_check_movabs (insn, 1)" 2604{ 2605 /* Recover the full memory rtx. */ 2606 operands[1] = SET_SRC (PATTERN (insn)); 2607 switch (which_alternative) 2608 { 2609 case 0: 2610 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}"; 2611 case 1: 2612 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 2613 default: 2614 gcc_unreachable (); 2615 } 2616} 2617 [(set_attr "type" "imov") 2618 (set_attr "modrm" "0,*") 2619 (set_attr "length_address" "8,0") 2620 (set_attr "length_immediate" "0") 2621 (set_attr "memory" "load") 2622 (set_attr "mode" "<MODE>")]) 2623 2624(define_insn "*swap<mode>" 2625 [(set (match_operand:SWI48 0 "register_operand" "+r") 2626 (match_operand:SWI48 1 "register_operand" "+r")) 2627 (set (match_dup 1) 2628 (match_dup 0))] 2629 "" 2630 "xchg{<imodesuffix>}\t%1, %0" 2631 [(set_attr "type" "imov") 2632 (set_attr "mode" "<MODE>") 2633 (set_attr "pent_pair" "np") 2634 (set_attr "athlon_decode" "vector") 2635 (set_attr "amdfam10_decode" "double") 2636 (set_attr "bdver1_decode" "double")]) 2637 2638(define_insn "*swap<mode>" 2639 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r") 2640 (match_operand:SWI12 1 "register_operand" "+<r>,r")) 2641 (set (match_dup 1) 2642 (match_dup 0))] 2643 "" 2644 "@ 2645 xchg{<imodesuffix>}\t%1, %0 2646 xchg{l}\t%k1, %k0" 2647 [(set_attr "type" "imov") 2648 (set_attr "mode" "<MODE>,SI") 2649 (set (attr "preferred_for_size") 2650 (cond [(eq_attr "alternative" "0") 2651 (symbol_ref "false")] 2652 (symbol_ref "true"))) 2653 ;; Potential partial reg stall on alternative 1. 2654 (set (attr "preferred_for_speed") 2655 (cond [(eq_attr "alternative" "1") 2656 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 2657 (symbol_ref "true"))) 2658 (set_attr "pent_pair" "np") 2659 (set_attr "athlon_decode" "vector") 2660 (set_attr "amdfam10_decode" "double") 2661 (set_attr "bdver1_decode" "double")]) 2662 2663(define_peephole2 2664 [(set (match_operand:SWI 0 "general_reg_operand") 2665 (match_operand:SWI 1 "general_reg_operand")) 2666 (set (match_dup 1) 2667 (match_operand:SWI 2 "general_reg_operand")) 2668 (set (match_dup 2) (match_dup 0))] 2669 "peep2_reg_dead_p (3, operands[0]) 2670 && optimize_insn_for_size_p ()" 2671 [(parallel [(set (match_dup 1) (match_dup 2)) 2672 (set (match_dup 2) (match_dup 1))])]) 2673 2674(define_expand "movstrict<mode>" 2675 [(set (strict_low_part (match_operand:SWI12 0 "register_operand")) 2676 (match_operand:SWI12 1 "general_operand"))] 2677 "" 2678{ 2679 gcc_assert (SUBREG_P (operands[0])); 2680 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun)) 2681 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0])))) 2682 FAIL; 2683}) 2684 2685(define_insn "*movstrict<mode>_1" 2686 [(set (strict_low_part 2687 (match_operand:SWI12 0 "register_operand" "+<r>")) 2688 (match_operand:SWI12 1 "general_operand" "<r>mn"))] 2689 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 2690 "mov{<imodesuffix>}\t{%1, %0|%0, %1}" 2691 [(set_attr "type" "imov") 2692 (set_attr "mode" "<MODE>")]) 2693 2694(define_insn "*movstrict<mode>_xor" 2695 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 2696 (match_operand:SWI12 1 "const0_operand")) 2697 (clobber (reg:CC FLAGS_REG))] 2698 "reload_completed" 2699 "xor{<imodesuffix>}\t%0, %0" 2700 [(set_attr "type" "alu1") 2701 (set_attr "mode" "<MODE>") 2702 (set_attr "length_immediate" "0")]) 2703 2704(define_expand "extv<mode>" 2705 [(set (match_operand:SWI24 0 "register_operand") 2706 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand") 2707 (match_operand:SI 2 "const_int_operand") 2708 (match_operand:SI 3 "const_int_operand")))] 2709 "" 2710{ 2711 /* Handle extractions from %ah et al. */ 2712 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 2713 FAIL; 2714 2715 unsigned int regno = reg_or_subregno (operands[1]); 2716 2717 /* Be careful to expand only with registers having upper parts. */ 2718 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno)) 2719 operands[1] = copy_to_reg (operands[1]); 2720}) 2721 2722(define_insn "*extv<mode>" 2723 [(set (match_operand:SWI24 0 "register_operand" "=R") 2724 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q") 2725 (const_int 8) 2726 (const_int 8)))] 2727 "" 2728 "movs{bl|x}\t{%h1, %k0|%k0, %h1}" 2729 [(set_attr "type" "imovx") 2730 (set_attr "mode" "SI")]) 2731 2732(define_expand "extzv<mode>" 2733 [(set (match_operand:SWI248 0 "register_operand") 2734 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand") 2735 (match_operand:SI 2 "const_int_operand") 2736 (match_operand:SI 3 "const_int_operand")))] 2737 "" 2738{ 2739 if (ix86_expand_pextr (operands)) 2740 DONE; 2741 2742 /* Handle extractions from %ah et al. */ 2743 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) 2744 FAIL; 2745 2746 unsigned int regno = reg_or_subregno (operands[1]); 2747 2748 /* Be careful to expand only with registers having upper parts. */ 2749 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno)) 2750 operands[1] = copy_to_reg (operands[1]); 2751}) 2752 2753(define_insn "*extzvqi_mem_rex64" 2754 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn") 2755 (subreg:QI 2756 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 2757 (const_int 8) 2758 (const_int 8)) 0))] 2759 "TARGET_64BIT && reload_completed" 2760 "mov{b}\t{%h1, %0|%0, %h1}" 2761 [(set_attr "type" "imov") 2762 (set_attr "mode" "QI")]) 2763 2764(define_insn "*extzv<mode>" 2765 [(set (match_operand:SWI248 0 "register_operand" "=R") 2766 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q") 2767 (const_int 8) 2768 (const_int 8)))] 2769 "" 2770 "movz{bl|x}\t{%h1, %k0|%k0, %h1}" 2771 [(set_attr "type" "imovx") 2772 (set_attr "mode" "SI")]) 2773 2774(define_insn "*extzvqi" 2775 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m") 2776 (subreg:QI 2777 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q") 2778 (const_int 8) 2779 (const_int 8)) 0))] 2780 "" 2781{ 2782 switch (get_attr_type (insn)) 2783 { 2784 case TYPE_IMOVX: 2785 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}"; 2786 default: 2787 return "mov{b}\t{%h1, %0|%0, %h1}"; 2788 } 2789} 2790 [(set_attr "isa" "*,*,nox64") 2791 (set (attr "type") 2792 (if_then_else (and (match_operand:QI 0 "register_operand") 2793 (ior (not (match_operand:QI 0 "QIreg_operand")) 2794 (match_test "TARGET_MOVX"))) 2795 (const_string "imovx") 2796 (const_string "imov"))) 2797 (set (attr "mode") 2798 (if_then_else (eq_attr "type" "imovx") 2799 (const_string "SI") 2800 (const_string "QI")))]) 2801 2802(define_peephole2 2803 [(set (match_operand:QI 0 "register_operand") 2804 (subreg:QI 2805 (zero_extract:SI (match_operand 1 "ext_register_operand") 2806 (const_int 8) 2807 (const_int 8)) 0)) 2808 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))] 2809 "TARGET_64BIT 2810 && peep2_reg_dead_p (2, operands[0])" 2811 [(set (match_dup 2) 2812 (subreg:QI 2813 (zero_extract:SI (match_dup 1) 2814 (const_int 8) 2815 (const_int 8)) 0))]) 2816 2817(define_expand "insv<mode>" 2818 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand") 2819 (match_operand:SI 1 "const_int_operand") 2820 (match_operand:SI 2 "const_int_operand")) 2821 (match_operand:SWI248 3 "register_operand"))] 2822 "" 2823{ 2824 rtx dst; 2825 2826 if (ix86_expand_pinsr (operands)) 2827 DONE; 2828 2829 /* Handle insertions to %ah et al. */ 2830 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8) 2831 FAIL; 2832 2833 unsigned int regno = reg_or_subregno (operands[0]); 2834 2835 /* Be careful to expand only with registers having upper parts. */ 2836 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno)) 2837 dst = copy_to_reg (operands[0]); 2838 else 2839 dst = operands[0]; 2840 2841 emit_insn (gen_insv<mode>_1 (dst, operands[3])); 2842 2843 /* Fix up the destination if needed. */ 2844 if (dst != operands[0]) 2845 emit_move_insn (operands[0], dst); 2846 2847 DONE; 2848}) 2849 2850(define_insn "*insvqi_1_mem_rex64" 2851 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2852 (const_int 8) 2853 (const_int 8)) 2854 (subreg:SI 2855 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))] 2856 "TARGET_64BIT && reload_completed" 2857 "mov{b}\t{%1, %h0|%h0, %1}" 2858 [(set_attr "type" "imov") 2859 (set_attr "mode" "QI")]) 2860 2861(define_insn "insv<mode>_1" 2862 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q") 2863 (const_int 8) 2864 (const_int 8)) 2865 (match_operand:SWI248 1 "general_operand" "QnBc,m"))] 2866 "" 2867{ 2868 if (CONST_INT_P (operands[1])) 2869 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode); 2870 return "mov{b}\t{%b1, %h0|%h0, %b1}"; 2871} 2872 [(set_attr "isa" "*,nox64") 2873 (set_attr "type" "imov") 2874 (set_attr "mode" "QI")]) 2875 2876(define_insn "*insvqi_1" 2877 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 2878 (const_int 8) 2879 (const_int 8)) 2880 (subreg:SI 2881 (match_operand:QI 1 "general_operand" "QnBc,m") 0))] 2882 "" 2883 "mov{b}\t{%1, %h0|%h0, %1}" 2884 [(set_attr "isa" "*,nox64") 2885 (set_attr "type" "imov") 2886 (set_attr "mode" "QI")]) 2887 2888(define_peephole2 2889 [(set (match_operand:QI 0 "register_operand") 2890 (match_operand:QI 1 "norex_memory_operand")) 2891 (set (zero_extract:SI (match_operand 2 "ext_register_operand") 2892 (const_int 8) 2893 (const_int 8)) 2894 (subreg:SI (match_dup 0) 0))] 2895 "TARGET_64BIT 2896 && peep2_reg_dead_p (2, operands[0])" 2897 [(set (zero_extract:SI (match_dup 2) 2898 (const_int 8) 2899 (const_int 8)) 2900 (subreg:SI (match_dup 1) 0))]) 2901 2902(define_code_iterator any_extract [sign_extract zero_extract]) 2903 2904(define_insn "*insvqi_2" 2905 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2906 (const_int 8) 2907 (const_int 8)) 2908 (any_extract:SI (match_operand 1 "ext_register_operand" "Q") 2909 (const_int 8) 2910 (const_int 8)))] 2911 "" 2912 "mov{b}\t{%h1, %h0|%h0, %h1}" 2913 [(set_attr "type" "imov") 2914 (set_attr "mode" "QI")]) 2915 2916(define_insn "*insvqi_3" 2917 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 2918 (const_int 8) 2919 (const_int 8)) 2920 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q") 2921 (const_int 8)))] 2922 "" 2923 "mov{b}\t{%h1, %h0|%h0, %h1}" 2924 [(set_attr "type" "imov") 2925 (set_attr "mode" "QI")]) 2926 2927;; Floating point push instructions. 2928 2929(define_insn "*pushtf" 2930 [(set (match_operand:TF 0 "push_operand" "=<,<") 2931 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))] 2932 "TARGET_64BIT || TARGET_SSE" 2933{ 2934 /* This insn should be already split before reg-stack. */ 2935 return "#"; 2936} 2937 [(set_attr "isa" "*,x64") 2938 (set_attr "type" "multi") 2939 (set_attr "unit" "sse,*") 2940 (set_attr "mode" "TF,DI")]) 2941 2942;; %%% Kill this when call knows how to work this out. 2943(define_split 2944 [(set (match_operand:TF 0 "push_operand") 2945 (match_operand:TF 1 "sse_reg_operand"))] 2946 "TARGET_SSE && reload_completed" 2947 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) 2948 (set (match_dup 0) (match_dup 1))] 2949{ 2950 /* Preserve memory attributes. */ 2951 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 2952}) 2953 2954(define_insn_and_split "*pushxf_rounded" 2955 [(set (mem:XF 2956 (pre_modify:P 2957 (reg:P SP_REG) 2958 (plus:P (reg:P SP_REG) (const_int -16)))) 2959 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))] 2960 "TARGET_64BIT" 2961 "#" 2962 "&& 1" 2963 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16))) 2964 (set (match_dup 1) (match_dup 0))] 2965{ 2966 rtx pat = PATTERN (curr_insn); 2967 operands[1] = SET_DEST (pat); 2968 2969 /* Preserve memory attributes. */ 2970 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx); 2971} 2972 [(set_attr "type" "multi") 2973 (set_attr "unit" "i387,*,*,*") 2974 (set (attr "mode") 2975 (cond [(eq_attr "alternative" "1,2,3") 2976 (const_string "DI") 2977 ] 2978 (const_string "XF"))) 2979 (set (attr "preferred_for_size") 2980 (cond [(eq_attr "alternative" "1") 2981 (symbol_ref "false")] 2982 (symbol_ref "true")))]) 2983 2984(define_insn "*pushxf" 2985 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<") 2986 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))] 2987 "" 2988{ 2989 /* This insn should be already split before reg-stack. */ 2990 return "#"; 2991} 2992 [(set_attr "isa" "*,*,*,nox64,x64") 2993 (set_attr "type" "multi") 2994 (set_attr "unit" "i387,*,*,*,*") 2995 (set (attr "mode") 2996 (cond [(eq_attr "alternative" "1,2,3,4") 2997 (if_then_else (match_test "TARGET_64BIT") 2998 (const_string "DI") 2999 (const_string "SI")) 3000 ] 3001 (const_string "XF"))) 3002 (set (attr "preferred_for_size") 3003 (cond [(eq_attr "alternative" "1") 3004 (symbol_ref "false")] 3005 (symbol_ref "true")))]) 3006 3007;; %%% Kill this when call knows how to work this out. 3008(define_split 3009 [(set (match_operand:XF 0 "push_operand") 3010 (match_operand:XF 1 "fp_register_operand"))] 3011 "reload_completed" 3012 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 3013 (set (match_dup 0) (match_dup 1))] 3014{ 3015 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode))); 3016 /* Preserve memory attributes. */ 3017 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 3018}) 3019 3020(define_insn "*pushdf" 3021 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<") 3022 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))] 3023 "" 3024{ 3025 /* This insn should be already split before reg-stack. */ 3026 return "#"; 3027} 3028 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2") 3029 (set_attr "type" "multi") 3030 (set_attr "unit" "i387,*,*,*,*,sse") 3031 (set_attr "mode" "DF,SI,SI,SI,DI,DF") 3032 (set (attr "preferred_for_size") 3033 (cond [(eq_attr "alternative" "1") 3034 (symbol_ref "false")] 3035 (symbol_ref "true"))) 3036 (set (attr "preferred_for_speed") 3037 (cond [(eq_attr "alternative" "1") 3038 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")] 3039 (symbol_ref "true")))]) 3040 3041;; %%% Kill this when call knows how to work this out. 3042(define_split 3043 [(set (match_operand:DF 0 "push_operand") 3044 (match_operand:DF 1 "any_fp_register_operand"))] 3045 "reload_completed" 3046 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 3047 (set (match_dup 0) (match_dup 1))] 3048{ 3049 /* Preserve memory attributes. */ 3050 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 3051}) 3052 3053(define_insn "*pushsf_rex64" 3054 [(set (match_operand:SF 0 "push_operand" "=X,X,X") 3055 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] 3056 "TARGET_64BIT" 3057{ 3058 /* Anything else should be already split before reg-stack. */ 3059 if (which_alternative != 1) 3060 return "#"; 3061 return "push{q}\t%q1"; 3062} 3063 [(set_attr "type" "multi,push,multi") 3064 (set_attr "unit" "i387,*,*") 3065 (set_attr "mode" "SF,DI,SF")]) 3066 3067(define_insn "*pushsf" 3068 [(set (match_operand:SF 0 "push_operand" "=<,<,<") 3069 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))] 3070 "!TARGET_64BIT" 3071{ 3072 /* Anything else should be already split before reg-stack. */ 3073 if (which_alternative != 1) 3074 return "#"; 3075 return "push{l}\t%1"; 3076} 3077 [(set_attr "type" "multi,push,multi") 3078 (set_attr "unit" "i387,*,*") 3079 (set_attr "mode" "SF,SI,SF")]) 3080 3081;; %%% Kill this when call knows how to work this out. 3082(define_split 3083 [(set (match_operand:SF 0 "push_operand") 3084 (match_operand:SF 1 "any_fp_register_operand"))] 3085 "reload_completed" 3086 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 3087 (set (match_dup 0) (match_dup 1))] 3088{ 3089 rtx op = XEXP (operands[0], 0); 3090 if (GET_CODE (op) == PRE_DEC) 3091 { 3092 gcc_assert (!TARGET_64BIT); 3093 op = GEN_INT (-4); 3094 } 3095 else 3096 { 3097 op = XEXP (XEXP (op, 1), 1); 3098 gcc_assert (CONST_INT_P (op)); 3099 } 3100 operands[2] = op; 3101 /* Preserve memory attributes. */ 3102 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx); 3103}) 3104 3105(define_split 3106 [(set (match_operand:SF 0 "push_operand") 3107 (match_operand:SF 1 "memory_operand"))] 3108 "reload_completed 3109 && find_constant_src (insn)" 3110 [(set (match_dup 0) (match_dup 2))] 3111 "operands[2] = find_constant_src (curr_insn);") 3112 3113(define_split 3114 [(set (match_operand 0 "push_operand") 3115 (match_operand 1 "general_gr_operand"))] 3116 "reload_completed 3117 && (GET_MODE (operands[0]) == TFmode 3118 || GET_MODE (operands[0]) == XFmode 3119 || GET_MODE (operands[0]) == DFmode)" 3120 [(const_int 0)] 3121 "ix86_split_long_move (operands); DONE;") 3122 3123;; Floating point move instructions. 3124 3125(define_expand "movtf" 3126 [(set (match_operand:TF 0 "nonimmediate_operand") 3127 (match_operand:TF 1 "nonimmediate_operand"))] 3128 "TARGET_64BIT || TARGET_SSE" 3129 "ix86_expand_move (TFmode, operands); DONE;") 3130 3131(define_expand "mov<mode>" 3132 [(set (match_operand:X87MODEF 0 "nonimmediate_operand") 3133 (match_operand:X87MODEF 1 "general_operand"))] 3134 "" 3135 "ix86_expand_move (<MODE>mode, operands); DONE;") 3136 3137(define_insn "*movtf_internal" 3138 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o") 3139 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))] 3140 "(TARGET_64BIT || TARGET_SSE) 3141 && !(MEM_P (operands[0]) && MEM_P (operands[1])) 3142 && (lra_in_progress || reload_completed 3143 || !CONST_DOUBLE_P (operands[1]) 3144 || ((optimize_function_for_size_p (cfun) 3145 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)) 3146 && standard_sse_constant_p (operands[1], TFmode) == 1 3147 && !memory_operand (operands[0], TFmode)) 3148 || (!TARGET_MEMORY_MISMATCH_STALL 3149 && memory_operand (operands[0], TFmode)))" 3150{ 3151 switch (get_attr_type (insn)) 3152 { 3153 case TYPE_SSELOG1: 3154 return standard_sse_constant_opcode (insn, operands); 3155 3156 case TYPE_SSEMOV: 3157 return ix86_output_ssemov (insn, operands); 3158 3159 case TYPE_MULTI: 3160 return "#"; 3161 3162 default: 3163 gcc_unreachable (); 3164 } 3165} 3166 [(set_attr "isa" "*,*,*,x64,x64") 3167 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi") 3168 (set (attr "prefix") 3169 (if_then_else (eq_attr "type" "sselog1,ssemov") 3170 (const_string "maybe_vex") 3171 (const_string "orig"))) 3172 (set (attr "mode") 3173 (cond [(eq_attr "alternative" "3,4") 3174 (const_string "DI") 3175 (match_test "TARGET_AVX") 3176 (const_string "TI") 3177 (ior (not (match_test "TARGET_SSE2")) 3178 (match_test "optimize_function_for_size_p (cfun)")) 3179 (const_string "V4SF") 3180 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") 3181 (const_string "V4SF") 3182 (and (eq_attr "alternative" "2") 3183 (match_test "TARGET_SSE_TYPELESS_STORES")) 3184 (const_string "V4SF") 3185 ] 3186 (const_string "TI")))]) 3187 3188(define_split 3189 [(set (match_operand:TF 0 "nonimmediate_gr_operand") 3190 (match_operand:TF 1 "general_gr_operand"))] 3191 "reload_completed" 3192 [(const_int 0)] 3193 "ix86_split_long_move (operands); DONE;") 3194 3195;; Possible store forwarding (partial memory) stall 3196;; in alternatives 4, 6, 7 and 8. 3197(define_insn "*movxf_internal" 3198 [(set (match_operand:XF 0 "nonimmediate_operand" 3199 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o") 3200 (match_operand:XF 1 "general_operand" 3201 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))] 3202 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3203 && (lra_in_progress || reload_completed 3204 || !CONST_DOUBLE_P (operands[1]) 3205 || ((optimize_function_for_size_p (cfun) 3206 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)) 3207 && standard_80387_constant_p (operands[1]) > 0 3208 && !memory_operand (operands[0], XFmode)) 3209 || (!TARGET_MEMORY_MISMATCH_STALL 3210 && memory_operand (operands[0], XFmode)) 3211 || !TARGET_HARD_XF_REGS)" 3212{ 3213 switch (get_attr_type (insn)) 3214 { 3215 case TYPE_FMOV: 3216 if (which_alternative == 2) 3217 return standard_80387_constant_opcode (operands[1]); 3218 return output_387_reg_move (insn, operands); 3219 3220 case TYPE_MULTI: 3221 return "#"; 3222 3223 default: 3224 gcc_unreachable (); 3225 } 3226} 3227 [(set (attr "isa") 3228 (cond [(eq_attr "alternative" "7,10") 3229 (const_string "nox64") 3230 (eq_attr "alternative" "8,11") 3231 (const_string "x64") 3232 ] 3233 (const_string "*"))) 3234 (set (attr "type") 3235 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11") 3236 (const_string "multi") 3237 ] 3238 (const_string "fmov"))) 3239 (set (attr "mode") 3240 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11") 3241 (if_then_else (match_test "TARGET_64BIT") 3242 (const_string "DI") 3243 (const_string "SI")) 3244 ] 3245 (const_string "XF"))) 3246 (set (attr "preferred_for_size") 3247 (cond [(eq_attr "alternative" "3,4") 3248 (symbol_ref "false")] 3249 (symbol_ref "true"))) 3250 (set (attr "enabled") 3251 (cond [(eq_attr "alternative" "9,10,11") 3252 (if_then_else 3253 (match_test "TARGET_HARD_XF_REGS") 3254 (symbol_ref "false") 3255 (const_string "*")) 3256 (not (match_test "TARGET_HARD_XF_REGS")) 3257 (symbol_ref "false") 3258 ] 3259 (const_string "*")))]) 3260 3261(define_split 3262 [(set (match_operand:XF 0 "nonimmediate_gr_operand") 3263 (match_operand:XF 1 "general_gr_operand"))] 3264 "reload_completed" 3265 [(const_int 0)] 3266 "ix86_split_long_move (operands); DONE;") 3267 3268;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7. 3269(define_insn "*movdf_internal" 3270 [(set (match_operand:DF 0 "nonimmediate_operand" 3271 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r ,o ,r ,m") 3272 (match_operand:DF 1 "general_operand" 3273 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))] 3274 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3275 && (lra_in_progress || reload_completed 3276 || !CONST_DOUBLE_P (operands[1]) 3277 || ((optimize_function_for_size_p (cfun) 3278 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)) 3279 && ((IS_STACK_MODE (DFmode) 3280 && standard_80387_constant_p (operands[1]) > 0) 3281 || (TARGET_SSE2 && TARGET_SSE_MATH 3282 && standard_sse_constant_p (operands[1], DFmode) == 1)) 3283 && !memory_operand (operands[0], DFmode)) 3284 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL) 3285 && memory_operand (operands[0], DFmode)) 3286 || !TARGET_HARD_DF_REGS)" 3287{ 3288 switch (get_attr_type (insn)) 3289 { 3290 case TYPE_FMOV: 3291 if (which_alternative == 2) 3292 return standard_80387_constant_opcode (operands[1]); 3293 return output_387_reg_move (insn, operands); 3294 3295 case TYPE_MULTI: 3296 return "#"; 3297 3298 case TYPE_IMOV: 3299 if (get_attr_mode (insn) == MODE_SI) 3300 return "mov{l}\t{%1, %k0|%k0, %1}"; 3301 else if (which_alternative == 11) 3302 return "movabs{q}\t{%1, %0|%0, %1}"; 3303 else 3304 return "mov{q}\t{%1, %0|%0, %1}"; 3305 3306 case TYPE_SSELOG1: 3307 return standard_sse_constant_opcode (insn, operands); 3308 3309 case TYPE_SSEMOV: 3310 return ix86_output_ssemov (insn, operands); 3311 3312 default: 3313 gcc_unreachable (); 3314 } 3315} 3316 [(set (attr "isa") 3317 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23") 3318 (const_string "nox64") 3319 (eq_attr "alternative" "8,9,10,11,24,25") 3320 (const_string "x64") 3321 (eq_attr "alternative" "12,13,14,15") 3322 (const_string "sse2") 3323 (eq_attr "alternative" "20,21") 3324 (const_string "x64_sse2") 3325 ] 3326 (const_string "*"))) 3327 (set (attr "type") 3328 (cond [(eq_attr "alternative" "0,1,2") 3329 (const_string "fmov") 3330 (eq_attr "alternative" "3,4,5,6,7,22,23") 3331 (const_string "multi") 3332 (eq_attr "alternative" "8,9,10,11,24,25") 3333 (const_string "imov") 3334 (eq_attr "alternative" "12,16") 3335 (const_string "sselog1") 3336 ] 3337 (const_string "ssemov"))) 3338 (set (attr "modrm") 3339 (if_then_else (eq_attr "alternative" "11") 3340 (const_string "0") 3341 (const_string "*"))) 3342 (set (attr "length_immediate") 3343 (if_then_else (eq_attr "alternative" "11") 3344 (const_string "8") 3345 (const_string "*"))) 3346 (set (attr "prefix") 3347 (if_then_else (eq_attr "type" "sselog1,ssemov") 3348 (const_string "maybe_vex") 3349 (const_string "orig"))) 3350 (set (attr "prefix_data16") 3351 (if_then_else 3352 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI")) 3353 (eq_attr "mode" "V1DF")) 3354 (const_string "1") 3355 (const_string "*"))) 3356 (set (attr "mode") 3357 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23") 3358 (const_string "SI") 3359 (eq_attr "alternative" "8,9,11,20,21,24,25") 3360 (const_string "DI") 3361 3362 /* xorps is one byte shorter for non-AVX targets. */ 3363 (eq_attr "alternative" "12,16") 3364 (cond [(match_test "TARGET_AVX") 3365 (const_string "V2DF") 3366 (ior (not (match_test "TARGET_SSE2")) 3367 (match_test "optimize_function_for_size_p (cfun)")) 3368 (const_string "V4SF") 3369 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3370 (const_string "TI") 3371 ] 3372 (const_string "V2DF")) 3373 3374 /* For architectures resolving dependencies on 3375 whole SSE registers use movapd to break dependency 3376 chains, otherwise use short move to avoid extra work. */ 3377 3378 /* movaps is one byte shorter for non-AVX targets. */ 3379 (eq_attr "alternative" "13,17") 3380 (cond [(match_test "TARGET_AVX") 3381 (const_string "DF") 3382 (ior (not (match_test "TARGET_SSE2")) 3383 (match_test "optimize_function_for_size_p (cfun)")) 3384 (const_string "V4SF") 3385 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL") 3386 (const_string "V4SF") 3387 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3388 (const_string "V2DF") 3389 ] 3390 (const_string "DF")) 3391 3392 /* For architectures resolving dependencies on register 3393 parts we may avoid extra work to zero out upper part 3394 of register. */ 3395 (eq_attr "alternative" "14,18") 3396 (cond [(not (match_test "TARGET_SSE2")) 3397 (const_string "V2SF") 3398 (match_test "TARGET_AVX") 3399 (const_string "DF") 3400 (match_test "TARGET_SSE_SPLIT_REGS") 3401 (const_string "V1DF") 3402 ] 3403 (const_string "DF")) 3404 3405 (and (eq_attr "alternative" "15,19") 3406 (not (match_test "TARGET_SSE2"))) 3407 (const_string "V2SF") 3408 ] 3409 (const_string "DF"))) 3410 (set (attr "preferred_for_size") 3411 (cond [(eq_attr "alternative" "3,4") 3412 (symbol_ref "false")] 3413 (symbol_ref "true"))) 3414 (set (attr "preferred_for_speed") 3415 (cond [(eq_attr "alternative" "3,4") 3416 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES") 3417 (eq_attr "alternative" "20") 3418 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 3419 (eq_attr "alternative" "21") 3420 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC") 3421 ] 3422 (symbol_ref "true"))) 3423 (set (attr "enabled") 3424 (cond [(eq_attr "alternative" "22,23,24,25") 3425 (if_then_else 3426 (match_test "TARGET_HARD_DF_REGS") 3427 (symbol_ref "false") 3428 (const_string "*")) 3429 (not (match_test "TARGET_HARD_DF_REGS")) 3430 (symbol_ref "false") 3431 ] 3432 (const_string "*")))]) 3433 3434(define_split 3435 [(set (match_operand:DF 0 "nonimmediate_gr_operand") 3436 (match_operand:DF 1 "general_gr_operand"))] 3437 "!TARGET_64BIT && reload_completed" 3438 [(const_int 0)] 3439 "ix86_split_long_move (operands); DONE;") 3440 3441(define_insn "*movsf_internal" 3442 [(set (match_operand:SF 0 "nonimmediate_operand" 3443 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m") 3444 (match_operand:SF 1 "general_operand" 3445 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))] 3446 "!(MEM_P (operands[0]) && MEM_P (operands[1])) 3447 && (lra_in_progress || reload_completed 3448 || !CONST_DOUBLE_P (operands[1]) 3449 || ((optimize_function_for_size_p (cfun) 3450 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC)) 3451 && ((IS_STACK_MODE (SFmode) 3452 && standard_80387_constant_p (operands[1]) > 0) 3453 || (TARGET_SSE && TARGET_SSE_MATH 3454 && standard_sse_constant_p (operands[1], SFmode) == 1))) 3455 || memory_operand (operands[0], SFmode) 3456 || !TARGET_HARD_SF_REGS)" 3457{ 3458 switch (get_attr_type (insn)) 3459 { 3460 case TYPE_FMOV: 3461 if (which_alternative == 2) 3462 return standard_80387_constant_opcode (operands[1]); 3463 return output_387_reg_move (insn, operands); 3464 3465 case TYPE_IMOV: 3466 return "mov{l}\t{%1, %0|%0, %1}"; 3467 3468 case TYPE_SSELOG1: 3469 return standard_sse_constant_opcode (insn, operands); 3470 3471 case TYPE_SSEMOV: 3472 return ix86_output_ssemov (insn, operands); 3473 3474 case TYPE_MMXMOV: 3475 switch (get_attr_mode (insn)) 3476 { 3477 case MODE_DI: 3478 return "movq\t{%1, %0|%0, %1}"; 3479 case MODE_SI: 3480 return "movd\t{%1, %0|%0, %1}"; 3481 3482 default: 3483 gcc_unreachable (); 3484 } 3485 3486 default: 3487 gcc_unreachable (); 3488 } 3489} 3490 [(set (attr "isa") 3491 (cond [(eq_attr "alternative" "9,10") 3492 (const_string "sse2") 3493 ] 3494 (const_string "*"))) 3495 (set (attr "type") 3496 (cond [(eq_attr "alternative" "0,1,2") 3497 (const_string "fmov") 3498 (eq_attr "alternative" "3,4,16,17") 3499 (const_string "imov") 3500 (eq_attr "alternative" "5") 3501 (const_string "sselog1") 3502 (eq_attr "alternative" "11,12,13,14,15") 3503 (const_string "mmxmov") 3504 ] 3505 (const_string "ssemov"))) 3506 (set (attr "prefix") 3507 (if_then_else (eq_attr "type" "sselog1,ssemov") 3508 (const_string "maybe_vex") 3509 (const_string "orig"))) 3510 (set (attr "prefix_data16") 3511 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI")) 3512 (const_string "1") 3513 (const_string "*"))) 3514 (set (attr "mode") 3515 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17") 3516 (const_string "SI") 3517 (eq_attr "alternative" "11") 3518 (const_string "DI") 3519 (eq_attr "alternative" "5") 3520 (cond [(and (match_test "TARGET_AVX512F") 3521 (not (match_test "TARGET_PREFER_AVX256"))) 3522 (const_string "V16SF") 3523 (match_test "TARGET_AVX") 3524 (const_string "V4SF") 3525 (ior (not (match_test "TARGET_SSE2")) 3526 (match_test "optimize_function_for_size_p (cfun)")) 3527 (const_string "V4SF") 3528 (match_test "TARGET_SSE_LOAD0_BY_PXOR") 3529 (const_string "TI") 3530 ] 3531 (const_string "V4SF")) 3532 3533 /* For architectures resolving dependencies on 3534 whole SSE registers use APS move to break dependency 3535 chains, otherwise use short move to avoid extra work. 3536 3537 Do the same for architectures resolving dependencies on 3538 the parts. While in DF mode it is better to always handle 3539 just register parts, the SF mode is different due to lack 3540 of instructions to load just part of the register. It is 3541 better to maintain the whole registers in single format 3542 to avoid problems on using packed logical operations. */ 3543 (eq_attr "alternative" "6") 3544 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY") 3545 (match_test "TARGET_SSE_SPLIT_REGS")) 3546 (const_string "V4SF") 3547 ] 3548 (const_string "SF")) 3549 ] 3550 (const_string "SF"))) 3551 (set (attr "preferred_for_speed") 3552 (cond [(eq_attr "alternative" "9,14") 3553 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 3554 (eq_attr "alternative" "10,15") 3555 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC") 3556 ] 3557 (symbol_ref "true"))) 3558 (set (attr "enabled") 3559 (cond [(eq_attr "alternative" "16,17") 3560 (if_then_else 3561 (match_test "TARGET_HARD_SF_REGS") 3562 (symbol_ref "false") 3563 (const_string "*")) 3564 (not (match_test "TARGET_HARD_SF_REGS")) 3565 (symbol_ref "false") 3566 ] 3567 (const_string "*")))]) 3568 3569(define_split 3570 [(set (match_operand 0 "any_fp_register_operand") 3571 (match_operand 1 "memory_operand"))] 3572 "reload_completed 3573 && (GET_MODE (operands[0]) == TFmode 3574 || GET_MODE (operands[0]) == XFmode 3575 || GET_MODE (operands[0]) == DFmode 3576 || GET_MODE (operands[0]) == SFmode) 3577 && ix86_standard_x87sse_constant_load_p (insn, operands[0])" 3578 [(set (match_dup 0) (match_dup 2))] 3579 "operands[2] = find_constant_src (curr_insn);") 3580 3581(define_split 3582 [(set (match_operand 0 "any_fp_register_operand") 3583 (float_extend (match_operand 1 "memory_operand")))] 3584 "reload_completed 3585 && (GET_MODE (operands[0]) == TFmode 3586 || GET_MODE (operands[0]) == XFmode 3587 || GET_MODE (operands[0]) == DFmode) 3588 && ix86_standard_x87sse_constant_load_p (insn, operands[0])" 3589 [(set (match_dup 0) (match_dup 2))] 3590 "operands[2] = find_constant_src (curr_insn);") 3591 3592;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence 3593(define_split 3594 [(set (match_operand:X87MODEF 0 "fp_register_operand") 3595 (match_operand:X87MODEF 1 "immediate_operand"))] 3596 "reload_completed 3597 && (standard_80387_constant_p (operands[1]) == 8 3598 || standard_80387_constant_p (operands[1]) == 9)" 3599 [(set (match_dup 0)(match_dup 1)) 3600 (set (match_dup 0) 3601 (neg:X87MODEF (match_dup 0)))] 3602{ 3603 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1]))) 3604 operands[1] = CONST0_RTX (<MODE>mode); 3605 else 3606 operands[1] = CONST1_RTX (<MODE>mode); 3607}) 3608 3609(define_insn "*swapxf" 3610 [(set (match_operand:XF 0 "register_operand" "+f") 3611 (match_operand:XF 1 "register_operand" "+f")) 3612 (set (match_dup 1) 3613 (match_dup 0))] 3614 "TARGET_80387" 3615{ 3616 if (STACK_TOP_P (operands[0])) 3617 return "fxch\t%1"; 3618 else 3619 return "fxch\t%0"; 3620} 3621 [(set_attr "type" "fxch") 3622 (set_attr "mode" "XF")]) 3623 3624 3625;; Zero extension instructions 3626 3627(define_expand "zero_extendsidi2" 3628 [(set (match_operand:DI 0 "nonimmediate_operand") 3629 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]) 3630 3631(define_insn "*zero_extendsidi2" 3632 [(set (match_operand:DI 0 "nonimmediate_operand" 3633 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k") 3634 (zero_extend:DI 3635 (match_operand:SI 1 "x86_64_zext_operand" 3636 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))] 3637 "" 3638{ 3639 switch (get_attr_type (insn)) 3640 { 3641 case TYPE_IMOVX: 3642 if (ix86_use_lea_for_mov (insn, operands)) 3643 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 3644 else 3645 return "mov{l}\t{%1, %k0|%k0, %1}"; 3646 3647 case TYPE_MULTI: 3648 return "#"; 3649 3650 case TYPE_MMXMOV: 3651 return "movd\t{%1, %0|%0, %1}"; 3652 3653 case TYPE_SSEMOV: 3654 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])) 3655 { 3656 if (EXT_REX_SSE_REG_P (operands[0]) 3657 || EXT_REX_SSE_REG_P (operands[1])) 3658 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}"; 3659 else 3660 return "%vpmovzxdq\t{%1, %0|%0, %1}"; 3661 } 3662 3663 if (GENERAL_REG_P (operands[0])) 3664 return "%vmovd\t{%1, %k0|%k0, %1}"; 3665 3666 return "%vmovd\t{%1, %0|%0, %1}"; 3667 3668 case TYPE_MSKMOV: 3669 return "kmovd\t{%1, %k0|%k0, %1}"; 3670 3671 default: 3672 gcc_unreachable (); 3673 } 3674} 3675 [(set (attr "isa") 3676 (cond [(eq_attr "alternative" "0,1,2") 3677 (const_string "nox64") 3678 (eq_attr "alternative" "3") 3679 (const_string "x64") 3680 (eq_attr "alternative" "7,8,9") 3681 (const_string "sse2") 3682 (eq_attr "alternative" "10") 3683 (const_string "sse4") 3684 (eq_attr "alternative" "11") 3685 (const_string "avx512f") 3686 (eq_attr "alternative" "12") 3687 (const_string "x64_avx512bw") 3688 (eq_attr "alternative" "13") 3689 (const_string "avx512bw") 3690 ] 3691 (const_string "*"))) 3692 (set (attr "mmx_isa") 3693 (if_then_else (eq_attr "alternative" "5,6") 3694 (const_string "native") 3695 (const_string "*"))) 3696 (set (attr "type") 3697 (cond [(eq_attr "alternative" "0,1,2,4") 3698 (const_string "multi") 3699 (eq_attr "alternative" "5,6") 3700 (const_string "mmxmov") 3701 (eq_attr "alternative" "7") 3702 (if_then_else (match_test "TARGET_64BIT") 3703 (const_string "ssemov") 3704 (const_string "multi")) 3705 (eq_attr "alternative" "8,9,10,11") 3706 (const_string "ssemov") 3707 (eq_attr "alternative" "12,13") 3708 (const_string "mskmov") 3709 ] 3710 (const_string "imovx"))) 3711 (set (attr "prefix_extra") 3712 (if_then_else (eq_attr "alternative" "10,11") 3713 (const_string "1") 3714 (const_string "*"))) 3715 (set (attr "prefix") 3716 (if_then_else (eq_attr "type" "ssemov") 3717 (const_string "maybe_vex") 3718 (const_string "orig"))) 3719 (set (attr "prefix_0f") 3720 (if_then_else (eq_attr "type" "imovx") 3721 (const_string "0") 3722 (const_string "*"))) 3723 (set (attr "mode") 3724 (cond [(eq_attr "alternative" "5,6") 3725 (const_string "DI") 3726 (and (eq_attr "alternative" "7") 3727 (match_test "TARGET_64BIT")) 3728 (const_string "TI") 3729 (eq_attr "alternative" "8,10,11") 3730 (const_string "TI") 3731 ] 3732 (const_string "SI"))) 3733 (set (attr "preferred_for_speed") 3734 (cond [(eq_attr "alternative" "7") 3735 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC") 3736 (eq_attr "alternative" "5,8") 3737 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC") 3738 ] 3739 (symbol_ref "true")))]) 3740 3741(define_split 3742 [(set (match_operand:DI 0 "memory_operand") 3743 (zero_extend:DI (match_operand:SI 1 "memory_operand")))] 3744 "reload_completed" 3745 [(set (match_dup 4) (const_int 0))] 3746 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3747 3748(define_split 3749 [(set (match_operand:DI 0 "general_reg_operand") 3750 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))] 3751 "!TARGET_64BIT && reload_completed 3752 && REGNO (operands[0]) == REGNO (operands[1])" 3753 [(set (match_dup 4) (const_int 0))] 3754 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3755 3756(define_split 3757 [(set (match_operand:DI 0 "nonimmediate_gr_operand") 3758 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))] 3759 "!TARGET_64BIT && reload_completed 3760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 3761 [(set (match_dup 3) (match_dup 1)) 3762 (set (match_dup 4) (const_int 0))] 3763 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);") 3764 3765(define_mode_attr kmov_isa 3766 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")]) 3767 3768(define_insn "zero_extend<mode>di2" 3769 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k") 3770 (zero_extend:DI 3771 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))] 3772 "TARGET_64BIT" 3773 "@ 3774 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1} 3775 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1} 3776 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}" 3777 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>") 3778 (set_attr "type" "imovx,mskmov,mskmov") 3779 (set_attr "mode" "SI,<MODE>,<MODE>")]) 3780 3781(define_expand "zero_extend<mode>si2" 3782 [(set (match_operand:SI 0 "register_operand") 3783 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))] 3784 "" 3785{ 3786 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3787 { 3788 operands[1] = force_reg (<MODE>mode, operands[1]); 3789 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1])); 3790 DONE; 3791 } 3792}) 3793 3794(define_insn_and_split "zero_extend<mode>si2_and" 3795 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>") 3796 (zero_extend:SI 3797 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m"))) 3798 (clobber (reg:CC FLAGS_REG))] 3799 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3800 "#" 3801 "&& reload_completed" 3802 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2))) 3803 (clobber (reg:CC FLAGS_REG))])] 3804{ 3805 if (!REG_P (operands[1]) 3806 || REGNO (operands[0]) != REGNO (operands[1])) 3807 { 3808 ix86_expand_clear (operands[0]); 3809 3810 gcc_assert (!TARGET_PARTIAL_REG_STALL); 3811 emit_insn (gen_rtx_SET 3812 (gen_rtx_STRICT_LOW_PART 3813 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])), 3814 operands[1])); 3815 DONE; 3816 } 3817 3818 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode)); 3819} 3820 [(set_attr "type" "alu1") 3821 (set_attr "mode" "SI")]) 3822 3823(define_insn "*zero_extend<mode>si2" 3824 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k") 3825 (zero_extend:SI 3826 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))] 3827 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" 3828 "@ 3829 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1} 3830 kmov<mskmodesuffix>\t{%1, %0|%0, %1} 3831 kmov<mskmodesuffix>\t{%1, %0|%0, %1}" 3832 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>") 3833 (set_attr "type" "imovx,mskmov,mskmov") 3834 (set_attr "mode" "SI,<MODE>,<MODE>")]) 3835 3836(define_expand "zero_extendqihi2" 3837 [(set (match_operand:HI 0 "register_operand") 3838 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))] 3839 "" 3840{ 3841 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)) 3842 { 3843 operands[1] = force_reg (QImode, operands[1]); 3844 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1])); 3845 DONE; 3846 } 3847}) 3848 3849(define_insn_and_split "zero_extendqihi2_and" 3850 [(set (match_operand:HI 0 "register_operand" "=r,?&q") 3851 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm"))) 3852 (clobber (reg:CC FLAGS_REG))] 3853 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 3854 "#" 3855 "&& reload_completed" 3856 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255))) 3857 (clobber (reg:CC FLAGS_REG))])] 3858{ 3859 if (!REG_P (operands[1]) 3860 || REGNO (operands[0]) != REGNO (operands[1])) 3861 { 3862 ix86_expand_clear (operands[0]); 3863 3864 gcc_assert (!TARGET_PARTIAL_REG_STALL); 3865 emit_insn (gen_rtx_SET 3866 (gen_rtx_STRICT_LOW_PART 3867 (VOIDmode, gen_lowpart (QImode, operands[0])), 3868 operands[1])); 3869 DONE; 3870 } 3871 3872 operands[0] = gen_lowpart (SImode, operands[0]); 3873} 3874 [(set_attr "type" "alu1") 3875 (set_attr "mode" "SI")]) 3876 3877; zero extend to SImode to avoid partial register stalls 3878(define_insn "*zero_extendqihi2" 3879 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k") 3880 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))] 3881 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))" 3882 "@ 3883 movz{bl|x}\t{%1, %k0|%k0, %1} 3884 kmovb\t{%1, %k0|%k0, %1} 3885 kmovb\t{%1, %0|%0, %1}" 3886 [(set_attr "isa" "*,avx512dq,avx512dq") 3887 (set_attr "type" "imovx,mskmov,mskmov") 3888 (set_attr "mode" "SI,QI,QI")]) 3889 3890;; Sign extension instructions 3891 3892(define_expand "extendsidi2" 3893 [(set (match_operand:DI 0 "register_operand") 3894 (sign_extend:DI (match_operand:SI 1 "register_operand")))] 3895 "" 3896{ 3897 if (!TARGET_64BIT) 3898 { 3899 emit_insn (gen_extendsidi2_1 (operands[0], operands[1])); 3900 DONE; 3901 } 3902}) 3903 3904(define_insn "*extendsidi2_rex64" 3905 [(set (match_operand:DI 0 "register_operand" "=*a,r") 3906 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))] 3907 "TARGET_64BIT" 3908 "@ 3909 {cltq|cdqe} 3910 movs{lq|x}\t{%1, %0|%0, %1}" 3911 [(set_attr "type" "imovx") 3912 (set_attr "mode" "DI") 3913 (set_attr "prefix_0f" "0") 3914 (set_attr "modrm" "0,1")]) 3915 3916(define_insn "extendsidi2_1" 3917 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o") 3918 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r"))) 3919 (clobber (reg:CC FLAGS_REG)) 3920 (clobber (match_scratch:SI 2 "=X,X,X,&r"))] 3921 "!TARGET_64BIT" 3922 "#") 3923 3924;; Split the memory case. If the source register doesn't die, it will stay 3925;; this way, if it does die, following peephole2s take care of it. 3926(define_split 3927 [(set (match_operand:DI 0 "memory_operand") 3928 (sign_extend:DI (match_operand:SI 1 "register_operand"))) 3929 (clobber (reg:CC FLAGS_REG)) 3930 (clobber (match_operand:SI 2 "register_operand"))] 3931 "reload_completed" 3932 [(const_int 0)] 3933{ 3934 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 3935 3936 emit_move_insn (operands[3], operands[1]); 3937 3938 /* Generate a cltd if possible and doing so it profitable. */ 3939 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 3940 && REGNO (operands[1]) == AX_REG 3941 && REGNO (operands[2]) == DX_REG) 3942 { 3943 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31))); 3944 } 3945 else 3946 { 3947 emit_move_insn (operands[2], operands[1]); 3948 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31))); 3949 } 3950 emit_move_insn (operands[4], operands[2]); 3951 DONE; 3952}) 3953 3954;; Peepholes for the case where the source register does die, after 3955;; being split with the above splitter. 3956(define_peephole2 3957 [(set (match_operand:SI 0 "memory_operand") 3958 (match_operand:SI 1 "general_reg_operand")) 3959 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1)) 3960 (parallel [(set (match_dup 2) 3961 (ashiftrt:SI (match_dup 2) (const_int 31))) 3962 (clobber (reg:CC FLAGS_REG))]) 3963 (set (match_operand:SI 3 "memory_operand") (match_dup 2))] 3964 "REGNO (operands[1]) != REGNO (operands[2]) 3965 && peep2_reg_dead_p (2, operands[1]) 3966 && peep2_reg_dead_p (4, operands[2]) 3967 && !reg_mentioned_p (operands[2], operands[3])" 3968 [(set (match_dup 0) (match_dup 1)) 3969 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3970 (clobber (reg:CC FLAGS_REG))]) 3971 (set (match_dup 3) (match_dup 1))]) 3972 3973(define_peephole2 3974 [(set (match_operand:SI 0 "memory_operand") 3975 (match_operand:SI 1 "general_reg_operand")) 3976 (parallel [(set (match_operand:SI 2 "general_reg_operand") 3977 (ashiftrt:SI (match_dup 1) (const_int 31))) 3978 (clobber (reg:CC FLAGS_REG))]) 3979 (set (match_operand:SI 3 "memory_operand") (match_dup 2))] 3980 "/* cltd is shorter than sarl $31, %eax */ 3981 !optimize_function_for_size_p (cfun) 3982 && REGNO (operands[1]) == AX_REG 3983 && REGNO (operands[2]) == DX_REG 3984 && peep2_reg_dead_p (2, operands[1]) 3985 && peep2_reg_dead_p (3, operands[2]) 3986 && !reg_mentioned_p (operands[2], operands[3])" 3987 [(set (match_dup 0) (match_dup 1)) 3988 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) 3989 (clobber (reg:CC FLAGS_REG))]) 3990 (set (match_dup 3) (match_dup 1))]) 3991 3992;; Extend to register case. Optimize case where source and destination 3993;; registers match and cases where we can use cltd. 3994(define_split 3995 [(set (match_operand:DI 0 "register_operand") 3996 (sign_extend:DI (match_operand:SI 1 "register_operand"))) 3997 (clobber (reg:CC FLAGS_REG)) 3998 (clobber (match_scratch:SI 2))] 3999 "reload_completed" 4000 [(const_int 0)] 4001{ 4002 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]); 4003 4004 if (REGNO (operands[3]) != REGNO (operands[1])) 4005 emit_move_insn (operands[3], operands[1]); 4006 4007 /* Generate a cltd if possible and doing so it profitable. */ 4008 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 4009 && REGNO (operands[3]) == AX_REG 4010 && REGNO (operands[4]) == DX_REG) 4011 { 4012 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31))); 4013 DONE; 4014 } 4015 4016 if (REGNO (operands[4]) != REGNO (operands[1])) 4017 emit_move_insn (operands[4], operands[1]); 4018 4019 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31))); 4020 DONE; 4021}) 4022 4023(define_insn "extend<mode>di2" 4024 [(set (match_operand:DI 0 "register_operand" "=r") 4025 (sign_extend:DI 4026 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))] 4027 "TARGET_64BIT" 4028 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}" 4029 [(set_attr "type" "imovx") 4030 (set_attr "mode" "DI")]) 4031 4032(define_insn "extendhisi2" 4033 [(set (match_operand:SI 0 "register_operand" "=*a,r") 4034 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))] 4035 "" 4036{ 4037 switch (get_attr_prefix_0f (insn)) 4038 { 4039 case 0: 4040 return "{cwtl|cwde}"; 4041 default: 4042 return "movs{wl|x}\t{%1, %0|%0, %1}"; 4043 } 4044} 4045 [(set_attr "type" "imovx") 4046 (set_attr "mode" "SI") 4047 (set (attr "prefix_0f") 4048 ;; movsx is short decodable while cwtl is vector decoded. 4049 (if_then_else (and (eq_attr "cpu" "!k6") 4050 (eq_attr "alternative" "0")) 4051 (const_string "0") 4052 (const_string "1"))) 4053 (set (attr "znver1_decode") 4054 (if_then_else (eq_attr "prefix_0f" "0") 4055 (const_string "double") 4056 (const_string "direct"))) 4057 (set (attr "modrm") 4058 (if_then_else (eq_attr "prefix_0f" "0") 4059 (const_string "0") 4060 (const_string "1")))]) 4061 4062(define_insn "*extendhisi2_zext" 4063 [(set (match_operand:DI 0 "register_operand" "=*a,r") 4064 (zero_extend:DI 4065 (sign_extend:SI 4066 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))] 4067 "TARGET_64BIT" 4068{ 4069 switch (get_attr_prefix_0f (insn)) 4070 { 4071 case 0: 4072 return "{cwtl|cwde}"; 4073 default: 4074 return "movs{wl|x}\t{%1, %k0|%k0, %1}"; 4075 } 4076} 4077 [(set_attr "type" "imovx") 4078 (set_attr "mode" "SI") 4079 (set (attr "prefix_0f") 4080 ;; movsx is short decodable while cwtl is vector decoded. 4081 (if_then_else (and (eq_attr "cpu" "!k6") 4082 (eq_attr "alternative" "0")) 4083 (const_string "0") 4084 (const_string "1"))) 4085 (set (attr "modrm") 4086 (if_then_else (eq_attr "prefix_0f" "0") 4087 (const_string "0") 4088 (const_string "1")))]) 4089 4090(define_insn "extendqisi2" 4091 [(set (match_operand:SI 0 "register_operand" "=r") 4092 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] 4093 "" 4094 "movs{bl|x}\t{%1, %0|%0, %1}" 4095 [(set_attr "type" "imovx") 4096 (set_attr "mode" "SI")]) 4097 4098(define_insn "*extendqisi2_zext" 4099 [(set (match_operand:DI 0 "register_operand" "=r") 4100 (zero_extend:DI 4101 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))] 4102 "TARGET_64BIT" 4103 "movs{bl|x}\t{%1, %k0|%k0, %1}" 4104 [(set_attr "type" "imovx") 4105 (set_attr "mode" "SI")]) 4106 4107(define_insn "extendqihi2" 4108 [(set (match_operand:HI 0 "register_operand" "=*a,r") 4109 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))] 4110 "" 4111{ 4112 switch (get_attr_prefix_0f (insn)) 4113 { 4114 case 0: 4115 return "{cbtw|cbw}"; 4116 default: 4117 return "movs{bw|x}\t{%1, %0|%0, %1}"; 4118 } 4119} 4120 [(set_attr "type" "imovx") 4121 (set_attr "mode" "HI") 4122 (set (attr "prefix_0f") 4123 ;; movsx is short decodable while cwtl is vector decoded. 4124 (if_then_else (and (eq_attr "cpu" "!k6") 4125 (eq_attr "alternative" "0")) 4126 (const_string "0") 4127 (const_string "1"))) 4128 (set (attr "modrm") 4129 (if_then_else (eq_attr "prefix_0f" "0") 4130 (const_string "0") 4131 (const_string "1")))]) 4132 4133;; Conversions between float and double. 4134 4135;; These are all no-ops in the model used for the 80387. 4136;; So just emit moves. 4137 4138;; %%% Kill these when call knows how to work out a DFmode push earlier. 4139(define_split 4140 [(set (match_operand:DF 0 "push_operand") 4141 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))] 4142 "reload_completed" 4143 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8))) 4144 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))]) 4145 4146(define_split 4147 [(set (match_operand:XF 0 "push_operand") 4148 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))] 4149 "reload_completed" 4150 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2))) 4151 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))] 4152 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));") 4153 4154(define_expand "extendsfdf2" 4155 [(set (match_operand:DF 0 "nonimm_ssenomem_operand") 4156 (float_extend:DF (match_operand:SF 1 "general_operand")))] 4157 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4158{ 4159 /* ??? Needed for compress_float_constant since all fp constants 4160 are TARGET_LEGITIMATE_CONSTANT_P. */ 4161 if (CONST_DOUBLE_P (operands[1])) 4162 { 4163 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387) 4164 && standard_80387_constant_p (operands[1]) > 0) 4165 { 4166 operands[1] = simplify_const_unary_operation 4167 (FLOAT_EXTEND, DFmode, operands[1], SFmode); 4168 emit_move_insn_1 (operands[0], operands[1]); 4169 DONE; 4170 } 4171 operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); 4172 } 4173}) 4174 4175(define_insn "*extendsfdf2" 4176 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v") 4177 (float_extend:DF 4178 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))] 4179 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4180{ 4181 switch (which_alternative) 4182 { 4183 case 0: 4184 case 1: 4185 return output_387_reg_move (insn, operands); 4186 4187 case 2: 4188 return "%vcvtss2sd\t{%d1, %0|%0, %d1}"; 4189 case 3: 4190 return "%vcvtss2sd\t{%1, %d0|%d0, %1}"; 4191 4192 default: 4193 gcc_unreachable (); 4194 } 4195} 4196 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt") 4197 (set_attr "avx_partial_xmm_update" "false,false,false,true") 4198 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex") 4199 (set_attr "mode" "SF,XF,DF,DF") 4200 (set (attr "enabled") 4201 (if_then_else 4202 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH")) 4203 (if_then_else 4204 (eq_attr "alternative" "0,1") 4205 (symbol_ref "TARGET_MIX_SSE_I387") 4206 (symbol_ref "true")) 4207 (if_then_else 4208 (eq_attr "alternative" "0,1") 4209 (symbol_ref "true") 4210 (symbol_ref "false"))))]) 4211 4212/* For converting SF(xmm2) to DF(xmm1), use the following code instead of 4213 cvtss2sd: 4214 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs 4215 cvtps2pd xmm2,xmm1 4216 We do the conversion post reload to avoid producing of 128bit spills 4217 that might lead to ICE on 32bit target. The sequence unlikely combine 4218 anyway. */ 4219(define_split 4220 [(set (match_operand:DF 0 "sse_reg_operand") 4221 (float_extend:DF 4222 (match_operand:SF 1 "nonimmediate_operand")))] 4223 "TARGET_USE_VECTOR_FP_CONVERTS 4224 && optimize_insn_for_speed_p () 4225 && reload_completed 4226 && (!EXT_REX_SSE_REG_P (operands[0]) 4227 || TARGET_AVX512VL)" 4228 [(set (match_dup 2) 4229 (float_extend:V2DF 4230 (vec_select:V2SF 4231 (match_dup 3) 4232 (parallel [(const_int 0) (const_int 1)]))))] 4233{ 4234 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode); 4235 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode); 4236 /* Use movss for loading from memory, unpcklps reg, reg for registers. 4237 Try to avoid move when unpacking can be done in source. */ 4238 if (REG_P (operands[1])) 4239 { 4240 /* If it is unsafe to overwrite upper half of source, we need 4241 to move to destination and unpack there. */ 4242 if (REGNO (operands[0]) != REGNO (operands[1]) 4243 || (EXT_REX_SSE_REG_P (operands[1]) 4244 && !TARGET_AVX512VL)) 4245 { 4246 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode); 4247 emit_move_insn (tmp, operands[1]); 4248 } 4249 else 4250 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode); 4251 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow 4252 =v, v, then vbroadcastss will be only needed for AVX512F without 4253 AVX512VL. */ 4254 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3]))) 4255 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3], 4256 operands[3])); 4257 else 4258 { 4259 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode); 4260 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp)); 4261 } 4262 } 4263 else 4264 emit_insn (gen_vec_setv4sf_0 (operands[3], 4265 CONST0_RTX (V4SFmode), operands[1])); 4266}) 4267 4268;; It's more profitable to split and then extend in the same register. 4269(define_peephole2 4270 [(set (match_operand:DF 0 "sse_reg_operand") 4271 (float_extend:DF 4272 (match_operand:SF 1 "memory_operand")))] 4273 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS 4274 && optimize_insn_for_speed_p ()" 4275 [(set (match_dup 2) (match_dup 1)) 4276 (set (match_dup 0) (float_extend:DF (match_dup 2)))] 4277 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);") 4278 4279;; Break partial SSE register dependency stall. This splitter should split 4280;; late in the pass sequence (after register rename pass), so allocated 4281;; registers won't change anymore 4282 4283(define_split 4284 [(set (match_operand:DF 0 "sse_reg_operand") 4285 (float_extend:DF 4286 (match_operand:SF 1 "nonimmediate_operand")))] 4287 "!TARGET_AVX 4288 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed 4289 && optimize_function_for_speed_p (cfun) 4290 && (!REG_P (operands[1]) 4291 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1]))) 4292 && (!EXT_REX_SSE_REG_P (operands[0]) 4293 || TARGET_AVX512VL)" 4294 [(set (match_dup 0) 4295 (vec_merge:V2DF 4296 (vec_duplicate:V2DF 4297 (float_extend:DF 4298 (match_dup 1))) 4299 (match_dup 0) 4300 (const_int 1)))] 4301{ 4302 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode); 4303 emit_move_insn (operands[0], CONST0_RTX (V2DFmode)); 4304}) 4305 4306(define_expand "extend<mode>xf2" 4307 [(set (match_operand:XF 0 "nonimmediate_operand") 4308 (float_extend:XF (match_operand:MODEF 1 "general_operand")))] 4309 "TARGET_80387" 4310{ 4311 /* ??? Needed for compress_float_constant since all fp constants 4312 are TARGET_LEGITIMATE_CONSTANT_P. */ 4313 if (CONST_DOUBLE_P (operands[1])) 4314 { 4315 if (standard_80387_constant_p (operands[1]) > 0) 4316 { 4317 operands[1] = simplify_const_unary_operation 4318 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode); 4319 emit_move_insn_1 (operands[0], operands[1]); 4320 DONE; 4321 } 4322 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1])); 4323 } 4324}) 4325 4326(define_insn "*extend<mode>xf2_i387" 4327 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") 4328 (float_extend:XF 4329 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))] 4330 "TARGET_80387" 4331 "* return output_387_reg_move (insn, operands);" 4332 [(set_attr "type" "fmov") 4333 (set_attr "mode" "<MODE>,XF")]) 4334 4335;; %%% This seems like bad news. 4336;; This cannot output into an f-reg because there is no way to be sure 4337;; of truncating in that case. Otherwise this is just like a simple move 4338;; insn. So we pretend we can output to a reg in order to get better 4339;; register preferencing, but we really use a stack slot. 4340 4341;; Conversion from DFmode to SFmode. 4342 4343(define_insn "truncdfsf2" 4344 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v") 4345 (float_truncate:SF 4346 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))] 4347 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)" 4348{ 4349 switch (which_alternative) 4350 { 4351 case 0: 4352 case 1: 4353 return output_387_reg_move (insn, operands); 4354 4355 case 2: 4356 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}"; 4357 case 3: 4358 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}"; 4359 4360 default: 4361 gcc_unreachable (); 4362 } 4363} 4364 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt") 4365 (set_attr "avx_partial_xmm_update" "false,false,false,true") 4366 (set_attr "mode" "SF") 4367 (set (attr "enabled") 4368 (if_then_else 4369 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH")) 4370 (cond [(eq_attr "alternative" "0") 4371 (symbol_ref "TARGET_MIX_SSE_I387") 4372 (eq_attr "alternative" "1") 4373 (symbol_ref "TARGET_MIX_SSE_I387 4374 && flag_unsafe_math_optimizations") 4375 ] 4376 (symbol_ref "true")) 4377 (cond [(eq_attr "alternative" "0") 4378 (symbol_ref "true") 4379 (eq_attr "alternative" "1") 4380 (symbol_ref "flag_unsafe_math_optimizations") 4381 ] 4382 (symbol_ref "false"))))]) 4383 4384/* For converting DF(xmm2) to SF(xmm1), use the following code instead of 4385 cvtsd2ss: 4386 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs 4387 cvtpd2ps xmm2,xmm1 4388 We do the conversion post reload to avoid producing of 128bit spills 4389 that might lead to ICE on 32bit target. The sequence unlikely combine 4390 anyway. */ 4391(define_split 4392 [(set (match_operand:SF 0 "sse_reg_operand") 4393 (float_truncate:SF 4394 (match_operand:DF 1 "nonimmediate_operand")))] 4395 "TARGET_USE_VECTOR_FP_CONVERTS 4396 && optimize_insn_for_speed_p () 4397 && reload_completed 4398 && (!EXT_REX_SSE_REG_P (operands[0]) 4399 || TARGET_AVX512VL)" 4400 [(set (match_dup 2) 4401 (vec_concat:V4SF 4402 (float_truncate:V2SF 4403 (match_dup 4)) 4404 (match_dup 3)))] 4405{ 4406 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode); 4407 operands[3] = CONST0_RTX (V2SFmode); 4408 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode); 4409 /* Use movsd for loading from memory, unpcklpd for registers. 4410 Try to avoid move when unpacking can be done in source, or SSE3 4411 movddup is available. */ 4412 if (REG_P (operands[1])) 4413 { 4414 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1])) 4415 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL)) 4416 { 4417 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode); 4418 emit_move_insn (tmp, operands[1]); 4419 operands[1] = tmp; 4420 } 4421 else if (!TARGET_SSE3) 4422 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode); 4423 emit_insn (gen_vec_dupv2df (operands[4], operands[1])); 4424 } 4425 else 4426 emit_insn (gen_vec_concatv2df (operands[4], operands[1], 4427 CONST0_RTX (DFmode))); 4428}) 4429 4430;; It's more profitable to split and then truncate in the same register. 4431(define_peephole2 4432 [(set (match_operand:SF 0 "sse_reg_operand") 4433 (float_truncate:SF 4434 (match_operand:DF 1 "memory_operand")))] 4435 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS 4436 && optimize_insn_for_speed_p ()" 4437 [(set (match_dup 2) (match_dup 1)) 4438 (set (match_dup 0) (float_truncate:SF (match_dup 2)))] 4439 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);") 4440 4441;; Break partial SSE register dependency stall. This splitter should split 4442;; late in the pass sequence (after register rename pass), so allocated 4443;; registers won't change anymore 4444 4445(define_split 4446 [(set (match_operand:SF 0 "sse_reg_operand") 4447 (float_truncate:SF 4448 (match_operand:DF 1 "nonimmediate_operand")))] 4449 "!TARGET_AVX 4450 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed 4451 && optimize_function_for_speed_p (cfun) 4452 && (!REG_P (operands[1]) 4453 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1]))) 4454 && (!EXT_REX_SSE_REG_P (operands[0]) 4455 || TARGET_AVX512VL)" 4456 [(set (match_dup 0) 4457 (vec_merge:V4SF 4458 (vec_duplicate:V4SF 4459 (float_truncate:SF 4460 (match_dup 1))) 4461 (match_dup 0) 4462 (const_int 1)))] 4463{ 4464 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode); 4465 emit_move_insn (operands[0], CONST0_RTX (V4SFmode)); 4466}) 4467 4468;; Conversion from XFmode to {SF,DF}mode 4469 4470(define_insn "truncxf<mode>2" 4471 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f") 4472 (float_truncate:MODEF 4473 (match_operand:XF 1 "register_operand" "f,f")))] 4474 "TARGET_80387" 4475 "* return output_387_reg_move (insn, operands);" 4476 [(set_attr "type" "fmov") 4477 (set_attr "mode" "<MODE>") 4478 (set (attr "enabled") 4479 (cond [(eq_attr "alternative" "1") 4480 (symbol_ref "flag_unsafe_math_optimizations") 4481 ] 4482 (symbol_ref "true")))]) 4483 4484;; Signed conversion to DImode. 4485 4486(define_expand "fix_truncxfdi2" 4487 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand") 4488 (fix:DI (match_operand:XF 1 "register_operand"))) 4489 (clobber (reg:CC FLAGS_REG))])] 4490 "TARGET_80387" 4491{ 4492 if (TARGET_FISTTP) 4493 { 4494 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1])); 4495 DONE; 4496 } 4497}) 4498 4499(define_expand "fix_trunc<mode>di2" 4500 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand") 4501 (fix:DI (match_operand:MODEF 1 "register_operand"))) 4502 (clobber (reg:CC FLAGS_REG))])] 4503 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))" 4504{ 4505 if (TARGET_FISTTP 4506 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4507 { 4508 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1])); 4509 DONE; 4510 } 4511 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)) 4512 { 4513 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode); 4514 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1])); 4515 if (out != operands[0]) 4516 emit_move_insn (operands[0], out); 4517 DONE; 4518 } 4519}) 4520 4521;; Signed conversion to SImode. 4522 4523(define_expand "fix_truncxfsi2" 4524 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 4525 (fix:SI (match_operand:XF 1 "register_operand"))) 4526 (clobber (reg:CC FLAGS_REG))])] 4527 "TARGET_80387" 4528{ 4529 if (TARGET_FISTTP) 4530 { 4531 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1])); 4532 DONE; 4533 } 4534}) 4535 4536(define_expand "fix_trunc<mode>si2" 4537 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand") 4538 (fix:SI (match_operand:MODEF 1 "register_operand"))) 4539 (clobber (reg:CC FLAGS_REG))])] 4540 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)" 4541{ 4542 if (TARGET_FISTTP 4543 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 4544 { 4545 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1])); 4546 DONE; 4547 } 4548 if (SSE_FLOAT_MODE_P (<MODE>mode)) 4549 { 4550 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); 4551 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1])); 4552 if (out != operands[0]) 4553 emit_move_insn (operands[0], out); 4554 DONE; 4555 } 4556}) 4557 4558;; Signed conversion to HImode. 4559 4560(define_expand "fix_trunc<mode>hi2" 4561 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand") 4562 (fix:HI (match_operand:X87MODEF 1 "register_operand"))) 4563 (clobber (reg:CC FLAGS_REG))])] 4564 "TARGET_80387 4565 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))" 4566{ 4567 if (TARGET_FISTTP) 4568 { 4569 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1])); 4570 DONE; 4571 } 4572}) 4573 4574;; Unsigned conversion to DImode 4575 4576(define_insn "fixuns_trunc<mode>di2" 4577 [(set (match_operand:DI 0 "register_operand" "=r") 4578 (unsigned_fix:DI 4579 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))] 4580 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH" 4581 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}" 4582 [(set_attr "type" "sseicvt") 4583 (set_attr "prefix" "evex") 4584 (set_attr "mode" "DI")]) 4585 4586;; Unsigned conversion to SImode. 4587 4588(define_expand "fixuns_trunc<mode>si2" 4589 [(parallel 4590 [(set (match_operand:SI 0 "register_operand") 4591 (unsigned_fix:SI 4592 (match_operand:MODEF 1 "nonimmediate_operand"))) 4593 (use (match_dup 2)) 4594 (clobber (match_scratch:<ssevecmode> 3)) 4595 (clobber (match_scratch:<ssevecmode> 4))])] 4596 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH" 4597{ 4598 machine_mode mode = <MODE>mode; 4599 machine_mode vecmode = <ssevecmode>mode; 4600 REAL_VALUE_TYPE TWO31r; 4601 rtx two31; 4602 4603 if (TARGET_AVX512F) 4604 { 4605 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1])); 4606 DONE; 4607 } 4608 4609 if (optimize_insn_for_size_p ()) 4610 FAIL; 4611 4612 real_ldexp (&TWO31r, &dconst1, 31); 4613 two31 = const_double_from_real_value (TWO31r, mode); 4614 two31 = ix86_build_const_vector (vecmode, true, two31); 4615 operands[2] = force_reg (vecmode, two31); 4616}) 4617 4618(define_insn "fixuns_trunc<mode>si2_avx512f" 4619 [(set (match_operand:SI 0 "register_operand" "=r") 4620 (unsigned_fix:SI 4621 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))] 4622 "TARGET_AVX512F && TARGET_SSE_MATH" 4623 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}" 4624 [(set_attr "type" "sseicvt") 4625 (set_attr "prefix" "evex") 4626 (set_attr "mode" "SI")]) 4627 4628(define_insn "*fixuns_trunc<mode>si2_avx512f_zext" 4629 [(set (match_operand:DI 0 "register_operand" "=r") 4630 (zero_extend:DI 4631 (unsigned_fix:SI 4632 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))] 4633 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH" 4634 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}" 4635 [(set_attr "type" "sseicvt") 4636 (set_attr "prefix" "evex") 4637 (set_attr "mode" "SI")]) 4638 4639(define_insn_and_split "*fixuns_trunc<mode>_1" 4640 [(set (match_operand:SI 0 "register_operand" "=&x,&x") 4641 (unsigned_fix:SI 4642 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm"))) 4643 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x")) 4644 (clobber (match_scratch:<ssevecmode> 1 "=x,&x")) 4645 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))] 4646 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH 4647 && optimize_function_for_speed_p (cfun)" 4648 "#" 4649 "&& reload_completed" 4650 [(const_int 0)] 4651{ 4652 ix86_split_convert_uns_si_sse (operands); 4653 DONE; 4654}) 4655 4656;; Unsigned conversion to HImode. 4657;; Without these patterns, we'll try the unsigned SI conversion which 4658;; is complex for SSE, rather than the signed SI conversion, which isn't. 4659 4660(define_expand "fixuns_trunc<mode>hi2" 4661 [(set (match_dup 2) 4662 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand"))) 4663 (set (match_operand:HI 0 "nonimmediate_operand") 4664 (subreg:HI (match_dup 2) 0))] 4665 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 4666 "operands[2] = gen_reg_rtx (SImode);") 4667 4668;; When SSE is available, it is always faster to use it! 4669(define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse" 4670 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 4671 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))] 4672 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) 4673 && (!TARGET_FISTTP || TARGET_SSE_MATH)" 4674 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}" 4675 [(set_attr "type" "sseicvt") 4676 (set_attr "prefix" "maybe_vex") 4677 (set (attr "prefix_rex") 4678 (if_then_else 4679 (match_test "<SWI48:MODE>mode == DImode") 4680 (const_string "1") 4681 (const_string "*"))) 4682 (set_attr "mode" "<MODEF:MODE>") 4683 (set_attr "athlon_decode" "double,vector") 4684 (set_attr "amdfam10_decode" "double,double") 4685 (set_attr "bdver1_decode" "double,double")]) 4686 4687;; Avoid vector decoded forms of the instruction. 4688(define_peephole2 4689 [(match_scratch:MODEF 2 "x") 4690 (set (match_operand:SWI48 0 "register_operand") 4691 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))] 4692 "TARGET_AVOID_VECTOR_DECODE 4693 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) 4694 && optimize_insn_for_speed_p ()" 4695 [(set (match_dup 2) (match_dup 1)) 4696 (set (match_dup 0) (fix:SWI48 (match_dup 2)))]) 4697 4698(define_insn "fix_trunc<mode>_i387_fisttp" 4699 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m") 4700 (fix:SWI248x (match_operand 1 "register_operand" "f"))) 4701 (clobber (match_scratch:XF 2 "=&f"))] 4702 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4703 && TARGET_FISTTP 4704 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4705 && (TARGET_64BIT || <MODE>mode != DImode)) 4706 && TARGET_SSE_MATH)" 4707 "* return output_fix_trunc (insn, operands, true);" 4708 [(set_attr "type" "fisttp") 4709 (set_attr "mode" "<MODE>")]) 4710 4711;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description 4712;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control 4713;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG 4714;; clobbering insns can be used. Look at emit_i387_cw_initialization () 4715;; function in i386.c. 4716(define_insn_and_split "*fix_trunc<mode>_i387_1" 4717 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 4718 (fix:SWI248x (match_operand 1 "register_operand"))) 4719 (clobber (reg:CC FLAGS_REG))] 4720 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4721 && !TARGET_FISTTP 4722 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1])) 4723 && (TARGET_64BIT || <MODE>mode != DImode)) 4724 && ix86_pre_reload_split ()" 4725 "#" 4726 "&& 1" 4727 [(const_int 0)] 4728{ 4729 ix86_optimize_mode_switching[I387_TRUNC] = 1; 4730 4731 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 4732 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC); 4733 4734 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1], 4735 operands[2], operands[3])); 4736 DONE; 4737} 4738 [(set_attr "type" "fistp") 4739 (set_attr "i387_cw" "trunc") 4740 (set_attr "mode" "<MODE>")]) 4741 4742(define_insn "fix_truncdi_i387" 4743 [(set (match_operand:DI 0 "nonimmediate_operand" "=m") 4744 (fix:DI (match_operand 1 "register_operand" "f"))) 4745 (use (match_operand:HI 2 "memory_operand" "m")) 4746 (use (match_operand:HI 3 "memory_operand" "m")) 4747 (clobber (match_scratch:XF 4 "=&f"))] 4748 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4749 && !TARGET_FISTTP 4750 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" 4751 "* return output_fix_trunc (insn, operands, false);" 4752 [(set_attr "type" "fistp") 4753 (set_attr "i387_cw" "trunc") 4754 (set_attr "mode" "DI")]) 4755 4756(define_insn "fix_trunc<mode>_i387" 4757 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m") 4758 (fix:SWI24 (match_operand 1 "register_operand" "f"))) 4759 (use (match_operand:HI 2 "memory_operand" "m")) 4760 (use (match_operand:HI 3 "memory_operand" "m"))] 4761 "X87_FLOAT_MODE_P (GET_MODE (operands[1])) 4762 && !TARGET_FISTTP 4763 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))" 4764 "* return output_fix_trunc (insn, operands, false);" 4765 [(set_attr "type" "fistp") 4766 (set_attr "i387_cw" "trunc") 4767 (set_attr "mode" "<MODE>")]) 4768 4769(define_insn "x86_fnstcw_1" 4770 [(set (match_operand:HI 0 "memory_operand" "=m") 4771 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))] 4772 "TARGET_80387" 4773 "fnstcw\t%0" 4774 [(set (attr "length") 4775 (symbol_ref "ix86_attr_length_address_default (insn) + 2")) 4776 (set_attr "mode" "HI") 4777 (set_attr "unit" "i387") 4778 (set_attr "bdver1_decode" "vector")]) 4779 4780;; Conversion between fixed point and floating point. 4781 4782;; Even though we only accept memory inputs, the backend _really_ 4783;; wants to be able to do this between registers. Thankfully, LRA 4784;; will fix this up for us during register allocation. 4785 4786(define_insn "floathi<mode>2" 4787 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 4788 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))] 4789 "TARGET_80387 4790 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 4791 || TARGET_MIX_SSE_I387)" 4792 "fild%Z1\t%1" 4793 [(set_attr "type" "fmov") 4794 (set_attr "mode" "<MODE>") 4795 (set_attr "znver1_decode" "double") 4796 (set_attr "fp_int_src" "true")]) 4797 4798(define_insn "float<SWI48x:mode>xf2" 4799 [(set (match_operand:XF 0 "register_operand" "=f") 4800 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))] 4801 "TARGET_80387" 4802 "fild%Z1\t%1" 4803 [(set_attr "type" "fmov") 4804 (set_attr "mode" "XF") 4805 (set_attr "znver1_decode" "double") 4806 (set_attr "fp_int_src" "true")]) 4807 4808(define_expand "float<SWI48x:mode><MODEF:mode>2" 4809 [(set (match_operand:MODEF 0 "register_operand") 4810 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))] 4811 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)) 4812 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 4813 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))") 4814 4815(define_insn "*float<SWI48:mode><MODEF:mode>2" 4816 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v") 4817 (float:MODEF 4818 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))] 4819 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode)) 4820 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)" 4821 "@ 4822 fild%Z1\t%1 4823 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1} 4824 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}" 4825 [(set_attr "type" "fmov,sseicvt,sseicvt") 4826 (set_attr "avx_partial_xmm_update" "false,true,true") 4827 (set_attr "prefix" "orig,maybe_vex,maybe_vex") 4828 (set_attr "mode" "<MODEF:MODE>") 4829 (set (attr "prefix_rex") 4830 (if_then_else 4831 (and (eq_attr "prefix" "maybe_vex") 4832 (match_test "<SWI48:MODE>mode == DImode")) 4833 (const_string "1") 4834 (const_string "*"))) 4835 (set_attr "unit" "i387,*,*") 4836 (set_attr "athlon_decode" "*,double,direct") 4837 (set_attr "amdfam10_decode" "*,vector,double") 4838 (set_attr "bdver1_decode" "*,double,direct") 4839 (set_attr "znver1_decode" "double,*,*") 4840 (set_attr "fp_int_src" "true") 4841 (set (attr "enabled") 4842 (if_then_else 4843 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")) 4844 (if_then_else 4845 (eq_attr "alternative" "0") 4846 (symbol_ref "TARGET_MIX_SSE_I387 4847 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, 4848 <SWI48:MODE>mode)") 4849 (symbol_ref "true")) 4850 (if_then_else 4851 (eq_attr "alternative" "0") 4852 (symbol_ref "true") 4853 (symbol_ref "false")))) 4854 (set (attr "preferred_for_speed") 4855 (cond [(eq_attr "alternative" "1") 4856 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")] 4857 (symbol_ref "true")))]) 4858 4859(define_insn "*floatdi<MODEF:mode>2_i387" 4860 [(set (match_operand:MODEF 0 "register_operand" "=f") 4861 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))] 4862 "!TARGET_64BIT 4863 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)" 4864 "fild%Z1\t%1" 4865 [(set_attr "type" "fmov") 4866 (set_attr "mode" "<MODEF:MODE>") 4867 (set_attr "znver1_decode" "double") 4868 (set_attr "fp_int_src" "true")]) 4869 4870;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory 4871;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs 4872;; alternative in sse2_loadld. 4873(define_split 4874 [(set (match_operand:MODEF 0 "sse_reg_operand") 4875 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))] 4876 "TARGET_SSE2 4877 && TARGET_USE_VECTOR_CONVERTS 4878 && optimize_function_for_speed_p (cfun) 4879 && reload_completed 4880 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC) 4881 && (!EXT_REX_SSE_REG_P (operands[0]) 4882 || TARGET_AVX512VL)" 4883 [(const_int 0)] 4884{ 4885 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode); 4886 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode); 4887 4888 emit_insn (gen_sse2_loadld (operands[4], 4889 CONST0_RTX (V4SImode), operands[1])); 4890 4891 if (<ssevecmode>mode == V4SFmode) 4892 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4])); 4893 else 4894 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4])); 4895 DONE; 4896}) 4897 4898;; Avoid store forwarding (partial memory) stall penalty 4899;; by passing DImode value through XMM registers. */ 4900 4901(define_split 4902 [(set (match_operand:X87MODEF 0 "register_operand") 4903 (float:X87MODEF 4904 (match_operand:DI 1 "register_operand")))] 4905 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC 4906 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 4907 && TARGET_SSE2 && optimize_function_for_speed_p (cfun) 4908 && can_create_pseudo_p ()" 4909 [(const_int 0)] 4910{ 4911 emit_insn (gen_floatdi<mode>2_i387_with_xmm 4912 (operands[0], operands[1], 4913 assign_386_stack_local (DImode, SLOT_TEMP))); 4914 DONE; 4915}) 4916 4917(define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm" 4918 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f") 4919 (float:X87MODEF 4920 (match_operand:DI 1 "register_operand" "r,r"))) 4921 (clobber (match_operand:DI 2 "memory_operand" "=m,m")) 4922 (clobber (match_scratch:V4SI 3 "=x,x")) 4923 (clobber (match_scratch:V4SI 4 "=X,x"))] 4924 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC 4925 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 4926 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)" 4927 "#" 4928 "&& reload_completed" 4929 [(set (match_dup 2) (match_dup 3)) 4930 (set (match_dup 0) (float:X87MODEF (match_dup 2)))] 4931{ 4932 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). 4933 Assemble the 64-bit DImode value in an xmm register. */ 4934 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode), 4935 gen_lowpart (SImode, operands[1]))); 4936 if (TARGET_SSE4_1) 4937 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3], 4938 gen_highpart (SImode, operands[1]), 4939 GEN_INT (2))); 4940 else 4941 { 4942 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode), 4943 gen_highpart (SImode, operands[1]))); 4944 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3], 4945 operands[4])); 4946 } 4947 operands[3] = gen_lowpart (DImode, operands[3]); 4948} 4949 [(set_attr "isa" "sse4,*") 4950 (set_attr "type" "multi") 4951 (set_attr "mode" "<X87MODEF:MODE>") 4952 (set_attr "unit" "i387") 4953 (set_attr "fp_int_src" "true")]) 4954 4955;; Break partial SSE register dependency stall. This splitter should split 4956;; late in the pass sequence (after register rename pass), so allocated 4957;; registers won't change anymore 4958 4959(define_split 4960 [(set (match_operand:MODEF 0 "sse_reg_operand") 4961 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))] 4962 "!TARGET_AVX 4963 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed 4964 && optimize_function_for_speed_p (cfun) 4965 && (!EXT_REX_SSE_REG_P (operands[0]) 4966 || TARGET_AVX512VL)" 4967 [(set (match_dup 0) 4968 (vec_merge:<MODEF:ssevecmode> 4969 (vec_duplicate:<MODEF:ssevecmode> 4970 (float:MODEF 4971 (match_dup 1))) 4972 (match_dup 0) 4973 (const_int 1)))] 4974{ 4975 const machine_mode vmode = <MODEF:ssevecmode>mode; 4976 4977 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode); 4978 emit_move_insn (operands[0], CONST0_RTX (vmode)); 4979}) 4980 4981(define_expand "floatuns<SWI12:mode><MODEF:mode>2" 4982 [(set (match_operand:MODEF 0 "register_operand") 4983 (unsigned_float:MODEF 4984 (match_operand:SWI12 1 "nonimmediate_operand")))] 4985 "!TARGET_64BIT 4986 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH" 4987{ 4988 operands[1] = convert_to_mode (SImode, operands[1], 1); 4989 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1])); 4990 DONE; 4991}) 4992 4993(define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512" 4994 [(set (match_operand:MODEF 0 "register_operand" "=v") 4995 (unsigned_float:MODEF 4996 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))] 4997 "TARGET_AVX512F && TARGET_SSE_MATH" 4998 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}" 4999 [(set_attr "type" "sseicvt") 5000 (set_attr "avx_partial_xmm_update" "true") 5001 (set_attr "prefix" "evex") 5002 (set_attr "mode" "<MODEF:MODE>")]) 5003 5004;; Avoid store forwarding (partial memory) stall penalty by extending 5005;; SImode value to DImode through XMM register instead of pushing two 5006;; SImode values to stack. Also note that fild loads from memory only. 5007 5008(define_insn_and_split "floatunssi<mode>2_i387_with_xmm" 5009 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 5010 (unsigned_float:X87MODEF 5011 (match_operand:SI 1 "nonimmediate_operand" "rm"))) 5012 (clobber (match_operand:DI 2 "memory_operand" "=m")) 5013 (clobber (match_scratch:DI 3 "=x"))] 5014 "!TARGET_64BIT 5015 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5016 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC" 5017 "#" 5018 "&& reload_completed" 5019 [(set (match_dup 3) (zero_extend:DI (match_dup 1))) 5020 (set (match_dup 2) (match_dup 3)) 5021 (set (match_dup 0) 5022 (float:X87MODEF (match_dup 2)))] 5023 "" 5024 [(set_attr "type" "multi") 5025 (set_attr "mode" "<MODE>")]) 5026 5027(define_expand "floatunssi<mode>2" 5028 [(set (match_operand:X87MODEF 0 "register_operand") 5029 (unsigned_float:X87MODEF 5030 (match_operand:SI 1 "nonimmediate_operand")))] 5031 "(!TARGET_64BIT 5032 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode) 5033 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC) 5034 || ((!TARGET_64BIT || TARGET_AVX512F) 5035 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 5036{ 5037 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 5038 { 5039 emit_insn (gen_floatunssi<mode>2_i387_with_xmm 5040 (operands[0], operands[1], 5041 assign_386_stack_local (DImode, SLOT_TEMP))); 5042 DONE; 5043 } 5044 if (!TARGET_AVX512F) 5045 { 5046 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]); 5047 DONE; 5048 } 5049}) 5050 5051(define_expand "floatunsdisf2" 5052 [(set (match_operand:SF 0 "register_operand") 5053 (unsigned_float:SF 5054 (match_operand:DI 1 "nonimmediate_operand")))] 5055 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH" 5056{ 5057 if (!TARGET_AVX512F) 5058 { 5059 x86_emit_floatuns (operands); 5060 DONE; 5061 } 5062}) 5063 5064(define_expand "floatunsdidf2" 5065 [(set (match_operand:DF 0 "register_operand") 5066 (unsigned_float:DF 5067 (match_operand:DI 1 "nonimmediate_operand")))] 5068 "((TARGET_64BIT && TARGET_AVX512F) 5069 || TARGET_KEEPS_VECTOR_ALIGNED_STACK) 5070 && TARGET_SSE2 && TARGET_SSE_MATH" 5071{ 5072 if (!TARGET_64BIT) 5073 { 5074 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]); 5075 DONE; 5076 } 5077 if (!TARGET_AVX512F) 5078 { 5079 x86_emit_floatuns (operands); 5080 DONE; 5081 } 5082}) 5083 5084;; Load effective address instructions 5085 5086(define_insn_and_split "*lea<mode>" 5087 [(set (match_operand:SWI48 0 "register_operand" "=r") 5088 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))] 5089 "" 5090{ 5091 if (SImode_address_operand (operands[1], VOIDmode)) 5092 { 5093 gcc_assert (TARGET_64BIT); 5094 return "lea{l}\t{%E1, %k0|%k0, %E1}"; 5095 } 5096 else 5097 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"; 5098} 5099 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)" 5100 [(const_int 0)] 5101{ 5102 machine_mode mode = <MODE>mode; 5103 rtx pat; 5104 5105 /* ix86_avoid_lea_for_addr re-recognizes insn and may 5106 change operands[] array behind our back. */ 5107 pat = PATTERN (curr_insn); 5108 5109 operands[0] = SET_DEST (pat); 5110 operands[1] = SET_SRC (pat); 5111 5112 /* Emit all operations in SImode for zero-extended addresses. */ 5113 if (SImode_address_operand (operands[1], VOIDmode)) 5114 mode = SImode; 5115 5116 ix86_split_lea_for_addr (curr_insn, operands, mode); 5117 5118 /* Zero-extend return register to DImode for zero-extended addresses. */ 5119 if (mode != <MODE>mode) 5120 emit_insn (gen_zero_extendsidi2 5121 (operands[0], gen_lowpart (mode, operands[0]))); 5122 5123 DONE; 5124} 5125 [(set_attr "type" "lea") 5126 (set (attr "mode") 5127 (if_then_else 5128 (match_operand 1 "SImode_address_operand") 5129 (const_string "SI") 5130 (const_string "<MODE>")))]) 5131 5132;; Add instructions 5133 5134(define_expand "add<mode>3" 5135 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 5136 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand") 5137 (match_operand:SDWIM 2 "<general_hilo_operand>")))] 5138 "" 5139 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;") 5140 5141(define_insn_and_split "*add<dwi>3_doubleword" 5142 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r") 5143 (plus:<DWI> 5144 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0") 5145 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))) 5146 (clobber (reg:CC FLAGS_REG))] 5147 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)" 5148 "#" 5149 "reload_completed" 5150 [(parallel [(set (reg:CCC FLAGS_REG) 5151 (compare:CCC 5152 (plus:DWIH (match_dup 1) (match_dup 2)) 5153 (match_dup 1))) 5154 (set (match_dup 0) 5155 (plus:DWIH (match_dup 1) (match_dup 2)))]) 5156 (parallel [(set (match_dup 3) 5157 (plus:DWIH 5158 (plus:DWIH 5159 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5160 (match_dup 4)) 5161 (match_dup 5))) 5162 (clobber (reg:CC FLAGS_REG))])] 5163{ 5164 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 5165 if (operands[2] == const0_rtx) 5166 { 5167 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]); 5168 DONE; 5169 } 5170}) 5171 5172(define_insn "*add<mode>_1" 5173 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r") 5174 (plus:SWI48 5175 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r") 5176 (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le"))) 5177 (clobber (reg:CC FLAGS_REG))] 5178 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5179{ 5180 switch (get_attr_type (insn)) 5181 { 5182 case TYPE_LEA: 5183 return "#"; 5184 5185 case TYPE_INCDEC: 5186 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5187 if (operands[2] == const1_rtx) 5188 return "inc{<imodesuffix>}\t%0"; 5189 else 5190 { 5191 gcc_assert (operands[2] == constm1_rtx); 5192 return "dec{<imodesuffix>}\t%0"; 5193 } 5194 5195 default: 5196 /* For most processors, ADD is faster than LEA. This alternative 5197 was added to use ADD as much as possible. */ 5198 if (which_alternative == 2) 5199 std::swap (operands[1], operands[2]); 5200 5201 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5202 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5203 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5204 5205 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5206 } 5207} 5208 [(set (attr "type") 5209 (cond [(eq_attr "alternative" "3") 5210 (const_string "lea") 5211 (match_operand:SWI48 2 "incdec_operand") 5212 (const_string "incdec") 5213 ] 5214 (const_string "alu"))) 5215 (set (attr "length_immediate") 5216 (if_then_else 5217 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5218 (const_string "1") 5219 (const_string "*"))) 5220 (set_attr "mode" "<MODE>")]) 5221 5222;; It may seem that nonimmediate operand is proper one for operand 1. 5223;; The addsi_1 pattern allows nonimmediate operand at that place and 5224;; we take care in ix86_binary_operator_ok to not allow two memory 5225;; operands so proper swapping will be done in reload. This allow 5226;; patterns constructed from addsi_1 to match. 5227 5228(define_insn "addsi_1_zext" 5229 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 5230 (zero_extend:DI 5231 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r") 5232 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le")))) 5233 (clobber (reg:CC FLAGS_REG))] 5234 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 5235{ 5236 switch (get_attr_type (insn)) 5237 { 5238 case TYPE_LEA: 5239 return "#"; 5240 5241 case TYPE_INCDEC: 5242 if (operands[2] == const1_rtx) 5243 return "inc{l}\t%k0"; 5244 else 5245 { 5246 gcc_assert (operands[2] == constm1_rtx); 5247 return "dec{l}\t%k0"; 5248 } 5249 5250 default: 5251 /* For most processors, ADD is faster than LEA. This alternative 5252 was added to use ADD as much as possible. */ 5253 if (which_alternative == 1) 5254 std::swap (operands[1], operands[2]); 5255 5256 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5257 return "sub{l}\t{%2, %k0|%k0, %2}"; 5258 5259 return "add{l}\t{%2, %k0|%k0, %2}"; 5260 } 5261} 5262 [(set (attr "type") 5263 (cond [(eq_attr "alternative" "2") 5264 (const_string "lea") 5265 (match_operand:SI 2 "incdec_operand") 5266 (const_string "incdec") 5267 ] 5268 (const_string "alu"))) 5269 (set (attr "length_immediate") 5270 (if_then_else 5271 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5272 (const_string "1") 5273 (const_string "*"))) 5274 (set_attr "mode" "SI")]) 5275 5276(define_insn "*addhi_1" 5277 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp") 5278 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp") 5279 (match_operand:HI 2 "general_operand" "rn,m,0,ln"))) 5280 (clobber (reg:CC FLAGS_REG))] 5281 "ix86_binary_operator_ok (PLUS, HImode, operands)" 5282{ 5283 switch (get_attr_type (insn)) 5284 { 5285 case TYPE_LEA: 5286 return "#"; 5287 5288 case TYPE_INCDEC: 5289 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5290 if (operands[2] == const1_rtx) 5291 return "inc{w}\t%0"; 5292 else 5293 { 5294 gcc_assert (operands[2] == constm1_rtx); 5295 return "dec{w}\t%0"; 5296 } 5297 5298 default: 5299 /* For most processors, ADD is faster than LEA. This alternative 5300 was added to use ADD as much as possible. */ 5301 if (which_alternative == 2) 5302 std::swap (operands[1], operands[2]); 5303 5304 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5305 if (x86_maybe_negate_const_int (&operands[2], HImode)) 5306 return "sub{w}\t{%2, %0|%0, %2}"; 5307 5308 return "add{w}\t{%2, %0|%0, %2}"; 5309 } 5310} 5311 [(set (attr "type") 5312 (cond [(eq_attr "alternative" "3") 5313 (const_string "lea") 5314 (match_operand:HI 2 "incdec_operand") 5315 (const_string "incdec") 5316 ] 5317 (const_string "alu"))) 5318 (set (attr "length_immediate") 5319 (if_then_else 5320 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5321 (const_string "1") 5322 (const_string "*"))) 5323 (set_attr "mode" "HI,HI,HI,SI")]) 5324 5325(define_insn "*addqi_1" 5326 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp") 5327 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp") 5328 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln"))) 5329 (clobber (reg:CC FLAGS_REG))] 5330 "ix86_binary_operator_ok (PLUS, QImode, operands)" 5331{ 5332 bool widen = (get_attr_mode (insn) != MODE_QI); 5333 5334 switch (get_attr_type (insn)) 5335 { 5336 case TYPE_LEA: 5337 return "#"; 5338 5339 case TYPE_INCDEC: 5340 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5341 if (operands[2] == const1_rtx) 5342 return widen ? "inc{l}\t%k0" : "inc{b}\t%0"; 5343 else 5344 { 5345 gcc_assert (operands[2] == constm1_rtx); 5346 return widen ? "dec{l}\t%k0" : "dec{b}\t%0"; 5347 } 5348 5349 default: 5350 /* For most processors, ADD is faster than LEA. These alternatives 5351 were added to use ADD as much as possible. */ 5352 if (which_alternative == 2 || which_alternative == 4) 5353 std::swap (operands[1], operands[2]); 5354 5355 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5356 if (x86_maybe_negate_const_int (&operands[2], QImode)) 5357 { 5358 if (widen) 5359 return "sub{l}\t{%2, %k0|%k0, %2}"; 5360 else 5361 return "sub{b}\t{%2, %0|%0, %2}"; 5362 } 5363 if (widen) 5364 return "add{l}\t{%k2, %k0|%k0, %k2}"; 5365 else 5366 return "add{b}\t{%2, %0|%0, %2}"; 5367 } 5368} 5369 [(set (attr "type") 5370 (cond [(eq_attr "alternative" "5") 5371 (const_string "lea") 5372 (match_operand:QI 2 "incdec_operand") 5373 (const_string "incdec") 5374 ] 5375 (const_string "alu"))) 5376 (set (attr "length_immediate") 5377 (if_then_else 5378 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5379 (const_string "1") 5380 (const_string "*"))) 5381 (set_attr "mode" "QI,QI,QI,SI,SI,SI") 5382 ;; Potential partial reg stall on alternatives 3 and 4. 5383 (set (attr "preferred_for_speed") 5384 (cond [(eq_attr "alternative" "3,4") 5385 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 5386 (symbol_ref "true")))]) 5387 5388(define_insn "*add<mode>_1_slp" 5389 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 5390 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0") 5391 (match_operand:SWI12 2 "general_operand" "<r>mn"))) 5392 (clobber (reg:CC FLAGS_REG))] 5393 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 5394 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 5395 && (rtx_equal_p (operands[0], operands[1]) 5396 || rtx_equal_p (operands[0], operands[2]))" 5397{ 5398 switch (get_attr_type (insn)) 5399 { 5400 case TYPE_INCDEC: 5401 if (operands[2] == const1_rtx) 5402 return "inc{<imodesuffix>}\t%0"; 5403 else 5404 { 5405 gcc_assert (operands[2] == constm1_rtx); 5406 return "dec{<imodesuffix>}\t%0"; 5407 } 5408 5409 default: 5410 if (x86_maybe_negate_const_int (&operands[2], QImode)) 5411 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5412 5413 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5414 } 5415} 5416 [(set (attr "type") 5417 (if_then_else (match_operand:QI 2 "incdec_operand") 5418 (const_string "incdec") 5419 (const_string "alu"))) 5420 (set_attr "mode" "<MODE>")]) 5421 5422;; Split non destructive adds if we cannot use lea. 5423(define_split 5424 [(set (match_operand:SWI48 0 "register_operand") 5425 (plus:SWI48 (match_operand:SWI48 1 "register_operand") 5426 (match_operand:SWI48 2 "x86_64_nonmemory_operand"))) 5427 (clobber (reg:CC FLAGS_REG))] 5428 "reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5429 [(set (match_dup 0) (match_dup 1)) 5430 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2))) 5431 (clobber (reg:CC FLAGS_REG))])]) 5432 5433;; Split non destructive adds if we cannot use lea. 5434(define_split 5435 [(set (match_operand:DI 0 "register_operand") 5436 (zero_extend:DI 5437 (plus:SI (match_operand:SI 1 "register_operand") 5438 (match_operand:SI 2 "x86_64_nonmemory_operand")))) 5439 (clobber (reg:CC FLAGS_REG))] 5440 "TARGET_64BIT 5441 && reload_completed && ix86_avoid_lea_for_add (insn, operands)" 5442 [(set (match_dup 3) (match_dup 1)) 5443 (parallel [(set (match_dup 0) 5444 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2)))) 5445 (clobber (reg:CC FLAGS_REG))])] 5446 "operands[3] = gen_lowpart (SImode, operands[0]);") 5447 5448;; Convert add to the lea pattern to avoid flags dependency. 5449(define_split 5450 [(set (match_operand:SWI 0 "register_operand") 5451 (plus:SWI (match_operand:SWI 1 "register_operand") 5452 (match_operand:SWI 2 "<nonmemory_operand>"))) 5453 (clobber (reg:CC FLAGS_REG))] 5454 "reload_completed && ix86_lea_for_add_ok (insn, operands)" 5455 [(set (match_dup 0) 5456 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))] 5457{ 5458 if (<MODE>mode != <LEAMODE>mode) 5459 { 5460 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]); 5461 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]); 5462 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]); 5463 } 5464}) 5465 5466;; Convert add to the lea pattern to avoid flags dependency. 5467(define_split 5468 [(set (match_operand:DI 0 "register_operand") 5469 (zero_extend:DI 5470 (plus:SI (match_operand:SI 1 "register_operand") 5471 (match_operand:SI 2 "x86_64_nonmemory_operand")))) 5472 (clobber (reg:CC FLAGS_REG))] 5473 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)" 5474 [(set (match_dup 0) 5475 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]) 5476 5477(define_insn "*add<mode>_2" 5478 [(set (reg FLAGS_REG) 5479 (compare 5480 (plus:SWI 5481 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>") 5482 (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0")) 5483 (const_int 0))) 5484 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>") 5485 (plus:SWI (match_dup 1) (match_dup 2)))] 5486 "ix86_match_ccmode (insn, CCGOCmode) 5487 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5488{ 5489 switch (get_attr_type (insn)) 5490 { 5491 case TYPE_INCDEC: 5492 if (operands[2] == const1_rtx) 5493 return "inc{<imodesuffix>}\t%0"; 5494 else 5495 { 5496 gcc_assert (operands[2] == constm1_rtx); 5497 return "dec{<imodesuffix>}\t%0"; 5498 } 5499 5500 default: 5501 if (which_alternative == 2) 5502 std::swap (operands[1], operands[2]); 5503 5504 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5505 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5506 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5507 5508 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5509 } 5510} 5511 [(set (attr "type") 5512 (if_then_else (match_operand:SWI 2 "incdec_operand") 5513 (const_string "incdec") 5514 (const_string "alu"))) 5515 (set (attr "length_immediate") 5516 (if_then_else 5517 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5518 (const_string "1") 5519 (const_string "*"))) 5520 (set_attr "mode" "<MODE>")]) 5521 5522;; See comment for addsi_1_zext why we do use nonimmediate_operand 5523(define_insn "*addsi_2_zext" 5524 [(set (reg FLAGS_REG) 5525 (compare 5526 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r") 5527 (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5528 (const_int 0))) 5529 (set (match_operand:DI 0 "register_operand" "=r,r") 5530 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5531 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 5532 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5533{ 5534 switch (get_attr_type (insn)) 5535 { 5536 case TYPE_INCDEC: 5537 if (operands[2] == const1_rtx) 5538 return "inc{l}\t%k0"; 5539 else 5540 { 5541 gcc_assert (operands[2] == constm1_rtx); 5542 return "dec{l}\t%k0"; 5543 } 5544 5545 default: 5546 if (which_alternative == 1) 5547 std::swap (operands[1], operands[2]); 5548 5549 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5550 return "sub{l}\t{%2, %k0|%k0, %2}"; 5551 5552 return "add{l}\t{%2, %k0|%k0, %2}"; 5553 } 5554} 5555 [(set (attr "type") 5556 (if_then_else (match_operand:SI 2 "incdec_operand") 5557 (const_string "incdec") 5558 (const_string "alu"))) 5559 (set (attr "length_immediate") 5560 (if_then_else 5561 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5562 (const_string "1") 5563 (const_string "*"))) 5564 (set_attr "mode" "SI")]) 5565 5566(define_insn "*add<mode>_3" 5567 [(set (reg FLAGS_REG) 5568 (compare 5569 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0")) 5570 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>"))) 5571 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 5572 "ix86_match_ccmode (insn, CCZmode) 5573 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 5574{ 5575 switch (get_attr_type (insn)) 5576 { 5577 case TYPE_INCDEC: 5578 if (operands[2] == const1_rtx) 5579 return "inc{<imodesuffix>}\t%0"; 5580 else 5581 { 5582 gcc_assert (operands[2] == constm1_rtx); 5583 return "dec{<imodesuffix>}\t%0"; 5584 } 5585 5586 default: 5587 if (which_alternative == 1) 5588 std::swap (operands[1], operands[2]); 5589 5590 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5591 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5592 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5593 5594 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5595 } 5596} 5597 [(set (attr "type") 5598 (if_then_else (match_operand:SWI 2 "incdec_operand") 5599 (const_string "incdec") 5600 (const_string "alu"))) 5601 (set (attr "length_immediate") 5602 (if_then_else 5603 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5604 (const_string "1") 5605 (const_string "*"))) 5606 (set_attr "mode" "<MODE>")]) 5607 5608;; See comment for addsi_1_zext why we do use nonimmediate_operand 5609(define_insn "*addsi_3_zext" 5610 [(set (reg FLAGS_REG) 5611 (compare 5612 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0")) 5613 (match_operand:SI 1 "nonimmediate_operand" "%0,r"))) 5614 (set (match_operand:DI 0 "register_operand" "=r,r") 5615 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 5616 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode) 5617 && ix86_binary_operator_ok (PLUS, SImode, operands)" 5618{ 5619 switch (get_attr_type (insn)) 5620 { 5621 case TYPE_INCDEC: 5622 if (operands[2] == const1_rtx) 5623 return "inc{l}\t%k0"; 5624 else 5625 { 5626 gcc_assert (operands[2] == constm1_rtx); 5627 return "dec{l}\t%k0"; 5628 } 5629 5630 default: 5631 if (which_alternative == 1) 5632 std::swap (operands[1], operands[2]); 5633 5634 if (x86_maybe_negate_const_int (&operands[2], SImode)) 5635 return "sub{l}\t{%2, %k0|%k0, %2}"; 5636 5637 return "add{l}\t{%2, %k0|%k0, %2}"; 5638 } 5639} 5640 [(set (attr "type") 5641 (if_then_else (match_operand:SI 2 "incdec_operand") 5642 (const_string "incdec") 5643 (const_string "alu"))) 5644 (set (attr "length_immediate") 5645 (if_then_else 5646 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5647 (const_string "1") 5648 (const_string "*"))) 5649 (set_attr "mode" "SI")]) 5650 5651; For comparisons against 1, -1 and 128, we may generate better code 5652; by converting cmp to add, inc or dec as done by peephole2. This pattern 5653; is matched then. We can't accept general immediate, because for 5654; case of overflows, the result is messed up. 5655; Also carry flag is reversed compared to cmp, so this conversion is valid 5656; only for comparisons not depending on it. 5657 5658(define_insn "*adddi_4" 5659 [(set (reg FLAGS_REG) 5660 (compare 5661 (match_operand:DI 1 "nonimmediate_operand" "0") 5662 (match_operand:DI 2 "x86_64_immediate_operand" "e"))) 5663 (clobber (match_scratch:DI 0 "=rm"))] 5664 "TARGET_64BIT 5665 && ix86_match_ccmode (insn, CCGCmode)" 5666{ 5667 switch (get_attr_type (insn)) 5668 { 5669 case TYPE_INCDEC: 5670 if (operands[2] == constm1_rtx) 5671 return "inc{q}\t%0"; 5672 else 5673 { 5674 gcc_assert (operands[2] == const1_rtx); 5675 return "dec{q}\t%0"; 5676 } 5677 5678 default: 5679 if (x86_maybe_negate_const_int (&operands[2], DImode)) 5680 return "add{q}\t{%2, %0|%0, %2}"; 5681 5682 return "sub{q}\t{%2, %0|%0, %2}"; 5683 } 5684} 5685 [(set (attr "type") 5686 (if_then_else (match_operand:DI 2 "incdec_operand") 5687 (const_string "incdec") 5688 (const_string "alu"))) 5689 (set (attr "length_immediate") 5690 (if_then_else 5691 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5692 (const_string "1") 5693 (const_string "*"))) 5694 (set_attr "mode" "DI")]) 5695 5696; For comparisons against 1, -1 and 128, we may generate better code 5697; by converting cmp to add, inc or dec as done by peephole2. This pattern 5698; is matched then. We can't accept general immediate, because for 5699; case of overflows, the result is messed up. 5700; Also carry flag is reversed compared to cmp, so this conversion is valid 5701; only for comparisons not depending on it. 5702 5703(define_insn "*add<mode>_4" 5704 [(set (reg FLAGS_REG) 5705 (compare 5706 (match_operand:SWI124 1 "nonimmediate_operand" "0") 5707 (match_operand:SWI124 2 "const_int_operand" "n"))) 5708 (clobber (match_scratch:SWI124 0 "=<r>m"))] 5709 "ix86_match_ccmode (insn, CCGCmode)" 5710{ 5711 switch (get_attr_type (insn)) 5712 { 5713 case TYPE_INCDEC: 5714 if (operands[2] == constm1_rtx) 5715 return "inc{<imodesuffix>}\t%0"; 5716 else 5717 { 5718 gcc_assert (operands[2] == const1_rtx); 5719 return "dec{<imodesuffix>}\t%0"; 5720 } 5721 5722 default: 5723 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5724 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5725 5726 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5727 } 5728} 5729 [(set (attr "type") 5730 (if_then_else (match_operand:<MODE> 2 "incdec_operand") 5731 (const_string "incdec") 5732 (const_string "alu"))) 5733 (set (attr "length_immediate") 5734 (if_then_else 5735 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5736 (const_string "1") 5737 (const_string "*"))) 5738 (set_attr "mode" "<MODE>")]) 5739 5740(define_insn "*add<mode>_5" 5741 [(set (reg FLAGS_REG) 5742 (compare 5743 (plus:SWI 5744 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>") 5745 (match_operand:SWI 2 "<general_operand>" "<g>,0")) 5746 (const_int 0))) 5747 (clobber (match_scratch:SWI 0 "=<r>,<r>"))] 5748 "ix86_match_ccmode (insn, CCGOCmode) 5749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 5750{ 5751 switch (get_attr_type (insn)) 5752 { 5753 case TYPE_INCDEC: 5754 if (operands[2] == const1_rtx) 5755 return "inc{<imodesuffix>}\t%0"; 5756 else 5757 { 5758 gcc_assert (operands[2] == constm1_rtx); 5759 return "dec{<imodesuffix>}\t%0"; 5760 } 5761 5762 default: 5763 if (which_alternative == 1) 5764 std::swap (operands[1], operands[2]); 5765 5766 gcc_assert (rtx_equal_p (operands[0], operands[1])); 5767 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 5768 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 5769 5770 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 5771 } 5772} 5773 [(set (attr "type") 5774 (if_then_else (match_operand:SWI 2 "incdec_operand") 5775 (const_string "incdec") 5776 (const_string "alu"))) 5777 (set (attr "length_immediate") 5778 (if_then_else 5779 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand")) 5780 (const_string "1") 5781 (const_string "*"))) 5782 (set_attr "mode" "<MODE>")]) 5783 5784(define_insn "addqi_ext_1" 5785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 5786 (const_int 8) 5787 (const_int 8)) 5788 (subreg:SI 5789 (plus:QI 5790 (subreg:QI 5791 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 5792 (const_int 8) 5793 (const_int 8)) 0) 5794 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 5795 (clobber (reg:CC FLAGS_REG))] 5796 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 5797 rtx_equal_p (operands[0], operands[1])" 5798{ 5799 switch (get_attr_type (insn)) 5800 { 5801 case TYPE_INCDEC: 5802 if (operands[2] == const1_rtx) 5803 return "inc{b}\t%h0"; 5804 else 5805 { 5806 gcc_assert (operands[2] == constm1_rtx); 5807 return "dec{b}\t%h0"; 5808 } 5809 5810 default: 5811 return "add{b}\t{%2, %h0|%h0, %2}"; 5812 } 5813} 5814 [(set_attr "isa" "*,nox64") 5815 (set (attr "type") 5816 (if_then_else (match_operand:QI 2 "incdec_operand") 5817 (const_string "incdec") 5818 (const_string "alu"))) 5819 (set_attr "mode" "QI")]) 5820 5821(define_insn "*addqi_ext_2" 5822 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 5823 (const_int 8) 5824 (const_int 8)) 5825 (subreg:SI 5826 (plus:QI 5827 (subreg:QI 5828 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 5829 (const_int 8) 5830 (const_int 8)) 0) 5831 (subreg:QI 5832 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 5833 (const_int 8) 5834 (const_int 8)) 0)) 0)) 5835 (clobber (reg:CC FLAGS_REG))] 5836 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 5837 rtx_equal_p (operands[0], operands[1]) 5838 || rtx_equal_p (operands[0], operands[2])" 5839 "add{b}\t{%h2, %h0|%h0, %h2}" 5840 [(set_attr "type" "alu") 5841 (set_attr "mode" "QI")]) 5842 5843;; Like DWI, but use POImode instead of OImode. 5844(define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")]) 5845 5846;; Add with jump on overflow. 5847(define_expand "addv<mode>4" 5848 [(parallel [(set (reg:CCO FLAGS_REG) 5849 (eq:CCO 5850 (plus:<DPWI> 5851 (sign_extend:<DPWI> 5852 (match_operand:SWIDWI 1 "nonimmediate_operand")) 5853 (match_dup 4)) 5854 (sign_extend:<DPWI> 5855 (plus:SWIDWI (match_dup 1) 5856 (match_operand:SWIDWI 2 5857 "<general_hilo_operand>"))))) 5858 (set (match_operand:SWIDWI 0 "register_operand") 5859 (plus:SWIDWI (match_dup 1) (match_dup 2)))]) 5860 (set (pc) (if_then_else 5861 (eq (reg:CCO FLAGS_REG) (const_int 0)) 5862 (label_ref (match_operand 3)) 5863 (pc)))] 5864 "" 5865{ 5866 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands); 5867 if (CONST_SCALAR_INT_P (operands[2])) 5868 operands[4] = operands[2]; 5869 else 5870 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]); 5871}) 5872 5873(define_insn "*addv<mode>4" 5874 [(set (reg:CCO FLAGS_REG) 5875 (eq:CCO (plus:<DWI> 5876 (sign_extend:<DWI> 5877 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) 5878 (sign_extend:<DWI> 5879 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m"))) 5880 (sign_extend:<DWI> 5881 (plus:SWI (match_dup 1) (match_dup 2))))) 5882 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 5883 (plus:SWI (match_dup 1) (match_dup 2)))] 5884 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 5885 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 5886 [(set_attr "type" "alu") 5887 (set_attr "mode" "<MODE>")]) 5888 5889(define_insn "addv<mode>4_1" 5890 [(set (reg:CCO FLAGS_REG) 5891 (eq:CCO (plus:<DWI> 5892 (sign_extend:<DWI> 5893 (match_operand:SWI 1 "nonimmediate_operand" "0")) 5894 (match_operand:<DWI> 3 "const_int_operand" "i")) 5895 (sign_extend:<DWI> 5896 (plus:SWI 5897 (match_dup 1) 5898 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>"))))) 5899 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 5900 (plus:SWI (match_dup 1) (match_dup 2)))] 5901 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands) 5902 && CONST_INT_P (operands[2]) 5903 && INTVAL (operands[2]) == INTVAL (operands[3])" 5904 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 5905 [(set_attr "type" "alu") 5906 (set_attr "mode" "<MODE>") 5907 (set (attr "length_immediate") 5908 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 5909 (const_string "1") 5910 (match_test "<MODE_SIZE> == 8") 5911 (const_string "4")] 5912 (const_string "<MODE_SIZE>")))]) 5913 5914;; Quad word integer modes as mode attribute. 5915(define_mode_attr QPWI [(SI "TI") (DI "POI")]) 5916 5917(define_insn_and_split "*addv<dwi>4_doubleword" 5918 [(set (reg:CCO FLAGS_REG) 5919 (eq:CCO 5920 (plus:<QPWI> 5921 (sign_extend:<QPWI> 5922 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")) 5923 (sign_extend:<QPWI> 5924 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o"))) 5925 (sign_extend:<QPWI> 5926 (plus:<DWI> (match_dup 1) (match_dup 2))))) 5927 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r") 5928 (plus:<DWI> (match_dup 1) (match_dup 2)))] 5929 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)" 5930 "#" 5931 "reload_completed" 5932 [(parallel [(set (reg:CCC FLAGS_REG) 5933 (compare:CCC 5934 (plus:DWIH (match_dup 1) (match_dup 2)) 5935 (match_dup 1))) 5936 (set (match_dup 0) 5937 (plus:DWIH (match_dup 1) (match_dup 2)))]) 5938 (parallel [(set (reg:CCO FLAGS_REG) 5939 (eq:CCO 5940 (plus:<DWI> 5941 (plus:<DWI> 5942 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)) 5943 (sign_extend:<DWI> (match_dup 4))) 5944 (sign_extend:<DWI> (match_dup 5))) 5945 (sign_extend:<DWI> 5946 (plus:DWIH 5947 (plus:DWIH 5948 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5949 (match_dup 4)) 5950 (match_dup 5))))) 5951 (set (match_dup 3) 5952 (plus:DWIH 5953 (plus:DWIH 5954 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5955 (match_dup 4)) 5956 (match_dup 5)))])] 5957{ 5958 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 5959}) 5960 5961(define_insn_and_split "*addv<dwi>4_doubleword_1" 5962 [(set (reg:CCO FLAGS_REG) 5963 (eq:CCO 5964 (plus:<QPWI> 5965 (sign_extend:<QPWI> 5966 (match_operand:<DWI> 1 "nonimmediate_operand" "%0")) 5967 (match_operand:<QPWI> 3 "const_scalar_int_operand" "")) 5968 (sign_extend:<QPWI> 5969 (plus:<DWI> 5970 (match_dup 1) 5971 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>"))))) 5972 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 5973 (plus:<DWI> (match_dup 1) (match_dup 2)))] 5974 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands) 5975 && CONST_SCALAR_INT_P (operands[2]) 5976 && rtx_equal_p (operands[2], operands[3])" 5977 "#" 5978 "reload_completed" 5979 [(parallel [(set (reg:CCC FLAGS_REG) 5980 (compare:CCC 5981 (plus:DWIH (match_dup 1) (match_dup 2)) 5982 (match_dup 1))) 5983 (set (match_dup 0) 5984 (plus:DWIH (match_dup 1) (match_dup 2)))]) 5985 (parallel [(set (reg:CCO FLAGS_REG) 5986 (eq:CCO 5987 (plus:<DWI> 5988 (plus:<DWI> 5989 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)) 5990 (sign_extend:<DWI> (match_dup 4))) 5991 (match_dup 5)) 5992 (sign_extend:<DWI> 5993 (plus:DWIH 5994 (plus:DWIH 5995 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 5996 (match_dup 4)) 5997 (match_dup 5))))) 5998 (set (match_dup 3) 5999 (plus:DWIH 6000 (plus:DWIH 6001 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 6002 (match_dup 4)) 6003 (match_dup 5)))])] 6004{ 6005 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 6006 if (operands[2] == const0_rtx) 6007 { 6008 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5], 6009 operands[5])); 6010 DONE; 6011 } 6012}) 6013 6014(define_insn "*addv<mode>4_overflow_1" 6015 [(set (reg:CCO FLAGS_REG) 6016 (eq:CCO 6017 (plus:<DWI> 6018 (plus:<DWI> 6019 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 6020 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6021 (sign_extend:<DWI> 6022 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))) 6023 (sign_extend:<DWI> 6024 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m"))) 6025 (sign_extend:<DWI> 6026 (plus:SWI 6027 (plus:SWI 6028 (match_operator:SWI 5 "ix86_carry_flag_operator" 6029 [(match_dup 3) (const_int 0)]) 6030 (match_dup 1)) 6031 (match_dup 2))))) 6032 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r") 6033 (plus:SWI 6034 (plus:SWI 6035 (match_op_dup 5 [(match_dup 3) (const_int 0)]) 6036 (match_dup 1)) 6037 (match_dup 2)))] 6038 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6039 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6040 [(set_attr "type" "alu") 6041 (set_attr "mode" "<MODE>")]) 6042 6043(define_insn "*addv<mode>4_overflow_2" 6044 [(set (reg:CCO FLAGS_REG) 6045 (eq:CCO 6046 (plus:<DWI> 6047 (plus:<DWI> 6048 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 6049 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6050 (sign_extend:<DWI> 6051 (match_operand:SWI 1 "nonimmediate_operand" "%0"))) 6052 (match_operand:<DWI> 6 "const_int_operand" "")) 6053 (sign_extend:<DWI> 6054 (plus:SWI 6055 (plus:SWI 6056 (match_operator:SWI 5 "ix86_carry_flag_operator" 6057 [(match_dup 3) (const_int 0)]) 6058 (match_dup 1)) 6059 (match_operand:SWI 2 "x86_64_immediate_operand" "e"))))) 6060 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm") 6061 (plus:SWI 6062 (plus:SWI 6063 (match_op_dup 5 [(match_dup 3) (const_int 0)]) 6064 (match_dup 1)) 6065 (match_dup 2)))] 6066 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands) 6067 && CONST_INT_P (operands[2]) 6068 && INTVAL (operands[2]) == INTVAL (operands[6])" 6069 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6070 [(set_attr "type" "alu") 6071 (set_attr "mode" "<MODE>") 6072 (set (attr "length_immediate") 6073 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 6074 (const_string "1") 6075 (const_string "4")))]) 6076 6077(define_expand "uaddv<mode>4" 6078 [(parallel [(set (reg:CCC FLAGS_REG) 6079 (compare:CCC 6080 (plus:SWIDWI 6081 (match_operand:SWIDWI 1 "nonimmediate_operand") 6082 (match_operand:SWIDWI 2 "<general_hilo_operand>")) 6083 (match_dup 1))) 6084 (set (match_operand:SWIDWI 0 "register_operand") 6085 (plus:SWIDWI (match_dup 1) (match_dup 2)))]) 6086 (set (pc) (if_then_else 6087 (ltu (reg:CCC FLAGS_REG) (const_int 0)) 6088 (label_ref (match_operand 3)) 6089 (pc)))] 6090 "" 6091 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);") 6092 6093;; The lea patterns for modes less than 32 bits need to be matched by 6094;; several insns converted to real lea by splitters. 6095 6096(define_insn_and_split "*lea<mode>_general_1" 6097 [(set (match_operand:SWI12 0 "register_operand" "=r") 6098 (plus:SWI12 6099 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6100 (match_operand:SWI12 2 "register_operand" "r")) 6101 (match_operand:SWI12 3 "immediate_operand" "i")))] 6102 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6103 "#" 6104 "&& reload_completed" 6105 [(set (match_dup 0) 6106 (plus:SI 6107 (plus:SI (match_dup 1) (match_dup 2)) 6108 (match_dup 3)))] 6109{ 6110 operands[0] = gen_lowpart (SImode, operands[0]); 6111 operands[1] = gen_lowpart (SImode, operands[1]); 6112 operands[2] = gen_lowpart (SImode, operands[2]); 6113 operands[3] = gen_lowpart (SImode, operands[3]); 6114} 6115 [(set_attr "type" "lea") 6116 (set_attr "mode" "SI")]) 6117 6118(define_insn_and_split "*lea<mode>_general_2" 6119 [(set (match_operand:SWI12 0 "register_operand" "=r") 6120 (plus:SWI12 6121 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6122 (match_operand 2 "const248_operand" "n")) 6123 (match_operand:SWI12 3 "nonmemory_operand" "ri")))] 6124 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6125 "#" 6126 "&& reload_completed" 6127 [(set (match_dup 0) 6128 (plus:SI 6129 (mult:SI (match_dup 1) (match_dup 2)) 6130 (match_dup 3)))] 6131{ 6132 operands[0] = gen_lowpart (SImode, operands[0]); 6133 operands[1] = gen_lowpart (SImode, operands[1]); 6134 operands[3] = gen_lowpart (SImode, operands[3]); 6135} 6136 [(set_attr "type" "lea") 6137 (set_attr "mode" "SI")]) 6138 6139(define_insn_and_split "*lea<mode>_general_2b" 6140 [(set (match_operand:SWI12 0 "register_operand" "=r") 6141 (plus:SWI12 6142 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6143 (match_operand 2 "const123_operand" "n")) 6144 (match_operand:SWI12 3 "nonmemory_operand" "ri")))] 6145 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6146 "#" 6147 "&& reload_completed" 6148 [(set (match_dup 0) 6149 (plus:SI 6150 (ashift:SI (match_dup 1) (match_dup 2)) 6151 (match_dup 3)))] 6152{ 6153 operands[0] = gen_lowpart (SImode, operands[0]); 6154 operands[1] = gen_lowpart (SImode, operands[1]); 6155 operands[3] = gen_lowpart (SImode, operands[3]); 6156} 6157 [(set_attr "type" "lea") 6158 (set_attr "mode" "SI")]) 6159 6160(define_insn_and_split "*lea<mode>_general_3" 6161 [(set (match_operand:SWI12 0 "register_operand" "=r") 6162 (plus:SWI12 6163 (plus:SWI12 6164 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6165 (match_operand 2 "const248_operand" "n")) 6166 (match_operand:SWI12 3 "register_operand" "r")) 6167 (match_operand:SWI12 4 "immediate_operand" "i")))] 6168 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6169 "#" 6170 "&& reload_completed" 6171 [(set (match_dup 0) 6172 (plus:SI 6173 (plus:SI 6174 (mult:SI (match_dup 1) (match_dup 2)) 6175 (match_dup 3)) 6176 (match_dup 4)))] 6177{ 6178 operands[0] = gen_lowpart (SImode, operands[0]); 6179 operands[1] = gen_lowpart (SImode, operands[1]); 6180 operands[3] = gen_lowpart (SImode, operands[3]); 6181 operands[4] = gen_lowpart (SImode, operands[4]); 6182} 6183 [(set_attr "type" "lea") 6184 (set_attr "mode" "SI")]) 6185 6186(define_insn_and_split "*lea<mode>_general_3b" 6187 [(set (match_operand:SWI12 0 "register_operand" "=r") 6188 (plus:SWI12 6189 (plus:SWI12 6190 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l") 6191 (match_operand 2 "const123_operand" "n")) 6192 (match_operand:SWI12 3 "register_operand" "r")) 6193 (match_operand:SWI12 4 "immediate_operand" "i")))] 6194 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)" 6195 "#" 6196 "&& reload_completed" 6197 [(set (match_dup 0) 6198 (plus:SI 6199 (plus:SI 6200 (ashift:SI (match_dup 1) (match_dup 2)) 6201 (match_dup 3)) 6202 (match_dup 4)))] 6203{ 6204 operands[0] = gen_lowpart (SImode, operands[0]); 6205 operands[1] = gen_lowpart (SImode, operands[1]); 6206 operands[3] = gen_lowpart (SImode, operands[3]); 6207 operands[4] = gen_lowpart (SImode, operands[4]); 6208} 6209 [(set_attr "type" "lea") 6210 (set_attr "mode" "SI")]) 6211 6212(define_insn_and_split "*lea<mode>_general_4" 6213 [(set (match_operand:SWI12 0 "register_operand" "=r") 6214 (any_or:SWI12 6215 (ashift:SWI12 6216 (match_operand:SWI12 1 "index_register_operand" "l") 6217 (match_operand 2 "const_0_to_3_operand" "n")) 6218 (match_operand 3 "const_int_operand" "n")))] 6219 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6220 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3]) 6221 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))" 6222 "#" 6223 "&& reload_completed" 6224 [(set (match_dup 0) 6225 (plus:SI 6226 (mult:SI (match_dup 1) (match_dup 2)) 6227 (match_dup 3)))] 6228{ 6229 operands[0] = gen_lowpart (SImode, operands[0]); 6230 operands[1] = gen_lowpart (SImode, operands[1]); 6231 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 6232} 6233 [(set_attr "type" "lea") 6234 (set_attr "mode" "SI")]) 6235 6236(define_insn_and_split "*lea<mode>_general_4" 6237 [(set (match_operand:SWI48 0 "register_operand" "=r") 6238 (any_or:SWI48 6239 (ashift:SWI48 6240 (match_operand:SWI48 1 "index_register_operand" "l") 6241 (match_operand 2 "const_0_to_3_operand" "n")) 6242 (match_operand 3 "const_int_operand" "n")))] 6243 "(unsigned HOST_WIDE_INT) INTVAL (operands[3]) 6244 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))" 6245 "#" 6246 "&& reload_completed" 6247 [(set (match_dup 0) 6248 (plus:SWI48 6249 (mult:SWI48 (match_dup 1) (match_dup 2)) 6250 (match_dup 3)))] 6251 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));" 6252 [(set_attr "type" "lea") 6253 (set_attr "mode" "<MODE>")]) 6254 6255;; Subtract instructions 6256 6257(define_expand "sub<mode>3" 6258 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 6259 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand") 6260 (match_operand:SDWIM 2 "<general_hilo_operand>")))] 6261 "" 6262 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;") 6263 6264(define_insn_and_split "*sub<dwi>3_doubleword" 6265 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r") 6266 (minus:<DWI> 6267 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0") 6268 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))) 6269 (clobber (reg:CC FLAGS_REG))] 6270 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6271 "#" 6272 "reload_completed" 6273 [(parallel [(set (reg:CC FLAGS_REG) 6274 (compare:CC (match_dup 1) (match_dup 2))) 6275 (set (match_dup 0) 6276 (minus:DWIH (match_dup 1) (match_dup 2)))]) 6277 (parallel [(set (match_dup 3) 6278 (minus:DWIH 6279 (minus:DWIH 6280 (match_dup 4) 6281 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))) 6282 (match_dup 5))) 6283 (clobber (reg:CC FLAGS_REG))])] 6284{ 6285 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 6286 if (operands[2] == const0_rtx) 6287 { 6288 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]); 6289 DONE; 6290 } 6291}) 6292 6293(define_insn "*sub<mode>_1" 6294 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6295 (minus:SWI 6296 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6297 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) 6298 (clobber (reg:CC FLAGS_REG))] 6299 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6300 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6301 [(set_attr "type" "alu") 6302 (set_attr "mode" "<MODE>")]) 6303 6304(define_insn "*subsi_1_zext" 6305 [(set (match_operand:DI 0 "register_operand" "=r") 6306 (zero_extend:DI 6307 (minus:SI (match_operand:SI 1 "register_operand" "0") 6308 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6309 (clobber (reg:CC FLAGS_REG))] 6310 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6311 "sub{l}\t{%2, %k0|%k0, %2}" 6312 [(set_attr "type" "alu") 6313 (set_attr "mode" "SI")]) 6314 6315(define_insn "*sub<mode>_1_slp" 6316 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 6317 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0") 6318 (match_operand:SWI12 2 "general_operand" "<r>mn"))) 6319 (clobber (reg:CC FLAGS_REG))] 6320 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 6321 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 6322 && rtx_equal_p (operands[0], operands[1])" 6323 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6324 [(set_attr "type" "alu") 6325 (set_attr "mode" "<MODE>")]) 6326 6327(define_insn "*sub<mode>_2" 6328 [(set (reg FLAGS_REG) 6329 (compare 6330 (minus:SWI 6331 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6332 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) 6333 (const_int 0))) 6334 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6335 (minus:SWI (match_dup 1) (match_dup 2)))] 6336 "ix86_match_ccmode (insn, CCGOCmode) 6337 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6338 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6339 [(set_attr "type" "alu") 6340 (set_attr "mode" "<MODE>")]) 6341 6342(define_insn "*subsi_2_zext" 6343 [(set (reg FLAGS_REG) 6344 (compare 6345 (minus:SI (match_operand:SI 1 "register_operand" "0") 6346 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6347 (const_int 0))) 6348 (set (match_operand:DI 0 "register_operand" "=r") 6349 (zero_extend:DI 6350 (minus:SI (match_dup 1) 6351 (match_dup 2))))] 6352 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode) 6353 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6354 "sub{l}\t{%2, %k0|%k0, %2}" 6355 [(set_attr "type" "alu") 6356 (set_attr "mode" "SI")]) 6357 6358;; Subtract with jump on overflow. 6359(define_expand "subv<mode>4" 6360 [(parallel [(set (reg:CCO FLAGS_REG) 6361 (eq:CCO 6362 (minus:<DPWI> 6363 (sign_extend:<DPWI> 6364 (match_operand:SWIDWI 1 "nonimmediate_operand")) 6365 (match_dup 4)) 6366 (sign_extend:<DPWI> 6367 (minus:SWIDWI (match_dup 1) 6368 (match_operand:SWIDWI 2 6369 "<general_hilo_operand>"))))) 6370 (set (match_operand:SWIDWI 0 "register_operand") 6371 (minus:SWIDWI (match_dup 1) (match_dup 2)))]) 6372 (set (pc) (if_then_else 6373 (eq (reg:CCO FLAGS_REG) (const_int 0)) 6374 (label_ref (match_operand 3)) 6375 (pc)))] 6376 "" 6377{ 6378 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands); 6379 if (CONST_SCALAR_INT_P (operands[2])) 6380 operands[4] = operands[2]; 6381 else 6382 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]); 6383}) 6384 6385(define_insn "*subv<mode>4" 6386 [(set (reg:CCO FLAGS_REG) 6387 (eq:CCO (minus:<DWI> 6388 (sign_extend:<DWI> 6389 (match_operand:SWI 1 "nonimmediate_operand" "0,0")) 6390 (sign_extend:<DWI> 6391 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m"))) 6392 (sign_extend:<DWI> 6393 (minus:SWI (match_dup 1) (match_dup 2))))) 6394 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6395 (minus:SWI (match_dup 1) (match_dup 2)))] 6396 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6397 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6398 [(set_attr "type" "alu") 6399 (set_attr "mode" "<MODE>")]) 6400 6401(define_insn "subv<mode>4_1" 6402 [(set (reg:CCO FLAGS_REG) 6403 (eq:CCO (minus:<DWI> 6404 (sign_extend:<DWI> 6405 (match_operand:SWI 1 "nonimmediate_operand" "0")) 6406 (match_operand:<DWI> 3 "const_int_operand" "i")) 6407 (sign_extend:<DWI> 6408 (minus:SWI 6409 (match_dup 1) 6410 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>"))))) 6411 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 6412 (minus:SWI (match_dup 1) (match_dup 2)))] 6413 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) 6414 && CONST_INT_P (operands[2]) 6415 && INTVAL (operands[2]) == INTVAL (operands[3])" 6416 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6417 [(set_attr "type" "alu") 6418 (set_attr "mode" "<MODE>") 6419 (set (attr "length_immediate") 6420 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 6421 (const_string "1") 6422 (match_test "<MODE_SIZE> == 8") 6423 (const_string "4")] 6424 (const_string "<MODE_SIZE>")))]) 6425 6426(define_insn_and_split "*subv<dwi>4_doubleword" 6427 [(set (reg:CCO FLAGS_REG) 6428 (eq:CCO 6429 (minus:<QPWI> 6430 (sign_extend:<QPWI> 6431 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")) 6432 (sign_extend:<QPWI> 6433 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o"))) 6434 (sign_extend:<QPWI> 6435 (minus:<DWI> (match_dup 1) (match_dup 2))))) 6436 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r") 6437 (minus:<DWI> (match_dup 1) (match_dup 2)))] 6438 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6439 "#" 6440 "reload_completed" 6441 [(parallel [(set (reg:CC FLAGS_REG) 6442 (compare:CC (match_dup 1) (match_dup 2))) 6443 (set (match_dup 0) 6444 (minus:DWIH (match_dup 1) (match_dup 2)))]) 6445 (parallel [(set (reg:CCO FLAGS_REG) 6446 (eq:CCO 6447 (minus:<DWI> 6448 (minus:<DWI> 6449 (sign_extend:<DWI> (match_dup 4)) 6450 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))) 6451 (sign_extend:<DWI> (match_dup 5))) 6452 (sign_extend:<DWI> 6453 (minus:DWIH 6454 (minus:DWIH 6455 (match_dup 4) 6456 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))) 6457 (match_dup 5))))) 6458 (set (match_dup 3) 6459 (minus:DWIH 6460 (minus:DWIH 6461 (match_dup 4) 6462 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))) 6463 (match_dup 5)))])] 6464{ 6465 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 6466}) 6467 6468(define_insn_and_split "*subv<dwi>4_doubleword_1" 6469 [(set (reg:CCO FLAGS_REG) 6470 (eq:CCO 6471 (minus:<QPWI> 6472 (sign_extend:<QPWI> 6473 (match_operand:<DWI> 1 "nonimmediate_operand" "0")) 6474 (match_operand:<QPWI> 3 "const_scalar_int_operand" "")) 6475 (sign_extend:<QPWI> 6476 (minus:<DWI> 6477 (match_dup 1) 6478 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>"))))) 6479 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 6480 (minus:<DWI> (match_dup 1) (match_dup 2)))] 6481 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) 6482 && CONST_SCALAR_INT_P (operands[2]) 6483 && rtx_equal_p (operands[2], operands[3])" 6484 "#" 6485 "reload_completed" 6486 [(parallel [(set (reg:CC FLAGS_REG) 6487 (compare:CC (match_dup 1) (match_dup 2))) 6488 (set (match_dup 0) 6489 (minus:DWIH (match_dup 1) (match_dup 2)))]) 6490 (parallel [(set (reg:CCO FLAGS_REG) 6491 (eq:CCO 6492 (minus:<DWI> 6493 (minus:<DWI> 6494 (sign_extend:<DWI> (match_dup 4)) 6495 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))) 6496 (match_dup 5)) 6497 (sign_extend:<DWI> 6498 (minus:DWIH 6499 (minus:DWIH 6500 (match_dup 4) 6501 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))) 6502 (match_dup 5))))) 6503 (set (match_dup 3) 6504 (minus:DWIH 6505 (minus:DWIH 6506 (match_dup 4) 6507 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))) 6508 (match_dup 5)))])] 6509{ 6510 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 6511 if (operands[2] == const0_rtx) 6512 { 6513 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5], 6514 operands[5])); 6515 DONE; 6516 } 6517}) 6518 6519(define_insn "*subv<mode>4_overflow_1" 6520 [(set (reg:CCO FLAGS_REG) 6521 (eq:CCO 6522 (minus:<DWI> 6523 (minus:<DWI> 6524 (sign_extend:<DWI> 6525 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) 6526 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 6527 [(match_operand 3 "flags_reg_operand") (const_int 0)])) 6528 (sign_extend:<DWI> 6529 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m"))) 6530 (sign_extend:<DWI> 6531 (minus:SWI 6532 (minus:SWI 6533 (match_dup 1) 6534 (match_operator:SWI 5 "ix86_carry_flag_operator" 6535 [(match_dup 3) (const_int 0)])) 6536 (match_dup 2))))) 6537 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r") 6538 (minus:SWI 6539 (minus:SWI 6540 (match_dup 1) 6541 (match_op_dup 5 [(match_dup 3) (const_int 0)])) 6542 (match_dup 2)))] 6543 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6544 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6545 [(set_attr "type" "alu") 6546 (set_attr "mode" "<MODE>")]) 6547 6548(define_insn "*subv<mode>4_overflow_2" 6549 [(set (reg:CCO FLAGS_REG) 6550 (eq:CCO 6551 (minus:<DWI> 6552 (minus:<DWI> 6553 (sign_extend:<DWI> 6554 (match_operand:SWI 1 "nonimmediate_operand" "%0")) 6555 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 6556 [(match_operand 3 "flags_reg_operand") (const_int 0)])) 6557 (match_operand:<DWI> 6 "const_int_operand" "")) 6558 (sign_extend:<DWI> 6559 (minus:SWI 6560 (minus:SWI 6561 (match_dup 1) 6562 (match_operator:SWI 5 "ix86_carry_flag_operator" 6563 [(match_dup 3) (const_int 0)])) 6564 (match_operand:SWI 2 "x86_64_immediate_operand" "e"))))) 6565 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm") 6566 (minus:SWI 6567 (minus:SWI 6568 (match_dup 1) 6569 (match_op_dup 5 [(match_dup 3) (const_int 0)])) 6570 (match_dup 2)))] 6571 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) 6572 && CONST_INT_P (operands[2]) 6573 && INTVAL (operands[2]) == INTVAL (operands[6])" 6574 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6575 [(set_attr "type" "alu") 6576 (set_attr "mode" "<MODE>") 6577 (set (attr "length_immediate") 6578 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 6579 (const_string "1") 6580 (const_string "4")))]) 6581 6582(define_expand "usubv<mode>4" 6583 [(parallel [(set (reg:CC FLAGS_REG) 6584 (compare:CC 6585 (match_operand:SWI 1 "nonimmediate_operand") 6586 (match_operand:SWI 2 "<general_operand>"))) 6587 (set (match_operand:SWI 0 "register_operand") 6588 (minus:SWI (match_dup 1) (match_dup 2)))]) 6589 (set (pc) (if_then_else 6590 (ltu (reg:CC FLAGS_REG) (const_int 0)) 6591 (label_ref (match_operand 3)) 6592 (pc)))] 6593 "" 6594 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);") 6595 6596(define_insn "*sub<mode>_3" 6597 [(set (reg FLAGS_REG) 6598 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6599 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) 6600 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6601 (minus:SWI (match_dup 1) (match_dup 2)))] 6602 "ix86_match_ccmode (insn, CCmode) 6603 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6604 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 6605 [(set_attr "type" "alu") 6606 (set_attr "mode" "<MODE>")]) 6607 6608(define_peephole2 6609 [(parallel 6610 [(set (reg:CC FLAGS_REG) 6611 (compare:CC (match_operand:SWI 0 "general_reg_operand") 6612 (match_operand:SWI 1 "general_gr_operand"))) 6613 (set (match_dup 0) 6614 (minus:SWI (match_dup 0) (match_dup 1)))])] 6615 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0" 6616 [(set (reg:CC FLAGS_REG) 6617 (compare:CC (match_dup 0) (match_dup 1)))]) 6618 6619;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into 6620;; subl $1, %eax; jnc .Lxx; 6621(define_peephole2 6622 [(parallel 6623 [(set (match_operand:SWI 0 "general_reg_operand") 6624 (plus:SWI (match_dup 0) (const_int -1))) 6625 (clobber (reg FLAGS_REG))]) 6626 (set (reg:CCZ FLAGS_REG) 6627 (compare:CCZ (match_dup 0) (const_int -1))) 6628 (set (pc) 6629 (if_then_else (match_operator 1 "bt_comparison_operator" 6630 [(reg:CCZ FLAGS_REG) (const_int 0)]) 6631 (match_operand 2) 6632 (pc)))] 6633 "peep2_regno_dead_p (3, FLAGS_REG)" 6634 [(parallel 6635 [(set (reg:CC FLAGS_REG) 6636 (compare:CC (match_dup 0) (const_int 1))) 6637 (set (match_dup 0) 6638 (minus:SWI (match_dup 0) (const_int 1)))]) 6639 (set (pc) 6640 (if_then_else (match_dup 3) 6641 (match_dup 2) 6642 (pc)))] 6643{ 6644 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG); 6645 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE 6646 ? GEU : LTU, VOIDmode, cc, const0_rtx); 6647}) 6648 6649(define_insn "*subsi_3_zext" 6650 [(set (reg FLAGS_REG) 6651 (compare (match_operand:SI 1 "register_operand" "0") 6652 (match_operand:SI 2 "x86_64_general_operand" "rme"))) 6653 (set (match_operand:DI 0 "register_operand" "=r") 6654 (zero_extend:DI 6655 (minus:SI (match_dup 1) 6656 (match_dup 2))))] 6657 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode) 6658 && ix86_binary_operator_ok (MINUS, SImode, operands)" 6659 "sub{l}\t{%2, %1|%1, %2}" 6660 [(set_attr "type" "alu") 6661 (set_attr "mode" "SI")]) 6662 6663;; Add with carry and subtract with borrow 6664 6665(define_insn "@add<mode>3_carry" 6666 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6667 (plus:SWI 6668 (plus:SWI 6669 (match_operator:SWI 4 "ix86_carry_flag_operator" 6670 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6671 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")) 6672 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) 6673 (clobber (reg:CC FLAGS_REG))] 6674 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6675 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6676 [(set_attr "type" "alu") 6677 (set_attr "use_carry" "1") 6678 (set_attr "pent_pair" "pu") 6679 (set_attr "mode" "<MODE>")]) 6680 6681(define_insn "*add<mode>3_carry_0" 6682 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 6683 (plus:SWI 6684 (match_operator:SWI 3 "ix86_carry_flag_operator" 6685 [(match_operand 2 "flags_reg_operand") (const_int 0)]) 6686 (match_operand:SWI 1 "nonimmediate_operand" "0"))) 6687 (clobber (reg:CC FLAGS_REG))] 6688 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)" 6689 "adc{<imodesuffix>}\t{$0, %0|%0, 0}" 6690 [(set_attr "type" "alu") 6691 (set_attr "use_carry" "1") 6692 (set_attr "pent_pair" "pu") 6693 (set_attr "mode" "<MODE>")]) 6694 6695(define_insn "*addsi3_carry_zext" 6696 [(set (match_operand:DI 0 "register_operand" "=r") 6697 (zero_extend:DI 6698 (plus:SI 6699 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator" 6700 [(reg FLAGS_REG) (const_int 0)]) 6701 (match_operand:SI 1 "register_operand" "%0")) 6702 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6703 (clobber (reg:CC FLAGS_REG))] 6704 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6705 "adc{l}\t{%2, %k0|%k0, %2}" 6706 [(set_attr "type" "alu") 6707 (set_attr "use_carry" "1") 6708 (set_attr "pent_pair" "pu") 6709 (set_attr "mode" "SI")]) 6710 6711(define_insn "*addsi3_carry_zext_0" 6712 [(set (match_operand:DI 0 "register_operand" "=r") 6713 (zero_extend:DI 6714 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator" 6715 [(reg FLAGS_REG) (const_int 0)]) 6716 (match_operand:SI 1 "register_operand" "0")))) 6717 (clobber (reg:CC FLAGS_REG))] 6718 "TARGET_64BIT" 6719 "adc{l}\t{$0, %k0|%k0, 0}" 6720 [(set_attr "type" "alu") 6721 (set_attr "use_carry" "1") 6722 (set_attr "pent_pair" "pu") 6723 (set_attr "mode" "SI")]) 6724 6725;; There is no point to generate ADCX instruction. ADC is shorter and faster. 6726 6727(define_insn "addcarry<mode>" 6728 [(set (reg:CCC FLAGS_REG) 6729 (compare:CCC 6730 (zero_extend:<DWI> 6731 (plus:SWI48 6732 (plus:SWI48 6733 (match_operator:SWI48 5 "ix86_carry_flag_operator" 6734 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6735 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")) 6736 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm"))) 6737 (plus:<DWI> 6738 (zero_extend:<DWI> (match_dup 2)) 6739 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 6740 [(match_dup 3) (const_int 0)])))) 6741 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 6742 (plus:SWI48 (plus:SWI48 (match_op_dup 5 6743 [(match_dup 3) (const_int 0)]) 6744 (match_dup 1)) 6745 (match_dup 2)))] 6746 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6747 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6748 [(set_attr "type" "alu") 6749 (set_attr "use_carry" "1") 6750 (set_attr "pent_pair" "pu") 6751 (set_attr "mode" "<MODE>")]) 6752 6753(define_expand "addcarry<mode>_0" 6754 [(parallel 6755 [(set (reg:CCC FLAGS_REG) 6756 (compare:CCC 6757 (plus:SWI48 6758 (match_operand:SWI48 1 "nonimmediate_operand") 6759 (match_operand:SWI48 2 "x86_64_general_operand")) 6760 (match_dup 1))) 6761 (set (match_operand:SWI48 0 "nonimmediate_operand") 6762 (plus:SWI48 (match_dup 1) (match_dup 2)))])] 6763 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)") 6764 6765(define_insn "*addcarry<mode>_1" 6766 [(set (reg:CCC FLAGS_REG) 6767 (compare:CCC 6768 (zero_extend:<DWI> 6769 (plus:SWI48 6770 (plus:SWI48 6771 (match_operator:SWI48 5 "ix86_carry_flag_operator" 6772 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6773 (match_operand:SWI48 1 "nonimmediate_operand" "%0")) 6774 (match_operand:SWI48 2 "x86_64_immediate_operand" "e"))) 6775 (plus:<DWI> 6776 (match_operand:<DWI> 6 "const_scalar_int_operand" "") 6777 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 6778 [(match_dup 3) (const_int 0)])))) 6779 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm") 6780 (plus:SWI48 (plus:SWI48 (match_op_dup 5 6781 [(match_dup 3) (const_int 0)]) 6782 (match_dup 1)) 6783 (match_dup 2)))] 6784 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands) 6785 && CONST_INT_P (operands[2]) 6786 /* Check that operands[6] is operands[2] zero extended from 6787 <MODE>mode to <DWI>mode. */ 6788 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0) 6789 ? (CONST_INT_P (operands[6]) 6790 && UINTVAL (operands[6]) == (UINTVAL (operands[2]) 6791 & GET_MODE_MASK (<MODE>mode))) 6792 : (CONST_WIDE_INT_P (operands[6]) 6793 && CONST_WIDE_INT_NUNITS (operands[6]) == 2 6794 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0) 6795 == UINTVAL (operands[2])) 6796 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))" 6797 "adc{<imodesuffix>}\t{%2, %0|%0, %2}" 6798 [(set_attr "type" "alu") 6799 (set_attr "use_carry" "1") 6800 (set_attr "pent_pair" "pu") 6801 (set_attr "mode" "<MODE>") 6802 (set (attr "length_immediate") 6803 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)") 6804 (const_string "1") 6805 (const_string "4")))]) 6806 6807(define_insn "@sub<mode>3_carry" 6808 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6809 (minus:SWI 6810 (minus:SWI 6811 (match_operand:SWI 1 "nonimmediate_operand" "0,0") 6812 (match_operator:SWI 4 "ix86_carry_flag_operator" 6813 [(match_operand 3 "flags_reg_operand") (const_int 0)])) 6814 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))) 6815 (clobber (reg:CC FLAGS_REG))] 6816 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6817 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6818 [(set_attr "type" "alu") 6819 (set_attr "use_carry" "1") 6820 (set_attr "pent_pair" "pu") 6821 (set_attr "mode" "<MODE>")]) 6822 6823(define_insn "*sub<mode>3_carry_0" 6824 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 6825 (minus:SWI 6826 (match_operand:SWI 1 "nonimmediate_operand" "0") 6827 (match_operator:SWI 3 "ix86_carry_flag_operator" 6828 [(match_operand 2 "flags_reg_operand") (const_int 0)]))) 6829 (clobber (reg:CC FLAGS_REG))] 6830 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)" 6831 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}" 6832 [(set_attr "type" "alu") 6833 (set_attr "use_carry" "1") 6834 (set_attr "pent_pair" "pu") 6835 (set_attr "mode" "<MODE>")]) 6836 6837(define_insn "*subsi3_carry_zext" 6838 [(set (match_operand:DI 0 "register_operand" "=r") 6839 (zero_extend:DI 6840 (minus:SI 6841 (minus:SI 6842 (match_operand:SI 1 "register_operand" "0") 6843 (match_operator:SI 3 "ix86_carry_flag_operator" 6844 [(reg FLAGS_REG) (const_int 0)])) 6845 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 6846 (clobber (reg:CC FLAGS_REG))] 6847 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)" 6848 "sbb{l}\t{%2, %k0|%k0, %2}" 6849 [(set_attr "type" "alu") 6850 (set_attr "use_carry" "1") 6851 (set_attr "pent_pair" "pu") 6852 (set_attr "mode" "SI")]) 6853 6854(define_insn "*subsi3_carry_zext_0" 6855 [(set (match_operand:DI 0 "register_operand" "=r") 6856 (zero_extend:DI 6857 (minus:SI 6858 (match_operand:SI 1 "register_operand" "0") 6859 (match_operator:SI 2 "ix86_carry_flag_operator" 6860 [(reg FLAGS_REG) (const_int 0)])))) 6861 (clobber (reg:CC FLAGS_REG))] 6862 "TARGET_64BIT" 6863 "sbb{l}\t{$0, %k0|%k0, 0}" 6864 [(set_attr "type" "alu") 6865 (set_attr "use_carry" "1") 6866 (set_attr "pent_pair" "pu") 6867 (set_attr "mode" "SI")]) 6868 6869(define_insn "@sub<mode>3_carry_ccc" 6870 [(set (reg:CCC FLAGS_REG) 6871 (compare:CCC 6872 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0")) 6873 (plus:<DWI> 6874 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)) 6875 (zero_extend:<DWI> 6876 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe"))))) 6877 (clobber (match_scratch:DWIH 0 "=r"))] 6878 "" 6879 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6880 [(set_attr "type" "alu") 6881 (set_attr "mode" "<MODE>")]) 6882 6883(define_insn "*sub<mode>3_carry_ccc_1" 6884 [(set (reg:CCC FLAGS_REG) 6885 (compare:CCC 6886 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0")) 6887 (plus:<DWI> 6888 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)) 6889 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf")))) 6890 (clobber (match_scratch:DWIH 0 "=r"))] 6891 "" 6892{ 6893 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0); 6894 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}"; 6895} 6896 [(set_attr "type" "alu") 6897 (set_attr "mode" "<MODE>")]) 6898 6899;; The sign flag is set from the 6900;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2))) 6901;; result, the overflow flag likewise, but the overflow flag is also 6902;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows. 6903(define_insn "@sub<mode>3_carry_ccgz" 6904 [(set (reg:CCGZ FLAGS_REG) 6905 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0") 6906 (match_operand:DWIH 2 "x86_64_general_operand" "rme") 6907 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))] 6908 UNSPEC_SBB)) 6909 (clobber (match_scratch:DWIH 0 "=r"))] 6910 "" 6911 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6912 [(set_attr "type" "alu") 6913 (set_attr "mode" "<MODE>")]) 6914 6915(define_insn "subborrow<mode>" 6916 [(set (reg:CCC FLAGS_REG) 6917 (compare:CCC 6918 (zero_extend:<DWI> 6919 (match_operand:SWI48 1 "nonimmediate_operand" "0")) 6920 (plus:<DWI> 6921 (match_operator:<DWI> 4 "ix86_carry_flag_operator" 6922 [(match_operand 3 "flags_reg_operand") (const_int 0)]) 6923 (zero_extend:<DWI> 6924 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))) 6925 (set (match_operand:SWI48 0 "register_operand" "=r") 6926 (minus:SWI48 (minus:SWI48 6927 (match_dup 1) 6928 (match_operator:SWI48 5 "ix86_carry_flag_operator" 6929 [(match_dup 3) (const_int 0)])) 6930 (match_dup 2)))] 6931 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)" 6932 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}" 6933 [(set_attr "type" "alu") 6934 (set_attr "use_carry" "1") 6935 (set_attr "pent_pair" "pu") 6936 (set_attr "mode" "<MODE>")]) 6937 6938(define_expand "subborrow<mode>_0" 6939 [(parallel 6940 [(set (reg:CC FLAGS_REG) 6941 (compare:CC 6942 (match_operand:SWI48 1 "nonimmediate_operand") 6943 (match_operand:SWI48 2 "<general_operand>"))) 6944 (set (match_operand:SWI48 0 "register_operand") 6945 (minus:SWI48 (match_dup 1) (match_dup 2)))])] 6946 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)") 6947 6948;; Overflow setting add instructions 6949 6950(define_expand "addqi3_cconly_overflow" 6951 [(parallel 6952 [(set (reg:CCC FLAGS_REG) 6953 (compare:CCC 6954 (plus:QI 6955 (match_operand:QI 0 "nonimmediate_operand") 6956 (match_operand:QI 1 "general_operand")) 6957 (match_dup 0))) 6958 (clobber (match_scratch:QI 2))])] 6959 "!(MEM_P (operands[0]) && MEM_P (operands[1]))") 6960 6961(define_insn "*add<mode>3_cconly_overflow_1" 6962 [(set (reg:CCC FLAGS_REG) 6963 (compare:CCC 6964 (plus:SWI 6965 (match_operand:SWI 1 "nonimmediate_operand" "%0") 6966 (match_operand:SWI 2 "<general_operand>" "<g>")) 6967 (match_dup 1))) 6968 (clobber (match_scratch:SWI 0 "=<r>"))] 6969 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 6970 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6971 [(set_attr "type" "alu") 6972 (set_attr "mode" "<MODE>")]) 6973 6974(define_insn "*add<mode>3_cc_overflow_1" 6975 [(set (reg:CCC FLAGS_REG) 6976 (compare:CCC 6977 (plus:SWI 6978 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 6979 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) 6980 (match_dup 1))) 6981 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 6982 (plus:SWI (match_dup 1) (match_dup 2)))] 6983 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 6984 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 6985 [(set_attr "type" "alu") 6986 (set_attr "mode" "<MODE>")]) 6987 6988(define_insn "*addsi3_zext_cc_overflow_1" 6989 [(set (reg:CCC FLAGS_REG) 6990 (compare:CCC 6991 (plus:SI 6992 (match_operand:SI 1 "nonimmediate_operand" "%0") 6993 (match_operand:SI 2 "x86_64_general_operand" "rme")) 6994 (match_dup 1))) 6995 (set (match_operand:DI 0 "register_operand" "=r") 6996 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 6997 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 6998 "add{l}\t{%2, %k0|%k0, %2}" 6999 [(set_attr "type" "alu") 7000 (set_attr "mode" "SI")]) 7001 7002(define_insn "*add<mode>3_cconly_overflow_2" 7003 [(set (reg:CCC FLAGS_REG) 7004 (compare:CCC 7005 (plus:SWI 7006 (match_operand:SWI 1 "nonimmediate_operand" "%0") 7007 (match_operand:SWI 2 "<general_operand>" "<g>")) 7008 (match_dup 2))) 7009 (clobber (match_scratch:SWI 0 "=<r>"))] 7010 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7011 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 7012 [(set_attr "type" "alu") 7013 (set_attr "mode" "<MODE>")]) 7014 7015(define_insn "*add<mode>3_cc_overflow_2" 7016 [(set (reg:CCC FLAGS_REG) 7017 (compare:CCC 7018 (plus:SWI 7019 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 7020 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) 7021 (match_dup 2))) 7022 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 7023 (plus:SWI (match_dup 1) (match_dup 2)))] 7024 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)" 7025 "add{<imodesuffix>}\t{%2, %0|%0, %2}" 7026 [(set_attr "type" "alu") 7027 (set_attr "mode" "<MODE>")]) 7028 7029(define_insn "*addsi3_zext_cc_overflow_2" 7030 [(set (reg:CCC FLAGS_REG) 7031 (compare:CCC 7032 (plus:SI 7033 (match_operand:SI 1 "nonimmediate_operand" "%0") 7034 (match_operand:SI 2 "x86_64_general_operand" "rme")) 7035 (match_dup 2))) 7036 (set (match_operand:DI 0 "register_operand" "=r") 7037 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))] 7038 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)" 7039 "add{l}\t{%2, %k0|%k0, %2}" 7040 [(set_attr "type" "alu") 7041 (set_attr "mode" "SI")]) 7042 7043(define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1" 7044 [(set (reg:CCC FLAGS_REG) 7045 (compare:CCC 7046 (plus:<DWI> 7047 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0") 7048 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")) 7049 (match_dup 1))) 7050 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r") 7051 (plus:<DWI> (match_dup 1) (match_dup 2)))] 7052 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)" 7053 "#" 7054 "reload_completed" 7055 [(parallel [(set (reg:CCC FLAGS_REG) 7056 (compare:CCC 7057 (plus:DWIH (match_dup 1) (match_dup 2)) 7058 (match_dup 1))) 7059 (set (match_dup 0) 7060 (plus:DWIH (match_dup 1) (match_dup 2)))]) 7061 (parallel [(set (reg:CCC FLAGS_REG) 7062 (compare:CCC 7063 (zero_extend:<DWI> 7064 (plus:DWIH 7065 (plus:DWIH 7066 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 7067 (match_dup 4)) 7068 (match_dup 5))) 7069 (plus:<DWI> 7070 (match_dup 6) 7071 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))))) 7072 (set (match_dup 3) 7073 (plus:DWIH 7074 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 7075 (match_dup 4)) 7076 (match_dup 5)))])] 7077{ 7078 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]); 7079 if (operands[2] == const0_rtx) 7080 { 7081 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5])); 7082 DONE; 7083 } 7084 if (CONST_INT_P (operands[5])) 7085 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode, 7086 operands[5], <MODE>mode); 7087 else 7088 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]); 7089}) 7090 7091;; x == 0 with zero flag test can be done also as x < 1U with carry flag 7092;; test, where the latter is preferrable if we have some carry consuming 7093;; instruction. 7094;; For x != 0, we need to use x < 1U with negation of carry, i.e. 7095;; + (1 - CF). 7096(define_insn_and_split "*add<mode>3_eq" 7097 [(set (match_operand:SWI 0 "nonimmediate_operand") 7098 (plus:SWI 7099 (plus:SWI 7100 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0)) 7101 (match_operand:SWI 1 "nonimmediate_operand")) 7102 (match_operand:SWI 2 "<general_operand>"))) 7103 (clobber (reg:CC FLAGS_REG))] 7104 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands) 7105 && ix86_pre_reload_split ()" 7106 "#" 7107 "&& 1" 7108 [(set (reg:CC FLAGS_REG) 7109 (compare:CC (match_dup 3) (const_int 1))) 7110 (parallel [(set (match_dup 0) 7111 (plus:SWI 7112 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)) 7113 (match_dup 1)) 7114 (match_dup 2))) 7115 (clobber (reg:CC FLAGS_REG))])]) 7116 7117(define_insn_and_split "*add<mode>3_ne" 7118 [(set (match_operand:SWI 0 "nonimmediate_operand") 7119 (plus:SWI 7120 (plus:SWI 7121 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0)) 7122 (match_operand:SWI 1 "nonimmediate_operand")) 7123 (match_operand:SWI 2 "<immediate_operand>"))) 7124 (clobber (reg:CC FLAGS_REG))] 7125 "CONST_INT_P (operands[2]) 7126 && (<MODE>mode != DImode 7127 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000)) 7128 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands) 7129 && ix86_pre_reload_split ()" 7130 "#" 7131 "&& 1" 7132 [(set (reg:CC FLAGS_REG) 7133 (compare:CC (match_dup 3) (const_int 1))) 7134 (parallel [(set (match_dup 0) 7135 (minus:SWI 7136 (minus:SWI (match_dup 1) 7137 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))) 7138 (match_dup 2))) 7139 (clobber (reg:CC FLAGS_REG))])] 7140{ 7141 operands[2] = gen_int_mode (~INTVAL (operands[2]), 7142 <MODE>mode == DImode ? SImode : <MODE>mode); 7143}) 7144 7145(define_insn_and_split "*add<mode>3_eq_0" 7146 [(set (match_operand:SWI 0 "nonimmediate_operand") 7147 (plus:SWI 7148 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0)) 7149 (match_operand:SWI 1 "<general_operand>"))) 7150 (clobber (reg:CC FLAGS_REG))] 7151 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands) 7152 && ix86_pre_reload_split ()" 7153 "#" 7154 "&& 1" 7155 [(set (reg:CC FLAGS_REG) 7156 (compare:CC (match_dup 2) (const_int 1))) 7157 (parallel [(set (match_dup 0) 7158 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)) 7159 (match_dup 1))) 7160 (clobber (reg:CC FLAGS_REG))])] 7161{ 7162 if (!nonimmediate_operand (operands[1], <MODE>mode)) 7163 operands[1] = force_reg (<MODE>mode, operands[1]); 7164}) 7165 7166(define_insn_and_split "*add<mode>3_ne_0" 7167 [(set (match_operand:SWI 0 "nonimmediate_operand") 7168 (plus:SWI 7169 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0)) 7170 (match_operand:SWI 1 "<general_operand>"))) 7171 (clobber (reg:CC FLAGS_REG))] 7172 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands) 7173 && ix86_pre_reload_split ()" 7174 "#" 7175 "&& 1" 7176 [(set (reg:CC FLAGS_REG) 7177 (compare:CC (match_dup 2) (const_int 1))) 7178 (parallel [(set (match_dup 0) 7179 (minus:SWI (minus:SWI 7180 (match_dup 1) 7181 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))) 7182 (const_int -1))) 7183 (clobber (reg:CC FLAGS_REG))])] 7184{ 7185 if (!nonimmediate_operand (operands[1], <MODE>mode)) 7186 operands[1] = force_reg (<MODE>mode, operands[1]); 7187}) 7188 7189(define_insn_and_split "*sub<mode>3_eq" 7190 [(set (match_operand:SWI 0 "nonimmediate_operand") 7191 (minus:SWI 7192 (minus:SWI 7193 (match_operand:SWI 1 "nonimmediate_operand") 7194 (eq:SWI (match_operand 3 "int_nonimmediate_operand") 7195 (const_int 0))) 7196 (match_operand:SWI 2 "<general_operand>"))) 7197 (clobber (reg:CC FLAGS_REG))] 7198 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands) 7199 && ix86_pre_reload_split ()" 7200 "#" 7201 "&& 1" 7202 [(set (reg:CC FLAGS_REG) 7203 (compare:CC (match_dup 3) (const_int 1))) 7204 (parallel [(set (match_dup 0) 7205 (minus:SWI 7206 (minus:SWI (match_dup 1) 7207 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))) 7208 (match_dup 2))) 7209 (clobber (reg:CC FLAGS_REG))])]) 7210 7211(define_insn_and_split "*sub<mode>3_ne" 7212 [(set (match_operand:SWI 0 "nonimmediate_operand") 7213 (plus:SWI 7214 (minus:SWI 7215 (match_operand:SWI 1 "nonimmediate_operand") 7216 (ne:SWI (match_operand 3 "int_nonimmediate_operand") 7217 (const_int 0))) 7218 (match_operand:SWI 2 "<immediate_operand>"))) 7219 (clobber (reg:CC FLAGS_REG))] 7220 "CONST_INT_P (operands[2]) 7221 && (<MODE>mode != DImode 7222 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000)) 7223 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands) 7224 && ix86_pre_reload_split ()" 7225 "#" 7226 "&& 1" 7227 [(set (reg:CC FLAGS_REG) 7228 (compare:CC (match_dup 3) (const_int 1))) 7229 (parallel [(set (match_dup 0) 7230 (plus:SWI 7231 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)) 7232 (match_dup 1)) 7233 (match_dup 2))) 7234 (clobber (reg:CC FLAGS_REG))])] 7235{ 7236 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1, 7237 <MODE>mode == DImode ? SImode : <MODE>mode); 7238}) 7239 7240(define_insn_and_split "*sub<mode>3_eq_1" 7241 [(set (match_operand:SWI 0 "nonimmediate_operand") 7242 (plus:SWI 7243 (minus:SWI 7244 (match_operand:SWI 1 "nonimmediate_operand") 7245 (eq:SWI (match_operand 3 "int_nonimmediate_operand") 7246 (const_int 0))) 7247 (match_operand:SWI 2 "<immediate_operand>"))) 7248 (clobber (reg:CC FLAGS_REG))] 7249 "CONST_INT_P (operands[2]) 7250 && (<MODE>mode != DImode 7251 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000)) 7252 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands) 7253 && ix86_pre_reload_split ()" 7254 "#" 7255 "&& 1" 7256 [(set (reg:CC FLAGS_REG) 7257 (compare:CC (match_dup 3) (const_int 1))) 7258 (parallel [(set (match_dup 0) 7259 (minus:SWI 7260 (minus:SWI (match_dup 1) 7261 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))) 7262 (match_dup 2))) 7263 (clobber (reg:CC FLAGS_REG))])] 7264{ 7265 operands[2] = gen_int_mode (-INTVAL (operands[2]), 7266 <MODE>mode == DImode ? SImode : <MODE>mode); 7267}) 7268 7269(define_insn_and_split "*sub<mode>3_eq_0" 7270 [(set (match_operand:SWI 0 "nonimmediate_operand") 7271 (minus:SWI 7272 (match_operand:SWI 1 "<general_operand>") 7273 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0)))) 7274 (clobber (reg:CC FLAGS_REG))] 7275 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands) 7276 && ix86_pre_reload_split ()" 7277 "#" 7278 "&& 1" 7279 [(set (reg:CC FLAGS_REG) 7280 (compare:CC (match_dup 2) (const_int 1))) 7281 (parallel [(set (match_dup 0) 7282 (minus:SWI (match_dup 1) 7283 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))) 7284 (clobber (reg:CC FLAGS_REG))])] 7285{ 7286 if (!nonimmediate_operand (operands[1], <MODE>mode)) 7287 operands[1] = force_reg (<MODE>mode, operands[1]); 7288}) 7289 7290(define_insn_and_split "*sub<mode>3_ne_0" 7291 [(set (match_operand:SWI 0 "nonimmediate_operand") 7292 (minus:SWI 7293 (match_operand:SWI 1 "<general_operand>") 7294 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0)))) 7295 (clobber (reg:CC FLAGS_REG))] 7296 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands) 7297 && ix86_pre_reload_split ()" 7298 "#" 7299 "&& 1" 7300 [(set (reg:CC FLAGS_REG) 7301 (compare:CC (match_dup 2) (const_int 1))) 7302 (parallel [(set (match_dup 0) 7303 (plus:SWI (plus:SWI 7304 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)) 7305 (match_dup 1)) 7306 (const_int -1))) 7307 (clobber (reg:CC FLAGS_REG))])] 7308{ 7309 if (!nonimmediate_operand (operands[1], <MODE>mode)) 7310 operands[1] = force_reg (<MODE>mode, operands[1]); 7311}) 7312 7313;; The patterns that match these are at the end of this file. 7314 7315(define_expand "<plusminus_insn>xf3" 7316 [(set (match_operand:XF 0 "register_operand") 7317 (plusminus:XF 7318 (match_operand:XF 1 "register_operand") 7319 (match_operand:XF 2 "register_operand")))] 7320 "TARGET_80387") 7321 7322(define_expand "<plusminus_insn><mode>3" 7323 [(set (match_operand:MODEF 0 "register_operand") 7324 (plusminus:MODEF 7325 (match_operand:MODEF 1 "register_operand") 7326 (match_operand:MODEF 2 "nonimmediate_operand")))] 7327 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7328 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 7329 7330;; Multiply instructions 7331 7332(define_expand "mul<mode>3" 7333 [(parallel [(set (match_operand:SWIM248 0 "register_operand") 7334 (mult:SWIM248 7335 (match_operand:SWIM248 1 "register_operand") 7336 (match_operand:SWIM248 2 "<general_operand>"))) 7337 (clobber (reg:CC FLAGS_REG))])]) 7338 7339(define_expand "mulqi3" 7340 [(parallel [(set (match_operand:QI 0 "register_operand") 7341 (mult:QI 7342 (match_operand:QI 1 "register_operand") 7343 (match_operand:QI 2 "nonimmediate_operand"))) 7344 (clobber (reg:CC FLAGS_REG))])] 7345 "TARGET_QIMODE_MATH") 7346 7347;; On AMDFAM10 7348;; IMUL reg32/64, reg32/64, imm8 Direct 7349;; IMUL reg32/64, mem32/64, imm8 VectorPath 7350;; IMUL reg32/64, reg32/64, imm32 Direct 7351;; IMUL reg32/64, mem32/64, imm32 VectorPath 7352;; IMUL reg32/64, reg32/64 Direct 7353;; IMUL reg32/64, mem32/64 Direct 7354;; 7355;; On BDVER1, all above IMULs use DirectPath 7356;; 7357;; On AMDFAM10 7358;; IMUL reg16, reg16, imm8 VectorPath 7359;; IMUL reg16, mem16, imm8 VectorPath 7360;; IMUL reg16, reg16, imm16 VectorPath 7361;; IMUL reg16, mem16, imm16 VectorPath 7362;; IMUL reg16, reg16 Direct 7363;; IMUL reg16, mem16 Direct 7364;; 7365;; On BDVER1, all HI MULs use DoublePath 7366 7367(define_insn "*mul<mode>3_1" 7368 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r") 7369 (mult:SWIM248 7370 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0") 7371 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr"))) 7372 (clobber (reg:CC FLAGS_REG))] 7373 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7374 "@ 7375 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 7376 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 7377 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 7378 [(set_attr "type" "imul") 7379 (set_attr "prefix_0f" "0,0,1") 7380 (set (attr "athlon_decode") 7381 (cond [(eq_attr "cpu" "athlon") 7382 (const_string "vector") 7383 (eq_attr "alternative" "1") 7384 (const_string "vector") 7385 (and (eq_attr "alternative" "2") 7386 (ior (match_test "<MODE>mode == HImode") 7387 (match_operand 1 "memory_operand"))) 7388 (const_string "vector")] 7389 (const_string "direct"))) 7390 (set (attr "amdfam10_decode") 7391 (cond [(and (eq_attr "alternative" "0,1") 7392 (ior (match_test "<MODE>mode == HImode") 7393 (match_operand 1 "memory_operand"))) 7394 (const_string "vector")] 7395 (const_string "direct"))) 7396 (set (attr "bdver1_decode") 7397 (if_then_else 7398 (match_test "<MODE>mode == HImode") 7399 (const_string "double") 7400 (const_string "direct"))) 7401 (set_attr "mode" "<MODE>")]) 7402 7403(define_insn "*mulsi3_1_zext" 7404 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 7405 (zero_extend:DI 7406 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0") 7407 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr")))) 7408 (clobber (reg:CC FLAGS_REG))] 7409 "TARGET_64BIT 7410 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7411 "@ 7412 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 7413 imul{l}\t{%2, %1, %k0|%k0, %1, %2} 7414 imul{l}\t{%2, %k0|%k0, %2}" 7415 [(set_attr "type" "imul") 7416 (set_attr "prefix_0f" "0,0,1") 7417 (set (attr "athlon_decode") 7418 (cond [(eq_attr "cpu" "athlon") 7419 (const_string "vector") 7420 (eq_attr "alternative" "1") 7421 (const_string "vector") 7422 (and (eq_attr "alternative" "2") 7423 (match_operand 1 "memory_operand")) 7424 (const_string "vector")] 7425 (const_string "direct"))) 7426 (set (attr "amdfam10_decode") 7427 (cond [(and (eq_attr "alternative" "0,1") 7428 (match_operand 1 "memory_operand")) 7429 (const_string "vector")] 7430 (const_string "direct"))) 7431 (set_attr "bdver1_decode" "direct") 7432 (set_attr "mode" "SI")]) 7433 7434;;On AMDFAM10 and BDVER1 7435;; MUL reg8 Direct 7436;; MUL mem8 Direct 7437 7438(define_insn "*mulqi3_1" 7439 [(set (match_operand:QI 0 "register_operand" "=a") 7440 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0") 7441 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7442 (clobber (reg:CC FLAGS_REG))] 7443 "TARGET_QIMODE_MATH 7444 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7445 "mul{b}\t%2" 7446 [(set_attr "type" "imul") 7447 (set_attr "length_immediate" "0") 7448 (set (attr "athlon_decode") 7449 (if_then_else (eq_attr "cpu" "athlon") 7450 (const_string "vector") 7451 (const_string "direct"))) 7452 (set_attr "amdfam10_decode" "direct") 7453 (set_attr "bdver1_decode" "direct") 7454 (set_attr "mode" "QI")]) 7455 7456;; Multiply with jump on overflow. 7457(define_expand "mulv<mode>4" 7458 [(parallel [(set (reg:CCO FLAGS_REG) 7459 (eq:CCO (mult:<DWI> 7460 (sign_extend:<DWI> 7461 (match_operand:SWI248 1 "register_operand")) 7462 (match_dup 4)) 7463 (sign_extend:<DWI> 7464 (mult:SWI248 (match_dup 1) 7465 (match_operand:SWI248 2 7466 "<general_operand>"))))) 7467 (set (match_operand:SWI248 0 "register_operand") 7468 (mult:SWI248 (match_dup 1) (match_dup 2)))]) 7469 (set (pc) (if_then_else 7470 (eq (reg:CCO FLAGS_REG) (const_int 0)) 7471 (label_ref (match_operand 3)) 7472 (pc)))] 7473 "" 7474{ 7475 if (CONST_INT_P (operands[2])) 7476 operands[4] = operands[2]; 7477 else 7478 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]); 7479}) 7480 7481(define_insn "*mulv<mode>4" 7482 [(set (reg:CCO FLAGS_REG) 7483 (eq:CCO (mult:<DWI> 7484 (sign_extend:<DWI> 7485 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0")) 7486 (sign_extend:<DWI> 7487 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr"))) 7488 (sign_extend:<DWI> 7489 (mult:SWI48 (match_dup 1) (match_dup 2))))) 7490 (set (match_operand:SWI48 0 "register_operand" "=r,r") 7491 (mult:SWI48 (match_dup 1) (match_dup 2)))] 7492 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7493 "@ 7494 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2} 7495 imul{<imodesuffix>}\t{%2, %0|%0, %2}" 7496 [(set_attr "type" "imul") 7497 (set_attr "prefix_0f" "0,1") 7498 (set (attr "athlon_decode") 7499 (cond [(eq_attr "cpu" "athlon") 7500 (const_string "vector") 7501 (eq_attr "alternative" "0") 7502 (const_string "vector") 7503 (and (eq_attr "alternative" "1") 7504 (match_operand 1 "memory_operand")) 7505 (const_string "vector")] 7506 (const_string "direct"))) 7507 (set (attr "amdfam10_decode") 7508 (cond [(and (eq_attr "alternative" "1") 7509 (match_operand 1 "memory_operand")) 7510 (const_string "vector")] 7511 (const_string "direct"))) 7512 (set_attr "bdver1_decode" "direct") 7513 (set_attr "mode" "<MODE>")]) 7514 7515(define_insn "*mulvhi4" 7516 [(set (reg:CCO FLAGS_REG) 7517 (eq:CCO (mult:SI 7518 (sign_extend:SI 7519 (match_operand:HI 1 "nonimmediate_operand" "%0")) 7520 (sign_extend:SI 7521 (match_operand:HI 2 "nonimmediate_operand" "mr"))) 7522 (sign_extend:SI 7523 (mult:HI (match_dup 1) (match_dup 2))))) 7524 (set (match_operand:HI 0 "register_operand" "=r") 7525 (mult:HI (match_dup 1) (match_dup 2)))] 7526 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7527 "imul{w}\t{%2, %0|%0, %2}" 7528 [(set_attr "type" "imul") 7529 (set_attr "prefix_0f" "1") 7530 (set_attr "athlon_decode" "vector") 7531 (set_attr "amdfam10_decode" "direct") 7532 (set_attr "bdver1_decode" "double") 7533 (set_attr "mode" "HI")]) 7534 7535(define_insn "*mulv<mode>4_1" 7536 [(set (reg:CCO FLAGS_REG) 7537 (eq:CCO (mult:<DWI> 7538 (sign_extend:<DWI> 7539 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm")) 7540 (match_operand:<DWI> 3 "const_int_operand" "K,i")) 7541 (sign_extend:<DWI> 7542 (mult:SWI248 (match_dup 1) 7543 (match_operand:SWI248 2 7544 "<immediate_operand>" "K,<i>"))))) 7545 (set (match_operand:SWI248 0 "register_operand" "=r,r") 7546 (mult:SWI248 (match_dup 1) (match_dup 2)))] 7547 "!(MEM_P (operands[1]) && MEM_P (operands[2])) 7548 && CONST_INT_P (operands[2]) 7549 && INTVAL (operands[2]) == INTVAL (operands[3])" 7550 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}" 7551 [(set_attr "type" "imul") 7552 (set (attr "prefix_0f") 7553 (if_then_else 7554 (match_test "<MODE>mode == HImode") 7555 (const_string "0") 7556 (const_string "*"))) 7557 (set (attr "athlon_decode") 7558 (cond [(eq_attr "cpu" "athlon") 7559 (const_string "vector") 7560 (eq_attr "alternative" "1") 7561 (const_string "vector")] 7562 (const_string "direct"))) 7563 (set (attr "amdfam10_decode") 7564 (cond [(ior (match_test "<MODE>mode == HImode") 7565 (match_operand 1 "memory_operand")) 7566 (const_string "vector")] 7567 (const_string "direct"))) 7568 (set (attr "bdver1_decode") 7569 (if_then_else 7570 (match_test "<MODE>mode == HImode") 7571 (const_string "double") 7572 (const_string "direct"))) 7573 (set_attr "mode" "<MODE>") 7574 (set (attr "length_immediate") 7575 (cond [(eq_attr "alternative" "0") 7576 (const_string "1") 7577 (match_test "<MODE_SIZE> == 8") 7578 (const_string "4")] 7579 (const_string "<MODE_SIZE>")))]) 7580 7581(define_expand "umulv<mode>4" 7582 [(parallel [(set (reg:CCO FLAGS_REG) 7583 (eq:CCO (mult:<DWI> 7584 (zero_extend:<DWI> 7585 (match_operand:SWI248 1 7586 "nonimmediate_operand")) 7587 (zero_extend:<DWI> 7588 (match_operand:SWI248 2 7589 "nonimmediate_operand"))) 7590 (zero_extend:<DWI> 7591 (mult:SWI248 (match_dup 1) (match_dup 2))))) 7592 (set (match_operand:SWI248 0 "register_operand") 7593 (mult:SWI248 (match_dup 1) (match_dup 2))) 7594 (clobber (match_scratch:SWI248 4))]) 7595 (set (pc) (if_then_else 7596 (eq (reg:CCO FLAGS_REG) (const_int 0)) 7597 (label_ref (match_operand 3)) 7598 (pc)))] 7599 "" 7600{ 7601 if (MEM_P (operands[1]) && MEM_P (operands[2])) 7602 operands[1] = force_reg (<MODE>mode, operands[1]); 7603}) 7604 7605(define_insn "*umulv<mode>4" 7606 [(set (reg:CCO FLAGS_REG) 7607 (eq:CCO (mult:<DWI> 7608 (zero_extend:<DWI> 7609 (match_operand:SWI248 1 "nonimmediate_operand" "%0")) 7610 (zero_extend:<DWI> 7611 (match_operand:SWI248 2 "nonimmediate_operand" "rm"))) 7612 (zero_extend:<DWI> 7613 (mult:SWI248 (match_dup 1) (match_dup 2))))) 7614 (set (match_operand:SWI248 0 "register_operand" "=a") 7615 (mult:SWI248 (match_dup 1) (match_dup 2))) 7616 (clobber (match_scratch:SWI248 3 "=d"))] 7617 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7618 "mul{<imodesuffix>}\t%2" 7619 [(set_attr "type" "imul") 7620 (set_attr "length_immediate" "0") 7621 (set (attr "athlon_decode") 7622 (if_then_else (eq_attr "cpu" "athlon") 7623 (const_string "vector") 7624 (const_string "double"))) 7625 (set_attr "amdfam10_decode" "double") 7626 (set_attr "bdver1_decode" "direct") 7627 (set_attr "mode" "<MODE>")]) 7628 7629(define_expand "<u>mulvqi4" 7630 [(parallel [(set (reg:CCO FLAGS_REG) 7631 (eq:CCO (mult:HI 7632 (any_extend:HI 7633 (match_operand:QI 1 "nonimmediate_operand")) 7634 (any_extend:HI 7635 (match_operand:QI 2 "nonimmediate_operand"))) 7636 (any_extend:HI 7637 (mult:QI (match_dup 1) (match_dup 2))))) 7638 (set (match_operand:QI 0 "register_operand") 7639 (mult:QI (match_dup 1) (match_dup 2)))]) 7640 (set (pc) (if_then_else 7641 (eq (reg:CCO FLAGS_REG) (const_int 0)) 7642 (label_ref (match_operand 3)) 7643 (pc)))] 7644 "TARGET_QIMODE_MATH" 7645{ 7646 if (MEM_P (operands[1]) && MEM_P (operands[2])) 7647 operands[1] = force_reg (QImode, operands[1]); 7648}) 7649 7650(define_insn "*<u>mulvqi4" 7651 [(set (reg:CCO FLAGS_REG) 7652 (eq:CCO (mult:HI 7653 (any_extend:HI 7654 (match_operand:QI 1 "nonimmediate_operand" "%0")) 7655 (any_extend:HI 7656 (match_operand:QI 2 "nonimmediate_operand" "qm"))) 7657 (any_extend:HI 7658 (mult:QI (match_dup 1) (match_dup 2))))) 7659 (set (match_operand:QI 0 "register_operand" "=a") 7660 (mult:QI (match_dup 1) (match_dup 2)))] 7661 "TARGET_QIMODE_MATH 7662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7663 "<sgnprefix>mul{b}\t%2" 7664 [(set_attr "type" "imul") 7665 (set_attr "length_immediate" "0") 7666 (set (attr "athlon_decode") 7667 (if_then_else (eq_attr "cpu" "athlon") 7668 (const_string "vector") 7669 (const_string "direct"))) 7670 (set_attr "amdfam10_decode" "direct") 7671 (set_attr "bdver1_decode" "direct") 7672 (set_attr "mode" "QI")]) 7673 7674(define_expand "<u>mul<mode><dwi>3" 7675 [(parallel [(set (match_operand:<DWI> 0 "register_operand") 7676 (mult:<DWI> 7677 (any_extend:<DWI> 7678 (match_operand:DWIH 1 "nonimmediate_operand")) 7679 (any_extend:<DWI> 7680 (match_operand:DWIH 2 "register_operand")))) 7681 (clobber (reg:CC FLAGS_REG))])]) 7682 7683(define_expand "<u>mulqihi3" 7684 [(parallel [(set (match_operand:HI 0 "register_operand") 7685 (mult:HI 7686 (any_extend:HI 7687 (match_operand:QI 1 "nonimmediate_operand")) 7688 (any_extend:HI 7689 (match_operand:QI 2 "register_operand")))) 7690 (clobber (reg:CC FLAGS_REG))])] 7691 "TARGET_QIMODE_MATH") 7692 7693(define_insn "*bmi2_umul<mode><dwi>3_1" 7694 [(set (match_operand:DWIH 0 "register_operand" "=r") 7695 (mult:DWIH 7696 (match_operand:DWIH 2 "nonimmediate_operand" "%d") 7697 (match_operand:DWIH 3 "nonimmediate_operand" "rm"))) 7698 (set (match_operand:DWIH 1 "register_operand" "=r") 7699 (truncate:DWIH 7700 (lshiftrt:<DWI> 7701 (mult:<DWI> (zero_extend:<DWI> (match_dup 2)) 7702 (zero_extend:<DWI> (match_dup 3))) 7703 (match_operand:QI 4 "const_int_operand" "n"))))] 7704 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT 7705 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7706 "mulx\t{%3, %0, %1|%1, %0, %3}" 7707 [(set_attr "type" "imulx") 7708 (set_attr "prefix" "vex") 7709 (set_attr "mode" "<MODE>")]) 7710 7711(define_insn "*umul<mode><dwi>3_1" 7712 [(set (match_operand:<DWI> 0 "register_operand" "=r,A") 7713 (mult:<DWI> 7714 (zero_extend:<DWI> 7715 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0")) 7716 (zero_extend:<DWI> 7717 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm")))) 7718 (clobber (reg:CC FLAGS_REG))] 7719 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7720 "@ 7721 # 7722 mul{<imodesuffix>}\t%2" 7723 [(set_attr "isa" "bmi2,*") 7724 (set_attr "type" "imulx,imul") 7725 (set_attr "length_immediate" "*,0") 7726 (set (attr "athlon_decode") 7727 (cond [(eq_attr "alternative" "1") 7728 (if_then_else (eq_attr "cpu" "athlon") 7729 (const_string "vector") 7730 (const_string "double"))] 7731 (const_string "*"))) 7732 (set_attr "amdfam10_decode" "*,double") 7733 (set_attr "bdver1_decode" "*,direct") 7734 (set_attr "prefix" "vex,orig") 7735 (set_attr "mode" "<MODE>")]) 7736 7737;; Convert mul to the mulx pattern to avoid flags dependency. 7738(define_split 7739 [(set (match_operand:<DWI> 0 "register_operand") 7740 (mult:<DWI> 7741 (zero_extend:<DWI> 7742 (match_operand:DWIH 1 "register_operand")) 7743 (zero_extend:<DWI> 7744 (match_operand:DWIH 2 "nonimmediate_operand")))) 7745 (clobber (reg:CC FLAGS_REG))] 7746 "TARGET_BMI2 && reload_completed 7747 && REGNO (operands[1]) == DX_REG" 7748 [(parallel [(set (match_dup 3) 7749 (mult:DWIH (match_dup 1) (match_dup 2))) 7750 (set (match_dup 4) 7751 (truncate:DWIH 7752 (lshiftrt:<DWI> 7753 (mult:<DWI> (zero_extend:<DWI> (match_dup 1)) 7754 (zero_extend:<DWI> (match_dup 2))) 7755 (match_dup 5))))])] 7756{ 7757 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]); 7758 7759 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); 7760}) 7761 7762(define_insn "*mul<mode><dwi>3_1" 7763 [(set (match_operand:<DWI> 0 "register_operand" "=A") 7764 (mult:<DWI> 7765 (sign_extend:<DWI> 7766 (match_operand:DWIH 1 "nonimmediate_operand" "%0")) 7767 (sign_extend:<DWI> 7768 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))) 7769 (clobber (reg:CC FLAGS_REG))] 7770 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7771 "imul{<imodesuffix>}\t%2" 7772 [(set_attr "type" "imul") 7773 (set_attr "length_immediate" "0") 7774 (set (attr "athlon_decode") 7775 (if_then_else (eq_attr "cpu" "athlon") 7776 (const_string "vector") 7777 (const_string "double"))) 7778 (set_attr "amdfam10_decode" "double") 7779 (set_attr "bdver1_decode" "direct") 7780 (set_attr "mode" "<MODE>")]) 7781 7782(define_insn "*<u>mulqihi3_1" 7783 [(set (match_operand:HI 0 "register_operand" "=a") 7784 (mult:HI 7785 (any_extend:HI 7786 (match_operand:QI 1 "nonimmediate_operand" "%0")) 7787 (any_extend:HI 7788 (match_operand:QI 2 "nonimmediate_operand" "qm")))) 7789 (clobber (reg:CC FLAGS_REG))] 7790 "TARGET_QIMODE_MATH 7791 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7792 "<sgnprefix>mul{b}\t%2" 7793 [(set_attr "type" "imul") 7794 (set_attr "length_immediate" "0") 7795 (set (attr "athlon_decode") 7796 (if_then_else (eq_attr "cpu" "athlon") 7797 (const_string "vector") 7798 (const_string "direct"))) 7799 (set_attr "amdfam10_decode" "direct") 7800 (set_attr "bdver1_decode" "direct") 7801 (set_attr "mode" "QI")]) 7802 7803(define_expand "<s>mul<mode>3_highpart" 7804 [(parallel [(set (match_operand:DWIH 0 "register_operand") 7805 (truncate:DWIH 7806 (lshiftrt:<DWI> 7807 (mult:<DWI> 7808 (any_extend:<DWI> 7809 (match_operand:DWIH 1 "nonimmediate_operand")) 7810 (any_extend:<DWI> 7811 (match_operand:DWIH 2 "register_operand"))) 7812 (match_dup 3)))) 7813 (clobber (match_scratch:DWIH 4)) 7814 (clobber (reg:CC FLAGS_REG))])] 7815 "" 7816 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 7817 7818(define_insn "*<s>muldi3_highpart_1" 7819 [(set (match_operand:DI 0 "register_operand" "=d") 7820 (truncate:DI 7821 (lshiftrt:TI 7822 (mult:TI 7823 (any_extend:TI 7824 (match_operand:DI 1 "nonimmediate_operand" "%a")) 7825 (any_extend:TI 7826 (match_operand:DI 2 "nonimmediate_operand" "rm"))) 7827 (const_int 64)))) 7828 (clobber (match_scratch:DI 3 "=1")) 7829 (clobber (reg:CC FLAGS_REG))] 7830 "TARGET_64BIT 7831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7832 "<sgnprefix>mul{q}\t%2" 7833 [(set_attr "type" "imul") 7834 (set_attr "length_immediate" "0") 7835 (set (attr "athlon_decode") 7836 (if_then_else (eq_attr "cpu" "athlon") 7837 (const_string "vector") 7838 (const_string "double"))) 7839 (set_attr "amdfam10_decode" "double") 7840 (set_attr "bdver1_decode" "direct") 7841 (set_attr "mode" "DI")]) 7842 7843(define_insn "*<s>mulsi3_highpart_zext" 7844 [(set (match_operand:DI 0 "register_operand" "=d") 7845 (zero_extend:DI (truncate:SI 7846 (lshiftrt:DI 7847 (mult:DI (any_extend:DI 7848 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7849 (any_extend:DI 7850 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7851 (const_int 32))))) 7852 (clobber (match_scratch:SI 3 "=1")) 7853 (clobber (reg:CC FLAGS_REG))] 7854 "TARGET_64BIT 7855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 7856 "<sgnprefix>mul{l}\t%2" 7857 [(set_attr "type" "imul") 7858 (set_attr "length_immediate" "0") 7859 (set (attr "athlon_decode") 7860 (if_then_else (eq_attr "cpu" "athlon") 7861 (const_string "vector") 7862 (const_string "double"))) 7863 (set_attr "amdfam10_decode" "double") 7864 (set_attr "bdver1_decode" "direct") 7865 (set_attr "mode" "SI")]) 7866 7867(define_insn "*<s>mulsi3_highpart_1" 7868 [(set (match_operand:SI 0 "register_operand" "=d") 7869 (truncate:SI 7870 (lshiftrt:DI 7871 (mult:DI 7872 (any_extend:DI 7873 (match_operand:SI 1 "nonimmediate_operand" "%a")) 7874 (any_extend:DI 7875 (match_operand:SI 2 "nonimmediate_operand" "rm"))) 7876 (const_int 32)))) 7877 (clobber (match_scratch:SI 3 "=1")) 7878 (clobber (reg:CC FLAGS_REG))] 7879 "!(MEM_P (operands[1]) && MEM_P (operands[2]))" 7880 "<sgnprefix>mul{l}\t%2" 7881 [(set_attr "type" "imul") 7882 (set_attr "length_immediate" "0") 7883 (set (attr "athlon_decode") 7884 (if_then_else (eq_attr "cpu" "athlon") 7885 (const_string "vector") 7886 (const_string "double"))) 7887 (set_attr "amdfam10_decode" "double") 7888 (set_attr "bdver1_decode" "direct") 7889 (set_attr "mode" "SI")]) 7890 7891;; The patterns that match these are at the end of this file. 7892 7893(define_expand "mulxf3" 7894 [(set (match_operand:XF 0 "register_operand") 7895 (mult:XF (match_operand:XF 1 "register_operand") 7896 (match_operand:XF 2 "register_operand")))] 7897 "TARGET_80387") 7898 7899(define_expand "mul<mode>3" 7900 [(set (match_operand:MODEF 0 "register_operand") 7901 (mult:MODEF (match_operand:MODEF 1 "register_operand") 7902 (match_operand:MODEF 2 "nonimmediate_operand")))] 7903 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7904 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)") 7905 7906;; Divide instructions 7907 7908;; The patterns that match these are at the end of this file. 7909 7910(define_expand "divxf3" 7911 [(set (match_operand:XF 0 "register_operand") 7912 (div:XF (match_operand:XF 1 "register_operand") 7913 (match_operand:XF 2 "register_operand")))] 7914 "TARGET_80387") 7915 7916(define_expand "div<mode>3" 7917 [(set (match_operand:MODEF 0 "register_operand") 7918 (div:MODEF (match_operand:MODEF 1 "register_operand") 7919 (match_operand:MODEF 2 "nonimmediate_operand")))] 7920 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)) 7921 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 7922{ 7923 if (<MODE>mode == SFmode 7924 && TARGET_SSE && TARGET_SSE_MATH 7925 && TARGET_RECIP_DIV 7926 && optimize_insn_for_speed_p () 7927 && flag_finite_math_only && !flag_trapping_math 7928 && flag_unsafe_math_optimizations) 7929 { 7930 ix86_emit_swdivsf (operands[0], operands[1], 7931 operands[2], SFmode); 7932 DONE; 7933 } 7934}) 7935 7936;; Divmod instructions. 7937 7938(define_code_iterator any_div [div udiv]) 7939(define_code_attr paired_mod [(div "mod") (udiv "umod")]) 7940 7941(define_expand "<u>divmod<mode>4" 7942 [(parallel [(set (match_operand:SWIM248 0 "register_operand") 7943 (any_div:SWIM248 7944 (match_operand:SWIM248 1 "register_operand") 7945 (match_operand:SWIM248 2 "nonimmediate_operand"))) 7946 (set (match_operand:SWIM248 3 "register_operand") 7947 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2))) 7948 (clobber (reg:CC FLAGS_REG))])]) 7949 7950;; Split with 8bit unsigned divide: 7951;; if (dividend an divisor are in [0-255]) 7952;; use 8bit unsigned integer divide 7953;; else 7954;; use original integer divide 7955(define_split 7956 [(set (match_operand:SWI48 0 "register_operand") 7957 (any_div:SWI48 (match_operand:SWI48 2 "register_operand") 7958 (match_operand:SWI48 3 "nonimmediate_operand"))) 7959 (set (match_operand:SWI48 1 "register_operand") 7960 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3))) 7961 (clobber (reg:CC FLAGS_REG))] 7962 "TARGET_USE_8BIT_IDIV 7963 && TARGET_QIMODE_MATH 7964 && can_create_pseudo_p () 7965 && !optimize_insn_for_size_p ()" 7966 [(const_int 0)] 7967 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;") 7968 7969(define_split 7970 [(set (match_operand:DI 0 "register_operand") 7971 (zero_extend:DI 7972 (any_div:SI (match_operand:SI 2 "register_operand") 7973 (match_operand:SI 3 "nonimmediate_operand")))) 7974 (set (match_operand:SI 1 "register_operand") 7975 (<paired_mod>:SI (match_dup 2) (match_dup 3))) 7976 (clobber (reg:CC FLAGS_REG))] 7977 "TARGET_64BIT 7978 && TARGET_USE_8BIT_IDIV 7979 && TARGET_QIMODE_MATH 7980 && can_create_pseudo_p () 7981 && !optimize_insn_for_size_p ()" 7982 [(const_int 0)] 7983 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;") 7984 7985(define_split 7986 [(set (match_operand:DI 1 "register_operand") 7987 (zero_extend:DI 7988 (<paired_mod>:SI (match_operand:SI 2 "register_operand") 7989 (match_operand:SI 3 "nonimmediate_operand")))) 7990 (set (match_operand:SI 0 "register_operand") 7991 (any_div:SI (match_dup 2) (match_dup 3))) 7992 (clobber (reg:CC FLAGS_REG))] 7993 "TARGET_64BIT 7994 && TARGET_USE_8BIT_IDIV 7995 && TARGET_QIMODE_MATH 7996 && can_create_pseudo_p () 7997 && !optimize_insn_for_size_p ()" 7998 [(const_int 0)] 7999 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;") 8000 8001(define_insn_and_split "divmod<mode>4_1" 8002 [(set (match_operand:SWI48 0 "register_operand" "=a") 8003 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0") 8004 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 8005 (set (match_operand:SWI48 1 "register_operand" "=&d") 8006 (mod:SWI48 (match_dup 2) (match_dup 3))) 8007 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8008 (clobber (reg:CC FLAGS_REG))] 8009 "" 8010 "#" 8011 "reload_completed" 8012 [(parallel [(set (match_dup 1) 8013 (ashiftrt:SWI48 (match_dup 4) (match_dup 5))) 8014 (clobber (reg:CC FLAGS_REG))]) 8015 (parallel [(set (match_dup 0) 8016 (div:SWI48 (match_dup 2) (match_dup 3))) 8017 (set (match_dup 1) 8018 (mod:SWI48 (match_dup 2) (match_dup 3))) 8019 (use (match_dup 1)) 8020 (clobber (reg:CC FLAGS_REG))])] 8021{ 8022 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 8023 8024 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 8025 operands[4] = operands[2]; 8026 else 8027 { 8028 /* Avoid use of cltd in favor of a mov+shift. */ 8029 emit_move_insn (operands[1], operands[2]); 8030 operands[4] = operands[1]; 8031 } 8032} 8033 [(set_attr "type" "multi") 8034 (set_attr "mode" "<MODE>")]) 8035 8036(define_insn_and_split "udivmod<mode>4_1" 8037 [(set (match_operand:SWI48 0 "register_operand" "=a") 8038 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 8039 (match_operand:SWI48 3 "nonimmediate_operand" "rm"))) 8040 (set (match_operand:SWI48 1 "register_operand" "=&d") 8041 (umod:SWI48 (match_dup 2) (match_dup 3))) 8042 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8043 (clobber (reg:CC FLAGS_REG))] 8044 "" 8045 "#" 8046 "reload_completed" 8047 [(set (match_dup 1) (const_int 0)) 8048 (parallel [(set (match_dup 0) 8049 (udiv:SWI48 (match_dup 2) (match_dup 3))) 8050 (set (match_dup 1) 8051 (umod:SWI48 (match_dup 2) (match_dup 3))) 8052 (use (match_dup 1)) 8053 (clobber (reg:CC FLAGS_REG))])] 8054 "" 8055 [(set_attr "type" "multi") 8056 (set_attr "mode" "<MODE>")]) 8057 8058(define_insn_and_split "divmodsi4_zext_1" 8059 [(set (match_operand:DI 0 "register_operand" "=a") 8060 (zero_extend:DI 8061 (div:SI (match_operand:SI 2 "register_operand" "0") 8062 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8063 (set (match_operand:SI 1 "register_operand" "=&d") 8064 (mod:SI (match_dup 2) (match_dup 3))) 8065 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8066 (clobber (reg:CC FLAGS_REG))] 8067 "TARGET_64BIT" 8068 "#" 8069 "&& reload_completed" 8070 [(parallel [(set (match_dup 1) 8071 (ashiftrt:SI (match_dup 4) (match_dup 5))) 8072 (clobber (reg:CC FLAGS_REG))]) 8073 (parallel [(set (match_dup 0) 8074 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3)))) 8075 (set (match_dup 1) 8076 (mod:SI (match_dup 2) (match_dup 3))) 8077 (use (match_dup 1)) 8078 (clobber (reg:CC FLAGS_REG))])] 8079{ 8080 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1); 8081 8082 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 8083 operands[4] = operands[2]; 8084 else 8085 { 8086 /* Avoid use of cltd in favor of a mov+shift. */ 8087 emit_move_insn (operands[1], operands[2]); 8088 operands[4] = operands[1]; 8089 } 8090} 8091 [(set_attr "type" "multi") 8092 (set_attr "mode" "SI")]) 8093 8094(define_insn_and_split "udivmodsi4_zext_1" 8095 [(set (match_operand:DI 0 "register_operand" "=a") 8096 (zero_extend:DI 8097 (udiv:SI (match_operand:SI 2 "register_operand" "0") 8098 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8099 (set (match_operand:SI 1 "register_operand" "=&d") 8100 (umod:SI (match_dup 2) (match_dup 3))) 8101 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8102 (clobber (reg:CC FLAGS_REG))] 8103 "TARGET_64BIT" 8104 "#" 8105 "&& reload_completed" 8106 [(set (match_dup 1) (const_int 0)) 8107 (parallel [(set (match_dup 0) 8108 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) 8109 (set (match_dup 1) 8110 (umod:SI (match_dup 2) (match_dup 3))) 8111 (use (match_dup 1)) 8112 (clobber (reg:CC FLAGS_REG))])] 8113 "" 8114 [(set_attr "type" "multi") 8115 (set_attr "mode" "SI")]) 8116 8117(define_insn_and_split "divmodsi4_zext_2" 8118 [(set (match_operand:DI 1 "register_operand" "=&d") 8119 (zero_extend:DI 8120 (mod:SI (match_operand:SI 2 "register_operand" "0") 8121 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8122 (set (match_operand:SI 0 "register_operand" "=a") 8123 (div:SI (match_dup 2) (match_dup 3))) 8124 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8125 (clobber (reg:CC FLAGS_REG))] 8126 "TARGET_64BIT" 8127 "#" 8128 "&& reload_completed" 8129 [(parallel [(set (match_dup 6) 8130 (ashiftrt:SI (match_dup 4) (match_dup 5))) 8131 (clobber (reg:CC FLAGS_REG))]) 8132 (parallel [(set (match_dup 1) 8133 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3)))) 8134 (set (match_dup 0) 8135 (div:SI (match_dup 2) (match_dup 3))) 8136 (use (match_dup 6)) 8137 (clobber (reg:CC FLAGS_REG))])] 8138{ 8139 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1); 8140 operands[6] = gen_lowpart (SImode, operands[1]); 8141 8142 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 8143 operands[4] = operands[2]; 8144 else 8145 { 8146 /* Avoid use of cltd in favor of a mov+shift. */ 8147 emit_move_insn (operands[6], operands[2]); 8148 operands[4] = operands[6]; 8149 } 8150} 8151 [(set_attr "type" "multi") 8152 (set_attr "mode" "SI")]) 8153 8154(define_insn_and_split "udivmodsi4_zext_2" 8155 [(set (match_operand:DI 1 "register_operand" "=&d") 8156 (zero_extend:DI 8157 (umod:SI (match_operand:SI 2 "register_operand" "0") 8158 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8159 (set (match_operand:SI 0 "register_operand" "=a") 8160 (udiv:SI (match_dup 2) (match_dup 3))) 8161 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT) 8162 (clobber (reg:CC FLAGS_REG))] 8163 "TARGET_64BIT" 8164 "#" 8165 "&& reload_completed" 8166 [(set (match_dup 4) (const_int 0)) 8167 (parallel [(set (match_dup 1) 8168 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) 8169 (set (match_dup 0) 8170 (udiv:SI (match_dup 2) (match_dup 3))) 8171 (use (match_dup 4)) 8172 (clobber (reg:CC FLAGS_REG))])] 8173 "operands[4] = gen_lowpart (SImode, operands[1]);" 8174 [(set_attr "type" "multi") 8175 (set_attr "mode" "SI")]) 8176 8177(define_insn_and_split "*divmod<mode>4" 8178 [(set (match_operand:SWIM248 0 "register_operand" "=a") 8179 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 8180 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 8181 (set (match_operand:SWIM248 1 "register_operand" "=&d") 8182 (mod:SWIM248 (match_dup 2) (match_dup 3))) 8183 (clobber (reg:CC FLAGS_REG))] 8184 "" 8185 "#" 8186 "reload_completed" 8187 [(parallel [(set (match_dup 1) 8188 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5))) 8189 (clobber (reg:CC FLAGS_REG))]) 8190 (parallel [(set (match_dup 0) 8191 (div:SWIM248 (match_dup 2) (match_dup 3))) 8192 (set (match_dup 1) 8193 (mod:SWIM248 (match_dup 2) (match_dup 3))) 8194 (use (match_dup 1)) 8195 (clobber (reg:CC FLAGS_REG))])] 8196{ 8197 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 8198 8199 if (<MODE>mode != HImode 8200 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)) 8201 operands[4] = operands[2]; 8202 else 8203 { 8204 /* Avoid use of cltd in favor of a mov+shift. */ 8205 emit_move_insn (operands[1], operands[2]); 8206 operands[4] = operands[1]; 8207 } 8208} 8209 [(set_attr "type" "multi") 8210 (set_attr "mode" "<MODE>")]) 8211 8212(define_insn_and_split "*udivmod<mode>4" 8213 [(set (match_operand:SWIM248 0 "register_operand" "=a") 8214 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0") 8215 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 8216 (set (match_operand:SWIM248 1 "register_operand" "=&d") 8217 (umod:SWIM248 (match_dup 2) (match_dup 3))) 8218 (clobber (reg:CC FLAGS_REG))] 8219 "" 8220 "#" 8221 "reload_completed" 8222 [(set (match_dup 1) (const_int 0)) 8223 (parallel [(set (match_dup 0) 8224 (udiv:SWIM248 (match_dup 2) (match_dup 3))) 8225 (set (match_dup 1) 8226 (umod:SWIM248 (match_dup 2) (match_dup 3))) 8227 (use (match_dup 1)) 8228 (clobber (reg:CC FLAGS_REG))])] 8229 "" 8230 [(set_attr "type" "multi") 8231 (set_attr "mode" "<MODE>")]) 8232 8233;; Optimize division or modulo by constant power of 2, if the constant 8234;; materializes only after expansion. 8235(define_insn_and_split "*udivmod<mode>4_pow2" 8236 [(set (match_operand:SWI48 0 "register_operand" "=r") 8237 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0") 8238 (match_operand:SWI48 3 "const_int_operand" "n"))) 8239 (set (match_operand:SWI48 1 "register_operand" "=r") 8240 (umod:SWI48 (match_dup 2) (match_dup 3))) 8241 (clobber (reg:CC FLAGS_REG))] 8242 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)" 8243 "#" 8244 "&& reload_completed" 8245 [(set (match_dup 1) (match_dup 2)) 8246 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4))) 8247 (clobber (reg:CC FLAGS_REG))]) 8248 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5))) 8249 (clobber (reg:CC FLAGS_REG))])] 8250{ 8251 int v = exact_log2 (UINTVAL (operands[3])); 8252 operands[4] = GEN_INT (v); 8253 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); 8254} 8255 [(set_attr "type" "multi") 8256 (set_attr "mode" "<MODE>")]) 8257 8258(define_insn_and_split "*divmodsi4_zext_1" 8259 [(set (match_operand:DI 0 "register_operand" "=a") 8260 (zero_extend:DI 8261 (div:SI (match_operand:SI 2 "register_operand" "0") 8262 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8263 (set (match_operand:SI 1 "register_operand" "=&d") 8264 (mod:SI (match_dup 2) (match_dup 3))) 8265 (clobber (reg:CC FLAGS_REG))] 8266 "TARGET_64BIT" 8267 "#" 8268 "&& reload_completed" 8269 [(parallel [(set (match_dup 1) 8270 (ashiftrt:SI (match_dup 4) (match_dup 5))) 8271 (clobber (reg:CC FLAGS_REG))]) 8272 (parallel [(set (match_dup 0) 8273 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3)))) 8274 (set (match_dup 1) 8275 (mod:SI (match_dup 2) (match_dup 3))) 8276 (use (match_dup 1)) 8277 (clobber (reg:CC FLAGS_REG))])] 8278{ 8279 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1); 8280 8281 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 8282 operands[4] = operands[2]; 8283 else 8284 { 8285 /* Avoid use of cltd in favor of a mov+shift. */ 8286 emit_move_insn (operands[1], operands[2]); 8287 operands[4] = operands[1]; 8288 } 8289} 8290 [(set_attr "type" "multi") 8291 (set_attr "mode" "SI")]) 8292 8293(define_insn_and_split "*udivmodsi4_zext_1" 8294 [(set (match_operand:DI 0 "register_operand" "=a") 8295 (zero_extend:DI 8296 (udiv:SI (match_operand:SI 2 "register_operand" "0") 8297 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8298 (set (match_operand:SI 1 "register_operand" "=&d") 8299 (umod:SI (match_dup 2) (match_dup 3))) 8300 (clobber (reg:CC FLAGS_REG))] 8301 "TARGET_64BIT" 8302 "#" 8303 "&& reload_completed" 8304 [(set (match_dup 1) (const_int 0)) 8305 (parallel [(set (match_dup 0) 8306 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3)))) 8307 (set (match_dup 1) 8308 (umod:SI (match_dup 2) (match_dup 3))) 8309 (use (match_dup 1)) 8310 (clobber (reg:CC FLAGS_REG))])] 8311 "" 8312 [(set_attr "type" "multi") 8313 (set_attr "mode" "SI")]) 8314 8315(define_insn_and_split "*udivmodsi4_pow2_zext_1" 8316 [(set (match_operand:DI 0 "register_operand" "=r") 8317 (zero_extend:DI 8318 (udiv:SI (match_operand:SI 2 "register_operand" "0") 8319 (match_operand:SI 3 "const_int_operand" "n")))) 8320 (set (match_operand:SI 1 "register_operand" "=r") 8321 (umod:SI (match_dup 2) (match_dup 3))) 8322 (clobber (reg:CC FLAGS_REG))] 8323 "TARGET_64BIT 8324 && exact_log2 (UINTVAL (operands[3])) > 0" 8325 "#" 8326 "&& reload_completed" 8327 [(set (match_dup 1) (match_dup 2)) 8328 (parallel [(set (match_dup 0) 8329 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4)))) 8330 (clobber (reg:CC FLAGS_REG))]) 8331 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5))) 8332 (clobber (reg:CC FLAGS_REG))])] 8333{ 8334 int v = exact_log2 (UINTVAL (operands[3])); 8335 operands[4] = GEN_INT (v); 8336 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); 8337} 8338 [(set_attr "type" "multi") 8339 (set_attr "mode" "SI")]) 8340 8341(define_insn_and_split "*divmodsi4_zext_2" 8342 [(set (match_operand:DI 1 "register_operand" "=&d") 8343 (zero_extend:DI 8344 (mod:SI (match_operand:SI 2 "register_operand" "0") 8345 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8346 (set (match_operand:SI 0 "register_operand" "=a") 8347 (div:SI (match_dup 2) (match_dup 3))) 8348 (clobber (reg:CC FLAGS_REG))] 8349 "TARGET_64BIT" 8350 "#" 8351 "&& reload_completed" 8352 [(parallel [(set (match_dup 6) 8353 (ashiftrt:SI (match_dup 4) (match_dup 5))) 8354 (clobber (reg:CC FLAGS_REG))]) 8355 (parallel [(set (match_dup 1) 8356 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3)))) 8357 (set (match_dup 0) 8358 (div:SI (match_dup 2) (match_dup 3))) 8359 (use (match_dup 6)) 8360 (clobber (reg:CC FLAGS_REG))])] 8361{ 8362 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1); 8363 operands[6] = gen_lowpart (SImode, operands[1]); 8364 8365 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD) 8366 operands[4] = operands[2]; 8367 else 8368 { 8369 /* Avoid use of cltd in favor of a mov+shift. */ 8370 emit_move_insn (operands[6], operands[2]); 8371 operands[4] = operands[6]; 8372 } 8373} 8374 [(set_attr "type" "multi") 8375 (set_attr "mode" "SI")]) 8376 8377(define_insn_and_split "*udivmodsi4_zext_2" 8378 [(set (match_operand:DI 1 "register_operand" "=&d") 8379 (zero_extend:DI 8380 (umod:SI (match_operand:SI 2 "register_operand" "0") 8381 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8382 (set (match_operand:SI 0 "register_operand" "=a") 8383 (udiv:SI (match_dup 2) (match_dup 3))) 8384 (clobber (reg:CC FLAGS_REG))] 8385 "TARGET_64BIT" 8386 "#" 8387 "&& reload_completed" 8388 [(set (match_dup 4) (const_int 0)) 8389 (parallel [(set (match_dup 1) 8390 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3)))) 8391 (set (match_dup 0) 8392 (udiv:SI (match_dup 2) (match_dup 3))) 8393 (use (match_dup 4)) 8394 (clobber (reg:CC FLAGS_REG))])] 8395 "operands[4] = gen_lowpart (SImode, operands[1]);" 8396 [(set_attr "type" "multi") 8397 (set_attr "mode" "SI")]) 8398 8399(define_insn_and_split "*udivmodsi4_pow2_zext_2" 8400 [(set (match_operand:DI 1 "register_operand" "=r") 8401 (zero_extend:DI 8402 (umod:SI (match_operand:SI 2 "register_operand" "0") 8403 (match_operand:SI 3 "const_int_operand" "n")))) 8404 (set (match_operand:SI 0 "register_operand" "=r") 8405 (umod:SI (match_dup 2) (match_dup 3))) 8406 (clobber (reg:CC FLAGS_REG))] 8407 "TARGET_64BIT 8408 && exact_log2 (UINTVAL (operands[3])) > 0" 8409 "#" 8410 "&& reload_completed" 8411 [(set (match_dup 1) (match_dup 2)) 8412 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4))) 8413 (clobber (reg:CC FLAGS_REG))]) 8414 (parallel [(set (match_dup 1) 8415 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5)))) 8416 (clobber (reg:CC FLAGS_REG))])] 8417{ 8418 int v = exact_log2 (UINTVAL (operands[3])); 8419 operands[4] = GEN_INT (v); 8420 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1); 8421} 8422 [(set_attr "type" "multi") 8423 (set_attr "mode" "SI")]) 8424 8425(define_insn "*<u>divmod<mode>4_noext" 8426 [(set (match_operand:SWIM248 0 "register_operand" "=a") 8427 (any_div:SWIM248 8428 (match_operand:SWIM248 2 "register_operand" "0") 8429 (match_operand:SWIM248 3 "nonimmediate_operand" "rm"))) 8430 (set (match_operand:SWIM248 1 "register_operand" "=d") 8431 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3))) 8432 (use (match_operand:SWIM248 4 "register_operand" "1")) 8433 (clobber (reg:CC FLAGS_REG))] 8434 "" 8435 "<sgnprefix>div{<imodesuffix>}\t%3" 8436 [(set_attr "type" "idiv") 8437 (set_attr "mode" "<MODE>")]) 8438 8439(define_insn "*<u>divmodsi4_noext_zext_1" 8440 [(set (match_operand:DI 0 "register_operand" "=a") 8441 (zero_extend:DI 8442 (any_div:SI (match_operand:SI 2 "register_operand" "0") 8443 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8444 (set (match_operand:SI 1 "register_operand" "=d") 8445 (<paired_mod>:SI (match_dup 2) (match_dup 3))) 8446 (use (match_operand:SI 4 "register_operand" "1")) 8447 (clobber (reg:CC FLAGS_REG))] 8448 "TARGET_64BIT" 8449 "<sgnprefix>div{l}\t%3" 8450 [(set_attr "type" "idiv") 8451 (set_attr "mode" "SI")]) 8452 8453(define_insn "*<u>divmodsi4_noext_zext_2" 8454 [(set (match_operand:DI 1 "register_operand" "=d") 8455 (zero_extend:DI 8456 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0") 8457 (match_operand:SI 3 "nonimmediate_operand" "rm")))) 8458 (set (match_operand:SI 0 "register_operand" "=a") 8459 (any_div:SI (match_dup 2) (match_dup 3))) 8460 (use (match_operand:SI 4 "register_operand" "1")) 8461 (clobber (reg:CC FLAGS_REG))] 8462 "TARGET_64BIT" 8463 "<sgnprefix>div{l}\t%3" 8464 [(set_attr "type" "idiv") 8465 (set_attr "mode" "SI")]) 8466 8467(define_expand "divmodqi4" 8468 [(parallel [(set (match_operand:QI 0 "register_operand") 8469 (div:QI 8470 (match_operand:QI 1 "register_operand") 8471 (match_operand:QI 2 "nonimmediate_operand"))) 8472 (set (match_operand:QI 3 "register_operand") 8473 (mod:QI (match_dup 1) (match_dup 2))) 8474 (clobber (reg:CC FLAGS_REG))])] 8475 "TARGET_QIMODE_MATH" 8476{ 8477 rtx div, mod; 8478 rtx tmp0, tmp1; 8479 8480 tmp0 = gen_reg_rtx (HImode); 8481 tmp1 = gen_reg_rtx (HImode); 8482 8483 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */ 8484 emit_insn (gen_extendqihi2 (tmp1, operands[1])); 8485 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2])); 8486 8487 /* Extract remainder from AH. */ 8488 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8)); 8489 tmp1 = lowpart_subreg (QImode, tmp1, SImode); 8490 rtx_insn *insn = emit_move_insn (operands[3], tmp1); 8491 8492 mod = gen_rtx_MOD (QImode, operands[1], operands[2]); 8493 set_unique_reg_note (insn, REG_EQUAL, mod); 8494 8495 /* Extract quotient from AL. */ 8496 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 8497 8498 div = gen_rtx_DIV (QImode, operands[1], operands[2]); 8499 set_unique_reg_note (insn, REG_EQUAL, div); 8500 8501 DONE; 8502}) 8503 8504(define_expand "udivmodqi4" 8505 [(parallel [(set (match_operand:QI 0 "register_operand") 8506 (udiv:QI 8507 (match_operand:QI 1 "register_operand") 8508 (match_operand:QI 2 "nonimmediate_operand"))) 8509 (set (match_operand:QI 3 "register_operand") 8510 (umod:QI (match_dup 1) (match_dup 2))) 8511 (clobber (reg:CC FLAGS_REG))])] 8512 "TARGET_QIMODE_MATH" 8513{ 8514 rtx div, mod; 8515 rtx tmp0, tmp1; 8516 8517 tmp0 = gen_reg_rtx (HImode); 8518 tmp1 = gen_reg_rtx (HImode); 8519 8520 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */ 8521 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1])); 8522 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2])); 8523 8524 /* Extract remainder from AH. */ 8525 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8)); 8526 tmp1 = lowpart_subreg (QImode, tmp1, SImode); 8527 rtx_insn *insn = emit_move_insn (operands[3], tmp1); 8528 8529 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]); 8530 set_unique_reg_note (insn, REG_EQUAL, mod); 8531 8532 /* Extract quotient from AL. */ 8533 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0)); 8534 8535 div = gen_rtx_UDIV (QImode, operands[1], operands[2]); 8536 set_unique_reg_note (insn, REG_EQUAL, div); 8537 8538 DONE; 8539}) 8540 8541;; Divide AX by r/m8, with result stored in 8542;; AL <- Quotient 8543;; AH <- Remainder 8544;; Change div/mod to HImode and extend the second argument to HImode 8545;; so that mode of div/mod matches with mode of arguments. Otherwise 8546;; combine may fail. 8547(define_insn "<u>divmodhiqi3" 8548 [(set (match_operand:HI 0 "register_operand" "=a") 8549 (ior:HI 8550 (ashift:HI 8551 (zero_extend:HI 8552 (truncate:QI 8553 (mod:HI (match_operand:HI 1 "register_operand" "0") 8554 (any_extend:HI 8555 (match_operand:QI 2 "nonimmediate_operand" "qm"))))) 8556 (const_int 8)) 8557 (zero_extend:HI 8558 (truncate:QI 8559 (div:HI (match_dup 1) (any_extend:HI (match_dup 2))))))) 8560 (clobber (reg:CC FLAGS_REG))] 8561 "TARGET_QIMODE_MATH" 8562 "<sgnprefix>div{b}\t%2" 8563 [(set_attr "type" "idiv") 8564 (set_attr "mode" "QI")]) 8565 8566;; We cannot use div/idiv for double division, because it causes 8567;; "division by zero" on the overflow and that's not what we expect 8568;; from truncate. Because true (non truncating) double division is 8569;; never generated, we can't create this insn anyway. 8570; 8571;(define_insn "" 8572; [(set (match_operand:SI 0 "register_operand" "=a") 8573; (truncate:SI 8574; (udiv:DI (match_operand:DI 1 "register_operand" "A") 8575; (zero_extend:DI 8576; (match_operand:SI 2 "nonimmediate_operand" "rm"))))) 8577; (set (match_operand:SI 3 "register_operand" "=d") 8578; (truncate:SI 8579; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) 8580; (clobber (reg:CC FLAGS_REG))] 8581; "" 8582; "div{l}\t{%2, %0|%0, %2}" 8583; [(set_attr "type" "idiv")]) 8584 8585;;- Logical AND instructions 8586 8587;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al. 8588;; Note that this excludes ah. 8589 8590(define_expand "@test<mode>_ccno_1" 8591 [(set (reg:CCNO FLAGS_REG) 8592 (compare:CCNO 8593 (and:SWI48 8594 (match_operand:SWI48 0 "nonimmediate_operand") 8595 (match_operand:SWI48 1 "<nonmemory_szext_operand>")) 8596 (const_int 0)))]) 8597 8598(define_expand "testqi_ccz_1" 8599 [(set (reg:CCZ FLAGS_REG) 8600 (compare:CCZ 8601 (and:QI 8602 (match_operand:QI 0 "nonimmediate_operand") 8603 (match_operand:QI 1 "nonmemory_operand")) 8604 (const_int 0)))]) 8605 8606(define_insn "*testdi_1" 8607 [(set (reg FLAGS_REG) 8608 (compare 8609 (and:DI 8610 (match_operand:DI 0 "nonimmediate_operand" "%r,rm") 8611 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re")) 8612 (const_int 0)))] 8613 "TARGET_64BIT 8614 && ix86_match_ccmode 8615 (insn, 8616 /* If we are going to emit testl instead of testq, and the operands[1] 8617 constant might have the SImode sign bit set, make sure the sign 8618 flag isn't tested, because the instruction will set the sign flag 8619 based on bit 31 rather than bit 63. If it isn't CONST_INT, 8620 conservatively assume it might have bit 31 set. */ 8621 (satisfies_constraint_Z (operands[1]) 8622 && (!CONST_INT_P (operands[1]) 8623 || val_signbit_known_set_p (SImode, INTVAL (operands[1])))) 8624 ? CCZmode : CCNOmode)" 8625 "@ 8626 test{l}\t{%k1, %k0|%k0, %k1} 8627 test{q}\t{%1, %0|%0, %1}" 8628 [(set_attr "type" "test") 8629 (set_attr "mode" "SI,DI")]) 8630 8631(define_insn "*testqi_1_maybe_si" 8632 [(set (reg FLAGS_REG) 8633 (compare 8634 (and:QI 8635 (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r") 8636 (match_operand:QI 1 "nonmemory_operand" "q,n,n,n")) 8637 (const_int 0)))] 8638 "ix86_match_ccmode (insn, 8639 CONST_INT_P (operands[1]) 8640 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)" 8641{ 8642 if (which_alternative == 3) 8643 { 8644 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0) 8645 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff); 8646 return "test{l}\t{%1, %k0|%k0, %1}"; 8647 } 8648 return "test{b}\t{%1, %0|%0, %1}"; 8649} 8650 [(set_attr "type" "test") 8651 (set_attr "mode" "QI,QI,QI,SI") 8652 (set_attr "pent_pair" "uv,uv,np,np")]) 8653 8654(define_insn "*test<mode>_1" 8655 [(set (reg FLAGS_REG) 8656 (compare 8657 (and:SWI124 8658 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m") 8659 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>")) 8660 (const_int 0)))] 8661 "ix86_match_ccmode (insn, CCNOmode)" 8662 "test{<imodesuffix>}\t{%1, %0|%0, %1}" 8663 [(set_attr "type" "test") 8664 (set_attr "mode" "<MODE>") 8665 (set_attr "pent_pair" "uv,uv,np")]) 8666 8667(define_expand "testqi_ext_1_ccno" 8668 [(set (reg:CCNO FLAGS_REG) 8669 (compare:CCNO 8670 (and:QI 8671 (subreg:QI 8672 (zero_extract:SI (match_operand 0 "ext_register_operand") 8673 (const_int 8) 8674 (const_int 8)) 0) 8675 (match_operand 1 "const_int_operand")) 8676 (const_int 0)))]) 8677 8678(define_insn "*testqi_ext_1" 8679 [(set (reg FLAGS_REG) 8680 (compare 8681 (and:QI 8682 (subreg:QI 8683 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q") 8684 (const_int 8) 8685 (const_int 8)) 0) 8686 (match_operand:QI 1 "general_operand" "QnBc,m")) 8687 (const_int 0)))] 8688 "ix86_match_ccmode (insn, CCNOmode)" 8689 "test{b}\t{%1, %h0|%h0, %1}" 8690 [(set_attr "isa" "*,nox64") 8691 (set_attr "type" "test") 8692 (set_attr "mode" "QI")]) 8693 8694(define_insn "*testqi_ext_2" 8695 [(set (reg FLAGS_REG) 8696 (compare 8697 (and:QI 8698 (subreg:QI 8699 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q") 8700 (const_int 8) 8701 (const_int 8)) 0) 8702 (subreg:QI 8703 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q") 8704 (const_int 8) 8705 (const_int 8)) 0)) 8706 (const_int 0)))] 8707 "ix86_match_ccmode (insn, CCNOmode)" 8708 "test{b}\t{%h1, %h0|%h0, %h1}" 8709 [(set_attr "type" "test") 8710 (set_attr "mode" "QI")]) 8711 8712;; Combine likes to form bit extractions for some tests. Humor it. 8713(define_insn_and_split "*testqi_ext_3" 8714 [(set (match_operand 0 "flags_reg_operand") 8715 (match_operator 1 "compare_operator" 8716 [(zero_extract:SWI248 8717 (match_operand 2 "nonimmediate_operand" "rm") 8718 (match_operand 3 "const_int_operand" "n") 8719 (match_operand 4 "const_int_operand" "n")) 8720 (const_int 0)]))] 8721 "((TARGET_64BIT && GET_MODE (operands[2]) == DImode) 8722 || GET_MODE (operands[2]) == SImode 8723 || GET_MODE (operands[2]) == HImode 8724 || GET_MODE (operands[2]) == QImode) 8725 /* Ensure that resulting mask is zero or sign extended operand. */ 8726 && INTVAL (operands[4]) >= 0 8727 && ((INTVAL (operands[3]) > 0 8728 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32) 8729 || (<MODE>mode == DImode 8730 && INTVAL (operands[3]) > 32 8731 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64)) 8732 && ix86_match_ccmode (insn, 8733 /* If zero_extract mode precision is the same 8734 as len, the SF of the zero_extract 8735 comparison will be the most significant 8736 extracted bit, but this could be matched 8737 after splitting only for pos 0 len all bits 8738 trivial extractions. Require CCZmode. */ 8739 (GET_MODE_PRECISION (<MODE>mode) 8740 == INTVAL (operands[3])) 8741 /* Otherwise, require CCZmode if we'd use a mask 8742 with the most significant bit set and can't 8743 widen it to wider mode. *testdi_1 also 8744 requires CCZmode if the mask has bit 8745 31 set and all bits above it clear. */ 8746 || (INTVAL (operands[3]) + INTVAL (operands[4]) 8747 >= 32) 8748 /* We can't widen also if val is not a REG. */ 8749 || (INTVAL (operands[3]) + INTVAL (operands[4]) 8750 == GET_MODE_PRECISION (GET_MODE (operands[2])) 8751 && !register_operand (operands[2], 8752 GET_MODE (operands[2]))) 8753 /* And we shouldn't widen if 8754 TARGET_PARTIAL_REG_STALL. */ 8755 || (TARGET_PARTIAL_REG_STALL 8756 && (INTVAL (operands[3]) + INTVAL (operands[4]) 8757 >= (paradoxical_subreg_p (operands[2]) 8758 && (GET_MODE_CLASS 8759 (GET_MODE (SUBREG_REG (operands[2]))) 8760 == MODE_INT) 8761 ? GET_MODE_PRECISION 8762 (GET_MODE (SUBREG_REG (operands[2]))) 8763 : GET_MODE_PRECISION 8764 (GET_MODE (operands[2]))))) 8765 ? CCZmode : CCNOmode)" 8766 "#" 8767 "&& 1" 8768 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 8769{ 8770 rtx val = operands[2]; 8771 HOST_WIDE_INT len = INTVAL (operands[3]); 8772 HOST_WIDE_INT pos = INTVAL (operands[4]); 8773 machine_mode mode = GET_MODE (val); 8774 8775 if (SUBREG_P (val)) 8776 { 8777 machine_mode submode = GET_MODE (SUBREG_REG (val)); 8778 8779 /* Narrow paradoxical subregs to prevent partial register stalls. */ 8780 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode) 8781 && GET_MODE_CLASS (submode) == MODE_INT 8782 && (GET_MODE (operands[0]) == CCZmode 8783 || pos + len < GET_MODE_PRECISION (submode) 8784 || REG_P (SUBREG_REG (val)))) 8785 { 8786 val = SUBREG_REG (val); 8787 mode = submode; 8788 } 8789 } 8790 8791 /* Small HImode tests can be converted to QImode. */ 8792 if (pos + len <= 8 8793 && register_operand (val, HImode)) 8794 { 8795 rtx nval = gen_lowpart (QImode, val); 8796 if (!MEM_P (nval) 8797 || GET_MODE (operands[0]) == CCZmode 8798 || pos + len < 8) 8799 { 8800 val = nval; 8801 mode = QImode; 8802 } 8803 } 8804 8805 gcc_assert (pos + len <= GET_MODE_PRECISION (mode)); 8806 8807 /* If the mask is going to have the sign bit set in the mode 8808 we want to do the comparison in and user isn't interested just 8809 in the zero flag, then we must widen the target mode. */ 8810 if (pos + len == GET_MODE_PRECISION (mode) 8811 && GET_MODE (operands[0]) != CCZmode) 8812 { 8813 gcc_assert (pos + len < 32 && !MEM_P (val)); 8814 mode = SImode; 8815 val = gen_lowpart (mode, val); 8816 } 8817 8818 wide_int mask 8819 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode)); 8820 8821 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode)); 8822}) 8823 8824;; Convert HImode/SImode test instructions with immediate to QImode ones. 8825;; i386 does not allow to encode test with 8bit sign extended immediate, so 8826;; this is relatively important trick. 8827;; Do the conversion only post-reload to avoid limiting of the register class 8828;; to QI regs. 8829(define_split 8830 [(set (match_operand 0 "flags_reg_operand") 8831 (match_operator 1 "compare_operator" 8832 [(and (match_operand 2 "QIreg_operand") 8833 (match_operand 3 "const_int_operand")) 8834 (const_int 0)]))] 8835 "reload_completed 8836 && GET_MODE (operands[2]) != QImode 8837 && ((ix86_match_ccmode (insn, CCZmode) 8838 && !(INTVAL (operands[3]) & ~(255 << 8))) 8839 || (ix86_match_ccmode (insn, CCNOmode) 8840 && !(INTVAL (operands[3]) & ~(127 << 8))))" 8841 [(set (match_dup 0) 8842 (match_op_dup 1 8843 [(and:QI 8844 (subreg:QI 8845 (zero_extract:SI (match_dup 2) 8846 (const_int 8) 8847 (const_int 8)) 0) 8848 (match_dup 3)) 8849 (const_int 0)]))] 8850{ 8851 operands[2] = gen_lowpart (SImode, operands[2]); 8852 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode); 8853}) 8854 8855(define_split 8856 [(set (match_operand 0 "flags_reg_operand") 8857 (match_operator 1 "compare_operator" 8858 [(and (match_operand 2 "nonimmediate_operand") 8859 (match_operand 3 "const_int_operand")) 8860 (const_int 0)]))] 8861 "reload_completed 8862 && GET_MODE (operands[2]) != QImode 8863 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2])) 8864 && ((ix86_match_ccmode (insn, CCZmode) 8865 && !(INTVAL (operands[3]) & ~255)) 8866 || (ix86_match_ccmode (insn, CCNOmode) 8867 && !(INTVAL (operands[3]) & ~127)))" 8868 [(set (match_dup 0) 8869 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 8870 (const_int 0)]))] 8871{ 8872 operands[2] = gen_lowpart (QImode, operands[2]); 8873 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode); 8874}) 8875 8876;; %%% This used to optimize known byte-wide and operations to memory, 8877;; and sometimes to QImode registers. If this is considered useful, 8878;; it should be done with splitters. 8879 8880(define_expand "and<mode>3" 8881 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand") 8882 (and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand") 8883 (match_operand:SWIM1248s 2 "<general_szext_operand>")))] 8884 "" 8885{ 8886 machine_mode mode = <MODE>mode; 8887 8888 if (<MODE>mode == DImode && !TARGET_64BIT) 8889 ; 8890 else if (const_int_operand (operands[2], <MODE>mode) 8891 && register_operand (operands[0], <MODE>mode) 8892 && !(TARGET_ZERO_EXTEND_WITH_AND 8893 && optimize_function_for_speed_p (cfun))) 8894 { 8895 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]); 8896 8897 if (ival == GET_MODE_MASK (SImode)) 8898 mode = SImode; 8899 else if (ival == GET_MODE_MASK (HImode)) 8900 mode = HImode; 8901 else if (ival == GET_MODE_MASK (QImode)) 8902 mode = QImode; 8903 } 8904 8905 if (mode != <MODE>mode) 8906 emit_insn (gen_extend_insn 8907 (operands[0], gen_lowpart (mode, operands[1]), 8908 <MODE>mode, mode, 1)); 8909 else 8910 ix86_expand_binary_operator (AND, <MODE>mode, operands); 8911 8912 DONE; 8913}) 8914 8915(define_insn_and_split "*anddi3_doubleword" 8916 [(set (match_operand:DI 0 "nonimmediate_operand") 8917 (and:DI 8918 (match_operand:DI 1 "nonimmediate_operand") 8919 (match_operand:DI 2 "x86_64_szext_general_operand"))) 8920 (clobber (reg:CC FLAGS_REG))] 8921 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 8922 && ix86_binary_operator_ok (AND, DImode, operands) 8923 && ix86_pre_reload_split ()" 8924 "#" 8925 "&& 1" 8926 [(const_int 0)] 8927{ 8928 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); 8929 8930 if (operands[2] == const0_rtx) 8931 emit_move_insn (operands[0], const0_rtx); 8932 else if (operands[2] == constm1_rtx) 8933 emit_move_insn (operands[0], operands[1]); 8934 else 8935 emit_insn (gen_andsi3 (operands[0], operands[1], operands[2])); 8936 8937 if (operands[5] == const0_rtx) 8938 emit_move_insn (operands[3], const0_rtx); 8939 else if (operands[5] == constm1_rtx) 8940 emit_move_insn (operands[3], operands[4]); 8941 else 8942 emit_insn (gen_andsi3 (operands[3], operands[4], operands[5])); 8943 8944 DONE; 8945}) 8946 8947(define_insn "*anddi_1" 8948 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r") 8949 (and:DI 8950 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm") 8951 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L"))) 8952 (clobber (reg:CC FLAGS_REG))] 8953 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)" 8954 "@ 8955 and{l}\t{%k2, %k0|%k0, %k2} 8956 and{q}\t{%2, %0|%0, %2} 8957 and{q}\t{%2, %0|%0, %2} 8958 #" 8959 [(set_attr "type" "alu,alu,alu,imovx") 8960 (set_attr "length_immediate" "*,*,*,0") 8961 (set (attr "prefix_rex") 8962 (if_then_else 8963 (and (eq_attr "type" "imovx") 8964 (and (match_test "INTVAL (operands[2]) == 0xff") 8965 (match_operand 1 "ext_QIreg_operand"))) 8966 (const_string "1") 8967 (const_string "*"))) 8968 (set_attr "mode" "SI,DI,DI,SI")]) 8969 8970(define_insn_and_split "*anddi_1_btr" 8971 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 8972 (and:DI 8973 (match_operand:DI 1 "nonimmediate_operand" "%0") 8974 (match_operand:DI 2 "const_int_operand" "n"))) 8975 (clobber (reg:CC FLAGS_REG))] 8976 "TARGET_64BIT && TARGET_USE_BT 8977 && ix86_binary_operator_ok (AND, DImode, operands) 8978 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)" 8979 "#" 8980 "&& reload_completed" 8981 [(parallel [(set (zero_extract:DI (match_dup 0) 8982 (const_int 1) 8983 (match_dup 3)) 8984 (const_int 0)) 8985 (clobber (reg:CC FLAGS_REG))])] 8986 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));" 8987 [(set_attr "type" "alu1") 8988 (set_attr "prefix_0f" "1") 8989 (set_attr "znver1_decode" "double") 8990 (set_attr "mode" "DI")]) 8991 8992;; Turn *anddi_1 into *andsi_1_zext if possible. 8993(define_split 8994 [(set (match_operand:DI 0 "register_operand") 8995 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0) 8996 (match_operand:DI 2 "x86_64_zext_immediate_operand"))) 8997 (clobber (reg:CC FLAGS_REG))] 8998 "TARGET_64BIT" 8999 [(parallel [(set (match_dup 0) 9000 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2)))) 9001 (clobber (reg:CC FLAGS_REG))])] 9002{ 9003 if (GET_CODE (operands[2]) == SYMBOL_REF 9004 || GET_CODE (operands[2]) == LABEL_REF) 9005 { 9006 operands[2] = shallow_copy_rtx (operands[2]); 9007 PUT_MODE (operands[2], SImode); 9008 } 9009 else if (GET_CODE (operands[2]) == CONST) 9010 { 9011 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */ 9012 operands[2] = copy_rtx (operands[2]); 9013 PUT_MODE (operands[2], SImode); 9014 PUT_MODE (XEXP (operands[2], 0), SImode); 9015 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode); 9016 } 9017 else 9018 operands[2] = gen_lowpart (SImode, operands[2]); 9019}) 9020 9021;; See comment for addsi_1_zext why we do use nonimmediate_operand 9022(define_insn "*andsi_1_zext" 9023 [(set (match_operand:DI 0 "register_operand" "=r") 9024 (zero_extend:DI 9025 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9026 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 9027 (clobber (reg:CC FLAGS_REG))] 9028 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)" 9029 "and{l}\t{%2, %k0|%k0, %2}" 9030 [(set_attr "type" "alu") 9031 (set_attr "mode" "SI")]) 9032 9033(define_insn "*and<mode>_1" 9034 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya") 9035 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm") 9036 (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L"))) 9037 (clobber (reg:CC FLAGS_REG))] 9038 "ix86_binary_operator_ok (AND, <MODE>mode, operands)" 9039 "@ 9040 and{<imodesuffix>}\t{%2, %0|%0, %2} 9041 and{<imodesuffix>}\t{%2, %0|%0, %2} 9042 #" 9043 [(set_attr "type" "alu,alu,imovx") 9044 (set_attr "length_immediate" "*,*,0") 9045 (set (attr "prefix_rex") 9046 (if_then_else 9047 (and (eq_attr "type" "imovx") 9048 (and (match_test "INTVAL (operands[2]) == 0xff") 9049 (match_operand 1 "ext_QIreg_operand"))) 9050 (const_string "1") 9051 (const_string "*"))) 9052 (set_attr "mode" "<MODE>,<MODE>,SI")]) 9053 9054(define_insn "*andqi_1" 9055 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 9056 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9057 (match_operand:QI 2 "general_operand" "qn,m,rn"))) 9058 (clobber (reg:CC FLAGS_REG))] 9059 "ix86_binary_operator_ok (AND, QImode, operands)" 9060 "@ 9061 and{b}\t{%2, %0|%0, %2} 9062 and{b}\t{%2, %0|%0, %2} 9063 and{l}\t{%k2, %k0|%k0, %k2}" 9064 [(set_attr "type" "alu") 9065 (set_attr "mode" "QI,QI,SI") 9066 ;; Potential partial reg stall on alternative 2. 9067 (set (attr "preferred_for_speed") 9068 (cond [(eq_attr "alternative" "2") 9069 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 9070 (symbol_ref "true")))]) 9071 9072(define_insn "*and<mode>_1_slp" 9073 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 9074 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0") 9075 (match_operand:SWI12 2 "general_operand" "<r>mn"))) 9076 (clobber (reg:CC FLAGS_REG))] 9077 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9078 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9079 && (rtx_equal_p (operands[0], operands[1]) 9080 || rtx_equal_p (operands[0], operands[2]))" 9081 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 9082 [(set_attr "type" "alu") 9083 (set_attr "mode" "<MODE>")]) 9084 9085(define_split 9086 [(set (match_operand:SWI248 0 "register_operand") 9087 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand") 9088 (match_operand:SWI248 2 "const_int_operand"))) 9089 (clobber (reg:CC FLAGS_REG))] 9090 "reload_completed 9091 && (!REG_P (operands[1]) 9092 || REGNO (operands[0]) != REGNO (operands[1]))" 9093 [(const_int 0)] 9094{ 9095 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]); 9096 machine_mode mode; 9097 9098 if (ival == GET_MODE_MASK (SImode)) 9099 mode = SImode; 9100 else if (ival == GET_MODE_MASK (HImode)) 9101 mode = HImode; 9102 else if (ival == GET_MODE_MASK (QImode)) 9103 mode = QImode; 9104 else 9105 gcc_unreachable (); 9106 9107 /* Zero extend to SImode to avoid partial register stalls. */ 9108 if (<MODE_SIZE> < GET_MODE_SIZE (SImode)) 9109 operands[0] = gen_lowpart (SImode, operands[0]); 9110 9111 emit_insn (gen_extend_insn 9112 (operands[0], gen_lowpart (mode, operands[1]), 9113 GET_MODE (operands[0]), mode, 1)); 9114 DONE; 9115}) 9116 9117(define_split 9118 [(set (match_operand:SWI48 0 "register_operand") 9119 (and:SWI48 (match_dup 0) 9120 (const_int -65536))) 9121 (clobber (reg:CC FLAGS_REG))] 9122 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL) 9123 || optimize_function_for_size_p (cfun)" 9124 [(set (strict_low_part (match_dup 1)) (const_int 0))] 9125 "operands[1] = gen_lowpart (HImode, operands[0]);") 9126 9127(define_split 9128 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9129 (and:SWI248 (match_dup 0) 9130 (const_int -256))) 9131 (clobber (reg:CC FLAGS_REG))] 9132 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9133 && reload_completed" 9134 [(set (strict_low_part (match_dup 1)) (const_int 0))] 9135 "operands[1] = gen_lowpart (QImode, operands[0]);") 9136 9137(define_split 9138 [(set (match_operand:SWI248 0 "QIreg_operand") 9139 (and:SWI248 (match_dup 0) 9140 (const_int -65281))) 9141 (clobber (reg:CC FLAGS_REG))] 9142 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9143 && reload_completed" 9144 [(parallel 9145 [(set (zero_extract:SI (match_dup 0) 9146 (const_int 8) 9147 (const_int 8)) 9148 (subreg:SI 9149 (xor:QI 9150 (subreg:QI 9151 (zero_extract:SI (match_dup 0) 9152 (const_int 8) 9153 (const_int 8)) 0) 9154 (subreg:QI 9155 (zero_extract:SI (match_dup 0) 9156 (const_int 8) 9157 (const_int 8)) 0)) 0)) 9158 (clobber (reg:CC FLAGS_REG))])] 9159 "operands[0] = gen_lowpart (SImode, operands[0]);") 9160 9161(define_insn "*anddi_2" 9162 [(set (reg FLAGS_REG) 9163 (compare 9164 (and:DI 9165 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") 9166 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m")) 9167 (const_int 0))) 9168 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r") 9169 (and:DI (match_dup 1) (match_dup 2)))] 9170 "TARGET_64BIT 9171 && ix86_match_ccmode 9172 (insn, 9173 /* If we are going to emit andl instead of andq, and the operands[2] 9174 constant might have the SImode sign bit set, make sure the sign 9175 flag isn't tested, because the instruction will set the sign flag 9176 based on bit 31 rather than bit 63. If it isn't CONST_INT, 9177 conservatively assume it might have bit 31 set. */ 9178 (satisfies_constraint_Z (operands[2]) 9179 && (!CONST_INT_P (operands[2]) 9180 || val_signbit_known_set_p (SImode, INTVAL (operands[2])))) 9181 ? CCZmode : CCNOmode) 9182 && ix86_binary_operator_ok (AND, DImode, operands)" 9183 "@ 9184 and{l}\t{%k2, %k0|%k0, %k2} 9185 and{q}\t{%2, %0|%0, %2} 9186 and{q}\t{%2, %0|%0, %2}" 9187 [(set_attr "type" "alu") 9188 (set_attr "mode" "SI,DI,DI")]) 9189 9190;; See comment for addsi_1_zext why we do use nonimmediate_operand 9191(define_insn "*andsi_2_zext" 9192 [(set (reg FLAGS_REG) 9193 (compare (and:SI 9194 (match_operand:SI 1 "nonimmediate_operand" "%0") 9195 (match_operand:SI 2 "x86_64_general_operand" "rme")) 9196 (const_int 0))) 9197 (set (match_operand:DI 0 "register_operand" "=r") 9198 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))] 9199 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9200 && ix86_binary_operator_ok (AND, SImode, operands)" 9201 "and{l}\t{%2, %k0|%k0, %2}" 9202 [(set_attr "type" "alu") 9203 (set_attr "mode" "SI")]) 9204 9205(define_insn "*andqi_2_maybe_si" 9206 [(set (reg FLAGS_REG) 9207 (compare (and:QI 9208 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9209 (match_operand:QI 2 "general_operand" "qn,m,n")) 9210 (const_int 0))) 9211 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 9212 (and:QI (match_dup 1) (match_dup 2)))] 9213 "ix86_binary_operator_ok (AND, QImode, operands) 9214 && ix86_match_ccmode (insn, 9215 CONST_INT_P (operands[2]) 9216 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)" 9217{ 9218 if (which_alternative == 2) 9219 { 9220 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0) 9221 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff); 9222 return "and{l}\t{%2, %k0|%k0, %2}"; 9223 } 9224 return "and{b}\t{%2, %0|%0, %2}"; 9225} 9226 [(set_attr "type" "alu") 9227 (set_attr "mode" "QI,QI,SI") 9228 ;; Potential partial reg stall on alternative 2. 9229 (set (attr "preferred_for_speed") 9230 (cond [(eq_attr "alternative" "2") 9231 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 9232 (symbol_ref "true")))]) 9233 9234(define_insn "*and<mode>_2" 9235 [(set (reg FLAGS_REG) 9236 (compare (and:SWI124 9237 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0") 9238 (match_operand:SWI124 2 "<general_operand>" "<r><i>,m")) 9239 (const_int 0))) 9240 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>") 9241 (and:SWI124 (match_dup 1) (match_dup 2)))] 9242 "ix86_match_ccmode (insn, CCNOmode) 9243 && ix86_binary_operator_ok (AND, <MODE>mode, operands)" 9244 "and{<imodesuffix>}\t{%2, %0|%0, %2}" 9245 [(set_attr "type" "alu") 9246 (set_attr "mode" "<MODE>")]) 9247 9248(define_insn "andqi_ext_1" 9249 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9250 (const_int 8) 9251 (const_int 8)) 9252 (subreg:SI 9253 (and:QI 9254 (subreg:QI 9255 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9256 (const_int 8) 9257 (const_int 8)) 0) 9258 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 9259 (clobber (reg:CC FLAGS_REG))] 9260 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9261 rtx_equal_p (operands[0], operands[1])" 9262 "and{b}\t{%2, %h0|%h0, %2}" 9263 [(set_attr "isa" "*,nox64") 9264 (set_attr "type" "alu") 9265 (set_attr "mode" "QI")]) 9266 9267;; Generated by peephole translating test to and. This shows up 9268;; often in fp comparisons. 9269(define_insn "*andqi_ext_1_cc" 9270 [(set (reg FLAGS_REG) 9271 (compare 9272 (and:QI 9273 (subreg:QI 9274 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9275 (const_int 8) 9276 (const_int 8)) 0) 9277 (match_operand:QI 2 "general_operand" "QnBc,m")) 9278 (const_int 0))) 9279 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9280 (const_int 8) 9281 (const_int 8)) 9282 (subreg:SI 9283 (and:QI 9284 (subreg:QI 9285 (zero_extract:SI (match_dup 1) 9286 (const_int 8) 9287 (const_int 8)) 0) 9288 (match_dup 2)) 0))] 9289 "ix86_match_ccmode (insn, CCNOmode) 9290 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9291 && rtx_equal_p (operands[0], operands[1])" 9292 "and{b}\t{%2, %h0|%h0, %2}" 9293 [(set_attr "isa" "*,nox64") 9294 (set_attr "type" "alu") 9295 (set_attr "mode" "QI")]) 9296 9297(define_insn "*andqi_ext_2" 9298 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 9299 (const_int 8) 9300 (const_int 8)) 9301 (subreg:SI 9302 (and:QI 9303 (subreg:QI 9304 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 9305 (const_int 8) 9306 (const_int 8)) 0) 9307 (subreg:QI 9308 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9309 (const_int 8) 9310 (const_int 8)) 0)) 0)) 9311 (clobber (reg:CC FLAGS_REG))] 9312 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9313 rtx_equal_p (operands[0], operands[1]) 9314 || rtx_equal_p (operands[0], operands[2])" 9315 "and{b}\t{%h2, %h0|%h0, %h2}" 9316 [(set_attr "type" "alu") 9317 (set_attr "mode" "QI")]) 9318 9319;; Convert wide AND instructions with immediate operand to shorter QImode 9320;; equivalents when possible. 9321;; Don't do the splitting with memory operands, since it introduces risk 9322;; of memory mismatch stalls. We may want to do the splitting for optimizing 9323;; for size, but that can (should?) be handled by generic code instead. 9324(define_split 9325 [(set (match_operand:SWI248 0 "QIreg_operand") 9326 (and:SWI248 (match_operand:SWI248 1 "register_operand") 9327 (match_operand:SWI248 2 "const_int_operand"))) 9328 (clobber (reg:CC FLAGS_REG))] 9329 "reload_completed 9330 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9331 && !(~INTVAL (operands[2]) & ~(255 << 8))" 9332 [(parallel 9333 [(set (zero_extract:SI (match_dup 0) 9334 (const_int 8) 9335 (const_int 8)) 9336 (subreg:SI 9337 (and:QI 9338 (subreg:QI 9339 (zero_extract:SI (match_dup 1) 9340 (const_int 8) 9341 (const_int 8)) 0) 9342 (match_dup 2)) 0)) 9343 (clobber (reg:CC FLAGS_REG))])] 9344{ 9345 operands[0] = gen_lowpart (SImode, operands[0]); 9346 operands[1] = gen_lowpart (SImode, operands[1]); 9347 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode); 9348}) 9349 9350;; Since AND can be encoded with sign extended immediate, this is only 9351;; profitable when 7th bit is not set. 9352(define_split 9353 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9354 (and:SWI248 (match_operand:SWI248 1 "general_operand") 9355 (match_operand:SWI248 2 "const_int_operand"))) 9356 (clobber (reg:CC FLAGS_REG))] 9357 "reload_completed 9358 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9359 && !(~INTVAL (operands[2]) & ~255) 9360 && !(INTVAL (operands[2]) & 128)" 9361 [(parallel [(set (strict_low_part (match_dup 0)) 9362 (and:QI (match_dup 1) 9363 (match_dup 2))) 9364 (clobber (reg:CC FLAGS_REG))])] 9365{ 9366 operands[0] = gen_lowpart (QImode, operands[0]); 9367 operands[1] = gen_lowpart (QImode, operands[1]); 9368 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 9369}) 9370 9371(define_insn "*andndi3_doubleword" 9372 [(set (match_operand:DI 0 "register_operand") 9373 (and:DI 9374 (not:DI (match_operand:DI 1 "register_operand")) 9375 (match_operand:DI 2 "nonimmediate_operand"))) 9376 (clobber (reg:CC FLAGS_REG))] 9377 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 9378 && ix86_pre_reload_split ()" 9379 "#") 9380 9381(define_split 9382 [(set (match_operand:DI 0 "register_operand") 9383 (and:DI 9384 (not:DI (match_operand:DI 1 "register_operand")) 9385 (match_operand:DI 2 "nonimmediate_operand"))) 9386 (clobber (reg:CC FLAGS_REG))] 9387 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2 9388 && can_create_pseudo_p ()" 9389 [(parallel [(set (match_dup 0) 9390 (and:SI (not:SI (match_dup 1)) (match_dup 2))) 9391 (clobber (reg:CC FLAGS_REG))]) 9392 (parallel [(set (match_dup 3) 9393 (and:SI (not:SI (match_dup 4)) (match_dup 5))) 9394 (clobber (reg:CC FLAGS_REG))])] 9395 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);") 9396 9397(define_split 9398 [(set (match_operand:DI 0 "register_operand") 9399 (and:DI 9400 (not:DI (match_operand:DI 1 "register_operand")) 9401 (match_operand:DI 2 "nonimmediate_operand"))) 9402 (clobber (reg:CC FLAGS_REG))] 9403 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2 9404 && can_create_pseudo_p ()" 9405 [(set (match_dup 6) (not:SI (match_dup 1))) 9406 (parallel [(set (match_dup 0) 9407 (and:SI (match_dup 6) (match_dup 2))) 9408 (clobber (reg:CC FLAGS_REG))]) 9409 (set (match_dup 7) (not:SI (match_dup 4))) 9410 (parallel [(set (match_dup 3) 9411 (and:SI (match_dup 7) (match_dup 5))) 9412 (clobber (reg:CC FLAGS_REG))])] 9413{ 9414 operands[6] = gen_reg_rtx (SImode); 9415 operands[7] = gen_reg_rtx (SImode); 9416 9417 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); 9418}) 9419 9420(define_insn "*andn<mode>_1" 9421 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 9422 (and:SWI48 9423 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r")) 9424 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))) 9425 (clobber (reg:CC FLAGS_REG))] 9426 "TARGET_BMI" 9427 "andn\t{%2, %1, %0|%0, %1, %2}" 9428 [(set_attr "type" "bitmanip") 9429 (set_attr "btver2_decode" "direct, double") 9430 (set_attr "mode" "<MODE>")]) 9431 9432(define_insn "*andn<mode>_1" 9433 [(set (match_operand:SWI12 0 "register_operand" "=r") 9434 (and:SWI12 9435 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r")) 9436 (match_operand:SWI12 2 "register_operand" "r"))) 9437 (clobber (reg:CC FLAGS_REG))] 9438 "TARGET_BMI" 9439 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}" 9440 [(set_attr "type" "bitmanip") 9441 (set_attr "btver2_decode" "direct") 9442 (set_attr "mode" "SI")]) 9443 9444(define_insn "*andn_<mode>_ccno" 9445 [(set (reg FLAGS_REG) 9446 (compare 9447 (and:SWI48 9448 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r")) 9449 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")) 9450 (const_int 0))) 9451 (clobber (match_scratch:SWI48 0 "=r,r"))] 9452 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)" 9453 "andn\t{%2, %1, %0|%0, %1, %2}" 9454 [(set_attr "type" "bitmanip") 9455 (set_attr "btver2_decode" "direct, double") 9456 (set_attr "mode" "<MODE>")]) 9457 9458;; Logical inclusive and exclusive OR instructions 9459 9460;; %%% This used to optimize known byte-wide and operations to memory. 9461;; If this is considered useful, it should be done with splitters. 9462 9463(define_expand "<code><mode>3" 9464 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand") 9465 (any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand") 9466 (match_operand:SWIM1248s 2 "<general_operand>")))] 9467 "" 9468 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 9469 9470(define_insn_and_split "*<code>di3_doubleword" 9471 [(set (match_operand:DI 0 "nonimmediate_operand") 9472 (any_or:DI 9473 (match_operand:DI 1 "nonimmediate_operand") 9474 (match_operand:DI 2 "x86_64_szext_general_operand"))) 9475 (clobber (reg:CC FLAGS_REG))] 9476 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 9477 && ix86_binary_operator_ok (<CODE>, DImode, operands) 9478 && ix86_pre_reload_split ()" 9479 "#" 9480 "&& 1" 9481 [(const_int 0)] 9482{ 9483 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); 9484 9485 if (operands[2] == const0_rtx) 9486 emit_move_insn (operands[0], operands[1]); 9487 else if (operands[2] == constm1_rtx) 9488 { 9489 if (<CODE> == IOR) 9490 emit_move_insn (operands[0], constm1_rtx); 9491 else 9492 ix86_expand_unary_operator (NOT, SImode, &operands[0]); 9493 } 9494 else 9495 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]); 9496 9497 if (operands[5] == const0_rtx) 9498 emit_move_insn (operands[3], operands[4]); 9499 else if (operands[5] == constm1_rtx) 9500 { 9501 if (<CODE> == IOR) 9502 emit_move_insn (operands[3], constm1_rtx); 9503 else 9504 ix86_expand_unary_operator (NOT, SImode, &operands[3]); 9505 } 9506 else 9507 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]); 9508 9509 DONE; 9510}) 9511 9512(define_insn "*<code><mode>_1" 9513 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r") 9514 (any_or:SWI248 9515 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0") 9516 (match_operand:SWI248 2 "<general_operand>" "r<i>,m"))) 9517 (clobber (reg:CC FLAGS_REG))] 9518 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9519 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9520 [(set_attr "type" "alu") 9521 (set_attr "mode" "<MODE>")]) 9522 9523(define_insn_and_split "*iordi_1_bts" 9524 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9525 (ior:DI 9526 (match_operand:DI 1 "nonimmediate_operand" "%0") 9527 (match_operand:DI 2 "const_int_operand" "n"))) 9528 (clobber (reg:CC FLAGS_REG))] 9529 "TARGET_64BIT && TARGET_USE_BT 9530 && ix86_binary_operator_ok (IOR, DImode, operands) 9531 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)" 9532 "#" 9533 "&& reload_completed" 9534 [(parallel [(set (zero_extract:DI (match_dup 0) 9535 (const_int 1) 9536 (match_dup 3)) 9537 (const_int 1)) 9538 (clobber (reg:CC FLAGS_REG))])] 9539 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));" 9540 [(set_attr "type" "alu1") 9541 (set_attr "prefix_0f" "1") 9542 (set_attr "znver1_decode" "double") 9543 (set_attr "mode" "DI")]) 9544 9545(define_insn_and_split "*xordi_1_btc" 9546 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") 9547 (xor:DI 9548 (match_operand:DI 1 "nonimmediate_operand" "%0") 9549 (match_operand:DI 2 "const_int_operand" "n"))) 9550 (clobber (reg:CC FLAGS_REG))] 9551 "TARGET_64BIT && TARGET_USE_BT 9552 && ix86_binary_operator_ok (XOR, DImode, operands) 9553 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)" 9554 "#" 9555 "&& reload_completed" 9556 [(parallel [(set (zero_extract:DI (match_dup 0) 9557 (const_int 1) 9558 (match_dup 3)) 9559 (not:DI (zero_extract:DI (match_dup 0) 9560 (const_int 1) 9561 (match_dup 3)))) 9562 (clobber (reg:CC FLAGS_REG))])] 9563 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));" 9564 [(set_attr "type" "alu1") 9565 (set_attr "prefix_0f" "1") 9566 (set_attr "znver1_decode" "double") 9567 (set_attr "mode" "DI")]) 9568 9569;; See comment for addsi_1_zext why we do use nonimmediate_operand 9570(define_insn "*<code>si_1_zext" 9571 [(set (match_operand:DI 0 "register_operand" "=r") 9572 (zero_extend:DI 9573 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9574 (match_operand:SI 2 "x86_64_general_operand" "rme")))) 9575 (clobber (reg:CC FLAGS_REG))] 9576 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9577 "<logic>{l}\t{%2, %k0|%k0, %2}" 9578 [(set_attr "type" "alu") 9579 (set_attr "mode" "SI")]) 9580 9581(define_insn "*<code>si_1_zext_imm" 9582 [(set (match_operand:DI 0 "register_operand" "=r") 9583 (any_or:DI 9584 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0")) 9585 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z"))) 9586 (clobber (reg:CC FLAGS_REG))] 9587 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9588 "<logic>{l}\t{%2, %k0|%k0, %2}" 9589 [(set_attr "type" "alu") 9590 (set_attr "mode" "SI")]) 9591 9592(define_insn "*<code>qi_1" 9593 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r") 9594 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") 9595 (match_operand:QI 2 "general_operand" "qn,m,rn"))) 9596 (clobber (reg:CC FLAGS_REG))] 9597 "ix86_binary_operator_ok (<CODE>, QImode, operands)" 9598 "@ 9599 <logic>{b}\t{%2, %0|%0, %2} 9600 <logic>{b}\t{%2, %0|%0, %2} 9601 <logic>{l}\t{%k2, %k0|%k0, %k2}" 9602 [(set_attr "type" "alu") 9603 (set_attr "mode" "QI,QI,SI") 9604 ;; Potential partial reg stall on alternative 2. 9605 (set (attr "preferred_for_speed") 9606 (cond [(eq_attr "alternative" "2") 9607 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 9608 (symbol_ref "true")))]) 9609 9610(define_insn "*<code><mode>_1_slp" 9611 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 9612 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0") 9613 (match_operand:SWI12 2 "general_operand" "<r>mn"))) 9614 (clobber (reg:CC FLAGS_REG))] 9615 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9616 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9617 && (rtx_equal_p (operands[0], operands[1]) 9618 || rtx_equal_p (operands[0], operands[2]))" 9619 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9620 [(set_attr "type" "alu") 9621 (set_attr "mode" "<MODE>")]) 9622 9623(define_insn "*<code><mode>_2" 9624 [(set (reg FLAGS_REG) 9625 (compare (any_or:SWI 9626 (match_operand:SWI 1 "nonimmediate_operand" "%0,0") 9627 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")) 9628 (const_int 0))) 9629 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>") 9630 (any_or:SWI (match_dup 1) (match_dup 2)))] 9631 "ix86_match_ccmode (insn, CCNOmode) 9632 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 9633 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9634 [(set_attr "type" "alu") 9635 (set_attr "mode" "<MODE>")]) 9636 9637;; See comment for addsi_1_zext why we do use nonimmediate_operand 9638;; ??? Special case for immediate operand is missing - it is tricky. 9639(define_insn "*<code>si_2_zext" 9640 [(set (reg FLAGS_REG) 9641 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0") 9642 (match_operand:SI 2 "x86_64_general_operand" "rme")) 9643 (const_int 0))) 9644 (set (match_operand:DI 0 "register_operand" "=r") 9645 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))] 9646 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9647 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9648 "<logic>{l}\t{%2, %k0|%k0, %2}" 9649 [(set_attr "type" "alu") 9650 (set_attr "mode" "SI")]) 9651 9652(define_insn "*<code>si_2_zext_imm" 9653 [(set (reg FLAGS_REG) 9654 (compare (any_or:SI 9655 (match_operand:SI 1 "nonimmediate_operand" "%0") 9656 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z")) 9657 (const_int 0))) 9658 (set (match_operand:DI 0 "register_operand" "=r") 9659 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))] 9660 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 9661 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 9662 "<logic>{l}\t{%2, %k0|%k0, %2}" 9663 [(set_attr "type" "alu") 9664 (set_attr "mode" "SI")]) 9665 9666(define_insn "*<code><mode>_3" 9667 [(set (reg FLAGS_REG) 9668 (compare (any_or:SWI 9669 (match_operand:SWI 1 "nonimmediate_operand" "%0") 9670 (match_operand:SWI 2 "<general_operand>" "<g>")) 9671 (const_int 0))) 9672 (clobber (match_scratch:SWI 0 "=<r>"))] 9673 "ix86_match_ccmode (insn, CCNOmode) 9674 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 9675 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}" 9676 [(set_attr "type" "alu") 9677 (set_attr "mode" "<MODE>")]) 9678 9679(define_insn "*<code>qi_ext_1" 9680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9681 (const_int 8) 9682 (const_int 8)) 9683 (subreg:SI 9684 (any_or:QI 9685 (subreg:QI 9686 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9687 (const_int 8) 9688 (const_int 8)) 0) 9689 (match_operand:QI 2 "general_operand" "QnBc,m")) 0)) 9690 (clobber (reg:CC FLAGS_REG))] 9691 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9692 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9693 && rtx_equal_p (operands[0], operands[1])" 9694 "<logic>{b}\t{%2, %h0|%h0, %2}" 9695 [(set_attr "isa" "*,nox64") 9696 (set_attr "type" "alu") 9697 (set_attr "mode" "QI")]) 9698 9699(define_insn "*<code>qi_ext_2" 9700 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q") 9701 (const_int 8) 9702 (const_int 8)) 9703 (subreg:SI 9704 (any_or:QI 9705 (subreg:QI 9706 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0") 9707 (const_int 8) 9708 (const_int 8)) 0) 9709 (subreg:QI 9710 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q") 9711 (const_int 8) 9712 (const_int 8)) 0)) 0)) 9713 (clobber (reg:CC FLAGS_REG))] 9714 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9715 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9716 && (rtx_equal_p (operands[0], operands[1]) 9717 || rtx_equal_p (operands[0], operands[2]))" 9718 "<logic>{b}\t{%h2, %h0|%h0, %h2}" 9719 [(set_attr "type" "alu") 9720 (set_attr "mode" "QI")]) 9721 9722;; Convert wide OR instructions with immediate operand to shorter QImode 9723;; equivalents when possible. 9724;; Don't do the splitting with memory operands, since it introduces risk 9725;; of memory mismatch stalls. We may want to do the splitting for optimizing 9726;; for size, but that can (should?) be handled by generic code instead. 9727(define_split 9728 [(set (match_operand:SWI248 0 "QIreg_operand") 9729 (any_or:SWI248 (match_operand:SWI248 1 "register_operand") 9730 (match_operand:SWI248 2 "const_int_operand"))) 9731 (clobber (reg:CC FLAGS_REG))] 9732 "reload_completed 9733 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9734 && !(INTVAL (operands[2]) & ~(255 << 8))" 9735 [(parallel 9736 [(set (zero_extract:SI (match_dup 0) 9737 (const_int 8) 9738 (const_int 8)) 9739 (subreg:SI 9740 (any_or:QI 9741 (subreg:QI 9742 (zero_extract:SI (match_dup 1) 9743 (const_int 8) 9744 (const_int 8)) 0) 9745 (match_dup 2)) 0)) 9746 (clobber (reg:CC FLAGS_REG))])] 9747{ 9748 operands[0] = gen_lowpart (SImode, operands[0]); 9749 operands[1] = gen_lowpart (SImode, operands[1]); 9750 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode); 9751}) 9752 9753;; Since OR can be encoded with sign extended immediate, this is only 9754;; profitable when 7th bit is set. 9755(define_split 9756 [(set (match_operand:SWI248 0 "any_QIreg_operand") 9757 (any_or:SWI248 (match_operand:SWI248 1 "general_operand") 9758 (match_operand:SWI248 2 "const_int_operand"))) 9759 (clobber (reg:CC FLAGS_REG))] 9760 "reload_completed 9761 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 9762 && !(INTVAL (operands[2]) & ~255) 9763 && (INTVAL (operands[2]) & 128)" 9764 [(parallel [(set (strict_low_part (match_dup 0)) 9765 (any_or:QI (match_dup 1) 9766 (match_dup 2))) 9767 (clobber (reg:CC FLAGS_REG))])] 9768{ 9769 operands[0] = gen_lowpart (QImode, operands[0]); 9770 operands[1] = gen_lowpart (QImode, operands[1]); 9771 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode); 9772}) 9773 9774(define_expand "xorqi_ext_1_cc" 9775 [(parallel [ 9776 (set (reg:CCNO FLAGS_REG) 9777 (compare:CCNO 9778 (xor:QI 9779 (subreg:QI 9780 (zero_extract:SI (match_operand 1 "ext_register_operand") 9781 (const_int 8) 9782 (const_int 8)) 0) 9783 (match_operand 2 "const_int_operand")) 9784 (const_int 0))) 9785 (set (zero_extract:SI (match_operand 0 "ext_register_operand") 9786 (const_int 8) 9787 (const_int 8)) 9788 (subreg:SI 9789 (xor:QI 9790 (subreg:QI 9791 (zero_extract:SI (match_dup 1) 9792 (const_int 8) 9793 (const_int 8)) 0) 9794 (match_dup 2)) 0))])]) 9795 9796(define_insn "*xorqi_ext_1_cc" 9797 [(set (reg FLAGS_REG) 9798 (compare 9799 (xor:QI 9800 (subreg:QI 9801 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0") 9802 (const_int 8) 9803 (const_int 8)) 0) 9804 (match_operand:QI 2 "general_operand" "QnBc,m")) 9805 (const_int 0))) 9806 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q") 9807 (const_int 8) 9808 (const_int 8)) 9809 (subreg:SI 9810 (xor:QI 9811 (subreg:QI 9812 (zero_extract:SI (match_dup 1) 9813 (const_int 8) 9814 (const_int 8)) 0) 9815 (match_dup 2)) 0))] 9816 "ix86_match_ccmode (insn, CCNOmode) 9817 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 9818 && rtx_equal_p (operands[0], operands[1])" 9819 "xor{b}\t{%2, %h0|%h0, %2}" 9820 [(set_attr "isa" "*,nox64") 9821 (set_attr "type" "alu") 9822 (set_attr "mode" "QI")]) 9823 9824;; Negation instructions 9825 9826(define_expand "neg<mode>2" 9827 [(set (match_operand:SDWIM 0 "nonimmediate_operand") 9828 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))] 9829 "" 9830 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;") 9831 9832(define_insn_and_split "*neg<dwi>2_doubleword" 9833 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro") 9834 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0"))) 9835 (clobber (reg:CC FLAGS_REG))] 9836 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)" 9837 "#" 9838 "reload_completed" 9839 [(parallel 9840 [(set (reg:CCZ FLAGS_REG) 9841 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0))) 9842 (set (match_dup 0) (neg:DWIH (match_dup 1)))]) 9843 (parallel 9844 [(set (match_dup 2) 9845 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)) 9846 (match_dup 3)) 9847 (const_int 0))) 9848 (clobber (reg:CC FLAGS_REG))]) 9849 (parallel 9850 [(set (match_dup 2) 9851 (neg:DWIH (match_dup 2))) 9852 (clobber (reg:CC FLAGS_REG))])] 9853 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);") 9854 9855(define_insn "*neg<mode>2_1" 9856 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9857 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))) 9858 (clobber (reg:CC FLAGS_REG))] 9859 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 9860 "neg{<imodesuffix>}\t%0" 9861 [(set_attr "type" "negnot") 9862 (set_attr "mode" "<MODE>")]) 9863 9864(define_insn "*negsi2_1_zext" 9865 [(set (match_operand:DI 0 "register_operand" "=r") 9866 (zero_extend:DI 9867 (neg:SI (match_operand:SI 1 "register_operand" "0")))) 9868 (clobber (reg:CC FLAGS_REG))] 9869 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9870 "neg{l}\t%k0" 9871 [(set_attr "type" "negnot") 9872 (set_attr "mode" "SI")]) 9873 9874;; The problem with neg is that it does not perform (compare x 0), 9875;; it really performs (compare 0 x), which leaves us with the zero 9876;; flag being the only useful item. 9877 9878(define_insn "*neg<mode>2_cmpz" 9879 [(set (reg:CCZ FLAGS_REG) 9880 (compare:CCZ 9881 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 9882 (const_int 0))) 9883 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9884 (neg:SWI (match_dup 1)))] 9885 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)" 9886 "neg{<imodesuffix>}\t%0" 9887 [(set_attr "type" "negnot") 9888 (set_attr "mode" "<MODE>")]) 9889 9890(define_insn "*negsi2_cmpz_zext" 9891 [(set (reg:CCZ FLAGS_REG) 9892 (compare:CCZ 9893 (neg:SI (match_operand:SI 1 "register_operand" "0")) 9894 (const_int 0))) 9895 (set (match_operand:DI 0 "register_operand" "=r") 9896 (zero_extend:DI 9897 (neg:SI (match_dup 1))))] 9898 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)" 9899 "neg{l}\t%k0" 9900 [(set_attr "type" "negnot") 9901 (set_attr "mode" "SI")]) 9902 9903;; Negate with jump on overflow. 9904(define_expand "negv<mode>3" 9905 [(parallel [(set (reg:CCO FLAGS_REG) 9906 (ne:CCO (match_operand:SWI 1 "register_operand") 9907 (match_dup 3))) 9908 (set (match_operand:SWI 0 "register_operand") 9909 (neg:SWI (match_dup 1)))]) 9910 (set (pc) (if_then_else 9911 (eq (reg:CCO FLAGS_REG) (const_int 0)) 9912 (label_ref (match_operand 2)) 9913 (pc)))] 9914 "" 9915{ 9916 operands[3] 9917 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1), 9918 <MODE>mode); 9919}) 9920 9921(define_insn "*negv<mode>3" 9922 [(set (reg:CCO FLAGS_REG) 9923 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0") 9924 (match_operand:SWI 2 "const_int_operand"))) 9925 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 9926 (neg:SWI (match_dup 1)))] 9927 "ix86_unary_operator_ok (NEG, <MODE>mode, operands) 9928 && mode_signbit_p (<MODE>mode, operands[2])" 9929 "neg{<imodesuffix>}\t%0" 9930 [(set_attr "type" "negnot") 9931 (set_attr "mode" "<MODE>")]) 9932 9933(define_expand "<code>tf2" 9934 [(set (match_operand:TF 0 "register_operand") 9935 (absneg:TF (match_operand:TF 1 "register_operand")))] 9936 "TARGET_SSE" 9937 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;") 9938 9939(define_insn "*<code>tf2_1" 9940 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv") 9941 (absneg:TF 9942 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))) 9943 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv")) 9944 (clobber (reg:CC FLAGS_REG))] 9945 "TARGET_SSE" 9946 "#" 9947 [(set_attr "isa" "noavx,noavx,avx,avx")]) 9948 9949(define_insn "*nabstf2_1" 9950 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv") 9951 (neg:TF 9952 (abs:TF 9953 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))) 9954 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))] 9955 "TARGET_SSE" 9956 "#" 9957 [(set_attr "isa" "noavx,noavx,avx,avx")]) 9958 9959;; Special expand pattern to handle integer mode abs 9960 9961(define_expand "abs<mode>2" 9962 [(set (match_operand:SWI48x 0 "register_operand") 9963 (abs:SWI48x 9964 (match_operand:SWI48x 1 "register_operand")))] 9965 "TARGET_EXPAND_ABS" 9966 { 9967 machine_mode mode = <MODE>mode; 9968 9969 /* Generate rtx abs using abs (x) = (((signed) x >> (W-1)) ^ x) - 9970 ((signed) x >> (W-1)) */ 9971 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode); 9972 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1], 9973 shift_amount, NULL_RTX, 9974 0, OPTAB_DIRECT); 9975 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1], 9976 operands[0], 0, OPTAB_DIRECT); 9977 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst, 9978 operands[0], 0, OPTAB_DIRECT); 9979 if (!rtx_equal_p (minus_dst, operands[0])) 9980 emit_move_insn (operands[0], minus_dst); 9981 DONE; 9982 }) 9983 9984(define_expand "<code><mode>2" 9985 [(set (match_operand:X87MODEF 0 "register_operand") 9986 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))] 9987 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 9988 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 9989 9990;; Changing of sign for FP values is doable using integer unit too. 9991(define_insn "*<code><mode>2_i387_1" 9992 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r") 9993 (absneg:X87MODEF 9994 (match_operand:X87MODEF 1 "register_operand" "0,0"))) 9995 (clobber (reg:CC FLAGS_REG))] 9996 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 9997 "#") 9998 9999(define_split 10000 [(set (match_operand:X87MODEF 0 "fp_register_operand") 10001 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand"))) 10002 (clobber (reg:CC FLAGS_REG))] 10003 "TARGET_80387 && reload_completed" 10004 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))]) 10005 10006(define_split 10007 [(set (match_operand:X87MODEF 0 "general_reg_operand") 10008 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand"))) 10009 (clobber (reg:CC FLAGS_REG))] 10010 "TARGET_80387 && reload_completed" 10011 [(const_int 0)] 10012 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 10013 10014(define_insn "*<code><mode>2_1" 10015 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r") 10016 (absneg:MODEF 10017 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0"))) 10018 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X")) 10019 (clobber (reg:CC FLAGS_REG))] 10020 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 10021 "#" 10022 [(set_attr "isa" "noavx,noavx,avx,*,*") 10023 (set (attr "enabled") 10024 (if_then_else 10025 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 10026 (if_then_else 10027 (eq_attr "alternative" "3,4") 10028 (symbol_ref "TARGET_MIX_SSE_I387") 10029 (const_string "*")) 10030 (if_then_else 10031 (eq_attr "alternative" "3,4") 10032 (symbol_ref "true") 10033 (symbol_ref "false"))))]) 10034 10035(define_split 10036 [(set (match_operand:SSEMODEF 0 "sse_reg_operand") 10037 (absneg:SSEMODEF 10038 (match_operand:SSEMODEF 1 "vector_operand"))) 10039 (use (match_operand:<ssevecmodef> 2 "vector_operand")) 10040 (clobber (reg:CC FLAGS_REG))] 10041 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10042 || (TARGET_SSE && (<MODE>mode == TFmode))) 10043 && reload_completed" 10044 [(set (match_dup 0) (match_dup 3))] 10045{ 10046 machine_mode mode = <MODE>mode; 10047 machine_mode vmode = <ssevecmodef>mode; 10048 enum rtx_code absneg_op = <CODE> == ABS ? AND : XOR; 10049 10050 operands[0] = lowpart_subreg (vmode, operands[0], mode); 10051 operands[1] = lowpart_subreg (vmode, operands[1], mode); 10052 10053 if (TARGET_AVX) 10054 { 10055 if (MEM_P (operands[1])) 10056 std::swap (operands[1], operands[2]); 10057 } 10058 else 10059 { 10060 if (operands_match_p (operands[0], operands[2])) 10061 std::swap (operands[1], operands[2]); 10062 } 10063 10064 operands[3] 10065 = gen_rtx_fmt_ee (absneg_op, vmode, operands[1], operands[2]); 10066}) 10067 10068(define_split 10069 [(set (match_operand:MODEF 0 "fp_register_operand") 10070 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand"))) 10071 (use (match_operand 2)) 10072 (clobber (reg:CC FLAGS_REG))] 10073 "TARGET_80387 && reload_completed" 10074 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))]) 10075 10076(define_split 10077 [(set (match_operand:MODEF 0 "general_reg_operand") 10078 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand"))) 10079 (use (match_operand 2)) 10080 (clobber (reg:CC FLAGS_REG))] 10081 "TARGET_80387 && reload_completed" 10082 [(const_int 0)] 10083 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;") 10084 10085(define_insn "*nabs<mode>2_1" 10086 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv") 10087 (neg:MODEF 10088 (abs:MODEF 10089 (match_operand:MODEF 1 "register_operand" "0,x,Yv")))) 10090 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))] 10091 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 10092 "#" 10093 [(set_attr "isa" "noavx,noavx,avx")]) 10094 10095(define_split 10096 [(set (match_operand:SSEMODEF 0 "sse_reg_operand") 10097 (neg:SSEMODEF 10098 (abs:SSEMODEF 10099 (match_operand:SSEMODEF 1 "vector_operand")))) 10100 (use (match_operand:<ssevecmodef> 2 "vector_operand"))] 10101 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10102 || (TARGET_SSE && (<MODE>mode == TFmode))) 10103 && reload_completed" 10104 [(set (match_dup 0) (match_dup 3))] 10105{ 10106 machine_mode mode = <MODE>mode; 10107 machine_mode vmode = <ssevecmodef>mode; 10108 10109 operands[0] = lowpart_subreg (vmode, operands[0], mode); 10110 operands[1] = lowpart_subreg (vmode, operands[1], mode); 10111 10112 if (TARGET_AVX) 10113 { 10114 if (MEM_P (operands[1])) 10115 std::swap (operands[1], operands[2]); 10116 } 10117 else 10118 { 10119 if (operands_match_p (operands[0], operands[2])) 10120 std::swap (operands[1], operands[2]); 10121 } 10122 10123 operands[3] 10124 = gen_rtx_fmt_ee (IOR, vmode, operands[1], operands[2]); 10125}) 10126 10127;; Conditionalize these after reload. If they match before reload, we 10128;; lose the clobber and ability to use integer instructions. 10129 10130(define_insn "*<code><mode>2_i387" 10131 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 10132 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))] 10133 "TARGET_80387 && reload_completed" 10134 "<absneg_mnemonic>" 10135 [(set_attr "type" "fsgn") 10136 (set_attr "mode" "<MODE>")]) 10137 10138;; Copysign instructions 10139 10140(define_expand "copysign<mode>3" 10141 [(match_operand:SSEMODEF 0 "register_operand") 10142 (match_operand:SSEMODEF 1 "nonmemory_operand") 10143 (match_operand:SSEMODEF 2 "register_operand")] 10144 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10145 || (TARGET_SSE && (<MODE>mode == TFmode))" 10146 "ix86_expand_copysign (operands); DONE;") 10147 10148(define_insn_and_split "@copysign<mode>3_const" 10149 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv") 10150 (unspec:SSEMODEF 10151 [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC") 10152 (match_operand:SSEMODEF 2 "register_operand" "0") 10153 (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")] 10154 UNSPEC_COPYSIGN))] 10155 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10156 || (TARGET_SSE && (<MODE>mode == TFmode))" 10157 "#" 10158 "&& reload_completed" 10159 [(const_int 0)] 10160 "ix86_split_copysign_const (operands); DONE;") 10161 10162(define_insn "@copysign<mode>3_var" 10163 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv") 10164 (unspec:SSEMODEF 10165 [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv") 10166 (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv") 10167 (match_operand:<ssevecmodef> 4 10168 "nonimmediate_operand" "X,Yvm,Yvm,0,0") 10169 (match_operand:<ssevecmodef> 5 10170 "nonimmediate_operand" "0,Yvm,1,Yvm,1")] 10171 UNSPEC_COPYSIGN)) 10172 (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))] 10173 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10174 || (TARGET_SSE && (<MODE>mode == TFmode))" 10175 "#") 10176 10177(define_split 10178 [(set (match_operand:SSEMODEF 0 "register_operand") 10179 (unspec:SSEMODEF 10180 [(match_operand:SSEMODEF 2 "register_operand") 10181 (match_operand:SSEMODEF 3 "register_operand") 10182 (match_operand:<ssevecmodef> 4) 10183 (match_operand:<ssevecmodef> 5)] 10184 UNSPEC_COPYSIGN)) 10185 (clobber (match_scratch:<ssevecmodef> 1))] 10186 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 10187 || (TARGET_SSE && (<MODE>mode == TFmode))) 10188 && reload_completed" 10189 [(const_int 0)] 10190 "ix86_split_copysign_var (operands); DONE;") 10191 10192(define_expand "xorsign<mode>3" 10193 [(match_operand:MODEF 0 "register_operand") 10194 (match_operand:MODEF 1 "register_operand") 10195 (match_operand:MODEF 2 "register_operand")] 10196 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 10197{ 10198 if (rtx_equal_p (operands[1], operands[2])) 10199 emit_insn (gen_abs<mode>2 (operands[0], operands[1])); 10200 else 10201 ix86_expand_xorsign (operands); 10202 DONE; 10203}) 10204 10205(define_insn_and_split "@xorsign<mode>3_1" 10206 [(set (match_operand:MODEF 0 "register_operand" "=&Yv") 10207 (unspec:MODEF 10208 [(match_operand:MODEF 1 "register_operand" "Yv") 10209 (match_operand:MODEF 2 "register_operand" "0") 10210 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")] 10211 UNSPEC_XORSIGN))] 10212 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 10213 "#" 10214 "&& reload_completed" 10215 [(const_int 0)] 10216 "ix86_split_xorsign (operands); DONE;") 10217 10218;; One complement instructions 10219 10220(define_expand "one_cmpl<mode>2" 10221 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand") 10222 (not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))] 10223 "" 10224 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;") 10225 10226(define_insn_and_split "*one_cmpldi2_doubleword" 10227 [(set (match_operand:DI 0 "nonimmediate_operand") 10228 (not:DI (match_operand:DI 1 "nonimmediate_operand")))] 10229 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2 10230 && ix86_unary_operator_ok (NOT, DImode, operands) 10231 && ix86_pre_reload_split ()" 10232 "#" 10233 "&& 1" 10234 [(set (match_dup 0) 10235 (not:SI (match_dup 1))) 10236 (set (match_dup 2) 10237 (not:SI (match_dup 3)))] 10238 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);") 10239 10240(define_insn "*one_cmpl<mode>2_1" 10241 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm") 10242 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))] 10243 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 10244 "not{<imodesuffix>}\t%0" 10245 [(set_attr "type" "negnot") 10246 (set_attr "mode" "<MODE>")]) 10247 10248(define_insn "*one_cmplsi2_1_zext" 10249 [(set (match_operand:DI 0 "register_operand" "=r") 10250 (zero_extend:DI 10251 (not:SI (match_operand:SI 1 "register_operand" "0"))))] 10252 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)" 10253 "not{l}\t%k0" 10254 [(set_attr "type" "negnot") 10255 (set_attr "mode" "SI")]) 10256 10257(define_insn "*one_cmplqi2_1" 10258 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r") 10259 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))] 10260 "ix86_unary_operator_ok (NOT, QImode, operands)" 10261 "@ 10262 not{b}\t%0 10263 not{l}\t%k0" 10264 [(set_attr "type" "negnot") 10265 (set_attr "mode" "QI,SI") 10266 ;; Potential partial reg stall on alternative 1. 10267 (set (attr "preferred_for_speed") 10268 (cond [(eq_attr "alternative" "1") 10269 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 10270 (symbol_ref "true")))]) 10271 10272(define_insn "*one_cmpl<mode>2_2" 10273 [(set (reg FLAGS_REG) 10274 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")) 10275 (const_int 0))) 10276 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10277 (not:SWI (match_dup 1)))] 10278 "ix86_match_ccmode (insn, CCNOmode) 10279 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)" 10280 "#" 10281 [(set_attr "type" "alu1") 10282 (set_attr "mode" "<MODE>")]) 10283 10284(define_split 10285 [(set (match_operand 0 "flags_reg_operand") 10286 (match_operator 2 "compare_operator" 10287 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand")) 10288 (const_int 0)])) 10289 (set (match_operand:SWI 1 "nonimmediate_operand") 10290 (not:SWI (match_dup 3)))] 10291 "ix86_match_ccmode (insn, CCNOmode)" 10292 [(parallel [(set (match_dup 0) 10293 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1)) 10294 (const_int 0)])) 10295 (set (match_dup 1) 10296 (xor:SWI (match_dup 3) (const_int -1)))])]) 10297 10298(define_insn "*one_cmplsi2_2_zext" 10299 [(set (reg FLAGS_REG) 10300 (compare (not:SI (match_operand:SI 1 "register_operand" "0")) 10301 (const_int 0))) 10302 (set (match_operand:DI 0 "register_operand" "=r") 10303 (zero_extend:DI (not:SI (match_dup 1))))] 10304 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode) 10305 && ix86_unary_operator_ok (NOT, SImode, operands)" 10306 "#" 10307 [(set_attr "type" "alu1") 10308 (set_attr "mode" "SI")]) 10309 10310(define_split 10311 [(set (match_operand 0 "flags_reg_operand") 10312 (match_operator 2 "compare_operator" 10313 [(not:SI (match_operand:SI 3 "register_operand")) 10314 (const_int 0)])) 10315 (set (match_operand:DI 1 "register_operand") 10316 (zero_extend:DI (not:SI (match_dup 3))))] 10317 "ix86_match_ccmode (insn, CCNOmode)" 10318 [(parallel [(set (match_dup 0) 10319 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1)) 10320 (const_int 0)])) 10321 (set (match_dup 1) 10322 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]) 10323 10324;; Shift instructions 10325 10326;; DImode shifts are implemented using the i386 "shift double" opcode, 10327;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count 10328;; is variable, then the count is in %cl and the "imm" operand is dropped 10329;; from the assembler input. 10330;; 10331;; This instruction shifts the target reg/mem as usual, but instead of 10332;; shifting in zeros, bits are shifted in from reg operand. If the insn 10333;; is a left shift double, bits are taken from the high order bits of 10334;; reg, else if the insn is a shift right double, bits are taken from the 10335;; low order bits of reg. So if %eax is "1234" and %edx is "5678", 10336;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345". 10337;; 10338;; Since sh[lr]d does not change the `reg' operand, that is done 10339;; separately, making all shifts emit pairs of shift double and normal 10340;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to 10341;; support a 63 bit shift, each shift where the count is in a reg expands 10342;; to a pair of shifts, a branch, a shift by 32 and a label. 10343;; 10344;; If the shift count is a constant, we need never emit more than one 10345;; shift pair, instead using moves and sign extension for counts greater 10346;; than 31. 10347 10348(define_expand "ashl<mode>3" 10349 [(set (match_operand:SDWIM 0 "<shift_operand>") 10350 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>") 10351 (match_operand:QI 2 "nonmemory_operand")))] 10352 "" 10353 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;") 10354 10355(define_insn_and_split "*ashl<dwi>3_doubleword_mask" 10356 [(set (match_operand:<DWI> 0 "register_operand") 10357 (ashift:<DWI> 10358 (match_operand:<DWI> 1 "register_operand") 10359 (subreg:QI 10360 (and:SI 10361 (match_operand:SI 2 "register_operand" "c") 10362 (match_operand:SI 3 "const_int_operand")) 0))) 10363 (clobber (reg:CC FLAGS_REG))] 10364 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0 10365 && ix86_pre_reload_split ()" 10366 "#" 10367 "&& 1" 10368 [(parallel 10369 [(set (match_dup 6) 10370 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2)) 10371 (lshiftrt:DWIH (match_dup 5) 10372 (minus:QI (match_dup 8) (match_dup 2))))) 10373 (clobber (reg:CC FLAGS_REG))]) 10374 (parallel 10375 [(set (match_dup 4) 10376 (ashift:DWIH (match_dup 5) (match_dup 2))) 10377 (clobber (reg:CC FLAGS_REG))])] 10378{ 10379 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); 10380 10381 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); 10382 10383 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) 10384 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) 10385 { 10386 rtx tem = gen_reg_rtx (SImode); 10387 emit_insn (gen_andsi3 (tem, operands[2], operands[3])); 10388 operands[2] = tem; 10389 } 10390 10391 operands[2] = gen_lowpart (QImode, operands[2]); 10392 10393 if (!rtx_equal_p (operands[6], operands[7])) 10394 emit_move_insn (operands[6], operands[7]); 10395}) 10396 10397(define_insn_and_split "*ashl<dwi>3_doubleword_mask_1" 10398 [(set (match_operand:<DWI> 0 "register_operand") 10399 (ashift:<DWI> 10400 (match_operand:<DWI> 1 "register_operand") 10401 (and:QI 10402 (match_operand:QI 2 "register_operand" "c") 10403 (match_operand:QI 3 "const_int_operand")))) 10404 (clobber (reg:CC FLAGS_REG))] 10405 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0 10406 && ix86_pre_reload_split ()" 10407 "#" 10408 "&& 1" 10409 [(parallel 10410 [(set (match_dup 6) 10411 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2)) 10412 (lshiftrt:DWIH (match_dup 5) 10413 (minus:QI (match_dup 8) (match_dup 2))))) 10414 (clobber (reg:CC FLAGS_REG))]) 10415 (parallel 10416 [(set (match_dup 4) 10417 (ashift:DWIH (match_dup 5) (match_dup 2))) 10418 (clobber (reg:CC FLAGS_REG))])] 10419{ 10420 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); 10421 10422 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); 10423 10424 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) 10425 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) 10426 { 10427 rtx tem = gen_reg_rtx (QImode); 10428 emit_insn (gen_andqi3 (tem, operands[2], operands[3])); 10429 operands[2] = tem; 10430 } 10431 10432 if (!rtx_equal_p (operands[6], operands[7])) 10433 emit_move_insn (operands[6], operands[7]); 10434}) 10435 10436(define_insn "*ashl<mode>3_doubleword" 10437 [(set (match_operand:DWI 0 "register_operand" "=&r") 10438 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n") 10439 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 10440 (clobber (reg:CC FLAGS_REG))] 10441 "" 10442 "#" 10443 [(set_attr "type" "multi")]) 10444 10445(define_split 10446 [(set (match_operand:DWI 0 "register_operand") 10447 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand") 10448 (match_operand:QI 2 "nonmemory_operand"))) 10449 (clobber (reg:CC FLAGS_REG))] 10450 "epilogue_completed" 10451 [(const_int 0)] 10452 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;") 10453 10454;; By default we don't ask for a scratch register, because when DWImode 10455;; values are manipulated, registers are already at a premium. But if 10456;; we have one handy, we won't turn it away. 10457 10458(define_peephole2 10459 [(match_scratch:DWIH 3 "r") 10460 (parallel [(set (match_operand:<DWI> 0 "register_operand") 10461 (ashift:<DWI> 10462 (match_operand:<DWI> 1 "nonmemory_operand") 10463 (match_operand:QI 2 "nonmemory_operand"))) 10464 (clobber (reg:CC FLAGS_REG))]) 10465 (match_dup 3)] 10466 "TARGET_CMOVE" 10467 [(const_int 0)] 10468 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;") 10469 10470(define_insn "x86_64_shld" 10471 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 10472 (ior:DI (ashift:DI (match_dup 0) 10473 (match_operand:QI 2 "nonmemory_operand" "Jc")) 10474 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r") 10475 (minus:QI (const_int 64) (match_dup 2))))) 10476 (clobber (reg:CC FLAGS_REG))] 10477 "TARGET_64BIT" 10478 "shld{q}\t{%s2%1, %0|%0, %1, %2}" 10479 [(set_attr "type" "ishift") 10480 (set_attr "prefix_0f" "1") 10481 (set_attr "mode" "DI") 10482 (set_attr "athlon_decode" "vector") 10483 (set_attr "amdfam10_decode" "vector") 10484 (set_attr "bdver1_decode" "vector")]) 10485 10486(define_insn "x86_shld" 10487 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 10488 (ior:SI (ashift:SI (match_dup 0) 10489 (match_operand:QI 2 "nonmemory_operand" "Ic")) 10490 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") 10491 (minus:QI (const_int 32) (match_dup 2))))) 10492 (clobber (reg:CC FLAGS_REG))] 10493 "" 10494 "shld{l}\t{%s2%1, %0|%0, %1, %2}" 10495 [(set_attr "type" "ishift") 10496 (set_attr "prefix_0f" "1") 10497 (set_attr "mode" "SI") 10498 (set_attr "pent_pair" "np") 10499 (set_attr "athlon_decode" "vector") 10500 (set_attr "amdfam10_decode" "vector") 10501 (set_attr "bdver1_decode" "vector")]) 10502 10503(define_expand "@x86_shift<mode>_adj_1" 10504 [(set (reg:CCZ FLAGS_REG) 10505 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand") 10506 (match_dup 4)) 10507 (const_int 0))) 10508 (set (match_operand:SWI48 0 "register_operand") 10509 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10510 (match_operand:SWI48 1 "register_operand") 10511 (match_dup 0))) 10512 (set (match_dup 1) 10513 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0)) 10514 (match_operand:SWI48 3 "register_operand") 10515 (match_dup 1)))] 10516 "TARGET_CMOVE" 10517 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));") 10518 10519(define_expand "@x86_shift<mode>_adj_2" 10520 [(use (match_operand:SWI48 0 "register_operand")) 10521 (use (match_operand:SWI48 1 "register_operand")) 10522 (use (match_operand:QI 2 "register_operand"))] 10523 "" 10524{ 10525 rtx_code_label *label = gen_label_rtx (); 10526 rtx tmp; 10527 10528 emit_insn (gen_testqi_ccz_1 (operands[2], 10529 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 10530 10531 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 10532 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 10533 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 10534 gen_rtx_LABEL_REF (VOIDmode, label), 10535 pc_rtx); 10536 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 10537 JUMP_LABEL (tmp) = label; 10538 10539 emit_move_insn (operands[0], operands[1]); 10540 ix86_expand_clear (operands[1]); 10541 10542 emit_label (label); 10543 LABEL_NUSES (label) = 1; 10544 10545 DONE; 10546}) 10547 10548;; Avoid useless masking of count operand. 10549(define_insn_and_split "*ashl<mode>3_mask" 10550 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10551 (ashift:SWI48 10552 (match_operand:SWI48 1 "nonimmediate_operand") 10553 (subreg:QI 10554 (and:SI 10555 (match_operand:SI 2 "register_operand" "c,r") 10556 (match_operand:SI 3 "const_int_operand")) 0))) 10557 (clobber (reg:CC FLAGS_REG))] 10558 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 10559 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10560 == GET_MODE_BITSIZE (<MODE>mode)-1 10561 && ix86_pre_reload_split ()" 10562 "#" 10563 "&& 1" 10564 [(parallel 10565 [(set (match_dup 0) 10566 (ashift:SWI48 (match_dup 1) 10567 (match_dup 2))) 10568 (clobber (reg:CC FLAGS_REG))])] 10569 "operands[2] = gen_lowpart (QImode, operands[2]);" 10570 [(set_attr "isa" "*,bmi2")]) 10571 10572(define_insn_and_split "*ashl<mode>3_mask_1" 10573 [(set (match_operand:SWI48 0 "nonimmediate_operand") 10574 (ashift:SWI48 10575 (match_operand:SWI48 1 "nonimmediate_operand") 10576 (and:QI 10577 (match_operand:QI 2 "register_operand" "c,r") 10578 (match_operand:QI 3 "const_int_operand")))) 10579 (clobber (reg:CC FLAGS_REG))] 10580 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands) 10581 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 10582 == GET_MODE_BITSIZE (<MODE>mode)-1 10583 && ix86_pre_reload_split ()" 10584 "#" 10585 "&& 1" 10586 [(parallel 10587 [(set (match_dup 0) 10588 (ashift:SWI48 (match_dup 1) 10589 (match_dup 2))) 10590 (clobber (reg:CC FLAGS_REG))])] 10591 "" 10592 [(set_attr "isa" "*,bmi2")]) 10593 10594(define_insn "*bmi2_ashl<mode>3_1" 10595 [(set (match_operand:SWI48 0 "register_operand" "=r") 10596 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 10597 (match_operand:SWI48 2 "register_operand" "r")))] 10598 "TARGET_BMI2" 10599 "shlx\t{%2, %1, %0|%0, %1, %2}" 10600 [(set_attr "type" "ishiftx") 10601 (set_attr "mode" "<MODE>")]) 10602 10603(define_insn "*ashl<mode>3_1" 10604 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r") 10605 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm") 10606 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r"))) 10607 (clobber (reg:CC FLAGS_REG))] 10608 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 10609{ 10610 switch (get_attr_type (insn)) 10611 { 10612 case TYPE_LEA: 10613 case TYPE_ISHIFTX: 10614 return "#"; 10615 10616 case TYPE_ALU: 10617 gcc_assert (operands[2] == const1_rtx); 10618 gcc_assert (rtx_equal_p (operands[0], operands[1])); 10619 return "add{<imodesuffix>}\t%0, %0"; 10620 10621 default: 10622 if (operands[2] == const1_rtx 10623 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10624 return "sal{<imodesuffix>}\t%0"; 10625 else 10626 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10627 } 10628} 10629 [(set_attr "isa" "*,*,bmi2") 10630 (set (attr "type") 10631 (cond [(eq_attr "alternative" "1") 10632 (const_string "lea") 10633 (eq_attr "alternative" "2") 10634 (const_string "ishiftx") 10635 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10636 (match_operand 0 "register_operand")) 10637 (match_operand 2 "const1_operand")) 10638 (const_string "alu") 10639 ] 10640 (const_string "ishift"))) 10641 (set (attr "length_immediate") 10642 (if_then_else 10643 (ior (eq_attr "type" "alu") 10644 (and (eq_attr "type" "ishift") 10645 (and (match_operand 2 "const1_operand") 10646 (ior (match_test "TARGET_SHIFT1") 10647 (match_test "optimize_function_for_size_p (cfun)"))))) 10648 (const_string "0") 10649 (const_string "*"))) 10650 (set_attr "mode" "<MODE>")]) 10651 10652;; Convert shift to the shiftx pattern to avoid flags dependency. 10653(define_split 10654 [(set (match_operand:SWI48 0 "register_operand") 10655 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 10656 (match_operand:QI 2 "register_operand"))) 10657 (clobber (reg:CC FLAGS_REG))] 10658 "TARGET_BMI2 && reload_completed" 10659 [(set (match_dup 0) 10660 (ashift:SWI48 (match_dup 1) (match_dup 2)))] 10661 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 10662 10663(define_insn "*bmi2_ashlsi3_1_zext" 10664 [(set (match_operand:DI 0 "register_operand" "=r") 10665 (zero_extend:DI 10666 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 10667 (match_operand:SI 2 "register_operand" "r"))))] 10668 "TARGET_64BIT && TARGET_BMI2" 10669 "shlx\t{%2, %1, %k0|%k0, %1, %2}" 10670 [(set_attr "type" "ishiftx") 10671 (set_attr "mode" "SI")]) 10672 10673(define_insn "*ashlsi3_1_zext" 10674 [(set (match_operand:DI 0 "register_operand" "=r,r,r") 10675 (zero_extend:DI 10676 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm") 10677 (match_operand:QI 2 "nonmemory_operand" "cI,M,r")))) 10678 (clobber (reg:CC FLAGS_REG))] 10679 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10680{ 10681 switch (get_attr_type (insn)) 10682 { 10683 case TYPE_LEA: 10684 case TYPE_ISHIFTX: 10685 return "#"; 10686 10687 case TYPE_ALU: 10688 gcc_assert (operands[2] == const1_rtx); 10689 return "add{l}\t%k0, %k0"; 10690 10691 default: 10692 if (operands[2] == const1_rtx 10693 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10694 return "sal{l}\t%k0"; 10695 else 10696 return "sal{l}\t{%2, %k0|%k0, %2}"; 10697 } 10698} 10699 [(set_attr "isa" "*,*,bmi2") 10700 (set (attr "type") 10701 (cond [(eq_attr "alternative" "1") 10702 (const_string "lea") 10703 (eq_attr "alternative" "2") 10704 (const_string "ishiftx") 10705 (and (match_test "TARGET_DOUBLE_WITH_ADD") 10706 (match_operand 2 "const1_operand")) 10707 (const_string "alu") 10708 ] 10709 (const_string "ishift"))) 10710 (set (attr "length_immediate") 10711 (if_then_else 10712 (ior (eq_attr "type" "alu") 10713 (and (eq_attr "type" "ishift") 10714 (and (match_operand 2 "const1_operand") 10715 (ior (match_test "TARGET_SHIFT1") 10716 (match_test "optimize_function_for_size_p (cfun)"))))) 10717 (const_string "0") 10718 (const_string "*"))) 10719 (set_attr "mode" "SI")]) 10720 10721;; Convert shift to the shiftx pattern to avoid flags dependency. 10722(define_split 10723 [(set (match_operand:DI 0 "register_operand") 10724 (zero_extend:DI 10725 (ashift:SI (match_operand:SI 1 "nonimmediate_operand") 10726 (match_operand:QI 2 "register_operand")))) 10727 (clobber (reg:CC FLAGS_REG))] 10728 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 10729 [(set (match_dup 0) 10730 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10731 "operands[2] = gen_lowpart (SImode, operands[2]);") 10732 10733(define_insn "*ashlhi3_1" 10734 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp") 10735 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l") 10736 (match_operand:QI 2 "nonmemory_operand" "cI,M"))) 10737 (clobber (reg:CC FLAGS_REG))] 10738 "ix86_binary_operator_ok (ASHIFT, HImode, operands)" 10739{ 10740 switch (get_attr_type (insn)) 10741 { 10742 case TYPE_LEA: 10743 return "#"; 10744 10745 case TYPE_ALU: 10746 gcc_assert (operands[2] == const1_rtx); 10747 return "add{w}\t%0, %0"; 10748 10749 default: 10750 if (operands[2] == const1_rtx 10751 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10752 return "sal{w}\t%0"; 10753 else 10754 return "sal{w}\t{%2, %0|%0, %2}"; 10755 } 10756} 10757 [(set (attr "type") 10758 (cond [(eq_attr "alternative" "1") 10759 (const_string "lea") 10760 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10761 (match_operand 0 "register_operand")) 10762 (match_operand 2 "const1_operand")) 10763 (const_string "alu") 10764 ] 10765 (const_string "ishift"))) 10766 (set (attr "length_immediate") 10767 (if_then_else 10768 (ior (eq_attr "type" "alu") 10769 (and (eq_attr "type" "ishift") 10770 (and (match_operand 2 "const1_operand") 10771 (ior (match_test "TARGET_SHIFT1") 10772 (match_test "optimize_function_for_size_p (cfun)"))))) 10773 (const_string "0") 10774 (const_string "*"))) 10775 (set_attr "mode" "HI,SI")]) 10776 10777(define_insn "*ashlqi3_1" 10778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp") 10779 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l") 10780 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M"))) 10781 (clobber (reg:CC FLAGS_REG))] 10782 "ix86_binary_operator_ok (ASHIFT, QImode, operands)" 10783{ 10784 switch (get_attr_type (insn)) 10785 { 10786 case TYPE_LEA: 10787 return "#"; 10788 10789 case TYPE_ALU: 10790 gcc_assert (operands[2] == const1_rtx); 10791 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1]))) 10792 return "add{l}\t%k0, %k0"; 10793 else 10794 return "add{b}\t%0, %0"; 10795 10796 default: 10797 if (operands[2] == const1_rtx 10798 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10799 { 10800 if (get_attr_mode (insn) == MODE_SI) 10801 return "sal{l}\t%k0"; 10802 else 10803 return "sal{b}\t%0"; 10804 } 10805 else 10806 { 10807 if (get_attr_mode (insn) == MODE_SI) 10808 return "sal{l}\t{%2, %k0|%k0, %2}"; 10809 else 10810 return "sal{b}\t{%2, %0|%0, %2}"; 10811 } 10812 } 10813} 10814 [(set (attr "type") 10815 (cond [(eq_attr "alternative" "2") 10816 (const_string "lea") 10817 (and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10818 (match_operand 0 "register_operand")) 10819 (match_operand 2 "const1_operand")) 10820 (const_string "alu") 10821 ] 10822 (const_string "ishift"))) 10823 (set (attr "length_immediate") 10824 (if_then_else 10825 (ior (eq_attr "type" "alu") 10826 (and (eq_attr "type" "ishift") 10827 (and (match_operand 2 "const1_operand") 10828 (ior (match_test "TARGET_SHIFT1") 10829 (match_test "optimize_function_for_size_p (cfun)"))))) 10830 (const_string "0") 10831 (const_string "*"))) 10832 (set_attr "mode" "QI,SI,SI") 10833 ;; Potential partial reg stall on alternative 1. 10834 (set (attr "preferred_for_speed") 10835 (cond [(eq_attr "alternative" "1") 10836 (symbol_ref "!TARGET_PARTIAL_REG_STALL")] 10837 (symbol_ref "true")))]) 10838 10839(define_insn "*ashl<mode>3_1_slp" 10840 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 10841 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0") 10842 (match_operand:QI 2 "nonmemory_operand" "cI"))) 10843 (clobber (reg:CC FLAGS_REG))] 10844 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 10845 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 10846 && rtx_equal_p (operands[0], operands[1])" 10847{ 10848 switch (get_attr_type (insn)) 10849 { 10850 case TYPE_ALU: 10851 gcc_assert (operands[2] == const1_rtx); 10852 return "add{<imodesuffix>}\t%0, %0"; 10853 10854 default: 10855 if (operands[2] == const1_rtx 10856 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10857 return "sal{<imodesuffix>}\t%0"; 10858 else 10859 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10860 } 10861} 10862 [(set (attr "type") 10863 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 10864 (match_operand 2 "const1_operand")) 10865 (const_string "alu") 10866 ] 10867 (const_string "ishift"))) 10868 (set (attr "length_immediate") 10869 (if_then_else 10870 (ior (eq_attr "type" "alu") 10871 (and (eq_attr "type" "ishift") 10872 (and (match_operand 2 "const1_operand") 10873 (ior (match_test "TARGET_SHIFT1") 10874 (match_test "optimize_function_for_size_p (cfun)"))))) 10875 (const_string "0") 10876 (const_string "*"))) 10877 (set_attr "mode" "<MODE>")]) 10878 10879;; Convert ashift to the lea pattern to avoid flags dependency. 10880(define_split 10881 [(set (match_operand:SWI 0 "register_operand") 10882 (ashift:SWI (match_operand:SWI 1 "index_register_operand") 10883 (match_operand 2 "const_0_to_3_operand"))) 10884 (clobber (reg:CC FLAGS_REG))] 10885 "reload_completed 10886 && REGNO (operands[0]) != REGNO (operands[1])" 10887 [(set (match_dup 0) 10888 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))] 10889{ 10890 if (<MODE>mode != <LEAMODE>mode) 10891 { 10892 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]); 10893 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]); 10894 } 10895 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10896}) 10897 10898;; Convert ashift to the lea pattern to avoid flags dependency. 10899(define_split 10900 [(set (match_operand:DI 0 "register_operand") 10901 (zero_extend:DI 10902 (ashift:SI (match_operand:SI 1 "index_register_operand") 10903 (match_operand 2 "const_0_to_3_operand")))) 10904 (clobber (reg:CC FLAGS_REG))] 10905 "TARGET_64BIT && reload_completed 10906 && REGNO (operands[0]) != REGNO (operands[1])" 10907 [(set (match_dup 0) 10908 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))] 10909{ 10910 operands[1] = gen_lowpart (SImode, operands[1]); 10911 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10912}) 10913 10914;; This pattern can't accept a variable shift count, since shifts by 10915;; zero don't affect the flags. We assume that shifts by constant 10916;; zero are optimized away. 10917(define_insn "*ashl<mode>3_cmp" 10918 [(set (reg FLAGS_REG) 10919 (compare 10920 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") 10921 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 10922 (const_int 0))) 10923 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 10924 (ashift:SWI (match_dup 1) (match_dup 2)))] 10925 "(optimize_function_for_size_p (cfun) 10926 || !TARGET_PARTIAL_FLAG_REG_STALL 10927 || (operands[2] == const1_rtx 10928 && (TARGET_SHIFT1 10929 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0]))))) 10930 && ix86_match_ccmode (insn, CCGOCmode) 10931 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)" 10932{ 10933 switch (get_attr_type (insn)) 10934 { 10935 case TYPE_ALU: 10936 gcc_assert (operands[2] == const1_rtx); 10937 return "add{<imodesuffix>}\t%0, %0"; 10938 10939 default: 10940 if (operands[2] == const1_rtx 10941 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10942 return "sal{<imodesuffix>}\t%0"; 10943 else 10944 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 10945 } 10946} 10947 [(set (attr "type") 10948 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 10949 (match_operand 0 "register_operand")) 10950 (match_operand 2 "const1_operand")) 10951 (const_string "alu") 10952 ] 10953 (const_string "ishift"))) 10954 (set (attr "length_immediate") 10955 (if_then_else 10956 (ior (eq_attr "type" "alu") 10957 (and (eq_attr "type" "ishift") 10958 (and (match_operand 2 "const1_operand") 10959 (ior (match_test "TARGET_SHIFT1") 10960 (match_test "optimize_function_for_size_p (cfun)"))))) 10961 (const_string "0") 10962 (const_string "*"))) 10963 (set_attr "mode" "<MODE>")]) 10964 10965(define_insn "*ashlsi3_cmp_zext" 10966 [(set (reg FLAGS_REG) 10967 (compare 10968 (ashift:SI (match_operand:SI 1 "register_operand" "0") 10969 (match_operand:QI 2 "const_1_to_31_operand" "I")) 10970 (const_int 0))) 10971 (set (match_operand:DI 0 "register_operand" "=r") 10972 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))] 10973 "TARGET_64BIT 10974 && (optimize_function_for_size_p (cfun) 10975 || !TARGET_PARTIAL_FLAG_REG_STALL 10976 || (operands[2] == const1_rtx 10977 && (TARGET_SHIFT1 10978 || TARGET_DOUBLE_WITH_ADD))) 10979 && ix86_match_ccmode (insn, CCGOCmode) 10980 && ix86_binary_operator_ok (ASHIFT, SImode, operands)" 10981{ 10982 switch (get_attr_type (insn)) 10983 { 10984 case TYPE_ALU: 10985 gcc_assert (operands[2] == const1_rtx); 10986 return "add{l}\t%k0, %k0"; 10987 10988 default: 10989 if (operands[2] == const1_rtx 10990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 10991 return "sal{l}\t%k0"; 10992 else 10993 return "sal{l}\t{%2, %k0|%k0, %2}"; 10994 } 10995} 10996 [(set (attr "type") 10997 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD") 10998 (match_operand 2 "const1_operand")) 10999 (const_string "alu") 11000 ] 11001 (const_string "ishift"))) 11002 (set (attr "length_immediate") 11003 (if_then_else 11004 (ior (eq_attr "type" "alu") 11005 (and (eq_attr "type" "ishift") 11006 (and (match_operand 2 "const1_operand") 11007 (ior (match_test "TARGET_SHIFT1") 11008 (match_test "optimize_function_for_size_p (cfun)"))))) 11009 (const_string "0") 11010 (const_string "*"))) 11011 (set_attr "mode" "SI")]) 11012 11013(define_insn "*ashl<mode>3_cconly" 11014 [(set (reg FLAGS_REG) 11015 (compare 11016 (ashift:SWI (match_operand:SWI 1 "register_operand" "0") 11017 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11018 (const_int 0))) 11019 (clobber (match_scratch:SWI 0 "=<r>"))] 11020 "(optimize_function_for_size_p (cfun) 11021 || !TARGET_PARTIAL_FLAG_REG_STALL 11022 || (operands[2] == const1_rtx 11023 && (TARGET_SHIFT1 11024 || TARGET_DOUBLE_WITH_ADD))) 11025 && ix86_match_ccmode (insn, CCGOCmode)" 11026{ 11027 switch (get_attr_type (insn)) 11028 { 11029 case TYPE_ALU: 11030 gcc_assert (operands[2] == const1_rtx); 11031 return "add{<imodesuffix>}\t%0, %0"; 11032 11033 default: 11034 if (operands[2] == const1_rtx 11035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11036 return "sal{<imodesuffix>}\t%0"; 11037 else 11038 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}"; 11039 } 11040} 11041 [(set (attr "type") 11042 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD") 11043 (match_operand 0 "register_operand")) 11044 (match_operand 2 "const1_operand")) 11045 (const_string "alu") 11046 ] 11047 (const_string "ishift"))) 11048 (set (attr "length_immediate") 11049 (if_then_else 11050 (ior (eq_attr "type" "alu") 11051 (and (eq_attr "type" "ishift") 11052 (and (match_operand 2 "const1_operand") 11053 (ior (match_test "TARGET_SHIFT1") 11054 (match_test "optimize_function_for_size_p (cfun)"))))) 11055 (const_string "0") 11056 (const_string "*"))) 11057 (set_attr "mode" "<MODE>")]) 11058 11059;; See comment above `ashl<mode>3' about how this works. 11060 11061(define_expand "<shift_insn><mode>3" 11062 [(set (match_operand:SDWIM 0 "<shift_operand>") 11063 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>") 11064 (match_operand:QI 2 "nonmemory_operand")))] 11065 "" 11066 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 11067 11068;; Avoid useless masking of count operand. 11069(define_insn_and_split "*<shift_insn><mode>3_mask" 11070 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11071 (any_shiftrt:SWI48 11072 (match_operand:SWI48 1 "nonimmediate_operand") 11073 (subreg:QI 11074 (and:SI 11075 (match_operand:SI 2 "register_operand" "c,r") 11076 (match_operand:SI 3 "const_int_operand")) 0))) 11077 (clobber (reg:CC FLAGS_REG))] 11078 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11079 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11080 == GET_MODE_BITSIZE (<MODE>mode)-1 11081 && ix86_pre_reload_split ()" 11082 "#" 11083 "&& 1" 11084 [(parallel 11085 [(set (match_dup 0) 11086 (any_shiftrt:SWI48 (match_dup 1) 11087 (match_dup 2))) 11088 (clobber (reg:CC FLAGS_REG))])] 11089 "operands[2] = gen_lowpart (QImode, operands[2]);" 11090 [(set_attr "isa" "*,bmi2")]) 11091 11092(define_insn_and_split "*<shift_insn><mode>3_mask_1" 11093 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11094 (any_shiftrt:SWI48 11095 (match_operand:SWI48 1 "nonimmediate_operand") 11096 (and:QI 11097 (match_operand:QI 2 "register_operand" "c,r") 11098 (match_operand:QI 3 "const_int_operand")))) 11099 (clobber (reg:CC FLAGS_REG))] 11100 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11101 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11102 == GET_MODE_BITSIZE (<MODE>mode)-1 11103 && ix86_pre_reload_split ()" 11104 "#" 11105 "&& 1" 11106 [(parallel 11107 [(set (match_dup 0) 11108 (any_shiftrt:SWI48 (match_dup 1) 11109 (match_dup 2))) 11110 (clobber (reg:CC FLAGS_REG))])] 11111 "" 11112 [(set_attr "isa" "*,bmi2")]) 11113 11114(define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask" 11115 [(set (match_operand:<DWI> 0 "register_operand") 11116 (any_shiftrt:<DWI> 11117 (match_operand:<DWI> 1 "register_operand") 11118 (subreg:QI 11119 (and:SI 11120 (match_operand:SI 2 "register_operand" "c") 11121 (match_operand:SI 3 "const_int_operand")) 0))) 11122 (clobber (reg:CC FLAGS_REG))] 11123 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0 11124 && ix86_pre_reload_split ()" 11125 "#" 11126 "&& 1" 11127 [(parallel 11128 [(set (match_dup 4) 11129 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) 11130 (ashift:DWIH (match_dup 7) 11131 (minus:QI (match_dup 8) (match_dup 2))))) 11132 (clobber (reg:CC FLAGS_REG))]) 11133 (parallel 11134 [(set (match_dup 6) 11135 (any_shiftrt:DWIH (match_dup 7) (match_dup 2))) 11136 (clobber (reg:CC FLAGS_REG))])] 11137{ 11138 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); 11139 11140 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); 11141 11142 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) 11143 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) 11144 { 11145 rtx tem = gen_reg_rtx (SImode); 11146 emit_insn (gen_andsi3 (tem, operands[2], operands[3])); 11147 operands[2] = tem; 11148 } 11149 11150 operands[2] = gen_lowpart (QImode, operands[2]); 11151 11152 if (!rtx_equal_p (operands[4], operands[5])) 11153 emit_move_insn (operands[4], operands[5]); 11154}) 11155 11156(define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1" 11157 [(set (match_operand:<DWI> 0 "register_operand") 11158 (any_shiftrt:<DWI> 11159 (match_operand:<DWI> 1 "register_operand") 11160 (and:QI 11161 (match_operand:QI 2 "register_operand" "c") 11162 (match_operand:QI 3 "const_int_operand")))) 11163 (clobber (reg:CC FLAGS_REG))] 11164 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0 11165 && ix86_pre_reload_split ()" 11166 "#" 11167 "&& 1" 11168 [(parallel 11169 [(set (match_dup 4) 11170 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) 11171 (ashift:DWIH (match_dup 7) 11172 (minus:QI (match_dup 8) (match_dup 2))))) 11173 (clobber (reg:CC FLAGS_REG))]) 11174 (parallel 11175 [(set (match_dup 6) 11176 (any_shiftrt:DWIH (match_dup 7) (match_dup 2))) 11177 (clobber (reg:CC FLAGS_REG))])] 11178{ 11179 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]); 11180 11181 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT); 11182 11183 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) 11184 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1)) 11185 { 11186 rtx tem = gen_reg_rtx (QImode); 11187 emit_insn (gen_andqi3 (tem, operands[2], operands[3])); 11188 operands[2] = tem; 11189 } 11190 11191 if (!rtx_equal_p (operands[4], operands[5])) 11192 emit_move_insn (operands[4], operands[5]); 11193}) 11194 11195(define_insn_and_split "*<shift_insn><mode>3_doubleword" 11196 [(set (match_operand:DWI 0 "register_operand" "=&r") 11197 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0") 11198 (match_operand:QI 2 "nonmemory_operand" "<S>c"))) 11199 (clobber (reg:CC FLAGS_REG))] 11200 "" 11201 "#" 11202 "epilogue_completed" 11203 [(const_int 0)] 11204 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;" 11205 [(set_attr "type" "multi")]) 11206 11207;; By default we don't ask for a scratch register, because when DWImode 11208;; values are manipulated, registers are already at a premium. But if 11209;; we have one handy, we won't turn it away. 11210 11211(define_peephole2 11212 [(match_scratch:DWIH 3 "r") 11213 (parallel [(set (match_operand:<DWI> 0 "register_operand") 11214 (any_shiftrt:<DWI> 11215 (match_operand:<DWI> 1 "register_operand") 11216 (match_operand:QI 2 "nonmemory_operand"))) 11217 (clobber (reg:CC FLAGS_REG))]) 11218 (match_dup 3)] 11219 "TARGET_CMOVE" 11220 [(const_int 0)] 11221 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;") 11222 11223(define_insn "x86_64_shrd" 11224 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m") 11225 (ior:DI (lshiftrt:DI (match_dup 0) 11226 (match_operand:QI 2 "nonmemory_operand" "Jc")) 11227 (ashift:DI (match_operand:DI 1 "register_operand" "r") 11228 (minus:QI (const_int 64) (match_dup 2))))) 11229 (clobber (reg:CC FLAGS_REG))] 11230 "TARGET_64BIT" 11231 "shrd{q}\t{%s2%1, %0|%0, %1, %2}" 11232 [(set_attr "type" "ishift") 11233 (set_attr "prefix_0f" "1") 11234 (set_attr "mode" "DI") 11235 (set_attr "athlon_decode" "vector") 11236 (set_attr "amdfam10_decode" "vector") 11237 (set_attr "bdver1_decode" "vector")]) 11238 11239(define_insn "x86_shrd" 11240 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m") 11241 (ior:SI (lshiftrt:SI (match_dup 0) 11242 (match_operand:QI 2 "nonmemory_operand" "Ic")) 11243 (ashift:SI (match_operand:SI 1 "register_operand" "r") 11244 (minus:QI (const_int 32) (match_dup 2))))) 11245 (clobber (reg:CC FLAGS_REG))] 11246 "" 11247 "shrd{l}\t{%s2%1, %0|%0, %1, %2}" 11248 [(set_attr "type" "ishift") 11249 (set_attr "prefix_0f" "1") 11250 (set_attr "mode" "SI") 11251 (set_attr "pent_pair" "np") 11252 (set_attr "athlon_decode" "vector") 11253 (set_attr "amdfam10_decode" "vector") 11254 (set_attr "bdver1_decode" "vector")]) 11255 11256;; Base name for insn mnemonic. 11257(define_mode_attr cvt_mnemonic 11258 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")]) 11259 11260(define_insn "ashr<mode>3_cvt" 11261 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm") 11262 (ashiftrt:SWI48 11263 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0") 11264 (match_operand:QI 2 "const_int_operand"))) 11265 (clobber (reg:CC FLAGS_REG))] 11266 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1 11267 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11268 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)" 11269 "@ 11270 <cvt_mnemonic> 11271 sar{<imodesuffix>}\t{%2, %0|%0, %2}" 11272 [(set_attr "type" "imovx,ishift") 11273 (set_attr "prefix_0f" "0,*") 11274 (set_attr "length_immediate" "0,*") 11275 (set_attr "modrm" "0,1") 11276 (set_attr "mode" "<MODE>")]) 11277 11278(define_insn "*ashrsi3_cvt_zext" 11279 [(set (match_operand:DI 0 "register_operand" "=*d,r") 11280 (zero_extend:DI 11281 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0") 11282 (match_operand:QI 2 "const_int_operand")))) 11283 (clobber (reg:CC FLAGS_REG))] 11284 "TARGET_64BIT && INTVAL (operands[2]) == 31 11285 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun)) 11286 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)" 11287 "@ 11288 {cltd|cdq} 11289 sar{l}\t{%2, %k0|%k0, %2}" 11290 [(set_attr "type" "imovx,ishift") 11291 (set_attr "prefix_0f" "0,*") 11292 (set_attr "length_immediate" "0,*") 11293 (set_attr "modrm" "0,1") 11294 (set_attr "mode" "SI")]) 11295 11296(define_expand "@x86_shift<mode>_adj_3" 11297 [(use (match_operand:SWI48 0 "register_operand")) 11298 (use (match_operand:SWI48 1 "register_operand")) 11299 (use (match_operand:QI 2 "register_operand"))] 11300 "" 11301{ 11302 rtx_code_label *label = gen_label_rtx (); 11303 rtx tmp; 11304 11305 emit_insn (gen_testqi_ccz_1 (operands[2], 11306 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)))); 11307 11308 tmp = gen_rtx_REG (CCZmode, FLAGS_REG); 11309 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx); 11310 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 11311 gen_rtx_LABEL_REF (VOIDmode, label), 11312 pc_rtx); 11313 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 11314 JUMP_LABEL (tmp) = label; 11315 11316 emit_move_insn (operands[0], operands[1]); 11317 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1], 11318 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1))); 11319 emit_label (label); 11320 LABEL_NUSES (label) = 1; 11321 11322 DONE; 11323}) 11324 11325(define_insn "*bmi2_<shift_insn><mode>3_1" 11326 [(set (match_operand:SWI48 0 "register_operand" "=r") 11327 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 11328 (match_operand:SWI48 2 "register_operand" "r")))] 11329 "TARGET_BMI2" 11330 "<shift>x\t{%2, %1, %0|%0, %1, %2}" 11331 [(set_attr "type" "ishiftx") 11332 (set_attr "mode" "<MODE>")]) 11333 11334(define_insn "*<shift_insn><mode>3_1" 11335 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 11336 (any_shiftrt:SWI48 11337 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 11338 (match_operand:QI 2 "nonmemory_operand" "c<S>,r"))) 11339 (clobber (reg:CC FLAGS_REG))] 11340 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11341{ 11342 switch (get_attr_type (insn)) 11343 { 11344 case TYPE_ISHIFTX: 11345 return "#"; 11346 11347 default: 11348 if (operands[2] == const1_rtx 11349 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11350 return "<shift>{<imodesuffix>}\t%0"; 11351 else 11352 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11353 } 11354} 11355 [(set_attr "isa" "*,bmi2") 11356 (set_attr "type" "ishift,ishiftx") 11357 (set (attr "length_immediate") 11358 (if_then_else 11359 (and (match_operand 2 "const1_operand") 11360 (ior (match_test "TARGET_SHIFT1") 11361 (match_test "optimize_function_for_size_p (cfun)"))) 11362 (const_string "0") 11363 (const_string "*"))) 11364 (set_attr "mode" "<MODE>")]) 11365 11366;; Convert shift to the shiftx pattern to avoid flags dependency. 11367(define_split 11368 [(set (match_operand:SWI48 0 "register_operand") 11369 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11370 (match_operand:QI 2 "register_operand"))) 11371 (clobber (reg:CC FLAGS_REG))] 11372 "TARGET_BMI2 && reload_completed" 11373 [(set (match_dup 0) 11374 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))] 11375 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);") 11376 11377(define_insn "*bmi2_<shift_insn>si3_1_zext" 11378 [(set (match_operand:DI 0 "register_operand" "=r") 11379 (zero_extend:DI 11380 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 11381 (match_operand:SI 2 "register_operand" "r"))))] 11382 "TARGET_64BIT && TARGET_BMI2" 11383 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}" 11384 [(set_attr "type" "ishiftx") 11385 (set_attr "mode" "SI")]) 11386 11387(define_insn "*<shift_insn>si3_1_zext" 11388 [(set (match_operand:DI 0 "register_operand" "=r,r") 11389 (zero_extend:DI 11390 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 11391 (match_operand:QI 2 "nonmemory_operand" "cI,r")))) 11392 (clobber (reg:CC FLAGS_REG))] 11393 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11394{ 11395 switch (get_attr_type (insn)) 11396 { 11397 case TYPE_ISHIFTX: 11398 return "#"; 11399 11400 default: 11401 if (operands[2] == const1_rtx 11402 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11403 return "<shift>{l}\t%k0"; 11404 else 11405 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 11406 } 11407} 11408 [(set_attr "isa" "*,bmi2") 11409 (set_attr "type" "ishift,ishiftx") 11410 (set (attr "length_immediate") 11411 (if_then_else 11412 (and (match_operand 2 "const1_operand") 11413 (ior (match_test "TARGET_SHIFT1") 11414 (match_test "optimize_function_for_size_p (cfun)"))) 11415 (const_string "0") 11416 (const_string "*"))) 11417 (set_attr "mode" "SI")]) 11418 11419;; Convert shift to the shiftx pattern to avoid flags dependency. 11420(define_split 11421 [(set (match_operand:DI 0 "register_operand") 11422 (zero_extend:DI 11423 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand") 11424 (match_operand:QI 2 "register_operand")))) 11425 (clobber (reg:CC FLAGS_REG))] 11426 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11427 [(set (match_dup 0) 11428 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 11429 "operands[2] = gen_lowpart (SImode, operands[2]);") 11430 11431(define_insn "*<shift_insn><mode>3_1" 11432 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 11433 (any_shiftrt:SWI12 11434 (match_operand:SWI12 1 "nonimmediate_operand" "0") 11435 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 11436 (clobber (reg:CC FLAGS_REG))] 11437 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11438{ 11439 if (operands[2] == const1_rtx 11440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11441 return "<shift>{<imodesuffix>}\t%0"; 11442 else 11443 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11444} 11445 [(set_attr "type" "ishift") 11446 (set (attr "length_immediate") 11447 (if_then_else 11448 (and (match_operand 2 "const1_operand") 11449 (ior (match_test "TARGET_SHIFT1") 11450 (match_test "optimize_function_for_size_p (cfun)"))) 11451 (const_string "0") 11452 (const_string "*"))) 11453 (set_attr "mode" "<MODE>")]) 11454 11455(define_insn "*<shift_insn><mode>3_1_slp" 11456 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 11457 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0") 11458 (match_operand:QI 2 "nonmemory_operand" "cI"))) 11459 (clobber (reg:CC FLAGS_REG))] 11460 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 11461 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 11462 && rtx_equal_p (operands[0], operands[1])" 11463{ 11464 if (operands[2] == const1_rtx 11465 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11466 return "<shift>{<imodesuffix>}\t%0"; 11467 else 11468 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11469} 11470 [(set_attr "type" "ishift") 11471 (set (attr "length_immediate") 11472 (if_then_else 11473 (and (match_operand 2 "const1_operand") 11474 (ior (match_test "TARGET_SHIFT1") 11475 (match_test "optimize_function_for_size_p (cfun)"))) 11476 (const_string "0") 11477 (const_string "*"))) 11478 (set_attr "mode" "<MODE>")]) 11479 11480;; This pattern can't accept a variable shift count, since shifts by 11481;; zero don't affect the flags. We assume that shifts by constant 11482;; zero are optimized away. 11483(define_insn "*<shift_insn><mode>3_cmp" 11484 [(set (reg FLAGS_REG) 11485 (compare 11486 (any_shiftrt:SWI 11487 (match_operand:SWI 1 "nonimmediate_operand" "0") 11488 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11489 (const_int 0))) 11490 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") 11491 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))] 11492 "(optimize_function_for_size_p (cfun) 11493 || !TARGET_PARTIAL_FLAG_REG_STALL 11494 || (operands[2] == const1_rtx 11495 && TARGET_SHIFT1)) 11496 && ix86_match_ccmode (insn, CCGOCmode) 11497 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11498{ 11499 if (operands[2] == const1_rtx 11500 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11501 return "<shift>{<imodesuffix>}\t%0"; 11502 else 11503 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11504} 11505 [(set_attr "type" "ishift") 11506 (set (attr "length_immediate") 11507 (if_then_else 11508 (and (match_operand 2 "const1_operand") 11509 (ior (match_test "TARGET_SHIFT1") 11510 (match_test "optimize_function_for_size_p (cfun)"))) 11511 (const_string "0") 11512 (const_string "*"))) 11513 (set_attr "mode" "<MODE>")]) 11514 11515(define_insn "*<shift_insn>si3_cmp_zext" 11516 [(set (reg FLAGS_REG) 11517 (compare 11518 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0") 11519 (match_operand:QI 2 "const_1_to_31_operand" "I")) 11520 (const_int 0))) 11521 (set (match_operand:DI 0 "register_operand" "=r") 11522 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))] 11523 "TARGET_64BIT 11524 && (optimize_function_for_size_p (cfun) 11525 || !TARGET_PARTIAL_FLAG_REG_STALL 11526 || (operands[2] == const1_rtx 11527 && TARGET_SHIFT1)) 11528 && ix86_match_ccmode (insn, CCGOCmode) 11529 && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11530{ 11531 if (operands[2] == const1_rtx 11532 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11533 return "<shift>{l}\t%k0"; 11534 else 11535 return "<shift>{l}\t{%2, %k0|%k0, %2}"; 11536} 11537 [(set_attr "type" "ishift") 11538 (set (attr "length_immediate") 11539 (if_then_else 11540 (and (match_operand 2 "const1_operand") 11541 (ior (match_test "TARGET_SHIFT1") 11542 (match_test "optimize_function_for_size_p (cfun)"))) 11543 (const_string "0") 11544 (const_string "*"))) 11545 (set_attr "mode" "SI")]) 11546 11547(define_insn "*<shift_insn><mode>3_cconly" 11548 [(set (reg FLAGS_REG) 11549 (compare 11550 (any_shiftrt:SWI 11551 (match_operand:SWI 1 "register_operand" "0") 11552 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")) 11553 (const_int 0))) 11554 (clobber (match_scratch:SWI 0 "=<r>"))] 11555 "(optimize_function_for_size_p (cfun) 11556 || !TARGET_PARTIAL_FLAG_REG_STALL 11557 || (operands[2] == const1_rtx 11558 && TARGET_SHIFT1)) 11559 && ix86_match_ccmode (insn, CCGOCmode)" 11560{ 11561 if (operands[2] == const1_rtx 11562 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11563 return "<shift>{<imodesuffix>}\t%0"; 11564 else 11565 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11566} 11567 [(set_attr "type" "ishift") 11568 (set (attr "length_immediate") 11569 (if_then_else 11570 (and (match_operand 2 "const1_operand") 11571 (ior (match_test "TARGET_SHIFT1") 11572 (match_test "optimize_function_for_size_p (cfun)"))) 11573 (const_string "0") 11574 (const_string "*"))) 11575 (set_attr "mode" "<MODE>")]) 11576 11577;; Rotate instructions 11578 11579(define_expand "<rotate_insn>ti3" 11580 [(set (match_operand:TI 0 "register_operand") 11581 (any_rotate:TI (match_operand:TI 1 "register_operand") 11582 (match_operand:QI 2 "nonmemory_operand")))] 11583 "TARGET_64BIT" 11584{ 11585 if (const_1_to_63_operand (operands[2], VOIDmode)) 11586 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword 11587 (operands[0], operands[1], operands[2])); 11588 else 11589 FAIL; 11590 11591 DONE; 11592}) 11593 11594(define_expand "<rotate_insn>di3" 11595 [(set (match_operand:DI 0 "shiftdi_operand") 11596 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand") 11597 (match_operand:QI 2 "nonmemory_operand")))] 11598 "" 11599{ 11600 if (TARGET_64BIT) 11601 ix86_expand_binary_operator (<CODE>, DImode, operands); 11602 else if (const_1_to_31_operand (operands[2], VOIDmode)) 11603 emit_insn (gen_ix86_<rotate_insn>di3_doubleword 11604 (operands[0], operands[1], operands[2])); 11605 else 11606 FAIL; 11607 11608 DONE; 11609}) 11610 11611(define_expand "<rotate_insn><mode>3" 11612 [(set (match_operand:SWIM124 0 "nonimmediate_operand") 11613 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand") 11614 (match_operand:QI 2 "nonmemory_operand")))] 11615 "" 11616 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") 11617 11618;; Avoid useless masking of count operand. 11619(define_insn_and_split "*<rotate_insn><mode>3_mask" 11620 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11621 (any_rotate:SWI48 11622 (match_operand:SWI48 1 "nonimmediate_operand") 11623 (subreg:QI 11624 (and:SI 11625 (match_operand:SI 2 "register_operand" "c") 11626 (match_operand:SI 3 "const_int_operand")) 0))) 11627 (clobber (reg:CC FLAGS_REG))] 11628 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11629 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11630 == GET_MODE_BITSIZE (<MODE>mode)-1 11631 && ix86_pre_reload_split ()" 11632 "#" 11633 "&& 1" 11634 [(parallel 11635 [(set (match_dup 0) 11636 (any_rotate:SWI48 (match_dup 1) 11637 (match_dup 2))) 11638 (clobber (reg:CC FLAGS_REG))])] 11639 "operands[2] = gen_lowpart (QImode, operands[2]);") 11640 11641(define_insn_and_split "*<rotate_insn><mode>3_mask_1" 11642 [(set (match_operand:SWI48 0 "nonimmediate_operand") 11643 (any_rotate:SWI48 11644 (match_operand:SWI48 1 "nonimmediate_operand") 11645 (and:QI 11646 (match_operand:QI 2 "register_operand" "c") 11647 (match_operand:QI 3 "const_int_operand")))) 11648 (clobber (reg:CC FLAGS_REG))] 11649 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands) 11650 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11651 == GET_MODE_BITSIZE (<MODE>mode)-1 11652 && ix86_pre_reload_split ()" 11653 "#" 11654 "&& 1" 11655 [(parallel 11656 [(set (match_dup 0) 11657 (any_rotate:SWI48 (match_dup 1) 11658 (match_dup 2))) 11659 (clobber (reg:CC FLAGS_REG))])]) 11660 11661;; Implement rotation using two double-precision 11662;; shift instructions and a scratch register. 11663 11664(define_insn_and_split "ix86_rotl<dwi>3_doubleword" 11665 [(set (match_operand:<DWI> 0 "register_operand" "=r") 11666 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 11667 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 11668 (clobber (reg:CC FLAGS_REG)) 11669 (clobber (match_scratch:DWIH 3 "=&r"))] 11670 "" 11671 "#" 11672 "reload_completed" 11673 [(set (match_dup 3) (match_dup 4)) 11674 (parallel 11675 [(set (match_dup 4) 11676 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) 11677 (lshiftrt:DWIH (match_dup 5) 11678 (minus:QI (match_dup 6) (match_dup 2))))) 11679 (clobber (reg:CC FLAGS_REG))]) 11680 (parallel 11681 [(set (match_dup 5) 11682 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) 11683 (lshiftrt:DWIH (match_dup 3) 11684 (minus:QI (match_dup 6) (match_dup 2))))) 11685 (clobber (reg:CC FLAGS_REG))])] 11686{ 11687 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 11688 11689 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 11690}) 11691 11692(define_insn_and_split "ix86_rotr<dwi>3_doubleword" 11693 [(set (match_operand:<DWI> 0 "register_operand" "=r") 11694 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") 11695 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) 11696 (clobber (reg:CC FLAGS_REG)) 11697 (clobber (match_scratch:DWIH 3 "=&r"))] 11698 "" 11699 "#" 11700 "reload_completed" 11701 [(set (match_dup 3) (match_dup 4)) 11702 (parallel 11703 [(set (match_dup 4) 11704 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2)) 11705 (ashift:DWIH (match_dup 5) 11706 (minus:QI (match_dup 6) (match_dup 2))))) 11707 (clobber (reg:CC FLAGS_REG))]) 11708 (parallel 11709 [(set (match_dup 5) 11710 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2)) 11711 (ashift:DWIH (match_dup 3) 11712 (minus:QI (match_dup 6) (match_dup 2))))) 11713 (clobber (reg:CC FLAGS_REG))])] 11714{ 11715 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 11716 11717 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]); 11718}) 11719 11720(define_mode_attr rorx_immediate_operand 11721 [(SI "const_0_to_31_operand") 11722 (DI "const_0_to_63_operand")]) 11723 11724(define_insn "*bmi2_rorx<mode>3_1" 11725 [(set (match_operand:SWI48 0 "register_operand" "=r") 11726 (rotatert:SWI48 11727 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 11728 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))] 11729 "TARGET_BMI2" 11730 "rorx\t{%2, %1, %0|%0, %1, %2}" 11731 [(set_attr "type" "rotatex") 11732 (set_attr "mode" "<MODE>")]) 11733 11734(define_insn "*<rotate_insn><mode>3_1" 11735 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r") 11736 (any_rotate:SWI48 11737 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm") 11738 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>"))) 11739 (clobber (reg:CC FLAGS_REG))] 11740 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11741{ 11742 switch (get_attr_type (insn)) 11743 { 11744 case TYPE_ROTATEX: 11745 return "#"; 11746 11747 default: 11748 if (operands[2] == const1_rtx 11749 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11750 return "<rotate>{<imodesuffix>}\t%0"; 11751 else 11752 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11753 } 11754} 11755 [(set_attr "isa" "*,bmi2") 11756 (set_attr "type" "rotate,rotatex") 11757 (set (attr "length_immediate") 11758 (if_then_else 11759 (and (eq_attr "type" "rotate") 11760 (and (match_operand 2 "const1_operand") 11761 (ior (match_test "TARGET_SHIFT1") 11762 (match_test "optimize_function_for_size_p (cfun)")))) 11763 (const_string "0") 11764 (const_string "*"))) 11765 (set_attr "mode" "<MODE>")]) 11766 11767;; Convert rotate to the rotatex pattern to avoid flags dependency. 11768(define_split 11769 [(set (match_operand:SWI48 0 "register_operand") 11770 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11771 (match_operand:QI 2 "const_int_operand"))) 11772 (clobber (reg:CC FLAGS_REG))] 11773 "TARGET_BMI2 && reload_completed" 11774 [(set (match_dup 0) 11775 (rotatert:SWI48 (match_dup 1) (match_dup 2)))] 11776{ 11777 int bitsize = GET_MODE_BITSIZE (<MODE>mode); 11778 11779 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize); 11780}) 11781 11782(define_split 11783 [(set (match_operand:SWI48 0 "register_operand") 11784 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 11785 (match_operand:QI 2 "const_int_operand"))) 11786 (clobber (reg:CC FLAGS_REG))] 11787 "TARGET_BMI2 && reload_completed" 11788 [(set (match_dup 0) 11789 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]) 11790 11791(define_insn "*bmi2_rorxsi3_1_zext" 11792 [(set (match_operand:DI 0 "register_operand" "=r") 11793 (zero_extend:DI 11794 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm") 11795 (match_operand:QI 2 "const_0_to_31_operand" "I"))))] 11796 "TARGET_64BIT && TARGET_BMI2" 11797 "rorx\t{%2, %1, %k0|%k0, %1, %2}" 11798 [(set_attr "type" "rotatex") 11799 (set_attr "mode" "SI")]) 11800 11801(define_insn "*<rotate_insn>si3_1_zext" 11802 [(set (match_operand:DI 0 "register_operand" "=r,r") 11803 (zero_extend:DI 11804 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm") 11805 (match_operand:QI 2 "nonmemory_operand" "cI,I")))) 11806 (clobber (reg:CC FLAGS_REG))] 11807 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" 11808{ 11809 switch (get_attr_type (insn)) 11810 { 11811 case TYPE_ROTATEX: 11812 return "#"; 11813 11814 default: 11815 if (operands[2] == const1_rtx 11816 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11817 return "<rotate>{l}\t%k0"; 11818 else 11819 return "<rotate>{l}\t{%2, %k0|%k0, %2}"; 11820 } 11821} 11822 [(set_attr "isa" "*,bmi2") 11823 (set_attr "type" "rotate,rotatex") 11824 (set (attr "length_immediate") 11825 (if_then_else 11826 (and (eq_attr "type" "rotate") 11827 (and (match_operand 2 "const1_operand") 11828 (ior (match_test "TARGET_SHIFT1") 11829 (match_test "optimize_function_for_size_p (cfun)")))) 11830 (const_string "0") 11831 (const_string "*"))) 11832 (set_attr "mode" "SI")]) 11833 11834;; Convert rotate to the rotatex pattern to avoid flags dependency. 11835(define_split 11836 [(set (match_operand:DI 0 "register_operand") 11837 (zero_extend:DI 11838 (rotate:SI (match_operand:SI 1 "nonimmediate_operand") 11839 (match_operand:QI 2 "const_int_operand")))) 11840 (clobber (reg:CC FLAGS_REG))] 11841 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11842 [(set (match_dup 0) 11843 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))] 11844{ 11845 int bitsize = GET_MODE_BITSIZE (SImode); 11846 11847 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize); 11848}) 11849 11850(define_split 11851 [(set (match_operand:DI 0 "register_operand") 11852 (zero_extend:DI 11853 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand") 11854 (match_operand:QI 2 "const_int_operand")))) 11855 (clobber (reg:CC FLAGS_REG))] 11856 "TARGET_64BIT && TARGET_BMI2 && reload_completed" 11857 [(set (match_dup 0) 11858 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]) 11859 11860(define_insn "*<rotate_insn><mode>3_1" 11861 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m") 11862 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0") 11863 (match_operand:QI 2 "nonmemory_operand" "c<S>"))) 11864 (clobber (reg:CC FLAGS_REG))] 11865 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" 11866{ 11867 if (operands[2] == const1_rtx 11868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11869 return "<rotate>{<imodesuffix>}\t%0"; 11870 else 11871 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11872} 11873 [(set_attr "type" "rotate") 11874 (set (attr "length_immediate") 11875 (if_then_else 11876 (and (match_operand 2 "const1_operand") 11877 (ior (match_test "TARGET_SHIFT1") 11878 (match_test "optimize_function_for_size_p (cfun)"))) 11879 (const_string "0") 11880 (const_string "*"))) 11881 (set_attr "mode" "<MODE>")]) 11882 11883(define_insn "*<rotate_insn><mode>3_1_slp" 11884 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>")) 11885 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0") 11886 (match_operand:QI 2 "nonmemory_operand" "cI"))) 11887 (clobber (reg:CC FLAGS_REG))] 11888 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) 11889 /* FIXME: without this LRA can't reload this pattern, see PR82524. */ 11890 && rtx_equal_p (operands[0], operands[1])" 11891{ 11892 if (operands[2] == const1_rtx 11893 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) 11894 return "<rotate>{<imodesuffix>}\t%0"; 11895 else 11896 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; 11897} 11898 [(set_attr "type" "rotate") 11899 (set (attr "length_immediate") 11900 (if_then_else 11901 (and (match_operand 2 "const1_operand") 11902 (ior (match_test "TARGET_SHIFT1") 11903 (match_test "optimize_function_for_size_p (cfun)"))) 11904 (const_string "0") 11905 (const_string "*"))) 11906 (set_attr "mode" "<MODE>")]) 11907 11908(define_split 11909 [(set (match_operand:HI 0 "QIreg_operand") 11910 (any_rotate:HI (match_dup 0) (const_int 8))) 11911 (clobber (reg:CC FLAGS_REG))] 11912 "reload_completed 11913 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" 11914 [(parallel [(set (strict_low_part (match_dup 0)) 11915 (bswap:HI (match_dup 0))) 11916 (clobber (reg:CC FLAGS_REG))])]) 11917 11918;; Bit set / bit test instructions 11919 11920;; %%% bts, btr, btc 11921 11922;; These instructions are *slow* when applied to memory. 11923 11924(define_code_attr btsc [(ior "bts") (xor "btc")]) 11925 11926(define_insn "*<btsc><mode>" 11927 [(set (match_operand:SWI48 0 "register_operand" "=r") 11928 (any_or:SWI48 11929 (ashift:SWI48 (const_int 1) 11930 (match_operand:QI 2 "register_operand" "r")) 11931 (match_operand:SWI48 1 "register_operand" "0"))) 11932 (clobber (reg:CC FLAGS_REG))] 11933 "TARGET_USE_BT" 11934 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}" 11935 [(set_attr "type" "alu1") 11936 (set_attr "prefix_0f" "1") 11937 (set_attr "znver1_decode" "double") 11938 (set_attr "mode" "<MODE>")]) 11939 11940;; Avoid useless masking of count operand. 11941(define_insn_and_split "*<btsc><mode>_mask" 11942 [(set (match_operand:SWI48 0 "register_operand") 11943 (any_or:SWI48 11944 (ashift:SWI48 11945 (const_int 1) 11946 (subreg:QI 11947 (and:SI 11948 (match_operand:SI 1 "register_operand") 11949 (match_operand:SI 2 "const_int_operand")) 0)) 11950 (match_operand:SWI48 3 "register_operand"))) 11951 (clobber (reg:CC FLAGS_REG))] 11952 "TARGET_USE_BT 11953 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11954 == GET_MODE_BITSIZE (<MODE>mode)-1 11955 && ix86_pre_reload_split ()" 11956 "#" 11957 "&& 1" 11958 [(parallel 11959 [(set (match_dup 0) 11960 (any_or:SWI48 11961 (ashift:SWI48 (const_int 1) 11962 (match_dup 1)) 11963 (match_dup 3))) 11964 (clobber (reg:CC FLAGS_REG))])] 11965 "operands[1] = gen_lowpart (QImode, operands[1]);") 11966 11967(define_insn_and_split "*<btsc><mode>_mask_1" 11968 [(set (match_operand:SWI48 0 "register_operand") 11969 (any_or:SWI48 11970 (ashift:SWI48 11971 (const_int 1) 11972 (and:QI 11973 (match_operand:QI 1 "register_operand") 11974 (match_operand:QI 2 "const_int_operand"))) 11975 (match_operand:SWI48 3 "register_operand"))) 11976 (clobber (reg:CC FLAGS_REG))] 11977 "TARGET_USE_BT 11978 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 11979 == GET_MODE_BITSIZE (<MODE>mode)-1 11980 && ix86_pre_reload_split ()" 11981 "#" 11982 "&& 1" 11983 [(parallel 11984 [(set (match_dup 0) 11985 (any_or:SWI48 11986 (ashift:SWI48 (const_int 1) 11987 (match_dup 1)) 11988 (match_dup 3))) 11989 (clobber (reg:CC FLAGS_REG))])]) 11990 11991(define_insn "*btr<mode>" 11992 [(set (match_operand:SWI48 0 "register_operand" "=r") 11993 (and:SWI48 11994 (rotate:SWI48 (const_int -2) 11995 (match_operand:QI 2 "register_operand" "r")) 11996 (match_operand:SWI48 1 "register_operand" "0"))) 11997 (clobber (reg:CC FLAGS_REG))] 11998 "TARGET_USE_BT" 11999 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}" 12000 [(set_attr "type" "alu1") 12001 (set_attr "prefix_0f" "1") 12002 (set_attr "znver1_decode" "double") 12003 (set_attr "mode" "<MODE>")]) 12004 12005;; Avoid useless masking of count operand. 12006(define_insn_and_split "*btr<mode>_mask" 12007 [(set (match_operand:SWI48 0 "register_operand") 12008 (and:SWI48 12009 (rotate:SWI48 12010 (const_int -2) 12011 (subreg:QI 12012 (and:SI 12013 (match_operand:SI 1 "register_operand") 12014 (match_operand:SI 2 "const_int_operand")) 0)) 12015 (match_operand:SWI48 3 "register_operand"))) 12016 (clobber (reg:CC FLAGS_REG))] 12017 "TARGET_USE_BT 12018 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 12019 == GET_MODE_BITSIZE (<MODE>mode)-1 12020 && ix86_pre_reload_split ()" 12021 "#" 12022 "&& 1" 12023 [(parallel 12024 [(set (match_dup 0) 12025 (and:SWI48 12026 (rotate:SWI48 (const_int -2) 12027 (match_dup 1)) 12028 (match_dup 3))) 12029 (clobber (reg:CC FLAGS_REG))])] 12030 "operands[1] = gen_lowpart (QImode, operands[1]);") 12031 12032(define_insn_and_split "*btr<mode>_mask_1" 12033 [(set (match_operand:SWI48 0 "register_operand") 12034 (and:SWI48 12035 (rotate:SWI48 12036 (const_int -2) 12037 (and:QI 12038 (match_operand:QI 1 "register_operand") 12039 (match_operand:QI 2 "const_int_operand"))) 12040 (match_operand:SWI48 3 "register_operand"))) 12041 (clobber (reg:CC FLAGS_REG))] 12042 "TARGET_USE_BT 12043 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 12044 == GET_MODE_BITSIZE (<MODE>mode)-1 12045 && ix86_pre_reload_split ()" 12046 "#" 12047 "&& 1" 12048 [(parallel 12049 [(set (match_dup 0) 12050 (and:SWI48 12051 (rotate:SWI48 (const_int -2) 12052 (match_dup 1)) 12053 (match_dup 3))) 12054 (clobber (reg:CC FLAGS_REG))])]) 12055 12056;; These instructions are never faster than the corresponding 12057;; and/ior/xor operations when using immediate operand, so with 12058;; 32-bit there's no point. But in 64-bit, we can't hold the 12059;; relevant immediates within the instruction itself, so operating 12060;; on bits in the high 32-bits of a register becomes easier. 12061;; 12062;; These are slow on Nocona, but fast on Athlon64. We do require the use 12063;; of btrq and btcq for corner cases of post-reload expansion of absdf and 12064;; negdf respectively, so they can never be disabled entirely. 12065 12066(define_insn "*btsq_imm" 12067 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 12068 (const_int 1) 12069 (match_operand 1 "const_0_to_63_operand" "J")) 12070 (const_int 1)) 12071 (clobber (reg:CC FLAGS_REG))] 12072 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 12073 "bts{q}\t{%1, %0|%0, %1}" 12074 [(set_attr "type" "alu1") 12075 (set_attr "prefix_0f" "1") 12076 (set_attr "znver1_decode" "double") 12077 (set_attr "mode" "DI")]) 12078 12079(define_insn "*btrq_imm" 12080 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 12081 (const_int 1) 12082 (match_operand 1 "const_0_to_63_operand" "J")) 12083 (const_int 0)) 12084 (clobber (reg:CC FLAGS_REG))] 12085 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 12086 "btr{q}\t{%1, %0|%0, %1}" 12087 [(set_attr "type" "alu1") 12088 (set_attr "prefix_0f" "1") 12089 (set_attr "znver1_decode" "double") 12090 (set_attr "mode" "DI")]) 12091 12092(define_insn "*btcq_imm" 12093 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm") 12094 (const_int 1) 12095 (match_operand 1 "const_0_to_63_operand" "J")) 12096 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) 12097 (clobber (reg:CC FLAGS_REG))] 12098 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" 12099 "btc{q}\t{%1, %0|%0, %1}" 12100 [(set_attr "type" "alu1") 12101 (set_attr "prefix_0f" "1") 12102 (set_attr "znver1_decode" "double") 12103 (set_attr "mode" "DI")]) 12104 12105;; Allow Nocona to avoid these instructions if a register is available. 12106 12107(define_peephole2 12108 [(match_scratch:DI 2 "r") 12109 (parallel [(set (zero_extract:DI 12110 (match_operand:DI 0 "nonimmediate_operand") 12111 (const_int 1) 12112 (match_operand 1 "const_0_to_63_operand")) 12113 (const_int 1)) 12114 (clobber (reg:CC FLAGS_REG))])] 12115 "TARGET_64BIT && !TARGET_USE_BT" 12116 [(parallel [(set (match_dup 0) 12117 (ior:DI (match_dup 0) (match_dup 3))) 12118 (clobber (reg:CC FLAGS_REG))])] 12119{ 12120 int i = INTVAL (operands[1]); 12121 12122 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); 12123 12124 if (!x86_64_immediate_operand (operands[3], DImode)) 12125 { 12126 emit_move_insn (operands[2], operands[3]); 12127 operands[3] = operands[2]; 12128 } 12129}) 12130 12131(define_peephole2 12132 [(match_scratch:DI 2 "r") 12133 (parallel [(set (zero_extract:DI 12134 (match_operand:DI 0 "nonimmediate_operand") 12135 (const_int 1) 12136 (match_operand 1 "const_0_to_63_operand")) 12137 (const_int 0)) 12138 (clobber (reg:CC FLAGS_REG))])] 12139 "TARGET_64BIT && !TARGET_USE_BT" 12140 [(parallel [(set (match_dup 0) 12141 (and:DI (match_dup 0) (match_dup 3))) 12142 (clobber (reg:CC FLAGS_REG))])] 12143{ 12144 int i = INTVAL (operands[1]); 12145 12146 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode); 12147 12148 if (!x86_64_immediate_operand (operands[3], DImode)) 12149 { 12150 emit_move_insn (operands[2], operands[3]); 12151 operands[3] = operands[2]; 12152 } 12153}) 12154 12155(define_peephole2 12156 [(match_scratch:DI 2 "r") 12157 (parallel [(set (zero_extract:DI 12158 (match_operand:DI 0 "nonimmediate_operand") 12159 (const_int 1) 12160 (match_operand 1 "const_0_to_63_operand")) 12161 (not:DI (zero_extract:DI 12162 (match_dup 0) (const_int 1) (match_dup 1)))) 12163 (clobber (reg:CC FLAGS_REG))])] 12164 "TARGET_64BIT && !TARGET_USE_BT" 12165 [(parallel [(set (match_dup 0) 12166 (xor:DI (match_dup 0) (match_dup 3))) 12167 (clobber (reg:CC FLAGS_REG))])] 12168{ 12169 int i = INTVAL (operands[1]); 12170 12171 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode); 12172 12173 if (!x86_64_immediate_operand (operands[3], DImode)) 12174 { 12175 emit_move_insn (operands[2], operands[3]); 12176 operands[3] = operands[2]; 12177 } 12178}) 12179 12180;; %%% bt 12181 12182(define_insn "*bt<mode>" 12183 [(set (reg:CCC FLAGS_REG) 12184 (compare:CCC 12185 (zero_extract:SWI48 12186 (match_operand:SWI48 0 "nonimmediate_operand" "r,m") 12187 (const_int 1) 12188 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>")) 12189 (const_int 0)))] 12190 "" 12191{ 12192 switch (get_attr_mode (insn)) 12193 { 12194 case MODE_SI: 12195 return "bt{l}\t{%1, %k0|%k0, %1}"; 12196 12197 case MODE_DI: 12198 return "bt{q}\t{%q1, %0|%0, %q1}"; 12199 12200 default: 12201 gcc_unreachable (); 12202 } 12203} 12204 [(set_attr "type" "alu1") 12205 (set_attr "prefix_0f" "1") 12206 (set (attr "mode") 12207 (if_then_else 12208 (and (match_test "CONST_INT_P (operands[1])") 12209 (match_test "INTVAL (operands[1]) < 32")) 12210 (const_string "SI") 12211 (const_string "<MODE>")))]) 12212 12213(define_insn_and_split "*jcc_bt<mode>" 12214 [(set (pc) 12215 (if_then_else (match_operator 0 "bt_comparison_operator" 12216 [(zero_extract:SWI48 12217 (match_operand:SWI48 1 "nonimmediate_operand") 12218 (const_int 1) 12219 (match_operand:SI 2 "nonmemory_operand")) 12220 (const_int 0)]) 12221 (label_ref (match_operand 3)) 12222 (pc))) 12223 (clobber (reg:CC FLAGS_REG))] 12224 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12225 && (CONST_INT_P (operands[2]) 12226 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode) 12227 && INTVAL (operands[2]) 12228 >= (optimize_function_for_size_p (cfun) ? 8 : 32)) 12229 : !memory_operand (operands[1], <MODE>mode)) 12230 && ix86_pre_reload_split ()" 12231 "#" 12232 "&& 1" 12233 [(set (reg:CCC FLAGS_REG) 12234 (compare:CCC 12235 (zero_extract:SWI48 12236 (match_dup 1) 12237 (const_int 1) 12238 (match_dup 2)) 12239 (const_int 0))) 12240 (set (pc) 12241 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12242 (label_ref (match_dup 3)) 12243 (pc)))] 12244{ 12245 operands[0] = shallow_copy_rtx (operands[0]); 12246 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12247}) 12248 12249(define_insn_and_split "*jcc_bt<mode>_1" 12250 [(set (pc) 12251 (if_then_else (match_operator 0 "bt_comparison_operator" 12252 [(zero_extract:SWI48 12253 (match_operand:SWI48 1 "register_operand") 12254 (const_int 1) 12255 (zero_extend:SI 12256 (match_operand:QI 2 "register_operand"))) 12257 (const_int 0)]) 12258 (label_ref (match_operand 3)) 12259 (pc))) 12260 (clobber (reg:CC FLAGS_REG))] 12261 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12262 && ix86_pre_reload_split ()" 12263 "#" 12264 "&& 1" 12265 [(set (reg:CCC FLAGS_REG) 12266 (compare:CCC 12267 (zero_extract:SWI48 12268 (match_dup 1) 12269 (const_int 1) 12270 (match_dup 2)) 12271 (const_int 0))) 12272 (set (pc) 12273 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12274 (label_ref (match_dup 3)) 12275 (pc)))] 12276{ 12277 operands[2] = lowpart_subreg (SImode, operands[2], QImode); 12278 operands[0] = shallow_copy_rtx (operands[0]); 12279 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12280}) 12281 12282;; Avoid useless masking of bit offset operand. 12283(define_insn_and_split "*jcc_bt<mode>_mask" 12284 [(set (pc) 12285 (if_then_else (match_operator 0 "bt_comparison_operator" 12286 [(zero_extract:SWI48 12287 (match_operand:SWI48 1 "register_operand") 12288 (const_int 1) 12289 (and:SI 12290 (match_operand:SI 2 "register_operand") 12291 (match_operand 3 "const_int_operand")))]) 12292 (label_ref (match_operand 4)) 12293 (pc))) 12294 (clobber (reg:CC FLAGS_REG))] 12295 "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) 12296 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1)) 12297 == GET_MODE_BITSIZE (<MODE>mode)-1 12298 && ix86_pre_reload_split ()" 12299 "#" 12300 "&& 1" 12301 [(set (reg:CCC FLAGS_REG) 12302 (compare:CCC 12303 (zero_extract:SWI48 12304 (match_dup 1) 12305 (const_int 1) 12306 (match_dup 2)) 12307 (const_int 0))) 12308 (set (pc) 12309 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) 12310 (label_ref (match_dup 4)) 12311 (pc)))] 12312{ 12313 operands[0] = shallow_copy_rtx (operands[0]); 12314 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); 12315}) 12316 12317;; Store-flag instructions. 12318 12319;; For all sCOND expanders, also expand the compare or test insn that 12320;; generates cc0. Generate an equality comparison if `seq' or `sne'. 12321 12322(define_insn_and_split "*setcc_di_1" 12323 [(set (match_operand:DI 0 "register_operand" "=q") 12324 (match_operator:DI 1 "ix86_comparison_operator" 12325 [(reg FLAGS_REG) (const_int 0)]))] 12326 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL" 12327 "#" 12328 "&& reload_completed" 12329 [(set (match_dup 2) (match_dup 1)) 12330 (set (match_dup 0) (zero_extend:DI (match_dup 2)))] 12331{ 12332 operands[1] = shallow_copy_rtx (operands[1]); 12333 PUT_MODE (operands[1], QImode); 12334 operands[2] = gen_lowpart (QImode, operands[0]); 12335}) 12336 12337(define_insn_and_split "*setcc_si_1_and" 12338 [(set (match_operand:SI 0 "register_operand" "=q") 12339 (match_operator:SI 1 "ix86_comparison_operator" 12340 [(reg FLAGS_REG) (const_int 0)])) 12341 (clobber (reg:CC FLAGS_REG))] 12342 "!TARGET_PARTIAL_REG_STALL 12343 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)" 12344 "#" 12345 "&& reload_completed" 12346 [(set (match_dup 2) (match_dup 1)) 12347 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) 12348 (clobber (reg:CC FLAGS_REG))])] 12349{ 12350 operands[1] = shallow_copy_rtx (operands[1]); 12351 PUT_MODE (operands[1], QImode); 12352 operands[2] = gen_lowpart (QImode, operands[0]); 12353}) 12354 12355(define_insn_and_split "*setcc_si_1_movzbl" 12356 [(set (match_operand:SI 0 "register_operand" "=q") 12357 (match_operator:SI 1 "ix86_comparison_operator" 12358 [(reg FLAGS_REG) (const_int 0)]))] 12359 "!TARGET_PARTIAL_REG_STALL 12360 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))" 12361 "#" 12362 "&& reload_completed" 12363 [(set (match_dup 2) (match_dup 1)) 12364 (set (match_dup 0) (zero_extend:SI (match_dup 2)))] 12365{ 12366 operands[1] = shallow_copy_rtx (operands[1]); 12367 PUT_MODE (operands[1], QImode); 12368 operands[2] = gen_lowpart (QImode, operands[0]); 12369}) 12370 12371(define_insn "*setcc_qi" 12372 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") 12373 (match_operator:QI 1 "ix86_comparison_operator" 12374 [(reg FLAGS_REG) (const_int 0)]))] 12375 "" 12376 "set%C1\t%0" 12377 [(set_attr "type" "setcc") 12378 (set_attr "mode" "QI")]) 12379 12380(define_insn "*setcc_qi_slp" 12381 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q")) 12382 (match_operator:QI 1 "ix86_comparison_operator" 12383 [(reg FLAGS_REG) (const_int 0)]))] 12384 "" 12385 "set%C1\t%0" 12386 [(set_attr "type" "setcc") 12387 (set_attr "mode" "QI")]) 12388 12389;; In general it is not safe to assume too much about CCmode registers, 12390;; so simplify-rtx stops when it sees a second one. Under certain 12391;; conditions this is safe on x86, so help combine not create 12392;; 12393;; seta %al 12394;; testb %al, %al 12395;; sete %al 12396 12397(define_split 12398 [(set (match_operand:QI 0 "nonimmediate_operand") 12399 (ne:QI (match_operator 1 "ix86_comparison_operator" 12400 [(reg FLAGS_REG) (const_int 0)]) 12401 (const_int 0)))] 12402 "" 12403 [(set (match_dup 0) (match_dup 1))] 12404{ 12405 operands[1] = shallow_copy_rtx (operands[1]); 12406 PUT_MODE (operands[1], QImode); 12407}) 12408 12409(define_split 12410 [(set (strict_low_part (match_operand:QI 0 "register_operand")) 12411 (ne:QI (match_operator 1 "ix86_comparison_operator" 12412 [(reg FLAGS_REG) (const_int 0)]) 12413 (const_int 0)))] 12414 "" 12415 [(set (match_dup 0) (match_dup 1))] 12416{ 12417 operands[1] = shallow_copy_rtx (operands[1]); 12418 PUT_MODE (operands[1], QImode); 12419}) 12420 12421(define_split 12422 [(set (match_operand:QI 0 "nonimmediate_operand") 12423 (eq:QI (match_operator 1 "ix86_comparison_operator" 12424 [(reg FLAGS_REG) (const_int 0)]) 12425 (const_int 0)))] 12426 "" 12427 [(set (match_dup 0) (match_dup 1))] 12428{ 12429 operands[1] = shallow_copy_rtx (operands[1]); 12430 PUT_MODE (operands[1], QImode); 12431 PUT_CODE (operands[1], 12432 ix86_reverse_condition (GET_CODE (operands[1]), 12433 GET_MODE (XEXP (operands[1], 0)))); 12434 12435 /* Make sure that (a) the CCmode we have for the flags is strong 12436 enough for the reversed compare or (b) we have a valid FP compare. */ 12437 if (! ix86_comparison_operator (operands[1], VOIDmode)) 12438 FAIL; 12439}) 12440 12441(define_split 12442 [(set (strict_low_part (match_operand:QI 0 "register_operand")) 12443 (eq:QI (match_operator 1 "ix86_comparison_operator" 12444 [(reg FLAGS_REG) (const_int 0)]) 12445 (const_int 0)))] 12446 "" 12447 [(set (match_dup 0) (match_dup 1))] 12448{ 12449 operands[1] = shallow_copy_rtx (operands[1]); 12450 PUT_MODE (operands[1], QImode); 12451 PUT_CODE (operands[1], 12452 ix86_reverse_condition (GET_CODE (operands[1]), 12453 GET_MODE (XEXP (operands[1], 0)))); 12454 12455 /* Make sure that (a) the CCmode we have for the flags is strong 12456 enough for the reversed compare or (b) we have a valid FP compare. */ 12457 if (! ix86_comparison_operator (operands[1], VOIDmode)) 12458 FAIL; 12459}) 12460 12461;; The SSE store flag instructions saves 0 or 0xffffffff to the result. 12462;; subsequent logical operations are used to imitate conditional moves. 12463;; 0xffffffff is NaN, but not in normalized form, so we can't represent 12464;; it directly. 12465 12466(define_insn "setcc_<mode>_sse" 12467 [(set (match_operand:MODEF 0 "register_operand" "=x,x") 12468 (match_operator:MODEF 3 "sse_comparison_operator" 12469 [(match_operand:MODEF 1 "register_operand" "0,x") 12470 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))] 12471 "SSE_FLOAT_MODE_P (<MODE>mode)" 12472 "@ 12473 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2} 12474 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 12475 [(set_attr "isa" "noavx,avx") 12476 (set_attr "type" "ssecmp") 12477 (set_attr "length_immediate" "1") 12478 (set_attr "prefix" "orig,vex") 12479 (set_attr "mode" "<MODE>")]) 12480 12481;; Basic conditional jump instructions. 12482;; We ignore the overflow flag for signed branch instructions. 12483 12484(define_insn "*jcc" 12485 [(set (pc) 12486 (if_then_else (match_operator 1 "ix86_comparison_operator" 12487 [(reg FLAGS_REG) (const_int 0)]) 12488 (label_ref (match_operand 0)) 12489 (pc)))] 12490 "" 12491 "%!%+j%C1\t%l0" 12492 [(set_attr "type" "ibr") 12493 (set_attr "modrm" "0") 12494 (set (attr "length") 12495 (if_then_else 12496 (and (ge (minus (match_dup 0) (pc)) 12497 (const_int -126)) 12498 (lt (minus (match_dup 0) (pc)) 12499 (const_int 128))) 12500 (const_int 2) 12501 (const_int 6)))]) 12502 12503;; In general it is not safe to assume too much about CCmode registers, 12504;; so simplify-rtx stops when it sees a second one. Under certain 12505;; conditions this is safe on x86, so help combine not create 12506;; 12507;; seta %al 12508;; testb %al, %al 12509;; je Lfoo 12510 12511(define_split 12512 [(set (pc) 12513 (if_then_else (ne (match_operator 0 "ix86_comparison_operator" 12514 [(reg FLAGS_REG) (const_int 0)]) 12515 (const_int 0)) 12516 (label_ref (match_operand 1)) 12517 (pc)))] 12518 "" 12519 [(set (pc) 12520 (if_then_else (match_dup 0) 12521 (label_ref (match_dup 1)) 12522 (pc)))] 12523{ 12524 operands[0] = shallow_copy_rtx (operands[0]); 12525 PUT_MODE (operands[0], VOIDmode); 12526}) 12527 12528(define_split 12529 [(set (pc) 12530 (if_then_else (eq (match_operator 0 "ix86_comparison_operator" 12531 [(reg FLAGS_REG) (const_int 0)]) 12532 (const_int 0)) 12533 (label_ref (match_operand 1)) 12534 (pc)))] 12535 "" 12536 [(set (pc) 12537 (if_then_else (match_dup 0) 12538 (label_ref (match_dup 1)) 12539 (pc)))] 12540{ 12541 operands[0] = shallow_copy_rtx (operands[0]); 12542 PUT_MODE (operands[0], VOIDmode); 12543 PUT_CODE (operands[0], 12544 ix86_reverse_condition (GET_CODE (operands[0]), 12545 GET_MODE (XEXP (operands[0], 0)))); 12546 12547 /* Make sure that (a) the CCmode we have for the flags is strong 12548 enough for the reversed compare or (b) we have a valid FP compare. */ 12549 if (! ix86_comparison_operator (operands[0], VOIDmode)) 12550 FAIL; 12551}) 12552 12553;; Unconditional and other jump instructions 12554 12555(define_insn "jump" 12556 [(set (pc) 12557 (label_ref (match_operand 0)))] 12558 "" 12559 "%!jmp\t%l0" 12560 [(set_attr "type" "ibr") 12561 (set_attr "modrm" "0") 12562 (set (attr "length") 12563 (if_then_else 12564 (and (ge (minus (match_dup 0) (pc)) 12565 (const_int -126)) 12566 (lt (minus (match_dup 0) (pc)) 12567 (const_int 128))) 12568 (const_int 2) 12569 (const_int 5)))]) 12570 12571(define_expand "indirect_jump" 12572 [(set (pc) (match_operand 0 "indirect_branch_operand"))] 12573 "" 12574{ 12575 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) 12576 operands[0] = convert_memory_address (word_mode, operands[0]); 12577 cfun->machine->has_local_indirect_jump = true; 12578}) 12579 12580(define_insn "*indirect_jump" 12581 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))] 12582 "" 12583 "* return ix86_output_indirect_jmp (operands[0]);" 12584 [(set (attr "type") 12585 (if_then_else (match_test "(cfun->machine->indirect_branch_type 12586 != indirect_branch_keep)") 12587 (const_string "multi") 12588 (const_string "ibr"))) 12589 (set_attr "length_immediate" "0")]) 12590 12591(define_expand "tablejump" 12592 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand")) 12593 (use (label_ref (match_operand 1)))])] 12594 "" 12595{ 12596 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit) 12597 relative. Convert the relative address to an absolute address. */ 12598 if (flag_pic) 12599 { 12600 rtx op0, op1; 12601 enum rtx_code code; 12602 12603 /* We can't use @GOTOFF for text labels on VxWorks; 12604 see gotoff_operand. */ 12605 if (TARGET_64BIT || TARGET_VXWORKS_RTP) 12606 { 12607 code = PLUS; 12608 op0 = operands[0]; 12609 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]); 12610 } 12611 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA) 12612 { 12613 code = PLUS; 12614 op0 = operands[0]; 12615 op1 = pic_offset_table_rtx; 12616 } 12617 else 12618 { 12619 code = MINUS; 12620 op0 = pic_offset_table_rtx; 12621 op1 = operands[0]; 12622 } 12623 12624 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0, 12625 OPTAB_DIRECT); 12626 } 12627 12628 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER) 12629 operands[0] = convert_memory_address (word_mode, operands[0]); 12630 cfun->machine->has_local_indirect_jump = true; 12631}) 12632 12633(define_insn "*tablejump_1" 12634 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw")) 12635 (use (label_ref (match_operand 1)))] 12636 "" 12637 "* return ix86_output_indirect_jmp (operands[0]);" 12638 [(set (attr "type") 12639 (if_then_else (match_test "(cfun->machine->indirect_branch_type 12640 != indirect_branch_keep)") 12641 (const_string "multi") 12642 (const_string "ibr"))) 12643 (set_attr "length_immediate" "0")]) 12644 12645;; Convert setcc + movzbl to xor + setcc if operands don't overlap. 12646 12647(define_peephole2 12648 [(set (reg FLAGS_REG) (match_operand 0)) 12649 (set (match_operand:QI 1 "register_operand") 12650 (match_operator:QI 2 "ix86_comparison_operator" 12651 [(reg FLAGS_REG) (const_int 0)])) 12652 (set (match_operand 3 "any_QIreg_operand") 12653 (zero_extend (match_dup 1)))] 12654 "(peep2_reg_dead_p (3, operands[1]) 12655 || operands_match_p (operands[1], operands[3])) 12656 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12657 && peep2_regno_dead_p (0, FLAGS_REG)" 12658 [(set (match_dup 4) (match_dup 0)) 12659 (set (strict_low_part (match_dup 5)) 12660 (match_dup 2))] 12661{ 12662 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12663 operands[5] = gen_lowpart (QImode, operands[3]); 12664 ix86_expand_clear (operands[3]); 12665}) 12666 12667(define_peephole2 12668 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 12669 (match_operand 4)]) 12670 (set (match_operand:QI 1 "register_operand") 12671 (match_operator:QI 2 "ix86_comparison_operator" 12672 [(reg FLAGS_REG) (const_int 0)])) 12673 (set (match_operand 3 "any_QIreg_operand") 12674 (zero_extend (match_dup 1)))] 12675 "(peep2_reg_dead_p (3, operands[1]) 12676 || operands_match_p (operands[1], operands[3])) 12677 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12678 && ! reg_overlap_mentioned_p (operands[3], operands[4]) 12679 && ! reg_set_p (operands[3], operands[4]) 12680 && peep2_regno_dead_p (0, FLAGS_REG)" 12681 [(parallel [(set (match_dup 5) (match_dup 0)) 12682 (match_dup 4)]) 12683 (set (strict_low_part (match_dup 6)) 12684 (match_dup 2))] 12685{ 12686 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12687 operands[6] = gen_lowpart (QImode, operands[3]); 12688 ix86_expand_clear (operands[3]); 12689}) 12690 12691(define_peephole2 12692 [(set (reg FLAGS_REG) (match_operand 0)) 12693 (parallel [(set (reg FLAGS_REG) (match_operand 1)) 12694 (match_operand 5)]) 12695 (set (match_operand:QI 2 "register_operand") 12696 (match_operator:QI 3 "ix86_comparison_operator" 12697 [(reg FLAGS_REG) (const_int 0)])) 12698 (set (match_operand 4 "any_QIreg_operand") 12699 (zero_extend (match_dup 2)))] 12700 "(peep2_reg_dead_p (4, operands[2]) 12701 || operands_match_p (operands[2], operands[4])) 12702 && ! reg_overlap_mentioned_p (operands[4], operands[0]) 12703 && ! reg_overlap_mentioned_p (operands[4], operands[1]) 12704 && ! reg_overlap_mentioned_p (operands[4], operands[5]) 12705 && ! reg_set_p (operands[4], operands[5]) 12706 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) 12707 && peep2_regno_dead_p (0, FLAGS_REG)" 12708 [(set (match_dup 6) (match_dup 0)) 12709 (parallel [(set (match_dup 7) (match_dup 1)) 12710 (match_dup 5)]) 12711 (set (strict_low_part (match_dup 8)) 12712 (match_dup 3))] 12713{ 12714 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12715 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); 12716 operands[8] = gen_lowpart (QImode, operands[4]); 12717 ix86_expand_clear (operands[4]); 12718}) 12719 12720;; Similar, but match zero extend with andsi3. 12721 12722(define_peephole2 12723 [(set (reg FLAGS_REG) (match_operand 0)) 12724 (set (match_operand:QI 1 "register_operand") 12725 (match_operator:QI 2 "ix86_comparison_operator" 12726 [(reg FLAGS_REG) (const_int 0)])) 12727 (parallel [(set (match_operand:SI 3 "any_QIreg_operand") 12728 (and:SI (match_dup 3) (const_int 255))) 12729 (clobber (reg:CC FLAGS_REG))])] 12730 "REGNO (operands[1]) == REGNO (operands[3]) 12731 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12732 && peep2_regno_dead_p (0, FLAGS_REG)" 12733 [(set (match_dup 4) (match_dup 0)) 12734 (set (strict_low_part (match_dup 5)) 12735 (match_dup 2))] 12736{ 12737 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12738 operands[5] = gen_lowpart (QImode, operands[3]); 12739 ix86_expand_clear (operands[3]); 12740}) 12741 12742(define_peephole2 12743 [(parallel [(set (reg FLAGS_REG) (match_operand 0)) 12744 (match_operand 4)]) 12745 (set (match_operand:QI 1 "register_operand") 12746 (match_operator:QI 2 "ix86_comparison_operator" 12747 [(reg FLAGS_REG) (const_int 0)])) 12748 (parallel [(set (match_operand 3 "any_QIreg_operand") 12749 (zero_extend (match_dup 1))) 12750 (clobber (reg:CC FLAGS_REG))])] 12751 "(peep2_reg_dead_p (3, operands[1]) 12752 || operands_match_p (operands[1], operands[3])) 12753 && ! reg_overlap_mentioned_p (operands[3], operands[0]) 12754 && ! reg_overlap_mentioned_p (operands[3], operands[4]) 12755 && ! reg_set_p (operands[3], operands[4]) 12756 && peep2_regno_dead_p (0, FLAGS_REG)" 12757 [(parallel [(set (match_dup 5) (match_dup 0)) 12758 (match_dup 4)]) 12759 (set (strict_low_part (match_dup 6)) 12760 (match_dup 2))] 12761{ 12762 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12763 operands[6] = gen_lowpart (QImode, operands[3]); 12764 ix86_expand_clear (operands[3]); 12765}) 12766 12767(define_peephole2 12768 [(set (reg FLAGS_REG) (match_operand 0)) 12769 (parallel [(set (reg FLAGS_REG) (match_operand 1)) 12770 (match_operand 5)]) 12771 (set (match_operand:QI 2 "register_operand") 12772 (match_operator:QI 3 "ix86_comparison_operator" 12773 [(reg FLAGS_REG) (const_int 0)])) 12774 (parallel [(set (match_operand 4 "any_QIreg_operand") 12775 (zero_extend (match_dup 2))) 12776 (clobber (reg:CC FLAGS_REG))])] 12777 "(peep2_reg_dead_p (4, operands[2]) 12778 || operands_match_p (operands[2], operands[4])) 12779 && ! reg_overlap_mentioned_p (operands[4], operands[0]) 12780 && ! reg_overlap_mentioned_p (operands[4], operands[1]) 12781 && ! reg_overlap_mentioned_p (operands[4], operands[5]) 12782 && ! reg_set_p (operands[4], operands[5]) 12783 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL) 12784 && peep2_regno_dead_p (0, FLAGS_REG)" 12785 [(set (match_dup 6) (match_dup 0)) 12786 (parallel [(set (match_dup 7) (match_dup 1)) 12787 (match_dup 5)]) 12788 (set (strict_low_part (match_dup 8)) 12789 (match_dup 3))] 12790{ 12791 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG); 12792 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG); 12793 operands[8] = gen_lowpart (QImode, operands[4]); 12794 ix86_expand_clear (operands[4]); 12795}) 12796 12797;; Call instructions. 12798 12799;; The predicates normally associated with named expanders are not properly 12800;; checked for calls. This is a bug in the generic code, but it isn't that 12801;; easy to fix. Ignore it for now and be prepared to fix things up. 12802 12803;; P6 processors will jump to the address after the decrement when %esp 12804;; is used as a call operand, so they will execute return address as a code. 12805;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17. 12806 12807;; Register constraint for call instruction. 12808(define_mode_attr c [(SI "l") (DI "r")]) 12809 12810;; Call subroutine returning no value. 12811 12812(define_expand "call" 12813 [(call (match_operand:QI 0) 12814 (match_operand 1)) 12815 (use (match_operand 2))] 12816 "" 12817{ 12818 ix86_expand_call (NULL, operands[0], operands[1], 12819 operands[2], NULL, false); 12820 DONE; 12821}) 12822 12823(define_expand "sibcall" 12824 [(call (match_operand:QI 0) 12825 (match_operand 1)) 12826 (use (match_operand 2))] 12827 "" 12828{ 12829 ix86_expand_call (NULL, operands[0], operands[1], 12830 operands[2], NULL, true); 12831 DONE; 12832}) 12833 12834(define_insn "*call" 12835 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz")) 12836 (match_operand 1))] 12837 "!SIBLING_CALL_P (insn)" 12838 "* return ix86_output_call_insn (insn, operands[0]);" 12839 [(set_attr "type" "call")]) 12840 12841;; This covers both call and sibcall since only GOT slot is allowed. 12842(define_insn "*call_got_x32" 12843 [(call (mem:QI (zero_extend:DI 12844 (match_operand:SI 0 "GOT_memory_operand" "Bg"))) 12845 (match_operand 1))] 12846 "TARGET_X32" 12847{ 12848 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0)); 12849 return ix86_output_call_insn (insn, fnaddr); 12850} 12851 [(set_attr "type" "call")]) 12852 12853;; Since sibcall never returns, we can only use call-clobbered register 12854;; as GOT base. 12855(define_insn "*sibcall_GOT_32" 12856 [(call (mem:QI 12857 (mem:SI (plus:SI 12858 (match_operand:SI 0 "register_no_elim_operand" "U") 12859 (match_operand:SI 1 "GOT32_symbol_operand")))) 12860 (match_operand 2))] 12861 "!TARGET_MACHO 12862 && !TARGET_64BIT 12863 && !TARGET_INDIRECT_BRANCH_REGISTER 12864 && SIBLING_CALL_P (insn)" 12865{ 12866 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]); 12867 fnaddr = gen_const_mem (SImode, fnaddr); 12868 return ix86_output_call_insn (insn, fnaddr); 12869} 12870 [(set_attr "type" "call")]) 12871 12872(define_insn "*sibcall" 12873 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz")) 12874 (match_operand 1))] 12875 "SIBLING_CALL_P (insn)" 12876 "* return ix86_output_call_insn (insn, operands[0]);" 12877 [(set_attr "type" "call")]) 12878 12879(define_insn "*sibcall_memory" 12880 [(call (mem:QI (match_operand:W 0 "memory_operand" "m")) 12881 (match_operand 1)) 12882 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12883 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" 12884 "* return ix86_output_call_insn (insn, operands[0]);" 12885 [(set_attr "type" "call")]) 12886 12887(define_peephole2 12888 [(set (match_operand:W 0 "register_operand") 12889 (match_operand:W 1 "memory_operand")) 12890 (call (mem:QI (match_dup 0)) 12891 (match_operand 3))] 12892 "!TARGET_X32 12893 && !TARGET_INDIRECT_BRANCH_REGISTER 12894 && SIBLING_CALL_P (peep2_next_insn (1)) 12895 && !reg_mentioned_p (operands[0], 12896 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12897 [(parallel [(call (mem:QI (match_dup 1)) 12898 (match_dup 3)) 12899 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12900 12901(define_peephole2 12902 [(set (match_operand:W 0 "register_operand") 12903 (match_operand:W 1 "memory_operand")) 12904 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12905 (call (mem:QI (match_dup 0)) 12906 (match_operand 3))] 12907 "!TARGET_X32 12908 && !TARGET_INDIRECT_BRANCH_REGISTER 12909 && SIBLING_CALL_P (peep2_next_insn (2)) 12910 && !reg_mentioned_p (operands[0], 12911 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12912 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12913 (parallel [(call (mem:QI (match_dup 1)) 12914 (match_dup 3)) 12915 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12916 12917(define_expand "call_pop" 12918 [(parallel [(call (match_operand:QI 0) 12919 (match_operand:SI 1)) 12920 (set (reg:SI SP_REG) 12921 (plus:SI (reg:SI SP_REG) 12922 (match_operand:SI 3)))])] 12923 "!TARGET_64BIT" 12924{ 12925 ix86_expand_call (NULL, operands[0], operands[1], 12926 operands[2], operands[3], false); 12927 DONE; 12928}) 12929 12930(define_insn "*call_pop" 12931 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz")) 12932 (match_operand 1)) 12933 (set (reg:SI SP_REG) 12934 (plus:SI (reg:SI SP_REG) 12935 (match_operand:SI 2 "immediate_operand" "i")))] 12936 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 12937 "* return ix86_output_call_insn (insn, operands[0]);" 12938 [(set_attr "type" "call")]) 12939 12940(define_insn "*sibcall_pop" 12941 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz")) 12942 (match_operand 1)) 12943 (set (reg:SI SP_REG) 12944 (plus:SI (reg:SI SP_REG) 12945 (match_operand:SI 2 "immediate_operand" "i")))] 12946 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 12947 "* return ix86_output_call_insn (insn, operands[0]);" 12948 [(set_attr "type" "call")]) 12949 12950(define_insn "*sibcall_pop_memory" 12951 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs")) 12952 (match_operand 1)) 12953 (set (reg:SI SP_REG) 12954 (plus:SI (reg:SI SP_REG) 12955 (match_operand:SI 2 "immediate_operand" "i"))) 12956 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 12957 "!TARGET_64BIT" 12958 "* return ix86_output_call_insn (insn, operands[0]);" 12959 [(set_attr "type" "call")]) 12960 12961(define_peephole2 12962 [(set (match_operand:SI 0 "register_operand") 12963 (match_operand:SI 1 "memory_operand")) 12964 (parallel [(call (mem:QI (match_dup 0)) 12965 (match_operand 3)) 12966 (set (reg:SI SP_REG) 12967 (plus:SI (reg:SI SP_REG) 12968 (match_operand:SI 4 "immediate_operand")))])] 12969 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 12970 && !reg_mentioned_p (operands[0], 12971 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 12972 [(parallel [(call (mem:QI (match_dup 1)) 12973 (match_dup 3)) 12974 (set (reg:SI SP_REG) 12975 (plus:SI (reg:SI SP_REG) 12976 (match_dup 4))) 12977 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12978 12979(define_peephole2 12980 [(set (match_operand:SI 0 "register_operand") 12981 (match_operand:SI 1 "memory_operand")) 12982 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12983 (parallel [(call (mem:QI (match_dup 0)) 12984 (match_operand 3)) 12985 (set (reg:SI SP_REG) 12986 (plus:SI (reg:SI SP_REG) 12987 (match_operand:SI 4 "immediate_operand")))])] 12988 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 12989 && !reg_mentioned_p (operands[0], 12990 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 12991 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 12992 (parallel [(call (mem:QI (match_dup 1)) 12993 (match_dup 3)) 12994 (set (reg:SI SP_REG) 12995 (plus:SI (reg:SI SP_REG) 12996 (match_dup 4))) 12997 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 12998 12999;; Combining simple memory jump instruction 13000 13001(define_peephole2 13002 [(set (match_operand:W 0 "register_operand") 13003 (match_operand:W 1 "memory_operand")) 13004 (set (pc) (match_dup 0))] 13005 "!TARGET_X32 13006 && !TARGET_INDIRECT_BRANCH_REGISTER 13007 && peep2_reg_dead_p (2, operands[0])" 13008 [(set (pc) (match_dup 1))]) 13009 13010;; Call subroutine, returning value in operand 0 13011 13012(define_expand "call_value" 13013 [(set (match_operand 0) 13014 (call (match_operand:QI 1) 13015 (match_operand 2))) 13016 (use (match_operand 3))] 13017 "" 13018{ 13019 ix86_expand_call (operands[0], operands[1], operands[2], 13020 operands[3], NULL, false); 13021 DONE; 13022}) 13023 13024(define_expand "sibcall_value" 13025 [(set (match_operand 0) 13026 (call (match_operand:QI 1) 13027 (match_operand 2))) 13028 (use (match_operand 3))] 13029 "" 13030{ 13031 ix86_expand_call (operands[0], operands[1], operands[2], 13032 operands[3], NULL, true); 13033 DONE; 13034}) 13035 13036(define_insn "*call_value" 13037 [(set (match_operand 0) 13038 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz")) 13039 (match_operand 2)))] 13040 "!SIBLING_CALL_P (insn)" 13041 "* return ix86_output_call_insn (insn, operands[1]);" 13042 [(set_attr "type" "callv")]) 13043 13044;; This covers both call and sibcall since only GOT slot is allowed. 13045(define_insn "*call_value_got_x32" 13046 [(set (match_operand 0) 13047 (call (mem:QI 13048 (zero_extend:DI 13049 (match_operand:SI 1 "GOT_memory_operand" "Bg"))) 13050 (match_operand 2)))] 13051 "TARGET_X32" 13052{ 13053 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0)); 13054 return ix86_output_call_insn (insn, fnaddr); 13055} 13056 [(set_attr "type" "callv")]) 13057 13058;; Since sibcall never returns, we can only use call-clobbered register 13059;; as GOT base. 13060(define_insn "*sibcall_value_GOT_32" 13061 [(set (match_operand 0) 13062 (call (mem:QI 13063 (mem:SI (plus:SI 13064 (match_operand:SI 1 "register_no_elim_operand" "U") 13065 (match_operand:SI 2 "GOT32_symbol_operand")))) 13066 (match_operand 3)))] 13067 "!TARGET_MACHO 13068 && !TARGET_64BIT 13069 && !TARGET_INDIRECT_BRANCH_REGISTER 13070 && SIBLING_CALL_P (insn)" 13071{ 13072 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]); 13073 fnaddr = gen_const_mem (SImode, fnaddr); 13074 return ix86_output_call_insn (insn, fnaddr); 13075} 13076 [(set_attr "type" "callv")]) 13077 13078(define_insn "*sibcall_value" 13079 [(set (match_operand 0) 13080 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz")) 13081 (match_operand 2)))] 13082 "SIBLING_CALL_P (insn)" 13083 "* return ix86_output_call_insn (insn, operands[1]);" 13084 [(set_attr "type" "callv")]) 13085 13086(define_insn "*sibcall_value_memory" 13087 [(set (match_operand 0) 13088 (call (mem:QI (match_operand:W 1 "memory_operand" "m")) 13089 (match_operand 2))) 13090 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 13091 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER" 13092 "* return ix86_output_call_insn (insn, operands[1]);" 13093 [(set_attr "type" "callv")]) 13094 13095(define_peephole2 13096 [(set (match_operand:W 0 "register_operand") 13097 (match_operand:W 1 "memory_operand")) 13098 (set (match_operand 2) 13099 (call (mem:QI (match_dup 0)) 13100 (match_operand 3)))] 13101 "!TARGET_X32 13102 && !TARGET_INDIRECT_BRANCH_REGISTER 13103 && SIBLING_CALL_P (peep2_next_insn (1)) 13104 && !reg_mentioned_p (operands[0], 13105 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 13106 [(parallel [(set (match_dup 2) 13107 (call (mem:QI (match_dup 1)) 13108 (match_dup 3))) 13109 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13110 13111(define_peephole2 13112 [(set (match_operand:W 0 "register_operand") 13113 (match_operand:W 1 "memory_operand")) 13114 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13115 (set (match_operand 2) 13116 (call (mem:QI (match_dup 0)) 13117 (match_operand 3)))] 13118 "!TARGET_X32 13119 && !TARGET_INDIRECT_BRANCH_REGISTER 13120 && SIBLING_CALL_P (peep2_next_insn (2)) 13121 && !reg_mentioned_p (operands[0], 13122 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 13123 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13124 (parallel [(set (match_dup 2) 13125 (call (mem:QI (match_dup 1)) 13126 (match_dup 3))) 13127 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13128 13129(define_expand "call_value_pop" 13130 [(parallel [(set (match_operand 0) 13131 (call (match_operand:QI 1) 13132 (match_operand:SI 2))) 13133 (set (reg:SI SP_REG) 13134 (plus:SI (reg:SI SP_REG) 13135 (match_operand:SI 4)))])] 13136 "!TARGET_64BIT" 13137{ 13138 ix86_expand_call (operands[0], operands[1], operands[2], 13139 operands[3], operands[4], false); 13140 DONE; 13141}) 13142 13143(define_insn "*call_value_pop" 13144 [(set (match_operand 0) 13145 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz")) 13146 (match_operand 2))) 13147 (set (reg:SI SP_REG) 13148 (plus:SI (reg:SI SP_REG) 13149 (match_operand:SI 3 "immediate_operand" "i")))] 13150 "!TARGET_64BIT && !SIBLING_CALL_P (insn)" 13151 "* return ix86_output_call_insn (insn, operands[1]);" 13152 [(set_attr "type" "callv")]) 13153 13154(define_insn "*sibcall_value_pop" 13155 [(set (match_operand 0) 13156 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz")) 13157 (match_operand 2))) 13158 (set (reg:SI SP_REG) 13159 (plus:SI (reg:SI SP_REG) 13160 (match_operand:SI 3 "immediate_operand" "i")))] 13161 "!TARGET_64BIT && SIBLING_CALL_P (insn)" 13162 "* return ix86_output_call_insn (insn, operands[1]);" 13163 [(set_attr "type" "callv")]) 13164 13165(define_insn "*sibcall_value_pop_memory" 13166 [(set (match_operand 0) 13167 (call (mem:QI (match_operand:SI 1 "memory_operand" "m")) 13168 (match_operand 2))) 13169 (set (reg:SI SP_REG) 13170 (plus:SI (reg:SI SP_REG) 13171 (match_operand:SI 3 "immediate_operand" "i"))) 13172 (unspec [(const_int 0)] UNSPEC_PEEPSIB)] 13173 "!TARGET_64BIT" 13174 "* return ix86_output_call_insn (insn, operands[1]);" 13175 [(set_attr "type" "callv")]) 13176 13177(define_peephole2 13178 [(set (match_operand:SI 0 "register_operand") 13179 (match_operand:SI 1 "memory_operand")) 13180 (parallel [(set (match_operand 2) 13181 (call (mem:QI (match_dup 0)) 13182 (match_operand 3))) 13183 (set (reg:SI SP_REG) 13184 (plus:SI (reg:SI SP_REG) 13185 (match_operand:SI 4 "immediate_operand")))])] 13186 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1)) 13187 && !reg_mentioned_p (operands[0], 13188 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))" 13189 [(parallel [(set (match_dup 2) 13190 (call (mem:QI (match_dup 1)) 13191 (match_dup 3))) 13192 (set (reg:SI SP_REG) 13193 (plus:SI (reg:SI SP_REG) 13194 (match_dup 4))) 13195 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13196 13197(define_peephole2 13198 [(set (match_operand:SI 0 "register_operand") 13199 (match_operand:SI 1 "memory_operand")) 13200 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13201 (parallel [(set (match_operand 2) 13202 (call (mem:QI (match_dup 0)) 13203 (match_operand 3))) 13204 (set (reg:SI SP_REG) 13205 (plus:SI (reg:SI SP_REG) 13206 (match_operand:SI 4 "immediate_operand")))])] 13207 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2)) 13208 && !reg_mentioned_p (operands[0], 13209 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))" 13210 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE) 13211 (parallel [(set (match_dup 2) 13212 (call (mem:QI (match_dup 1)) 13213 (match_dup 3))) 13214 (set (reg:SI SP_REG) 13215 (plus:SI (reg:SI SP_REG) 13216 (match_dup 4))) 13217 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])]) 13218 13219;; Call subroutine returning any type. 13220 13221(define_expand "untyped_call" 13222 [(parallel [(call (match_operand 0) 13223 (const_int 0)) 13224 (match_operand 1) 13225 (match_operand 2)])] 13226 "" 13227{ 13228 int i; 13229 13230 /* In order to give reg-stack an easier job in validating two 13231 coprocessor registers as containing a possible return value, 13232 simply pretend the untyped call returns a complex long double 13233 value. 13234 13235 We can't use SSE_REGPARM_MAX here since callee is unprototyped 13236 and should have the default ABI. */ 13237 13238 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387 13239 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL), 13240 operands[0], const0_rtx, 13241 GEN_INT ((TARGET_64BIT 13242 ? (ix86_abi == SYSV_ABI 13243 ? X86_64_SSE_REGPARM_MAX 13244 : X86_64_MS_SSE_REGPARM_MAX) 13245 : X86_32_SSE_REGPARM_MAX) 13246 - 1), 13247 NULL, false); 13248 13249 for (i = 0; i < XVECLEN (operands[2], 0); i++) 13250 { 13251 rtx set = XVECEXP (operands[2], 0, i); 13252 emit_move_insn (SET_DEST (set), SET_SRC (set)); 13253 } 13254 13255 /* The optimizer does not know that the call sets the function value 13256 registers we stored in the result block. We avoid problems by 13257 claiming that all hard registers are used and clobbered at this 13258 point. */ 13259 emit_insn (gen_blockage ()); 13260 13261 DONE; 13262}) 13263 13264;; Prologue and epilogue instructions 13265 13266;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 13267;; all of memory. This blocks insns from being moved across this point. 13268 13269(define_insn "blockage" 13270 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)] 13271 "" 13272 "" 13273 [(set_attr "length" "0")]) 13274 13275;; Do not schedule instructions accessing memory across this point. 13276 13277(define_expand "memory_blockage" 13278 [(set (match_dup 0) 13279 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 13280 "" 13281{ 13282 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 13283 MEM_VOLATILE_P (operands[0]) = 1; 13284}) 13285 13286(define_insn "*memory_blockage" 13287 [(set (match_operand:BLK 0) 13288 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))] 13289 "" 13290 "" 13291 [(set_attr "length" "0")]) 13292 13293;; As USE insns aren't meaningful after reload, this is used instead 13294;; to prevent deleting instructions setting registers for PIC code 13295(define_insn "prologue_use" 13296 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)] 13297 "" 13298 "" 13299 [(set_attr "length" "0")]) 13300 13301;; Insn emitted into the body of a function to return from a function. 13302;; This is only done if the function's epilogue is known to be simple. 13303;; See comments for ix86_can_use_return_insn_p in i386.c. 13304 13305(define_expand "return" 13306 [(simple_return)] 13307 "ix86_can_use_return_insn_p ()" 13308{ 13309 if (crtl->args.pops_args) 13310 { 13311 rtx popc = GEN_INT (crtl->args.pops_args); 13312 emit_jump_insn (gen_simple_return_pop_internal (popc)); 13313 DONE; 13314 } 13315}) 13316 13317;; We need to disable this for TARGET_SEH, as otherwise 13318;; shrink-wrapped prologue gets enabled too. This might exceed 13319;; the maximum size of prologue in unwind information. 13320;; Also disallow shrink-wrapping if using stack slot to pass the 13321;; static chain pointer - the first instruction has to be pushl %esi 13322;; and it can't be moved around, as we use alternate entry points 13323;; in that case. 13324 13325(define_expand "simple_return" 13326 [(simple_return)] 13327 "!TARGET_SEH && !ix86_static_chain_on_stack" 13328{ 13329 if (crtl->args.pops_args) 13330 { 13331 rtx popc = GEN_INT (crtl->args.pops_args); 13332 emit_jump_insn (gen_simple_return_pop_internal (popc)); 13333 DONE; 13334 } 13335}) 13336 13337(define_insn "simple_return_internal" 13338 [(simple_return)] 13339 "reload_completed" 13340 "* return ix86_output_function_return (false);" 13341 [(set_attr "length" "1") 13342 (set_attr "atom_unit" "jeu") 13343 (set_attr "length_immediate" "0") 13344 (set_attr "modrm" "0")]) 13345 13346(define_insn "interrupt_return" 13347 [(simple_return) 13348 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)] 13349 "reload_completed" 13350{ 13351 return TARGET_64BIT ? "iretq" : "iret"; 13352}) 13353 13354;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET 13355;; instruction Athlon and K8 have. 13356 13357(define_insn "simple_return_internal_long" 13358 [(simple_return) 13359 (unspec [(const_int 0)] UNSPEC_REP)] 13360 "reload_completed" 13361 "* return ix86_output_function_return (true);" 13362 [(set_attr "length" "2") 13363 (set_attr "atom_unit" "jeu") 13364 (set_attr "length_immediate" "0") 13365 (set_attr "prefix_rep" "1") 13366 (set_attr "modrm" "0")]) 13367 13368(define_insn_and_split "simple_return_pop_internal" 13369 [(simple_return) 13370 (use (match_operand:SI 0 "const_int_operand"))] 13371 "reload_completed" 13372 "%!ret\t%0" 13373 "&& cfun->machine->function_return_type != indirect_branch_keep" 13374 [(const_int 0)] 13375 "ix86_split_simple_return_pop_internal (operands[0]); DONE;" 13376 [(set_attr "length" "3") 13377 (set_attr "atom_unit" "jeu") 13378 (set_attr "length_immediate" "2") 13379 (set_attr "modrm" "0")]) 13380 13381(define_expand "simple_return_indirect_internal" 13382 [(parallel 13383 [(simple_return) 13384 (use (match_operand 0 "register_operand"))])]) 13385 13386(define_insn "*simple_return_indirect_internal<mode>" 13387 [(simple_return) 13388 (use (match_operand:W 0 "register_operand" "r"))] 13389 "reload_completed" 13390 "* return ix86_output_indirect_function_return (operands[0]);" 13391 [(set (attr "type") 13392 (if_then_else (match_test "(cfun->machine->indirect_branch_type 13393 != indirect_branch_keep)") 13394 (const_string "multi") 13395 (const_string "ibr"))) 13396 (set_attr "length_immediate" "0")]) 13397 13398(define_insn "nop" 13399 [(const_int 0)] 13400 "" 13401 "nop" 13402 [(set_attr "length" "1") 13403 (set_attr "length_immediate" "0") 13404 (set_attr "modrm" "0")]) 13405 13406;; Generate nops. Operand 0 is the number of nops, up to 8. 13407(define_insn "nops" 13408 [(unspec_volatile [(match_operand 0 "const_int_operand")] 13409 UNSPECV_NOPS)] 13410 "reload_completed" 13411{ 13412 int num = INTVAL (operands[0]); 13413 13414 gcc_assert (IN_RANGE (num, 1, 8)); 13415 13416 while (num--) 13417 fputs ("\tnop\n", asm_out_file); 13418 13419 return ""; 13420} 13421 [(set (attr "length") (symbol_ref "INTVAL (operands[0])")) 13422 (set_attr "length_immediate" "0") 13423 (set_attr "modrm" "0")]) 13424 13425;; Pad to 16-byte boundary, max skip in op0. Used to avoid 13426;; branch prediction penalty for the third jump in a 16-byte 13427;; block on K8. 13428 13429(define_insn "pad" 13430 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)] 13431 "" 13432{ 13433#ifdef ASM_OUTPUT_MAX_SKIP_PAD 13434 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0])); 13435#else 13436 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that. 13437 The align insn is used to avoid 3 jump instructions in the row to improve 13438 branch prediction and the benefits hardly outweigh the cost of extra 8 13439 nops on the average inserted by full alignment pseudo operation. */ 13440#endif 13441 return ""; 13442} 13443 [(set_attr "length" "16")]) 13444 13445(define_expand "prologue" 13446 [(const_int 0)] 13447 "" 13448 "ix86_expand_prologue (); DONE;") 13449 13450(define_expand "set_got" 13451 [(parallel 13452 [(set (match_operand:SI 0 "register_operand") 13453 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 13454 (clobber (reg:CC FLAGS_REG))])] 13455 "!TARGET_64BIT" 13456{ 13457 if (flag_pic && !TARGET_VXWORKS_RTP) 13458 ix86_pc_thunk_call_expanded = true; 13459}) 13460 13461(define_insn "*set_got" 13462 [(set (match_operand:SI 0 "register_operand" "=r") 13463 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT)) 13464 (clobber (reg:CC FLAGS_REG))] 13465 "!TARGET_64BIT" 13466 "* return output_set_got (operands[0], NULL_RTX);" 13467 [(set_attr "type" "multi") 13468 (set_attr "length" "12")]) 13469 13470(define_expand "set_got_labelled" 13471 [(parallel 13472 [(set (match_operand:SI 0 "register_operand") 13473 (unspec:SI [(label_ref (match_operand 1))] 13474 UNSPEC_SET_GOT)) 13475 (clobber (reg:CC FLAGS_REG))])] 13476 "!TARGET_64BIT" 13477{ 13478 if (flag_pic && !TARGET_VXWORKS_RTP) 13479 ix86_pc_thunk_call_expanded = true; 13480}) 13481 13482(define_insn "*set_got_labelled" 13483 [(set (match_operand:SI 0 "register_operand" "=r") 13484 (unspec:SI [(label_ref (match_operand 1))] 13485 UNSPEC_SET_GOT)) 13486 (clobber (reg:CC FLAGS_REG))] 13487 "!TARGET_64BIT" 13488 "* return output_set_got (operands[0], operands[1]);" 13489 [(set_attr "type" "multi") 13490 (set_attr "length" "12")]) 13491 13492(define_insn "set_got_rex64" 13493 [(set (match_operand:DI 0 "register_operand" "=r") 13494 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))] 13495 "TARGET_64BIT" 13496 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}" 13497 [(set_attr "type" "lea") 13498 (set_attr "length_address" "4") 13499 (set_attr "mode" "DI")]) 13500 13501(define_insn "set_rip_rex64" 13502 [(set (match_operand:DI 0 "register_operand" "=r") 13503 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))] 13504 "TARGET_64BIT" 13505 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}" 13506 [(set_attr "type" "lea") 13507 (set_attr "length_address" "4") 13508 (set_attr "mode" "DI")]) 13509 13510(define_insn "set_got_offset_rex64" 13511 [(set (match_operand:DI 0 "register_operand" "=r") 13512 (unspec:DI 13513 [(label_ref (match_operand 1))] 13514 UNSPEC_SET_GOT_OFFSET))] 13515 "TARGET_LP64" 13516 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}" 13517 [(set_attr "type" "imov") 13518 (set_attr "length_immediate" "0") 13519 (set_attr "length_address" "8") 13520 (set_attr "mode" "DI")]) 13521 13522(define_expand "epilogue" 13523 [(const_int 0)] 13524 "" 13525 "ix86_expand_epilogue (1); DONE;") 13526 13527(define_expand "sibcall_epilogue" 13528 [(const_int 0)] 13529 "" 13530 "ix86_expand_epilogue (0); DONE;") 13531 13532(define_expand "eh_return" 13533 [(use (match_operand 0 "register_operand"))] 13534 "" 13535{ 13536 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0]; 13537 13538 /* Tricky bit: we write the address of the handler to which we will 13539 be returning into someone else's stack frame, one word below the 13540 stack address we wish to restore. */ 13541 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa); 13542 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD); 13543 /* Return address is always in word_mode. */ 13544 tmp = gen_rtx_MEM (word_mode, tmp); 13545 if (GET_MODE (ra) != word_mode) 13546 ra = convert_to_mode (word_mode, ra, 1); 13547 emit_move_insn (tmp, ra); 13548 13549 emit_jump_insn (gen_eh_return_internal ()); 13550 emit_barrier (); 13551 DONE; 13552}) 13553 13554(define_insn_and_split "eh_return_internal" 13555 [(eh_return)] 13556 "" 13557 "#" 13558 "epilogue_completed" 13559 [(const_int 0)] 13560 "ix86_expand_epilogue (2); DONE;") 13561 13562(define_expand "@leave_<mode>" 13563 [(parallel 13564 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0))) 13565 (set (reg:W BP_REG) (mem:W (reg:W BP_REG))) 13566 (clobber (mem:BLK (scratch)))])] 13567 "" 13568 "operands[0] = GEN_INT (<MODE_SIZE>);") 13569 13570(define_insn "*leave" 13571 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4))) 13572 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG))) 13573 (clobber (mem:BLK (scratch)))] 13574 "!TARGET_64BIT" 13575 "leave" 13576 [(set_attr "type" "leave")]) 13577 13578(define_insn "*leave_rex64" 13579 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8))) 13580 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG))) 13581 (clobber (mem:BLK (scratch)))] 13582 "TARGET_64BIT" 13583 "leave" 13584 [(set_attr "type" "leave")]) 13585 13586;; Handle -fsplit-stack. 13587 13588(define_expand "split_stack_prologue" 13589 [(const_int 0)] 13590 "" 13591{ 13592 ix86_expand_split_stack_prologue (); 13593 DONE; 13594}) 13595 13596;; In order to support the call/return predictor, we use a return 13597;; instruction which the middle-end doesn't see. 13598(define_insn "split_stack_return" 13599 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")] 13600 UNSPECV_SPLIT_STACK_RETURN)] 13601 "" 13602{ 13603 if (operands[0] == const0_rtx) 13604 return "ret"; 13605 else 13606 return "ret\t%0"; 13607} 13608 [(set_attr "atom_unit" "jeu") 13609 (set_attr "modrm" "0") 13610 (set (attr "length") 13611 (if_then_else (match_operand:SI 0 "const0_operand") 13612 (const_int 1) 13613 (const_int 3))) 13614 (set (attr "length_immediate") 13615 (if_then_else (match_operand:SI 0 "const0_operand") 13616 (const_int 0) 13617 (const_int 2)))]) 13618 13619;; If there are operand 0 bytes available on the stack, jump to 13620;; operand 1. 13621 13622(define_expand "split_stack_space_check" 13623 [(set (pc) (if_then_else 13624 (ltu (minus (reg SP_REG) 13625 (match_operand 0 "register_operand")) 13626 (match_dup 2)) 13627 (label_ref (match_operand 1)) 13628 (pc)))] 13629 "" 13630{ 13631 rtx reg = gen_reg_rtx (Pmode); 13632 13633 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0])); 13634 13635 operands[2] = ix86_split_stack_guard (); 13636 ix86_expand_branch (GEU, reg, operands[2], operands[1]); 13637 13638 DONE; 13639}) 13640 13641;; Bit manipulation instructions. 13642 13643(define_expand "ffs<mode>2" 13644 [(set (match_dup 2) (const_int -1)) 13645 (parallel [(set (match_dup 3) (match_dup 4)) 13646 (set (match_operand:SWI48 0 "register_operand") 13647 (ctz:SWI48 13648 (match_operand:SWI48 1 "nonimmediate_operand")))]) 13649 (set (match_dup 0) (if_then_else:SWI48 13650 (eq (match_dup 3) (const_int 0)) 13651 (match_dup 2) 13652 (match_dup 0))) 13653 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1))) 13654 (clobber (reg:CC FLAGS_REG))])] 13655 "" 13656{ 13657 machine_mode flags_mode; 13658 13659 if (<MODE>mode == SImode && !TARGET_CMOVE) 13660 { 13661 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1])); 13662 DONE; 13663 } 13664 13665 flags_mode = TARGET_BMI ? CCCmode : CCZmode; 13666 13667 operands[2] = gen_reg_rtx (<MODE>mode); 13668 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG); 13669 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 13670}) 13671 13672(define_insn_and_split "ffssi2_no_cmove" 13673 [(set (match_operand:SI 0 "register_operand" "=r") 13674 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))) 13675 (clobber (match_scratch:SI 2 "=&q")) 13676 (clobber (reg:CC FLAGS_REG))] 13677 "!TARGET_CMOVE" 13678 "#" 13679 "&& reload_completed" 13680 [(parallel [(set (match_dup 4) (match_dup 5)) 13681 (set (match_dup 0) (ctz:SI (match_dup 1)))]) 13682 (set (strict_low_part (match_dup 3)) 13683 (eq:QI (match_dup 4) (const_int 0))) 13684 (parallel [(set (match_dup 2) (neg:SI (match_dup 2))) 13685 (clobber (reg:CC FLAGS_REG))]) 13686 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2))) 13687 (clobber (reg:CC FLAGS_REG))]) 13688 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1))) 13689 (clobber (reg:CC FLAGS_REG))])] 13690{ 13691 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode; 13692 13693 operands[3] = gen_lowpart (QImode, operands[2]); 13694 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG); 13695 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx); 13696 13697 ix86_expand_clear (operands[2]); 13698}) 13699 13700(define_insn_and_split "*tzcnt<mode>_1" 13701 [(set (reg:CCC FLAGS_REG) 13702 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13703 (const_int 0))) 13704 (set (match_operand:SWI48 0 "register_operand" "=r") 13705 (ctz:SWI48 (match_dup 1)))] 13706 "TARGET_BMI" 13707 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13708 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13709 && optimize_function_for_speed_p (cfun) 13710 && !reg_mentioned_p (operands[0], operands[1])" 13711 [(parallel 13712 [(set (reg:CCC FLAGS_REG) 13713 (compare:CCC (match_dup 1) (const_int 0))) 13714 (set (match_dup 0) 13715 (ctz:SWI48 (match_dup 1))) 13716 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])] 13717 "ix86_expand_clear (operands[0]);" 13718 [(set_attr "type" "alu1") 13719 (set_attr "prefix_0f" "1") 13720 (set_attr "prefix_rep" "1") 13721 (set_attr "btver2_decode" "double") 13722 (set_attr "mode" "<MODE>")]) 13723 13724; False dependency happens when destination is only updated by tzcnt, 13725; lzcnt or popcnt. There is no false dependency when destination is 13726; also used in source. 13727(define_insn "*tzcnt<mode>_1_falsedep" 13728 [(set (reg:CCC FLAGS_REG) 13729 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13730 (const_int 0))) 13731 (set (match_operand:SWI48 0 "register_operand" "=r") 13732 (ctz:SWI48 (match_dup 1))) 13733 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13734 UNSPEC_INSN_FALSE_DEP)] 13735 "TARGET_BMI" 13736 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13737 [(set_attr "type" "alu1") 13738 (set_attr "prefix_0f" "1") 13739 (set_attr "prefix_rep" "1") 13740 (set_attr "btver2_decode" "double") 13741 (set_attr "mode" "<MODE>")]) 13742 13743(define_insn "*bsf<mode>_1" 13744 [(set (reg:CCZ FLAGS_REG) 13745 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13746 (const_int 0))) 13747 (set (match_operand:SWI48 0 "register_operand" "=r") 13748 (ctz:SWI48 (match_dup 1)))] 13749 "" 13750 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}" 13751 [(set_attr "type" "alu1") 13752 (set_attr "prefix_0f" "1") 13753 (set_attr "btver2_decode" "double") 13754 (set_attr "znver1_decode" "vector") 13755 (set_attr "mode" "<MODE>")]) 13756 13757(define_insn_and_split "ctz<mode>2" 13758 [(set (match_operand:SWI48 0 "register_operand" "=r") 13759 (ctz:SWI48 13760 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13761 (clobber (reg:CC FLAGS_REG))] 13762 "" 13763{ 13764 if (TARGET_BMI) 13765 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13766 else if (optimize_function_for_size_p (cfun)) 13767 ; 13768 else if (TARGET_GENERIC) 13769 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 13770 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13771 13772 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13773} 13774 "(TARGET_BMI || TARGET_GENERIC) 13775 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13776 && optimize_function_for_speed_p (cfun) 13777 && !reg_mentioned_p (operands[0], operands[1])" 13778 [(parallel 13779 [(set (match_dup 0) 13780 (ctz:SWI48 (match_dup 1))) 13781 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13782 (clobber (reg:CC FLAGS_REG))])] 13783 "ix86_expand_clear (operands[0]);" 13784 [(set_attr "type" "alu1") 13785 (set_attr "prefix_0f" "1") 13786 (set (attr "prefix_rep") 13787 (if_then_else 13788 (ior (match_test "TARGET_BMI") 13789 (and (not (match_test "optimize_function_for_size_p (cfun)")) 13790 (match_test "TARGET_GENERIC"))) 13791 (const_string "1") 13792 (const_string "0"))) 13793 (set_attr "mode" "<MODE>")]) 13794 13795; False dependency happens when destination is only updated by tzcnt, 13796; lzcnt or popcnt. There is no false dependency when destination is 13797; also used in source. 13798(define_insn "*ctz<mode>2_falsedep" 13799 [(set (match_operand:SWI48 0 "register_operand" "=r") 13800 (ctz:SWI48 13801 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13802 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13803 UNSPEC_INSN_FALSE_DEP) 13804 (clobber (reg:CC FLAGS_REG))] 13805 "" 13806{ 13807 if (TARGET_BMI) 13808 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 13809 else if (TARGET_GENERIC) 13810 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */ 13811 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}"; 13812 else 13813 gcc_unreachable (); 13814} 13815 [(set_attr "type" "alu1") 13816 (set_attr "prefix_0f" "1") 13817 (set_attr "prefix_rep" "1") 13818 (set_attr "mode" "<MODE>")]) 13819 13820(define_insn "bsr_rex64" 13821 [(set (reg:CCZ FLAGS_REG) 13822 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm") 13823 (const_int 0))) 13824 (set (match_operand:DI 0 "register_operand" "=r") 13825 (minus:DI (const_int 63) 13826 (clz:DI (match_dup 1))))] 13827 "TARGET_64BIT" 13828 "bsr{q}\t{%1, %0|%0, %1}" 13829 [(set_attr "type" "alu1") 13830 (set_attr "prefix_0f" "1") 13831 (set_attr "znver1_decode" "vector") 13832 (set_attr "mode" "DI")]) 13833 13834(define_insn "bsr" 13835 [(set (reg:CCZ FLAGS_REG) 13836 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm") 13837 (const_int 0))) 13838 (set (match_operand:SI 0 "register_operand" "=r") 13839 (minus:SI (const_int 31) 13840 (clz:SI (match_dup 1))))] 13841 "" 13842 "bsr{l}\t{%1, %0|%0, %1}" 13843 [(set_attr "type" "alu1") 13844 (set_attr "prefix_0f" "1") 13845 (set_attr "znver1_decode" "vector") 13846 (set_attr "mode" "SI")]) 13847 13848(define_expand "clz<mode>2" 13849 [(parallel 13850 [(set (reg:CCZ FLAGS_REG) 13851 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm") 13852 (const_int 0))) 13853 (set (match_operand:SWI48 0 "register_operand") 13854 (minus:SWI48 13855 (match_dup 2) 13856 (clz:SWI48 (match_dup 1))))]) 13857 (parallel 13858 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2))) 13859 (clobber (reg:CC FLAGS_REG))])] 13860 "" 13861{ 13862 if (TARGET_LZCNT) 13863 { 13864 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1])); 13865 DONE; 13866 } 13867 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1); 13868}) 13869 13870(define_insn_and_split "clz<mode>2_lzcnt" 13871 [(set (match_operand:SWI48 0 "register_operand" "=r") 13872 (clz:SWI48 13873 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13874 (clobber (reg:CC FLAGS_REG))] 13875 "TARGET_LZCNT" 13876 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 13877 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13878 && optimize_function_for_speed_p (cfun) 13879 && !reg_mentioned_p (operands[0], operands[1])" 13880 [(parallel 13881 [(set (match_dup 0) 13882 (clz:SWI48 (match_dup 1))) 13883 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13884 (clobber (reg:CC FLAGS_REG))])] 13885 "ix86_expand_clear (operands[0]);" 13886 [(set_attr "prefix_rep" "1") 13887 (set_attr "type" "bitmanip") 13888 (set_attr "mode" "<MODE>")]) 13889 13890; False dependency happens when destination is only updated by tzcnt, 13891; lzcnt or popcnt. There is no false dependency when destination is 13892; also used in source. 13893(define_insn "*clz<mode>2_lzcnt_falsedep" 13894 [(set (match_operand:SWI48 0 "register_operand" "=r") 13895 (clz:SWI48 13896 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 13897 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13898 UNSPEC_INSN_FALSE_DEP) 13899 (clobber (reg:CC FLAGS_REG))] 13900 "TARGET_LZCNT" 13901 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}" 13902 [(set_attr "prefix_rep" "1") 13903 (set_attr "type" "bitmanip") 13904 (set_attr "mode" "<MODE>")]) 13905 13906(define_int_iterator LT_ZCNT 13907 [(UNSPEC_TZCNT "TARGET_BMI") 13908 (UNSPEC_LZCNT "TARGET_LZCNT")]) 13909 13910(define_int_attr lt_zcnt 13911 [(UNSPEC_TZCNT "tzcnt") 13912 (UNSPEC_LZCNT "lzcnt")]) 13913 13914(define_int_attr lt_zcnt_type 13915 [(UNSPEC_TZCNT "alu1") 13916 (UNSPEC_LZCNT "bitmanip")]) 13917 13918;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version 13919;; provides operand size as output when source operand is zero. 13920 13921(define_insn_and_split "<lt_zcnt>_<mode>" 13922 [(set (match_operand:SWI48 0 "register_operand" "=r") 13923 (unspec:SWI48 13924 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13925 (clobber (reg:CC FLAGS_REG))] 13926 "" 13927 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" 13928 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 13929 && optimize_function_for_speed_p (cfun) 13930 && !reg_mentioned_p (operands[0], operands[1])" 13931 [(parallel 13932 [(set (match_dup 0) 13933 (unspec:SWI48 [(match_dup 1)] LT_ZCNT)) 13934 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 13935 (clobber (reg:CC FLAGS_REG))])] 13936 "ix86_expand_clear (operands[0]);" 13937 [(set_attr "type" "<lt_zcnt_type>") 13938 (set_attr "prefix_0f" "1") 13939 (set_attr "prefix_rep" "1") 13940 (set_attr "mode" "<MODE>")]) 13941 13942; False dependency happens when destination is only updated by tzcnt, 13943; lzcnt or popcnt. There is no false dependency when destination is 13944; also used in source. 13945(define_insn "*<lt_zcnt>_<mode>_falsedep" 13946 [(set (match_operand:SWI48 0 "register_operand" "=r") 13947 (unspec:SWI48 13948 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13949 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 13950 UNSPEC_INSN_FALSE_DEP) 13951 (clobber (reg:CC FLAGS_REG))] 13952 "" 13953 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}" 13954 [(set_attr "type" "<lt_zcnt_type>") 13955 (set_attr "prefix_0f" "1") 13956 (set_attr "prefix_rep" "1") 13957 (set_attr "mode" "<MODE>")]) 13958 13959(define_insn "<lt_zcnt>_hi" 13960 [(set (match_operand:HI 0 "register_operand" "=r") 13961 (unspec:HI 13962 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT)) 13963 (clobber (reg:CC FLAGS_REG))] 13964 "" 13965 "<lt_zcnt>{w}\t{%1, %0|%0, %1}" 13966 [(set_attr "type" "<lt_zcnt_type>") 13967 (set_attr "prefix_0f" "1") 13968 (set_attr "prefix_rep" "1") 13969 (set_attr "mode" "HI")]) 13970 13971;; BMI instructions. 13972 13973(define_insn "bmi_bextr_<mode>" 13974 [(set (match_operand:SWI48 0 "register_operand" "=r,r") 13975 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 13976 (match_operand:SWI48 2 "register_operand" "r,r")] 13977 UNSPEC_BEXTR)) 13978 (clobber (reg:CC FLAGS_REG))] 13979 "TARGET_BMI" 13980 "bextr\t{%2, %1, %0|%0, %1, %2}" 13981 [(set_attr "type" "bitmanip") 13982 (set_attr "btver2_decode" "direct, double") 13983 (set_attr "mode" "<MODE>")]) 13984 13985(define_insn "*bmi_bextr_<mode>_ccz" 13986 [(set (reg:CCZ FLAGS_REG) 13987 (compare:CCZ 13988 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m") 13989 (match_operand:SWI48 2 "register_operand" "r,r")] 13990 UNSPEC_BEXTR) 13991 (const_int 0))) 13992 (clobber (match_scratch:SWI48 0 "=r,r"))] 13993 "TARGET_BMI" 13994 "bextr\t{%2, %1, %0|%0, %1, %2}" 13995 [(set_attr "type" "bitmanip") 13996 (set_attr "btver2_decode" "direct, double") 13997 (set_attr "mode" "<MODE>")]) 13998 13999(define_insn "*bmi_blsi_<mode>" 14000 [(set (match_operand:SWI48 0 "register_operand" "=r") 14001 (and:SWI48 14002 (neg:SWI48 14003 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 14004 (match_dup 1))) 14005 (clobber (reg:CC FLAGS_REG))] 14006 "TARGET_BMI" 14007 "blsi\t{%1, %0|%0, %1}" 14008 [(set_attr "type" "bitmanip") 14009 (set_attr "btver2_decode" "double") 14010 (set_attr "mode" "<MODE>")]) 14011 14012(define_insn "*bmi_blsmsk_<mode>" 14013 [(set (match_operand:SWI48 0 "register_operand" "=r") 14014 (xor:SWI48 14015 (plus:SWI48 14016 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14017 (const_int -1)) 14018 (match_dup 1))) 14019 (clobber (reg:CC FLAGS_REG))] 14020 "TARGET_BMI" 14021 "blsmsk\t{%1, %0|%0, %1}" 14022 [(set_attr "type" "bitmanip") 14023 (set_attr "btver2_decode" "double") 14024 (set_attr "mode" "<MODE>")]) 14025 14026(define_insn "*bmi_blsr_<mode>" 14027 [(set (match_operand:SWI48 0 "register_operand" "=r") 14028 (and:SWI48 14029 (plus:SWI48 14030 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14031 (const_int -1)) 14032 (match_dup 1))) 14033 (clobber (reg:CC FLAGS_REG))] 14034 "TARGET_BMI" 14035 "blsr\t{%1, %0|%0, %1}" 14036 [(set_attr "type" "bitmanip") 14037 (set_attr "btver2_decode" "double") 14038 (set_attr "mode" "<MODE>")]) 14039 14040(define_insn "*bmi_blsr_<mode>_cmp" 14041 [(set (reg:CCZ FLAGS_REG) 14042 (compare:CCZ 14043 (and:SWI48 14044 (plus:SWI48 14045 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14046 (const_int -1)) 14047 (match_dup 1)) 14048 (const_int 0))) 14049 (set (match_operand:SWI48 0 "register_operand" "=r") 14050 (and:SWI48 14051 (plus:SWI48 14052 (match_dup 1) 14053 (const_int -1)) 14054 (match_dup 1)))] 14055 "TARGET_BMI" 14056 "blsr\t{%1, %0|%0, %1}" 14057 [(set_attr "type" "bitmanip") 14058 (set_attr "btver2_decode" "double") 14059 (set_attr "mode" "<MODE>")]) 14060 14061(define_insn "*bmi_blsr_<mode>_ccz" 14062 [(set (reg:CCZ FLAGS_REG) 14063 (compare:CCZ 14064 (and:SWI48 14065 (plus:SWI48 14066 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14067 (const_int -1)) 14068 (match_dup 1)) 14069 (const_int 0))) 14070 (clobber (match_scratch:SWI48 0 "=r"))] 14071 "TARGET_BMI" 14072 "blsr\t{%1, %0|%0, %1}" 14073 [(set_attr "type" "bitmanip") 14074 (set_attr "btver2_decode" "double") 14075 (set_attr "mode" "<MODE>")]) 14076 14077;; BMI2 instructions. 14078(define_expand "bmi2_bzhi_<mode>3" 14079 [(parallel 14080 [(set (match_operand:SWI48 0 "register_operand") 14081 (if_then_else:SWI48 14082 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand") 14083 (const_int 255)) 14084 (const_int 0)) 14085 (zero_extract:SWI48 14086 (match_operand:SWI48 1 "nonimmediate_operand") 14087 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255)) 14088 (match_dup 3)) 14089 (const_int 0)) 14090 (const_int 0))) 14091 (clobber (reg:CC FLAGS_REG))])] 14092 "TARGET_BMI2" 14093 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);") 14094 14095(define_insn "*bmi2_bzhi_<mode>3" 14096 [(set (match_operand:SWI48 0 "register_operand" "=r") 14097 (if_then_else:SWI48 14098 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r") 14099 (const_int 255)) 14100 (const_int 0)) 14101 (zero_extract:SWI48 14102 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14103 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255)) 14104 (match_operand:SWI48 3 "const_int_operand" "n")) 14105 (const_int 0)) 14106 (const_int 0))) 14107 (clobber (reg:CC FLAGS_REG))] 14108 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 14109 "bzhi\t{%2, %1, %0|%0, %1, %2}" 14110 [(set_attr "type" "bitmanip") 14111 (set_attr "prefix" "vex") 14112 (set_attr "mode" "<MODE>")]) 14113 14114(define_insn "*bmi2_bzhi_<mode>3_1" 14115 [(set (match_operand:SWI48 0 "register_operand" "=r") 14116 (if_then_else:SWI48 14117 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0)) 14118 (zero_extract:SWI48 14119 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14120 (umin:SWI48 (zero_extend:SWI48 (match_dup 2)) 14121 (match_operand:SWI48 3 "const_int_operand" "n")) 14122 (const_int 0)) 14123 (const_int 0))) 14124 (clobber (reg:CC FLAGS_REG))] 14125 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 14126 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 14127 [(set_attr "type" "bitmanip") 14128 (set_attr "prefix" "vex") 14129 (set_attr "mode" "<MODE>")]) 14130 14131(define_insn "*bmi2_bzhi_<mode>3_1_ccz" 14132 [(set (reg:CCZ FLAGS_REG) 14133 (compare:CCZ 14134 (if_then_else:SWI48 14135 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0)) 14136 (zero_extract:SWI48 14137 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14138 (umin:SWI48 (zero_extend:SWI48 (match_dup 2)) 14139 (match_operand:SWI48 3 "const_int_operand" "n")) 14140 (const_int 0)) 14141 (const_int 0)) 14142 (const_int 0))) 14143 (clobber (match_scratch:SWI48 0 "=r"))] 14144 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT" 14145 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 14146 [(set_attr "type" "bitmanip") 14147 (set_attr "prefix" "vex") 14148 (set_attr "mode" "<MODE>")]) 14149 14150(define_insn "*bmi2_bzhi_<mode>3_2" 14151 [(set (match_operand:SWI48 0 "register_operand" "=r") 14152 (and:SWI48 14153 (plus:SWI48 14154 (ashift:SWI48 (const_int 1) 14155 (match_operand:QI 2 "register_operand" "r")) 14156 (const_int -1)) 14157 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14158 (clobber (reg:CC FLAGS_REG))] 14159 "TARGET_BMI2" 14160 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 14161 [(set_attr "type" "bitmanip") 14162 (set_attr "prefix" "vex") 14163 (set_attr "mode" "<MODE>")]) 14164 14165(define_insn "*bmi2_bzhi_<mode>3_3" 14166 [(set (match_operand:SWI48 0 "register_operand" "=r") 14167 (and:SWI48 14168 (not:SWI48 14169 (ashift:SWI48 (const_int -1) 14170 (match_operand:QI 2 "register_operand" "r"))) 14171 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14172 (clobber (reg:CC FLAGS_REG))] 14173 "TARGET_BMI2" 14174 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}" 14175 [(set_attr "type" "bitmanip") 14176 (set_attr "prefix" "vex") 14177 (set_attr "mode" "<MODE>")]) 14178 14179(define_insn "bmi2_pdep_<mode>3" 14180 [(set (match_operand:SWI48 0 "register_operand" "=r") 14181 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 14182 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 14183 UNSPEC_PDEP))] 14184 "TARGET_BMI2" 14185 "pdep\t{%2, %1, %0|%0, %1, %2}" 14186 [(set_attr "type" "bitmanip") 14187 (set_attr "prefix" "vex") 14188 (set_attr "mode" "<MODE>")]) 14189 14190(define_insn "bmi2_pext_<mode>3" 14191 [(set (match_operand:SWI48 0 "register_operand" "=r") 14192 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r") 14193 (match_operand:SWI48 2 "nonimmediate_operand" "rm")] 14194 UNSPEC_PEXT))] 14195 "TARGET_BMI2" 14196 "pext\t{%2, %1, %0|%0, %1, %2}" 14197 [(set_attr "type" "bitmanip") 14198 (set_attr "prefix" "vex") 14199 (set_attr "mode" "<MODE>")]) 14200 14201;; TBM instructions. 14202(define_expand "tbm_bextri_<mode>" 14203 [(parallel 14204 [(set (match_operand:SWI48 0 "register_operand") 14205 (zero_extract:SWI48 14206 (match_operand:SWI48 1 "nonimmediate_operand") 14207 (match_operand 2 "const_0_to_255_operand" "N") 14208 (match_operand 3 "const_0_to_255_operand" "N"))) 14209 (clobber (reg:CC FLAGS_REG))])] 14210 "TARGET_TBM" 14211{ 14212 if (operands[2] == const0_rtx 14213 || INTVAL (operands[3]) >= <MODE_SIZE> * BITS_PER_UNIT) 14214 { 14215 emit_move_insn (operands[0], const0_rtx); 14216 DONE; 14217 } 14218 if (INTVAL (operands[2]) + INTVAL (operands[3]) 14219 > <MODE_SIZE> * BITS_PER_UNIT) 14220 operands[2] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - INTVAL (operands[3])); 14221}) 14222 14223(define_insn "*tbm_bextri_<mode>" 14224 [(set (match_operand:SWI48 0 "register_operand" "=r") 14225 (zero_extract:SWI48 14226 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14227 (match_operand 2 "const_0_to_255_operand" "N") 14228 (match_operand 3 "const_0_to_255_operand" "N"))) 14229 (clobber (reg:CC FLAGS_REG))] 14230 "TARGET_TBM" 14231{ 14232 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3])); 14233 return "bextr\t{%2, %1, %0|%0, %1, %2}"; 14234} 14235 [(set_attr "type" "bitmanip") 14236 (set_attr "mode" "<MODE>")]) 14237 14238(define_insn "*tbm_blcfill_<mode>" 14239 [(set (match_operand:SWI48 0 "register_operand" "=r") 14240 (and:SWI48 14241 (plus:SWI48 14242 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14243 (const_int 1)) 14244 (match_dup 1))) 14245 (clobber (reg:CC FLAGS_REG))] 14246 "TARGET_TBM" 14247 "blcfill\t{%1, %0|%0, %1}" 14248 [(set_attr "type" "bitmanip") 14249 (set_attr "mode" "<MODE>")]) 14250 14251(define_insn "*tbm_blci_<mode>" 14252 [(set (match_operand:SWI48 0 "register_operand" "=r") 14253 (ior:SWI48 14254 (not:SWI48 14255 (plus:SWI48 14256 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14257 (const_int 1))) 14258 (match_dup 1))) 14259 (clobber (reg:CC FLAGS_REG))] 14260 "TARGET_TBM" 14261 "blci\t{%1, %0|%0, %1}" 14262 [(set_attr "type" "bitmanip") 14263 (set_attr "mode" "<MODE>")]) 14264 14265(define_insn "*tbm_blcic_<mode>" 14266 [(set (match_operand:SWI48 0 "register_operand" "=r") 14267 (and:SWI48 14268 (plus:SWI48 14269 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14270 (const_int 1)) 14271 (not:SWI48 14272 (match_dup 1)))) 14273 (clobber (reg:CC FLAGS_REG))] 14274 "TARGET_TBM" 14275 "blcic\t{%1, %0|%0, %1}" 14276 [(set_attr "type" "bitmanip") 14277 (set_attr "mode" "<MODE>")]) 14278 14279(define_insn "*tbm_blcmsk_<mode>" 14280 [(set (match_operand:SWI48 0 "register_operand" "=r") 14281 (xor:SWI48 14282 (plus:SWI48 14283 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14284 (const_int 1)) 14285 (match_dup 1))) 14286 (clobber (reg:CC FLAGS_REG))] 14287 "TARGET_TBM" 14288 "blcmsk\t{%1, %0|%0, %1}" 14289 [(set_attr "type" "bitmanip") 14290 (set_attr "mode" "<MODE>")]) 14291 14292(define_insn "*tbm_blcs_<mode>" 14293 [(set (match_operand:SWI48 0 "register_operand" "=r") 14294 (ior:SWI48 14295 (plus:SWI48 14296 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14297 (const_int 1)) 14298 (match_dup 1))) 14299 (clobber (reg:CC FLAGS_REG))] 14300 "TARGET_TBM" 14301 "blcs\t{%1, %0|%0, %1}" 14302 [(set_attr "type" "bitmanip") 14303 (set_attr "mode" "<MODE>")]) 14304 14305(define_insn "*tbm_blsfill_<mode>" 14306 [(set (match_operand:SWI48 0 "register_operand" "=r") 14307 (ior:SWI48 14308 (plus:SWI48 14309 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14310 (const_int -1)) 14311 (match_dup 1))) 14312 (clobber (reg:CC FLAGS_REG))] 14313 "TARGET_TBM" 14314 "blsfill\t{%1, %0|%0, %1}" 14315 [(set_attr "type" "bitmanip") 14316 (set_attr "mode" "<MODE>")]) 14317 14318(define_insn "*tbm_blsic_<mode>" 14319 [(set (match_operand:SWI48 0 "register_operand" "=r") 14320 (ior:SWI48 14321 (plus:SWI48 14322 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14323 (const_int -1)) 14324 (not:SWI48 14325 (match_dup 1)))) 14326 (clobber (reg:CC FLAGS_REG))] 14327 "TARGET_TBM" 14328 "blsic\t{%1, %0|%0, %1}" 14329 [(set_attr "type" "bitmanip") 14330 (set_attr "mode" "<MODE>")]) 14331 14332(define_insn "*tbm_t1mskc_<mode>" 14333 [(set (match_operand:SWI48 0 "register_operand" "=r") 14334 (ior:SWI48 14335 (plus:SWI48 14336 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14337 (const_int 1)) 14338 (not:SWI48 14339 (match_dup 1)))) 14340 (clobber (reg:CC FLAGS_REG))] 14341 "TARGET_TBM" 14342 "t1mskc\t{%1, %0|%0, %1}" 14343 [(set_attr "type" "bitmanip") 14344 (set_attr "mode" "<MODE>")]) 14345 14346(define_insn "*tbm_tzmsk_<mode>" 14347 [(set (match_operand:SWI48 0 "register_operand" "=r") 14348 (and:SWI48 14349 (plus:SWI48 14350 (match_operand:SWI48 1 "nonimmediate_operand" "rm") 14351 (const_int -1)) 14352 (not:SWI48 14353 (match_dup 1)))) 14354 (clobber (reg:CC FLAGS_REG))] 14355 "TARGET_TBM" 14356 "tzmsk\t{%1, %0|%0, %1}" 14357 [(set_attr "type" "bitmanip") 14358 (set_attr "mode" "<MODE>")]) 14359 14360(define_insn_and_split "popcount<mode>2" 14361 [(set (match_operand:SWI48 0 "register_operand" "=r") 14362 (popcount:SWI48 14363 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14364 (clobber (reg:CC FLAGS_REG))] 14365 "TARGET_POPCNT" 14366{ 14367#if TARGET_MACHO 14368 return "popcnt\t{%1, %0|%0, %1}"; 14369#else 14370 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 14371#endif 14372} 14373 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 14374 && optimize_function_for_speed_p (cfun) 14375 && !reg_mentioned_p (operands[0], operands[1])" 14376 [(parallel 14377 [(set (match_dup 0) 14378 (popcount:SWI48 (match_dup 1))) 14379 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 14380 (clobber (reg:CC FLAGS_REG))])] 14381 "ix86_expand_clear (operands[0]);" 14382 [(set_attr "prefix_rep" "1") 14383 (set_attr "type" "bitmanip") 14384 (set_attr "mode" "<MODE>")]) 14385 14386; False dependency happens when destination is only updated by tzcnt, 14387; lzcnt or popcnt. There is no false dependency when destination is 14388; also used in source. 14389(define_insn "*popcount<mode>2_falsedep" 14390 [(set (match_operand:SWI48 0 "register_operand" "=r") 14391 (popcount:SWI48 14392 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))) 14393 (unspec [(match_operand:SWI48 2 "register_operand" "0")] 14394 UNSPEC_INSN_FALSE_DEP) 14395 (clobber (reg:CC FLAGS_REG))] 14396 "TARGET_POPCNT" 14397{ 14398#if TARGET_MACHO 14399 return "popcnt\t{%1, %0|%0, %1}"; 14400#else 14401 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}"; 14402#endif 14403} 14404 [(set_attr "prefix_rep" "1") 14405 (set_attr "type" "bitmanip") 14406 (set_attr "mode" "<MODE>")]) 14407 14408(define_insn_and_split "*popcountsi2_zext" 14409 [(set (match_operand:DI 0 "register_operand" "=r") 14410 (and:DI 14411 (subreg:DI 14412 (popcount:SI 14413 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0) 14414 (const_int 63))) 14415 (clobber (reg:CC FLAGS_REG))] 14416 "TARGET_POPCNT && TARGET_64BIT" 14417{ 14418#if TARGET_MACHO 14419 return "popcnt\t{%1, %k0|%k0, %1}"; 14420#else 14421 return "popcnt{l}\t{%1, %k0|%k0, %1}"; 14422#endif 14423} 14424 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed 14425 && optimize_function_for_speed_p (cfun) 14426 && !reg_mentioned_p (operands[0], operands[1])" 14427 [(parallel 14428 [(set (match_dup 0) 14429 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63))) 14430 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP) 14431 (clobber (reg:CC FLAGS_REG))])] 14432 "ix86_expand_clear (operands[0]);" 14433 [(set_attr "prefix_rep" "1") 14434 (set_attr "type" "bitmanip") 14435 (set_attr "mode" "SI")]) 14436 14437; False dependency happens when destination is only updated by tzcnt, 14438; lzcnt or popcnt. There is no false dependency when destination is 14439; also used in source. 14440(define_insn "*popcountsi2_zext_falsedep" 14441 [(set (match_operand:DI 0 "register_operand" "=r") 14442 (and:DI 14443 (subreg:DI 14444 (popcount:SI 14445 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0) 14446 (const_int 63))) 14447 (unspec [(match_operand:DI 2 "register_operand" "0")] 14448 UNSPEC_INSN_FALSE_DEP) 14449 (clobber (reg:CC FLAGS_REG))] 14450 "TARGET_POPCNT && TARGET_64BIT" 14451{ 14452#if TARGET_MACHO 14453 return "popcnt\t{%1, %k0|%k0, %1}"; 14454#else 14455 return "popcnt{l}\t{%1, %k0|%k0, %1}"; 14456#endif 14457} 14458 [(set_attr "prefix_rep" "1") 14459 (set_attr "type" "bitmanip") 14460 (set_attr "mode" "SI")]) 14461 14462(define_insn_and_split "*popcounthi2_1" 14463 [(set (match_operand:SI 0 "register_operand") 14464 (popcount:SI 14465 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand")))) 14466 (clobber (reg:CC FLAGS_REG))] 14467 "TARGET_POPCNT 14468 && ix86_pre_reload_split ()" 14469 "#" 14470 "&& 1" 14471 [(const_int 0)] 14472{ 14473 rtx tmp = gen_reg_rtx (HImode); 14474 14475 emit_insn (gen_popcounthi2 (tmp, operands[1])); 14476 emit_insn (gen_zero_extendhisi2 (operands[0], tmp)); 14477 DONE; 14478}) 14479 14480(define_insn "popcounthi2" 14481 [(set (match_operand:HI 0 "register_operand" "=r") 14482 (popcount:HI 14483 (match_operand:HI 1 "nonimmediate_operand" "rm"))) 14484 (clobber (reg:CC FLAGS_REG))] 14485 "TARGET_POPCNT" 14486{ 14487#if TARGET_MACHO 14488 return "popcnt\t{%1, %0|%0, %1}"; 14489#else 14490 return "popcnt{w}\t{%1, %0|%0, %1}"; 14491#endif 14492} 14493 [(set_attr "prefix_rep" "1") 14494 (set_attr "type" "bitmanip") 14495 (set_attr "mode" "HI")]) 14496 14497(define_expand "bswapdi2" 14498 [(set (match_operand:DI 0 "register_operand") 14499 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))] 14500 "TARGET_64BIT" 14501{ 14502 if (!TARGET_MOVBE) 14503 operands[1] = force_reg (DImode, operands[1]); 14504}) 14505 14506(define_expand "bswapsi2" 14507 [(set (match_operand:SI 0 "register_operand") 14508 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))] 14509 "" 14510{ 14511 if (TARGET_MOVBE) 14512 ; 14513 else if (TARGET_BSWAP) 14514 operands[1] = force_reg (SImode, operands[1]); 14515 else 14516 { 14517 rtx x = operands[0]; 14518 14519 emit_move_insn (x, operands[1]); 14520 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 14521 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16))); 14522 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x))); 14523 DONE; 14524 } 14525}) 14526 14527(define_insn "*bswap<mode>2_movbe" 14528 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m") 14529 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))] 14530 "TARGET_MOVBE 14531 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 14532 "@ 14533 bswap\t%0 14534 movbe{<imodesuffix>}\t{%1, %0|%0, %1} 14535 movbe{<imodesuffix>}\t{%1, %0|%0, %1}" 14536 [(set_attr "type" "bitmanip,imov,imov") 14537 (set_attr "modrm" "0,1,1") 14538 (set_attr "prefix_0f" "*,1,1") 14539 (set_attr "prefix_extra" "*,1,1") 14540 (set_attr "mode" "<MODE>")]) 14541 14542(define_insn "*bswap<mode>2" 14543 [(set (match_operand:SWI48 0 "register_operand" "=r") 14544 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))] 14545 "TARGET_BSWAP" 14546 "bswap\t%0" 14547 [(set_attr "type" "bitmanip") 14548 (set_attr "modrm" "0") 14549 (set_attr "mode" "<MODE>")]) 14550 14551(define_expand "bswaphi2" 14552 [(set (match_operand:HI 0 "register_operand") 14553 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))] 14554 "TARGET_MOVBE") 14555 14556(define_insn "*bswaphi2_movbe" 14557 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m") 14558 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))] 14559 "TARGET_MOVBE 14560 && !(MEM_P (operands[0]) && MEM_P (operands[1]))" 14561 "@ 14562 xchg{b}\t{%h0, %b0|%b0, %h0} 14563 movbe{w}\t{%1, %0|%0, %1} 14564 movbe{w}\t{%1, %0|%0, %1}" 14565 [(set_attr "type" "imov") 14566 (set_attr "modrm" "*,1,1") 14567 (set_attr "prefix_0f" "*,1,1") 14568 (set_attr "prefix_extra" "*,1,1") 14569 (set_attr "pent_pair" "np,*,*") 14570 (set_attr "athlon_decode" "vector,*,*") 14571 (set_attr "amdfam10_decode" "double,*,*") 14572 (set_attr "bdver1_decode" "double,*,*") 14573 (set_attr "mode" "QI,HI,HI")]) 14574 14575(define_peephole2 14576 [(set (match_operand:HI 0 "general_reg_operand") 14577 (bswap:HI (match_dup 0)))] 14578 "TARGET_MOVBE 14579 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)) 14580 && peep2_regno_dead_p (0, FLAGS_REG)" 14581 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8))) 14582 (clobber (reg:CC FLAGS_REG))])]) 14583 14584(define_insn "bswaphi_lowpart" 14585 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r")) 14586 (bswap:HI (match_dup 0))) 14587 (clobber (reg:CC FLAGS_REG))] 14588 "" 14589 "@ 14590 xchg{b}\t{%h0, %b0|%b0, %h0} 14591 rol{w}\t{$8, %0|%0, 8}" 14592 [(set (attr "preferred_for_size") 14593 (cond [(eq_attr "alternative" "0") 14594 (symbol_ref "true")] 14595 (symbol_ref "false"))) 14596 (set (attr "preferred_for_speed") 14597 (cond [(eq_attr "alternative" "0") 14598 (symbol_ref "TARGET_USE_XCHGB")] 14599 (symbol_ref "!TARGET_USE_XCHGB"))) 14600 (set_attr "length" "2,4") 14601 (set_attr "mode" "QI,HI")]) 14602 14603(define_expand "paritydi2" 14604 [(set (match_operand:DI 0 "register_operand") 14605 (parity:DI (match_operand:DI 1 "register_operand")))] 14606 "! TARGET_POPCNT" 14607{ 14608 rtx scratch = gen_reg_rtx (QImode); 14609 14610 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, 14611 NULL_RTX, operands[1])); 14612 14613 ix86_expand_setcc (scratch, ORDERED, 14614 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 14615 14616 if (TARGET_64BIT) 14617 emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); 14618 else 14619 { 14620 rtx tmp = gen_reg_rtx (SImode); 14621 14622 emit_insn (gen_zero_extendqisi2 (tmp, scratch)); 14623 emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); 14624 } 14625 DONE; 14626}) 14627 14628(define_expand "paritysi2" 14629 [(set (match_operand:SI 0 "register_operand") 14630 (parity:SI (match_operand:SI 1 "register_operand")))] 14631 "! TARGET_POPCNT" 14632{ 14633 rtx scratch = gen_reg_rtx (QImode); 14634 14635 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); 14636 14637 ix86_expand_setcc (scratch, ORDERED, 14638 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx); 14639 14640 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 14641 DONE; 14642}) 14643 14644(define_insn_and_split "paritydi2_cmp" 14645 [(set (reg:CC FLAGS_REG) 14646 (unspec:CC [(match_operand:DI 3 "register_operand" "0")] 14647 UNSPEC_PARITY)) 14648 (clobber (match_scratch:DI 0 "=r")) 14649 (clobber (match_scratch:SI 1 "=&r")) 14650 (clobber (match_scratch:HI 2 "=Q"))] 14651 "! TARGET_POPCNT" 14652 "#" 14653 "&& reload_completed" 14654 [(parallel 14655 [(set (match_dup 1) 14656 (xor:SI (match_dup 1) (match_dup 4))) 14657 (clobber (reg:CC FLAGS_REG))]) 14658 (parallel 14659 [(set (reg:CC FLAGS_REG) 14660 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 14661 (clobber (match_dup 1)) 14662 (clobber (match_dup 2))])] 14663{ 14664 operands[4] = gen_lowpart (SImode, operands[3]); 14665 14666 if (TARGET_64BIT) 14667 { 14668 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); 14669 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); 14670 } 14671 else 14672 operands[1] = gen_highpart (SImode, operands[3]); 14673}) 14674 14675(define_insn_and_split "paritysi2_cmp" 14676 [(set (reg:CC FLAGS_REG) 14677 (unspec:CC [(match_operand:SI 2 "register_operand" "0")] 14678 UNSPEC_PARITY)) 14679 (clobber (match_scratch:SI 0 "=r")) 14680 (clobber (match_scratch:HI 1 "=&Q"))] 14681 "! TARGET_POPCNT" 14682 "#" 14683 "&& reload_completed" 14684 [(parallel 14685 [(set (match_dup 1) 14686 (xor:HI (match_dup 1) (match_dup 3))) 14687 (clobber (reg:CC FLAGS_REG))]) 14688 (parallel 14689 [(set (reg:CC FLAGS_REG) 14690 (unspec:CC [(match_dup 1)] UNSPEC_PARITY)) 14691 (clobber (match_dup 1))])] 14692{ 14693 operands[3] = gen_lowpart (HImode, operands[2]); 14694 14695 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); 14696 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); 14697}) 14698 14699(define_insn "*parityhi2_cmp" 14700 [(set (reg:CC FLAGS_REG) 14701 (unspec:CC [(match_operand:HI 1 "register_operand" "0")] 14702 UNSPEC_PARITY)) 14703 (clobber (match_scratch:HI 0 "=Q"))] 14704 "! TARGET_POPCNT" 14705 "xor{b}\t{%h0, %b0|%b0, %h0}" 14706 [(set_attr "length" "2") 14707 (set_attr "mode" "HI")]) 14708 14709 14710;; Thread-local storage patterns for ELF. 14711;; 14712;; Note that these code sequences must appear exactly as shown 14713;; in order to allow linker relaxation. 14714 14715(define_insn "*tls_global_dynamic_32_gnu" 14716 [(set (match_operand:SI 0 "register_operand" "=a") 14717 (unspec:SI 14718 [(match_operand:SI 1 "register_operand" "Yb") 14719 (match_operand 2 "tls_symbolic_operand") 14720 (match_operand 3 "constant_call_address_operand" "Bz") 14721 (reg:SI SP_REG)] 14722 UNSPEC_TLS_GD)) 14723 (clobber (match_scratch:SI 4 "=d")) 14724 (clobber (match_scratch:SI 5 "=c")) 14725 (clobber (reg:CC FLAGS_REG))] 14726 "!TARGET_64BIT && TARGET_GNU_TLS" 14727{ 14728 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14729 output_asm_insn 14730 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands); 14731 else 14732 output_asm_insn 14733 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands); 14734 if (TARGET_SUN_TLS) 14735#ifdef HAVE_AS_IX86_TLSGDPLT 14736 return "call\t%a2@tlsgdplt"; 14737#else 14738 return "call\t%p3@plt"; 14739#endif 14740 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14741 return "call\t%P3"; 14742 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}"; 14743} 14744 [(set_attr "type" "multi") 14745 (set_attr "length" "12")]) 14746 14747(define_expand "tls_global_dynamic_32" 14748 [(parallel 14749 [(set (match_operand:SI 0 "register_operand") 14750 (unspec:SI [(match_operand:SI 2 "register_operand") 14751 (match_operand 1 "tls_symbolic_operand") 14752 (match_operand 3 "constant_call_address_operand") 14753 (reg:SI SP_REG)] 14754 UNSPEC_TLS_GD)) 14755 (clobber (match_scratch:SI 4)) 14756 (clobber (match_scratch:SI 5)) 14757 (clobber (reg:CC FLAGS_REG))])] 14758 "" 14759 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14760 14761(define_insn "*tls_global_dynamic_64_<mode>" 14762 [(set (match_operand:P 0 "register_operand" "=a") 14763 (call:P 14764 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz")) 14765 (match_operand 3))) 14766 (unspec:P [(match_operand 1 "tls_symbolic_operand") 14767 (reg:P SP_REG)] 14768 UNSPEC_TLS_GD)] 14769 "TARGET_64BIT" 14770{ 14771 if (!TARGET_X32) 14772 /* The .loc directive has effect for 'the immediately following assembly 14773 instruction'. So for a sequence: 14774 .loc f l 14775 .byte x 14776 insn1 14777 the 'immediately following assembly instruction' is insn1. 14778 We want to emit an insn prefix here, but if we use .byte (as shown in 14779 'ELF Handling For Thread-Local Storage'), a preceding .loc will point 14780 inside the insn sequence, rather than to the start. After relaxation 14781 of the sequence by the linker, the .loc might point inside an insn. 14782 Use data16 prefix instead, which doesn't have this problem. */ 14783 fputs ("\tdata16", asm_out_file); 14784 output_asm_insn 14785 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 14786 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14787 fputs (ASM_SHORT "0x6666\n", asm_out_file); 14788 else 14789 fputs (ASM_BYTE "0x66\n", asm_out_file); 14790 fputs ("\trex64\n", asm_out_file); 14791 if (TARGET_SUN_TLS) 14792 return "call\t%p2@plt"; 14793 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14794 return "call\t%P2"; 14795 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}"; 14796} 14797 [(set_attr "type" "multi") 14798 (set (attr "length") 14799 (symbol_ref "TARGET_X32 ? 15 : 16"))]) 14800 14801(define_insn "*tls_global_dynamic_64_largepic" 14802 [(set (match_operand:DI 0 "register_operand" "=a") 14803 (call:DI 14804 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b") 14805 (match_operand:DI 3 "immediate_operand" "i"))) 14806 (match_operand 4))) 14807 (unspec:DI [(match_operand 1 "tls_symbolic_operand") 14808 (reg:DI SP_REG)] 14809 UNSPEC_TLS_GD)] 14810 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 14811 && GET_CODE (operands[3]) == CONST 14812 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC 14813 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF" 14814{ 14815 output_asm_insn 14816 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands); 14817 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands); 14818 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands); 14819 return "call\t{*%%rax|rax}"; 14820} 14821 [(set_attr "type" "multi") 14822 (set_attr "length" "22")]) 14823 14824(define_expand "@tls_global_dynamic_64_<mode>" 14825 [(parallel 14826 [(set (match_operand:P 0 "register_operand") 14827 (call:P 14828 (mem:QI (match_operand 2)) 14829 (const_int 0))) 14830 (unspec:P [(match_operand 1 "tls_symbolic_operand") 14831 (reg:P SP_REG)] 14832 UNSPEC_TLS_GD)])] 14833 "TARGET_64BIT" 14834 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14835 14836(define_insn "*tls_local_dynamic_base_32_gnu" 14837 [(set (match_operand:SI 0 "register_operand" "=a") 14838 (unspec:SI 14839 [(match_operand:SI 1 "register_operand" "Yb") 14840 (match_operand 2 "constant_call_address_operand" "Bz") 14841 (reg:SI SP_REG)] 14842 UNSPEC_TLS_LD_BASE)) 14843 (clobber (match_scratch:SI 3 "=d")) 14844 (clobber (match_scratch:SI 4 "=c")) 14845 (clobber (reg:CC FLAGS_REG))] 14846 "!TARGET_64BIT && TARGET_GNU_TLS" 14847{ 14848 output_asm_insn 14849 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands); 14850 if (TARGET_SUN_TLS) 14851 { 14852 if (HAVE_AS_IX86_TLSLDMPLT) 14853 return "call\t%&@tlsldmplt"; 14854 else 14855 return "call\t%p2@plt"; 14856 } 14857 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14858 return "call\t%P2"; 14859 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}"; 14860} 14861 [(set_attr "type" "multi") 14862 (set_attr "length" "11")]) 14863 14864(define_expand "tls_local_dynamic_base_32" 14865 [(parallel 14866 [(set (match_operand:SI 0 "register_operand") 14867 (unspec:SI 14868 [(match_operand:SI 1 "register_operand") 14869 (match_operand 2 "constant_call_address_operand") 14870 (reg:SI SP_REG)] 14871 UNSPEC_TLS_LD_BASE)) 14872 (clobber (match_scratch:SI 3)) 14873 (clobber (match_scratch:SI 4)) 14874 (clobber (reg:CC FLAGS_REG))])] 14875 "" 14876 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14877 14878(define_insn "*tls_local_dynamic_base_64_<mode>" 14879 [(set (match_operand:P 0 "register_operand" "=a") 14880 (call:P 14881 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz")) 14882 (match_operand 2))) 14883 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)] 14884 "TARGET_64BIT" 14885{ 14886 output_asm_insn 14887 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 14888 if (TARGET_SUN_TLS) 14889 return "call\t%p1@plt"; 14890 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT) 14891 return "call\t%P1"; 14892 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}"; 14893} 14894 [(set_attr "type" "multi") 14895 (set_attr "length" "12")]) 14896 14897(define_insn "*tls_local_dynamic_base_64_largepic" 14898 [(set (match_operand:DI 0 "register_operand" "=a") 14899 (call:DI 14900 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b") 14901 (match_operand:DI 2 "immediate_operand" "i"))) 14902 (match_operand 3))) 14903 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)] 14904 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF 14905 && GET_CODE (operands[2]) == CONST 14906 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC 14907 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF" 14908{ 14909 output_asm_insn 14910 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands); 14911 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands); 14912 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands); 14913 return "call\t{*%%rax|rax}"; 14914} 14915 [(set_attr "type" "multi") 14916 (set_attr "length" "22")]) 14917 14918(define_expand "@tls_local_dynamic_base_64_<mode>" 14919 [(parallel 14920 [(set (match_operand:P 0 "register_operand") 14921 (call:P 14922 (mem:QI (match_operand 1)) 14923 (const_int 0))) 14924 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])] 14925 "TARGET_64BIT" 14926 "ix86_tls_descriptor_calls_expanded_in_cfun = true;") 14927 14928;; Local dynamic of a single variable is a lose. Show combine how 14929;; to convert that back to global dynamic. 14930 14931(define_insn_and_split "*tls_local_dynamic_32_once" 14932 [(set (match_operand:SI 0 "register_operand" "=a") 14933 (plus:SI 14934 (unspec:SI [(match_operand:SI 1 "register_operand" "b") 14935 (match_operand 2 "constant_call_address_operand" "Bz") 14936 (reg:SI SP_REG)] 14937 UNSPEC_TLS_LD_BASE) 14938 (const:SI (unspec:SI 14939 [(match_operand 3 "tls_symbolic_operand")] 14940 UNSPEC_DTPOFF)))) 14941 (clobber (match_scratch:SI 4 "=d")) 14942 (clobber (match_scratch:SI 5 "=c")) 14943 (clobber (reg:CC FLAGS_REG))] 14944 "" 14945 "#" 14946 "" 14947 [(parallel 14948 [(set (match_dup 0) 14949 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2) 14950 (reg:SI SP_REG)] 14951 UNSPEC_TLS_GD)) 14952 (clobber (match_dup 4)) 14953 (clobber (match_dup 5)) 14954 (clobber (reg:CC FLAGS_REG))])]) 14955 14956;; Load and add the thread base pointer from %<tp_seg>:0. 14957(define_insn_and_split "*load_tp_<mode>" 14958 [(set (match_operand:PTR 0 "register_operand" "=r") 14959 (unspec:PTR [(const_int 0)] UNSPEC_TP))] 14960 "" 14961 "#" 14962 "" 14963 [(set (match_dup 0) 14964 (match_dup 1))] 14965{ 14966 addr_space_t as = DEFAULT_TLS_SEG_REG; 14967 14968 operands[1] = gen_const_mem (<MODE>mode, const0_rtx); 14969 set_mem_addr_space (operands[1], as); 14970}) 14971 14972(define_insn_and_split "*load_tp_x32_zext" 14973 [(set (match_operand:DI 0 "register_operand" "=r") 14974 (zero_extend:DI 14975 (unspec:SI [(const_int 0)] UNSPEC_TP)))] 14976 "TARGET_X32" 14977 "#" 14978 "" 14979 [(set (match_dup 0) 14980 (zero_extend:DI (match_dup 1)))] 14981{ 14982 addr_space_t as = DEFAULT_TLS_SEG_REG; 14983 14984 operands[1] = gen_const_mem (SImode, const0_rtx); 14985 set_mem_addr_space (operands[1], as); 14986}) 14987 14988(define_insn_and_split "*add_tp_<mode>" 14989 [(set (match_operand:PTR 0 "register_operand" "=r") 14990 (plus:PTR 14991 (unspec:PTR [(const_int 0)] UNSPEC_TP) 14992 (match_operand:PTR 1 "register_operand" "0"))) 14993 (clobber (reg:CC FLAGS_REG))] 14994 "" 14995 "#" 14996 "" 14997 [(parallel 14998 [(set (match_dup 0) 14999 (plus:PTR (match_dup 1) (match_dup 2))) 15000 (clobber (reg:CC FLAGS_REG))])] 15001{ 15002 addr_space_t as = DEFAULT_TLS_SEG_REG; 15003 15004 operands[2] = gen_const_mem (<MODE>mode, const0_rtx); 15005 set_mem_addr_space (operands[2], as); 15006}) 15007 15008(define_insn_and_split "*add_tp_x32_zext" 15009 [(set (match_operand:DI 0 "register_operand" "=r") 15010 (zero_extend:DI 15011 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP) 15012 (match_operand:SI 1 "register_operand" "0")))) 15013 (clobber (reg:CC FLAGS_REG))] 15014 "TARGET_X32" 15015 "#" 15016 "" 15017 [(parallel 15018 [(set (match_dup 0) 15019 (zero_extend:DI 15020 (plus:SI (match_dup 1) (match_dup 2)))) 15021 (clobber (reg:CC FLAGS_REG))])] 15022{ 15023 addr_space_t as = DEFAULT_TLS_SEG_REG; 15024 15025 operands[2] = gen_const_mem (SImode, const0_rtx); 15026 set_mem_addr_space (operands[2], as); 15027}) 15028 15029;; The Sun linker took the AMD64 TLS spec literally and can only handle 15030;; %rax as destination of the initial executable code sequence. 15031(define_insn "tls_initial_exec_64_sun" 15032 [(set (match_operand:DI 0 "register_operand" "=a") 15033 (unspec:DI 15034 [(match_operand 1 "tls_symbolic_operand")] 15035 UNSPEC_TLS_IE_SUN)) 15036 (clobber (reg:CC FLAGS_REG))] 15037 "TARGET_64BIT && TARGET_SUN_TLS" 15038{ 15039 output_asm_insn 15040 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands); 15041 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}"; 15042} 15043 [(set_attr "type" "multi")]) 15044 15045;; GNU2 TLS patterns can be split. 15046 15047(define_expand "tls_dynamic_gnu2_32" 15048 [(set (match_dup 3) 15049 (plus:SI (match_operand:SI 2 "register_operand") 15050 (const:SI 15051 (unspec:SI [(match_operand 1 "tls_symbolic_operand")] 15052 UNSPEC_TLSDESC)))) 15053 (parallel 15054 [(set (match_operand:SI 0 "register_operand") 15055 (unspec:SI [(match_dup 1) (match_dup 3) 15056 (match_dup 2) (reg:SI SP_REG)] 15057 UNSPEC_TLSDESC)) 15058 (clobber (reg:CC FLAGS_REG))])] 15059 "!TARGET_64BIT && TARGET_GNU2_TLS" 15060{ 15061 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 15062 ix86_tls_descriptor_calls_expanded_in_cfun = true; 15063}) 15064 15065(define_insn "*tls_dynamic_gnu2_lea_32" 15066 [(set (match_operand:SI 0 "register_operand" "=r") 15067 (plus:SI (match_operand:SI 1 "register_operand" "b") 15068 (const:SI 15069 (unspec:SI [(match_operand 2 "tls_symbolic_operand")] 15070 UNSPEC_TLSDESC))))] 15071 "!TARGET_64BIT && TARGET_GNU2_TLS" 15072 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}" 15073 [(set_attr "type" "lea") 15074 (set_attr "mode" "SI") 15075 (set_attr "length" "6") 15076 (set_attr "length_address" "4")]) 15077 15078(define_insn "*tls_dynamic_gnu2_call_32" 15079 [(set (match_operand:SI 0 "register_operand" "=a") 15080 (unspec:SI [(match_operand 1 "tls_symbolic_operand") 15081 (match_operand:SI 2 "register_operand" "0") 15082 ;; we have to make sure %ebx still points to the GOT 15083 (match_operand:SI 3 "register_operand" "b") 15084 (reg:SI SP_REG)] 15085 UNSPEC_TLSDESC)) 15086 (clobber (reg:CC FLAGS_REG))] 15087 "!TARGET_64BIT && TARGET_GNU2_TLS" 15088 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}" 15089 [(set_attr "type" "call") 15090 (set_attr "length" "2") 15091 (set_attr "length_address" "0")]) 15092 15093(define_insn_and_split "*tls_dynamic_gnu2_combine_32" 15094 [(set (match_operand:SI 0 "register_operand" "=&a") 15095 (plus:SI 15096 (unspec:SI [(match_operand 3 "tls_modbase_operand") 15097 (match_operand:SI 4) 15098 (match_operand:SI 2 "register_operand" "b") 15099 (reg:SI SP_REG)] 15100 UNSPEC_TLSDESC) 15101 (const:SI (unspec:SI 15102 [(match_operand 1 "tls_symbolic_operand")] 15103 UNSPEC_DTPOFF)))) 15104 (clobber (reg:CC FLAGS_REG))] 15105 "!TARGET_64BIT && TARGET_GNU2_TLS" 15106 "#" 15107 "" 15108 [(set (match_dup 0) (match_dup 5))] 15109{ 15110 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0]; 15111 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2])); 15112}) 15113 15114(define_expand "@tls_dynamic_gnu2_64_<mode>" 15115 [(set (match_dup 2) 15116 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")] 15117 UNSPEC_TLSDESC)) 15118 (parallel 15119 [(set (match_operand:PTR 0 "register_operand") 15120 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)] 15121 UNSPEC_TLSDESC)) 15122 (clobber (reg:CC FLAGS_REG))])] 15123 "TARGET_64BIT && TARGET_GNU2_TLS" 15124{ 15125 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0]; 15126 ix86_tls_descriptor_calls_expanded_in_cfun = true; 15127}) 15128 15129(define_insn "*tls_dynamic_gnu2_lea_64_<mode>" 15130 [(set (match_operand:PTR 0 "register_operand" "=r") 15131 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")] 15132 UNSPEC_TLSDESC))] 15133 "TARGET_64BIT && TARGET_GNU2_TLS" 15134 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}" 15135 [(set_attr "type" "lea") 15136 (set_attr "mode" "<MODE>") 15137 (set_attr "length" "7") 15138 (set_attr "length_address" "4")]) 15139 15140(define_insn "*tls_dynamic_gnu2_call_64_<mode>" 15141 [(set (match_operand:PTR 0 "register_operand" "=a") 15142 (unspec:PTR [(match_operand 1 "tls_symbolic_operand") 15143 (match_operand:PTR 2 "register_operand" "0") 15144 (reg:PTR SP_REG)] 15145 UNSPEC_TLSDESC)) 15146 (clobber (reg:CC FLAGS_REG))] 15147 "TARGET_64BIT && TARGET_GNU2_TLS" 15148 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}" 15149 [(set_attr "type" "call") 15150 (set_attr "length" "2") 15151 (set_attr "length_address" "0")]) 15152 15153(define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>" 15154 [(set (match_operand:PTR 0 "register_operand" "=&a") 15155 (plus:PTR 15156 (unspec:PTR [(match_operand 2 "tls_modbase_operand") 15157 (match_operand:PTR 3) 15158 (reg:PTR SP_REG)] 15159 UNSPEC_TLSDESC) 15160 (const:PTR (unspec:PTR 15161 [(match_operand 1 "tls_symbolic_operand")] 15162 UNSPEC_DTPOFF)))) 15163 (clobber (reg:CC FLAGS_REG))] 15164 "TARGET_64BIT && TARGET_GNU2_TLS" 15165 "#" 15166 "" 15167 [(set (match_dup 0) (match_dup 4))] 15168{ 15169 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0]; 15170 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1])); 15171}) 15172 15173(define_split 15174 [(match_operand 0 "tls_address_pattern")] 15175 "TARGET_TLS_DIRECT_SEG_REFS" 15176 [(match_dup 0)] 15177 "operands[0] = ix86_rewrite_tls_address (operands[0]);") 15178 15179 15180;; These patterns match the binary 387 instructions for addM3, subM3, 15181;; mulM3 and divM3. There are three patterns for each of DFmode and 15182;; SFmode. The first is the normal insn, the second the same insn but 15183;; with one operand a conversion, and the third the same insn but with 15184;; the other operand a conversion. The conversion may be SFmode or 15185;; SImode if the target mode DFmode, but only SImode if the target mode 15186;; is SFmode. 15187 15188;; Gcc is slightly more smart about handling normal two address instructions 15189;; so use special patterns for add and mull. 15190 15191(define_insn "*fop_xf_comm_i387" 15192 [(set (match_operand:XF 0 "register_operand" "=f") 15193 (match_operator:XF 3 "binary_fp_operator" 15194 [(match_operand:XF 1 "register_operand" "%0") 15195 (match_operand:XF 2 "register_operand" "f")]))] 15196 "TARGET_80387 15197 && COMMUTATIVE_ARITH_P (operands[3])" 15198 "* return output_387_binary_op (insn, operands);" 15199 [(set (attr "type") 15200 (if_then_else (match_operand:XF 3 "mult_operator") 15201 (const_string "fmul") 15202 (const_string "fop"))) 15203 (set_attr "mode" "XF")]) 15204 15205(define_insn "*fop_<mode>_comm" 15206 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v") 15207 (match_operator:MODEF 3 "binary_fp_operator" 15208 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v") 15209 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))] 15210 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15211 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))) 15212 && COMMUTATIVE_ARITH_P (operands[3]) 15213 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 15214 "* return output_387_binary_op (insn, operands);" 15215 [(set (attr "type") 15216 (if_then_else (eq_attr "alternative" "1,2") 15217 (if_then_else (match_operand:MODEF 3 "mult_operator") 15218 (const_string "ssemul") 15219 (const_string "sseadd")) 15220 (if_then_else (match_operand:MODEF 3 "mult_operator") 15221 (const_string "fmul") 15222 (const_string "fop")))) 15223 (set_attr "isa" "*,noavx,avx") 15224 (set_attr "prefix" "orig,orig,vex") 15225 (set_attr "mode" "<MODE>") 15226 (set (attr "enabled") 15227 (if_then_else 15228 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 15229 (if_then_else 15230 (eq_attr "alternative" "0") 15231 (symbol_ref "TARGET_MIX_SSE_I387 15232 && X87_ENABLE_ARITH (<MODE>mode)") 15233 (const_string "*")) 15234 (if_then_else 15235 (eq_attr "alternative" "0") 15236 (symbol_ref "true") 15237 (symbol_ref "false"))))]) 15238 15239(define_insn "*rcpsf2_sse" 15240 [(set (match_operand:SF 0 "register_operand" "=x,x,x") 15241 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")] 15242 UNSPEC_RCP))] 15243 "TARGET_SSE && TARGET_SSE_MATH" 15244 "@ 15245 %vrcpss\t{%d1, %0|%0, %d1} 15246 %vrcpss\t{%d1, %0|%0, %d1} 15247 %vrcpss\t{%1, %d0|%d0, %1}" 15248 [(set_attr "type" "sse") 15249 (set_attr "atom_sse_attr" "rcp") 15250 (set_attr "btver2_sse_attr" "rcp") 15251 (set_attr "prefix" "maybe_vex") 15252 (set_attr "mode" "SF") 15253 (set_attr "avx_partial_xmm_update" "false,false,true") 15254 (set (attr "preferred_for_speed") 15255 (cond [(match_test "TARGET_AVX") 15256 (symbol_ref "true") 15257 (eq_attr "alternative" "1,2") 15258 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY") 15259 ] 15260 (symbol_ref "true")))]) 15261 15262(define_insn "*fop_xf_1_i387" 15263 [(set (match_operand:XF 0 "register_operand" "=f,f") 15264 (match_operator:XF 3 "binary_fp_operator" 15265 [(match_operand:XF 1 "register_operand" "0,f") 15266 (match_operand:XF 2 "register_operand" "f,0")]))] 15267 "TARGET_80387 15268 && !COMMUTATIVE_ARITH_P (operands[3])" 15269 "* return output_387_binary_op (insn, operands);" 15270 [(set (attr "type") 15271 (if_then_else (match_operand:XF 3 "div_operator") 15272 (const_string "fdiv") 15273 (const_string "fop"))) 15274 (set_attr "mode" "XF")]) 15275 15276(define_insn "*fop_<mode>_1" 15277 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v") 15278 (match_operator:MODEF 3 "binary_fp_operator" 15279 [(match_operand:MODEF 1 15280 "x87nonimm_ssenomem_operand" "0,fm,0,v") 15281 (match_operand:MODEF 2 15282 "nonimmediate_operand" "fm,0,xm,vm")]))] 15283 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15284 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))) 15285 && !COMMUTATIVE_ARITH_P (operands[3]) 15286 && !(MEM_P (operands[1]) && MEM_P (operands[2]))" 15287 "* return output_387_binary_op (insn, operands);" 15288 [(set (attr "type") 15289 (if_then_else (eq_attr "alternative" "2,3") 15290 (if_then_else (match_operand:MODEF 3 "div_operator") 15291 (const_string "ssediv") 15292 (const_string "sseadd")) 15293 (if_then_else (match_operand:MODEF 3 "div_operator") 15294 (const_string "fdiv") 15295 (const_string "fop")))) 15296 (set_attr "isa" "*,*,noavx,avx") 15297 (set_attr "prefix" "orig,orig,orig,vex") 15298 (set_attr "mode" "<MODE>") 15299 (set (attr "enabled") 15300 (if_then_else 15301 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH")) 15302 (if_then_else 15303 (eq_attr "alternative" "0,1") 15304 (symbol_ref "TARGET_MIX_SSE_I387 15305 && X87_ENABLE_ARITH (<MODE>mode)") 15306 (const_string "*")) 15307 (if_then_else 15308 (eq_attr "alternative" "0,1") 15309 (symbol_ref "true") 15310 (symbol_ref "false"))))]) 15311 15312(define_insn "*fop_<X87MODEF:mode>_2_i387" 15313 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 15314 (match_operator:X87MODEF 3 "binary_fp_operator" 15315 [(float:X87MODEF 15316 (match_operand:SWI24 1 "nonimmediate_operand" "m")) 15317 (match_operand:X87MODEF 2 "register_operand" "0")]))] 15318 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode) 15319 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 15320 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 15321 || optimize_function_for_size_p (cfun))" 15322 "* return output_387_binary_op (insn, operands);" 15323 [(set (attr "type") 15324 (cond [(match_operand:X87MODEF 3 "mult_operator") 15325 (const_string "fmul") 15326 (match_operand:X87MODEF 3 "div_operator") 15327 (const_string "fdiv") 15328 ] 15329 (const_string "fop"))) 15330 (set_attr "fp_int_src" "true") 15331 (set_attr "mode" "<SWI24:MODE>")]) 15332 15333(define_insn "*fop_<X87MODEF:mode>_3_i387" 15334 [(set (match_operand:X87MODEF 0 "register_operand" "=f") 15335 (match_operator:X87MODEF 3 "binary_fp_operator" 15336 [(match_operand:X87MODEF 1 "register_operand" "0") 15337 (float:X87MODEF 15338 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))] 15339 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode) 15340 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 15341 && (TARGET_USE_<SWI24:MODE>MODE_FIOP 15342 || optimize_function_for_size_p (cfun))" 15343 "* return output_387_binary_op (insn, operands);" 15344 [(set (attr "type") 15345 (cond [(match_operand:X87MODEF 3 "mult_operator") 15346 (const_string "fmul") 15347 (match_operand:X87MODEF 3 "div_operator") 15348 (const_string "fdiv") 15349 ] 15350 (const_string "fop"))) 15351 (set_attr "fp_int_src" "true") 15352 (set_attr "mode" "<SWI24:MODE>")]) 15353 15354(define_insn "*fop_xf_4_i387" 15355 [(set (match_operand:XF 0 "register_operand" "=f,f") 15356 (match_operator:XF 3 "binary_fp_operator" 15357 [(float_extend:XF 15358 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0")) 15359 (match_operand:XF 2 "register_operand" "0,f")]))] 15360 "TARGET_80387" 15361 "* return output_387_binary_op (insn, operands);" 15362 [(set (attr "type") 15363 (cond [(match_operand:XF 3 "mult_operator") 15364 (const_string "fmul") 15365 (match_operand:XF 3 "div_operator") 15366 (const_string "fdiv") 15367 ] 15368 (const_string "fop"))) 15369 (set_attr "mode" "<MODE>")]) 15370 15371(define_insn "*fop_df_4_i387" 15372 [(set (match_operand:DF 0 "register_operand" "=f,f") 15373 (match_operator:DF 3 "binary_fp_operator" 15374 [(float_extend:DF 15375 (match_operand:SF 1 "nonimmediate_operand" "fm,0")) 15376 (match_operand:DF 2 "register_operand" "0,f")]))] 15377 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15378 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15379 "* return output_387_binary_op (insn, operands);" 15380 [(set (attr "type") 15381 (cond [(match_operand:DF 3 "mult_operator") 15382 (const_string "fmul") 15383 (match_operand:DF 3 "div_operator") 15384 (const_string "fdiv") 15385 ] 15386 (const_string "fop"))) 15387 (set_attr "mode" "SF")]) 15388 15389(define_insn "*fop_xf_5_i387" 15390 [(set (match_operand:XF 0 "register_operand" "=f,f") 15391 (match_operator:XF 3 "binary_fp_operator" 15392 [(match_operand:XF 1 "register_operand" "0,f") 15393 (float_extend:XF 15394 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 15395 "TARGET_80387" 15396 "* return output_387_binary_op (insn, operands);" 15397 [(set (attr "type") 15398 (cond [(match_operand:XF 3 "mult_operator") 15399 (const_string "fmul") 15400 (match_operand:XF 3 "div_operator") 15401 (const_string "fdiv") 15402 ] 15403 (const_string "fop"))) 15404 (set_attr "mode" "<MODE>")]) 15405 15406(define_insn "*fop_df_5_i387" 15407 [(set (match_operand:DF 0 "register_operand" "=f,f") 15408 (match_operator:DF 3 "binary_fp_operator" 15409 [(match_operand:DF 1 "register_operand" "0,f") 15410 (float_extend:DF 15411 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15412 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15413 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15414 "* return output_387_binary_op (insn, operands);" 15415 [(set (attr "type") 15416 (cond [(match_operand:DF 3 "mult_operator") 15417 (const_string "fmul") 15418 (match_operand:DF 3 "div_operator") 15419 (const_string "fdiv") 15420 ] 15421 (const_string "fop"))) 15422 (set_attr "mode" "SF")]) 15423 15424(define_insn "*fop_xf_6_i387" 15425 [(set (match_operand:XF 0 "register_operand" "=f,f") 15426 (match_operator:XF 3 "binary_fp_operator" 15427 [(float_extend:XF 15428 (match_operand:MODEF 1 "register_operand" "0,f")) 15429 (float_extend:XF 15430 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))] 15431 "TARGET_80387" 15432 "* return output_387_binary_op (insn, operands);" 15433 [(set (attr "type") 15434 (cond [(match_operand:XF 3 "mult_operator") 15435 (const_string "fmul") 15436 (match_operand:XF 3 "div_operator") 15437 (const_string "fdiv") 15438 ] 15439 (const_string "fop"))) 15440 (set_attr "mode" "<MODE>")]) 15441 15442(define_insn "*fop_df_6_i387" 15443 [(set (match_operand:DF 0 "register_operand" "=f,f") 15444 (match_operator:DF 3 "binary_fp_operator" 15445 [(float_extend:DF 15446 (match_operand:SF 1 "register_operand" "0,f")) 15447 (float_extend:DF 15448 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] 15449 "TARGET_80387 && X87_ENABLE_ARITH (DFmode) 15450 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 15451 "* return output_387_binary_op (insn, operands);" 15452 [(set (attr "type") 15453 (cond [(match_operand:DF 3 "mult_operator") 15454 (const_string "fmul") 15455 (match_operand:DF 3 "div_operator") 15456 (const_string "fdiv") 15457 ] 15458 (const_string "fop"))) 15459 (set_attr "mode" "SF")]) 15460 15461;; FPU special functions. 15462 15463;; This pattern implements a no-op XFmode truncation for 15464;; all fancy i386 XFmode math functions. 15465 15466(define_insn "truncxf<mode>2_i387_noop_unspec" 15467 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf") 15468 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")] 15469 UNSPEC_TRUNC_NOOP))] 15470 "TARGET_USE_FANCY_MATH_387" 15471 "* return output_387_reg_move (insn, operands);" 15472 [(set_attr "type" "fmov") 15473 (set_attr "mode" "<MODE>")]) 15474 15475(define_insn "sqrtxf2" 15476 [(set (match_operand:XF 0 "register_operand" "=f") 15477 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] 15478 "TARGET_USE_FANCY_MATH_387" 15479 "fsqrt" 15480 [(set_attr "type" "fpspc") 15481 (set_attr "mode" "XF") 15482 (set_attr "athlon_decode" "direct") 15483 (set_attr "amdfam10_decode" "direct") 15484 (set_attr "bdver1_decode" "direct")]) 15485 15486(define_insn "*rsqrtsf2_sse" 15487 [(set (match_operand:SF 0 "register_operand" "=x,x,x") 15488 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")] 15489 UNSPEC_RSQRT))] 15490 "TARGET_SSE && TARGET_SSE_MATH" 15491 "@ 15492 %vrsqrtss\t{%d1, %0|%0, %d1} 15493 %vrsqrtss\t{%d1, %0|%0, %d1} 15494 %vrsqrtss\t{%1, %d0|%d0, %1}" 15495 [(set_attr "type" "sse") 15496 (set_attr "atom_sse_attr" "rcp") 15497 (set_attr "btver2_sse_attr" "rcp") 15498 (set_attr "prefix" "maybe_vex") 15499 (set_attr "mode" "SF") 15500 (set_attr "avx_partial_xmm_update" "false,false,true") 15501 (set (attr "preferred_for_speed") 15502 (cond [(match_test "TARGET_AVX") 15503 (symbol_ref "true") 15504 (eq_attr "alternative" "1,2") 15505 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY") 15506 ] 15507 (symbol_ref "true")))]) 15508 15509(define_expand "rsqrtsf2" 15510 [(set (match_operand:SF 0 "register_operand") 15511 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")] 15512 UNSPEC_RSQRT))] 15513 "TARGET_SSE && TARGET_SSE_MATH" 15514{ 15515 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1); 15516 DONE; 15517}) 15518 15519(define_insn "*sqrt<mode>2_sse" 15520 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v") 15521 (sqrt:MODEF 15522 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))] 15523 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 15524 "@ 15525 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1} 15526 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1} 15527 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}" 15528 [(set_attr "type" "sse") 15529 (set_attr "atom_sse_attr" "sqrt") 15530 (set_attr "btver2_sse_attr" "sqrt") 15531 (set_attr "prefix" "maybe_vex") 15532 (set_attr "avx_partial_xmm_update" "false,false,true") 15533 (set_attr "mode" "<MODE>") 15534 (set (attr "preferred_for_speed") 15535 (cond [(match_test "TARGET_AVX") 15536 (symbol_ref "true") 15537 (eq_attr "alternative" "1,2") 15538 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY") 15539 ] 15540 (symbol_ref "true")))]) 15541 15542(define_expand "sqrt<mode>2" 15543 [(set (match_operand:MODEF 0 "register_operand") 15544 (sqrt:MODEF 15545 (match_operand:MODEF 1 "nonimmediate_operand")))] 15546 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode)) 15547 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 15548{ 15549 if (<MODE>mode == SFmode 15550 && TARGET_SSE && TARGET_SSE_MATH 15551 && TARGET_RECIP_SQRT 15552 && !optimize_function_for_size_p (cfun) 15553 && flag_finite_math_only && !flag_trapping_math 15554 && flag_unsafe_math_optimizations) 15555 { 15556 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0); 15557 DONE; 15558 } 15559 15560 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)) 15561 { 15562 rtx op0 = gen_reg_rtx (XFmode); 15563 rtx op1 = gen_reg_rtx (XFmode); 15564 15565 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15566 emit_insn (gen_sqrtxf2 (op0, op1)); 15567 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 15568 DONE; 15569 } 15570}) 15571 15572(define_expand "hypot<mode>3" 15573 [(use (match_operand:MODEF 0 "register_operand")) 15574 (use (match_operand:MODEF 1 "general_operand")) 15575 (use (match_operand:MODEF 2 "general_operand"))] 15576 "TARGET_USE_FANCY_MATH_387 15577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15578 || TARGET_MIX_SSE_I387) 15579 && flag_finite_math_only 15580 && flag_unsafe_math_optimizations" 15581{ 15582 rtx op0 = gen_reg_rtx (XFmode); 15583 rtx op1 = gen_reg_rtx (XFmode); 15584 rtx op2 = gen_reg_rtx (XFmode); 15585 15586 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15587 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15588 15589 emit_insn (gen_mulxf3 (op1, op1, op1)); 15590 emit_insn (gen_mulxf3 (op2, op2, op2)); 15591 emit_insn (gen_addxf3 (op0, op2, op1)); 15592 emit_insn (gen_sqrtxf2 (op0, op0)); 15593 15594 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 15595 DONE; 15596}) 15597 15598(define_insn "x86_fnstsw_1" 15599 [(set (match_operand:HI 0 "register_operand" "=a") 15600 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))] 15601 "TARGET_80387" 15602 "fnstsw\t%0" 15603 [(set_attr "length" "2") 15604 (set_attr "mode" "SI") 15605 (set_attr "unit" "i387")]) 15606 15607(define_insn "fpremxf4_i387" 15608 [(set (match_operand:XF 0 "register_operand" "=f") 15609 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15610 (match_operand:XF 3 "register_operand" "1")] 15611 UNSPEC_FPREM_F)) 15612 (set (match_operand:XF 1 "register_operand" "=f") 15613 (unspec:XF [(match_dup 2) (match_dup 3)] 15614 UNSPEC_FPREM_U)) 15615 (set (reg:CCFP FPSR_REG) 15616 (unspec:CCFP [(match_dup 2) (match_dup 3)] 15617 UNSPEC_C2_FLAG))] 15618 "TARGET_USE_FANCY_MATH_387 15619 && flag_finite_math_only" 15620 "fprem" 15621 [(set_attr "type" "fpspc") 15622 (set_attr "znver1_decode" "vector") 15623 (set_attr "mode" "XF")]) 15624 15625(define_expand "fmodxf3" 15626 [(use (match_operand:XF 0 "register_operand")) 15627 (use (match_operand:XF 1 "general_operand")) 15628 (use (match_operand:XF 2 "general_operand"))] 15629 "TARGET_USE_FANCY_MATH_387 15630 && flag_finite_math_only" 15631{ 15632 rtx_code_label *label = gen_label_rtx (); 15633 15634 rtx op1 = gen_reg_rtx (XFmode); 15635 rtx op2 = gen_reg_rtx (XFmode); 15636 15637 emit_move_insn (op2, operands[2]); 15638 emit_move_insn (op1, operands[1]); 15639 15640 emit_label (label); 15641 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 15642 ix86_emit_fp_unordered_jump (label); 15643 LABEL_NUSES (label) = 1; 15644 15645 emit_move_insn (operands[0], op1); 15646 DONE; 15647}) 15648 15649(define_expand "fmod<mode>3" 15650 [(use (match_operand:MODEF 0 "register_operand")) 15651 (use (match_operand:MODEF 1 "general_operand")) 15652 (use (match_operand:MODEF 2 "general_operand"))] 15653 "TARGET_USE_FANCY_MATH_387 15654 && flag_finite_math_only" 15655{ 15656 rtx (*gen_truncxf) (rtx, rtx); 15657 15658 rtx_code_label *label = gen_label_rtx (); 15659 15660 rtx op1 = gen_reg_rtx (XFmode); 15661 rtx op2 = gen_reg_rtx (XFmode); 15662 15663 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15664 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15665 15666 emit_label (label); 15667 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2)); 15668 ix86_emit_fp_unordered_jump (label); 15669 LABEL_NUSES (label) = 1; 15670 15671 /* Truncate the result properly for strict SSE math. */ 15672 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15673 && !TARGET_MIX_SSE_I387) 15674 gen_truncxf = gen_truncxf<mode>2; 15675 else 15676 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 15677 15678 emit_insn (gen_truncxf (operands[0], op1)); 15679 DONE; 15680}) 15681 15682(define_insn "fprem1xf4_i387" 15683 [(set (match_operand:XF 0 "register_operand" "=f") 15684 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15685 (match_operand:XF 3 "register_operand" "1")] 15686 UNSPEC_FPREM1_F)) 15687 (set (match_operand:XF 1 "register_operand" "=f") 15688 (unspec:XF [(match_dup 2) (match_dup 3)] 15689 UNSPEC_FPREM1_U)) 15690 (set (reg:CCFP FPSR_REG) 15691 (unspec:CCFP [(match_dup 2) (match_dup 3)] 15692 UNSPEC_C2_FLAG))] 15693 "TARGET_USE_FANCY_MATH_387 15694 && flag_finite_math_only" 15695 "fprem1" 15696 [(set_attr "type" "fpspc") 15697 (set_attr "znver1_decode" "vector") 15698 (set_attr "mode" "XF")]) 15699 15700(define_expand "remainderxf3" 15701 [(use (match_operand:XF 0 "register_operand")) 15702 (use (match_operand:XF 1 "general_operand")) 15703 (use (match_operand:XF 2 "general_operand"))] 15704 "TARGET_USE_FANCY_MATH_387 15705 && flag_finite_math_only" 15706{ 15707 rtx_code_label *label = gen_label_rtx (); 15708 15709 rtx op1 = gen_reg_rtx (XFmode); 15710 rtx op2 = gen_reg_rtx (XFmode); 15711 15712 emit_move_insn (op2, operands[2]); 15713 emit_move_insn (op1, operands[1]); 15714 15715 emit_label (label); 15716 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 15717 ix86_emit_fp_unordered_jump (label); 15718 LABEL_NUSES (label) = 1; 15719 15720 emit_move_insn (operands[0], op1); 15721 DONE; 15722}) 15723 15724(define_expand "remainder<mode>3" 15725 [(use (match_operand:MODEF 0 "register_operand")) 15726 (use (match_operand:MODEF 1 "general_operand")) 15727 (use (match_operand:MODEF 2 "general_operand"))] 15728 "TARGET_USE_FANCY_MATH_387 15729 && flag_finite_math_only" 15730{ 15731 rtx (*gen_truncxf) (rtx, rtx); 15732 15733 rtx_code_label *label = gen_label_rtx (); 15734 15735 rtx op1 = gen_reg_rtx (XFmode); 15736 rtx op2 = gen_reg_rtx (XFmode); 15737 15738 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15739 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15740 15741 emit_label (label); 15742 15743 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2)); 15744 ix86_emit_fp_unordered_jump (label); 15745 LABEL_NUSES (label) = 1; 15746 15747 /* Truncate the result properly for strict SSE math. */ 15748 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 15749 && !TARGET_MIX_SSE_I387) 15750 gen_truncxf = gen_truncxf<mode>2; 15751 else 15752 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec; 15753 15754 emit_insn (gen_truncxf (operands[0], op1)); 15755 DONE; 15756}) 15757 15758(define_int_iterator SINCOS 15759 [UNSPEC_SIN 15760 UNSPEC_COS]) 15761 15762(define_int_attr sincos 15763 [(UNSPEC_SIN "sin") 15764 (UNSPEC_COS "cos")]) 15765 15766(define_insn "<sincos>xf2" 15767 [(set (match_operand:XF 0 "register_operand" "=f") 15768 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 15769 SINCOS))] 15770 "TARGET_USE_FANCY_MATH_387 15771 && flag_unsafe_math_optimizations" 15772 "f<sincos>" 15773 [(set_attr "type" "fpspc") 15774 (set_attr "znver1_decode" "vector") 15775 (set_attr "mode" "XF")]) 15776 15777(define_expand "<sincos><mode>2" 15778 [(set (match_operand:MODEF 0 "register_operand") 15779 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")] 15780 SINCOS))] 15781 "TARGET_USE_FANCY_MATH_387 15782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15783 || TARGET_MIX_SSE_I387) 15784 && flag_unsafe_math_optimizations" 15785{ 15786 rtx op0 = gen_reg_rtx (XFmode); 15787 rtx op1 = gen_reg_rtx (XFmode); 15788 15789 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15790 emit_insn (gen_<sincos>xf2 (op0, op1)); 15791 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 15792 DONE; 15793}) 15794 15795(define_insn "sincosxf3" 15796 [(set (match_operand:XF 0 "register_operand" "=f") 15797 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15798 UNSPEC_SINCOS_COS)) 15799 (set (match_operand:XF 1 "register_operand" "=f") 15800 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))] 15801 "TARGET_USE_FANCY_MATH_387 15802 && flag_unsafe_math_optimizations" 15803 "fsincos" 15804 [(set_attr "type" "fpspc") 15805 (set_attr "znver1_decode" "vector") 15806 (set_attr "mode" "XF")]) 15807 15808(define_expand "sincos<mode>3" 15809 [(use (match_operand:MODEF 0 "register_operand")) 15810 (use (match_operand:MODEF 1 "register_operand")) 15811 (use (match_operand:MODEF 2 "general_operand"))] 15812 "TARGET_USE_FANCY_MATH_387 15813 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15814 || TARGET_MIX_SSE_I387) 15815 && flag_unsafe_math_optimizations" 15816{ 15817 rtx op0 = gen_reg_rtx (XFmode); 15818 rtx op1 = gen_reg_rtx (XFmode); 15819 rtx op2 = gen_reg_rtx (XFmode); 15820 15821 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15822 emit_insn (gen_sincosxf3 (op0, op1, op2)); 15823 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 15824 emit_insn (gen_truncxf<mode>2 (operands[1], op1)); 15825 DONE; 15826}) 15827 15828(define_insn "fptanxf4_i387" 15829 [(set (match_operand:SF 0 "register_operand" "=f") 15830 (match_operand:SF 3 "const1_operand")) 15831 (set (match_operand:XF 1 "register_operand" "=f") 15832 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 15833 UNSPEC_TAN))] 15834 "TARGET_USE_FANCY_MATH_387 15835 && flag_unsafe_math_optimizations" 15836 "fptan" 15837 [(set_attr "type" "fpspc") 15838 (set_attr "znver1_decode" "vector") 15839 (set_attr "mode" "XF")]) 15840 15841(define_expand "tanxf2" 15842 [(use (match_operand:XF 0 "register_operand")) 15843 (use (match_operand:XF 1 "register_operand"))] 15844 "TARGET_USE_FANCY_MATH_387 15845 && flag_unsafe_math_optimizations" 15846{ 15847 rtx one = gen_reg_rtx (SFmode); 15848 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], 15849 CONST1_RTX (SFmode))); 15850 DONE; 15851}) 15852 15853(define_expand "tan<mode>2" 15854 [(use (match_operand:MODEF 0 "register_operand")) 15855 (use (match_operand:MODEF 1 "general_operand"))] 15856 "TARGET_USE_FANCY_MATH_387 15857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15858 || TARGET_MIX_SSE_I387) 15859 && flag_unsafe_math_optimizations" 15860{ 15861 rtx op0 = gen_reg_rtx (XFmode); 15862 rtx op1 = gen_reg_rtx (XFmode); 15863 15864 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15865 emit_insn (gen_tanxf2 (op0, op1)); 15866 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 15867 DONE; 15868}) 15869 15870(define_insn "atan2xf3" 15871 [(set (match_operand:XF 0 "register_operand" "=f") 15872 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 15873 (match_operand:XF 1 "register_operand" "f")] 15874 UNSPEC_FPATAN)) 15875 (clobber (match_scratch:XF 3 "=1"))] 15876 "TARGET_USE_FANCY_MATH_387 15877 && flag_unsafe_math_optimizations" 15878 "fpatan" 15879 [(set_attr "type" "fpspc") 15880 (set_attr "znver1_decode" "vector") 15881 (set_attr "mode" "XF")]) 15882 15883(define_expand "atan2<mode>3" 15884 [(use (match_operand:MODEF 0 "register_operand")) 15885 (use (match_operand:MODEF 1 "general_operand")) 15886 (use (match_operand:MODEF 2 "general_operand"))] 15887 "TARGET_USE_FANCY_MATH_387 15888 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15889 || TARGET_MIX_SSE_I387) 15890 && flag_unsafe_math_optimizations" 15891{ 15892 rtx op0 = gen_reg_rtx (XFmode); 15893 rtx op1 = gen_reg_rtx (XFmode); 15894 rtx op2 = gen_reg_rtx (XFmode); 15895 15896 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 15897 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15898 15899 emit_insn (gen_atan2xf3 (op0, op1, op2)); 15900 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 15901 DONE; 15902}) 15903 15904(define_expand "atanxf2" 15905 [(parallel [(set (match_operand:XF 0 "register_operand") 15906 (unspec:XF [(match_dup 2) 15907 (match_operand:XF 1 "register_operand")] 15908 UNSPEC_FPATAN)) 15909 (clobber (match_scratch:XF 3))])] 15910 "TARGET_USE_FANCY_MATH_387 15911 && flag_unsafe_math_optimizations" 15912 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));") 15913 15914(define_expand "atan<mode>2" 15915 [(use (match_operand:MODEF 0 "register_operand")) 15916 (use (match_operand:MODEF 1 "general_operand"))] 15917 "TARGET_USE_FANCY_MATH_387 15918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15919 || TARGET_MIX_SSE_I387) 15920 && flag_unsafe_math_optimizations" 15921{ 15922 rtx op0 = gen_reg_rtx (XFmode); 15923 rtx op1 = gen_reg_rtx (XFmode); 15924 15925 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15926 emit_insn (gen_atanxf2 (op0, op1)); 15927 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 15928 DONE; 15929}) 15930 15931(define_expand "asinxf2" 15932 [(set (match_dup 2) 15933 (mult:XF (match_operand:XF 1 "register_operand") 15934 (match_dup 1))) 15935 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 15936 (set (match_dup 5) (sqrt:XF (match_dup 4))) 15937 (parallel [(set (match_operand:XF 0 "register_operand") 15938 (unspec:XF [(match_dup 5) (match_dup 1)] 15939 UNSPEC_FPATAN)) 15940 (clobber (match_scratch:XF 6))])] 15941 "TARGET_USE_FANCY_MATH_387 15942 && flag_unsafe_math_optimizations" 15943{ 15944 int i; 15945 15946 for (i = 2; i < 6; i++) 15947 operands[i] = gen_reg_rtx (XFmode); 15948 15949 emit_move_insn (operands[3], CONST1_RTX (XFmode)); 15950}) 15951 15952(define_expand "asin<mode>2" 15953 [(use (match_operand:MODEF 0 "register_operand")) 15954 (use (match_operand:MODEF 1 "general_operand"))] 15955 "TARGET_USE_FANCY_MATH_387 15956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15957 || TARGET_MIX_SSE_I387) 15958 && flag_unsafe_math_optimizations" 15959{ 15960 rtx op0 = gen_reg_rtx (XFmode); 15961 rtx op1 = gen_reg_rtx (XFmode); 15962 15963 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 15964 emit_insn (gen_asinxf2 (op0, op1)); 15965 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 15966 DONE; 15967}) 15968 15969(define_expand "acosxf2" 15970 [(set (match_dup 2) 15971 (mult:XF (match_operand:XF 1 "register_operand") 15972 (match_dup 1))) 15973 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2))) 15974 (set (match_dup 5) (sqrt:XF (match_dup 4))) 15975 (parallel [(set (match_operand:XF 0 "register_operand") 15976 (unspec:XF [(match_dup 1) (match_dup 5)] 15977 UNSPEC_FPATAN)) 15978 (clobber (match_scratch:XF 6))])] 15979 "TARGET_USE_FANCY_MATH_387 15980 && flag_unsafe_math_optimizations" 15981{ 15982 int i; 15983 15984 for (i = 2; i < 6; i++) 15985 operands[i] = gen_reg_rtx (XFmode); 15986 15987 emit_move_insn (operands[3], CONST1_RTX (XFmode)); 15988}) 15989 15990(define_expand "acos<mode>2" 15991 [(use (match_operand:MODEF 0 "register_operand")) 15992 (use (match_operand:MODEF 1 "general_operand"))] 15993 "TARGET_USE_FANCY_MATH_387 15994 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 15995 || TARGET_MIX_SSE_I387) 15996 && flag_unsafe_math_optimizations" 15997{ 15998 rtx op0 = gen_reg_rtx (XFmode); 15999 rtx op1 = gen_reg_rtx (XFmode); 16000 16001 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16002 emit_insn (gen_acosxf2 (op0, op1)); 16003 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16004 DONE; 16005}) 16006 16007(define_expand "sinhxf2" 16008 [(use (match_operand:XF 0 "register_operand")) 16009 (use (match_operand:XF 1 "register_operand"))] 16010 "TARGET_USE_FANCY_MATH_387 16011 && flag_finite_math_only 16012 && flag_unsafe_math_optimizations" 16013{ 16014 ix86_emit_i387_sinh (operands[0], operands[1]); 16015 DONE; 16016}) 16017 16018(define_expand "sinh<mode>2" 16019 [(use (match_operand:MODEF 0 "register_operand")) 16020 (use (match_operand:MODEF 1 "general_operand"))] 16021 "TARGET_USE_FANCY_MATH_387 16022 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16023 || TARGET_MIX_SSE_I387) 16024 && flag_finite_math_only 16025 && flag_unsafe_math_optimizations" 16026{ 16027 rtx op0 = gen_reg_rtx (XFmode); 16028 rtx op1 = gen_reg_rtx (XFmode); 16029 16030 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16031 emit_insn (gen_sinhxf2 (op0, op1)); 16032 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16033 DONE; 16034}) 16035 16036(define_expand "coshxf2" 16037 [(use (match_operand:XF 0 "register_operand")) 16038 (use (match_operand:XF 1 "register_operand"))] 16039 "TARGET_USE_FANCY_MATH_387 16040 && flag_unsafe_math_optimizations" 16041{ 16042 ix86_emit_i387_cosh (operands[0], operands[1]); 16043 DONE; 16044}) 16045 16046(define_expand "cosh<mode>2" 16047 [(use (match_operand:MODEF 0 "register_operand")) 16048 (use (match_operand:MODEF 1 "general_operand"))] 16049 "TARGET_USE_FANCY_MATH_387 16050 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16051 || TARGET_MIX_SSE_I387) 16052 && flag_unsafe_math_optimizations" 16053{ 16054 rtx op0 = gen_reg_rtx (XFmode); 16055 rtx op1 = gen_reg_rtx (XFmode); 16056 16057 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16058 emit_insn (gen_coshxf2 (op0, op1)); 16059 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16060 DONE; 16061}) 16062 16063(define_expand "tanhxf2" 16064 [(use (match_operand:XF 0 "register_operand")) 16065 (use (match_operand:XF 1 "register_operand"))] 16066 "TARGET_USE_FANCY_MATH_387 16067 && flag_unsafe_math_optimizations" 16068{ 16069 ix86_emit_i387_tanh (operands[0], operands[1]); 16070 DONE; 16071}) 16072 16073(define_expand "tanh<mode>2" 16074 [(use (match_operand:MODEF 0 "register_operand")) 16075 (use (match_operand:MODEF 1 "general_operand"))] 16076 "TARGET_USE_FANCY_MATH_387 16077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16078 || TARGET_MIX_SSE_I387) 16079 && flag_unsafe_math_optimizations" 16080{ 16081 rtx op0 = gen_reg_rtx (XFmode); 16082 rtx op1 = gen_reg_rtx (XFmode); 16083 16084 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16085 emit_insn (gen_tanhxf2 (op0, op1)); 16086 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16087 DONE; 16088}) 16089 16090(define_expand "asinhxf2" 16091 [(use (match_operand:XF 0 "register_operand")) 16092 (use (match_operand:XF 1 "register_operand"))] 16093 "TARGET_USE_FANCY_MATH_387 16094 && flag_finite_math_only 16095 && flag_unsafe_math_optimizations" 16096{ 16097 ix86_emit_i387_asinh (operands[0], operands[1]); 16098 DONE; 16099}) 16100 16101(define_expand "asinh<mode>2" 16102 [(use (match_operand:MODEF 0 "register_operand")) 16103 (use (match_operand:MODEF 1 "general_operand"))] 16104 "TARGET_USE_FANCY_MATH_387 16105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16106 || TARGET_MIX_SSE_I387) 16107 && flag_finite_math_only 16108 && flag_unsafe_math_optimizations" 16109{ 16110 rtx op0 = gen_reg_rtx (XFmode); 16111 rtx op1 = gen_reg_rtx (XFmode); 16112 16113 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16114 emit_insn (gen_asinhxf2 (op0, op1)); 16115 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16116 DONE; 16117}) 16118 16119(define_expand "acoshxf2" 16120 [(use (match_operand:XF 0 "register_operand")) 16121 (use (match_operand:XF 1 "register_operand"))] 16122 "TARGET_USE_FANCY_MATH_387 16123 && flag_unsafe_math_optimizations" 16124{ 16125 ix86_emit_i387_acosh (operands[0], operands[1]); 16126 DONE; 16127}) 16128 16129(define_expand "acosh<mode>2" 16130 [(use (match_operand:MODEF 0 "register_operand")) 16131 (use (match_operand:MODEF 1 "general_operand"))] 16132 "TARGET_USE_FANCY_MATH_387 16133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16134 || TARGET_MIX_SSE_I387) 16135 && flag_unsafe_math_optimizations" 16136{ 16137 rtx op0 = gen_reg_rtx (XFmode); 16138 rtx op1 = gen_reg_rtx (XFmode); 16139 16140 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16141 emit_insn (gen_acoshxf2 (op0, op1)); 16142 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16143 DONE; 16144}) 16145 16146(define_expand "atanhxf2" 16147 [(use (match_operand:XF 0 "register_operand")) 16148 (use (match_operand:XF 1 "register_operand"))] 16149 "TARGET_USE_FANCY_MATH_387 16150 && flag_unsafe_math_optimizations" 16151{ 16152 ix86_emit_i387_atanh (operands[0], operands[1]); 16153 DONE; 16154}) 16155 16156(define_expand "atanh<mode>2" 16157 [(use (match_operand:MODEF 0 "register_operand")) 16158 (use (match_operand:MODEF 1 "general_operand"))] 16159 "TARGET_USE_FANCY_MATH_387 16160 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16161 || TARGET_MIX_SSE_I387) 16162 && flag_unsafe_math_optimizations" 16163{ 16164 rtx op0 = gen_reg_rtx (XFmode); 16165 rtx op1 = gen_reg_rtx (XFmode); 16166 16167 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16168 emit_insn (gen_atanhxf2 (op0, op1)); 16169 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16170 DONE; 16171}) 16172 16173(define_insn "fyl2xxf3_i387" 16174 [(set (match_operand:XF 0 "register_operand" "=f") 16175 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 16176 (match_operand:XF 2 "register_operand" "f")] 16177 UNSPEC_FYL2X)) 16178 (clobber (match_scratch:XF 3 "=2"))] 16179 "TARGET_USE_FANCY_MATH_387 16180 && flag_unsafe_math_optimizations" 16181 "fyl2x" 16182 [(set_attr "type" "fpspc") 16183 (set_attr "znver1_decode" "vector") 16184 (set_attr "mode" "XF")]) 16185 16186(define_expand "logxf2" 16187 [(parallel [(set (match_operand:XF 0 "register_operand") 16188 (unspec:XF [(match_operand:XF 1 "register_operand") 16189 (match_dup 2)] UNSPEC_FYL2X)) 16190 (clobber (match_scratch:XF 3))])] 16191 "TARGET_USE_FANCY_MATH_387 16192 && flag_unsafe_math_optimizations" 16193{ 16194 operands[2] 16195 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */ 16196}) 16197 16198(define_expand "log<mode>2" 16199 [(use (match_operand:MODEF 0 "register_operand")) 16200 (use (match_operand:MODEF 1 "general_operand"))] 16201 "TARGET_USE_FANCY_MATH_387 16202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16203 || TARGET_MIX_SSE_I387) 16204 && flag_unsafe_math_optimizations" 16205{ 16206 rtx op0 = gen_reg_rtx (XFmode); 16207 rtx op1 = gen_reg_rtx (XFmode); 16208 16209 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16210 emit_insn (gen_logxf2 (op0, op1)); 16211 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16212 DONE; 16213}) 16214 16215(define_expand "log10xf2" 16216 [(parallel [(set (match_operand:XF 0 "register_operand") 16217 (unspec:XF [(match_operand:XF 1 "register_operand") 16218 (match_dup 2)] UNSPEC_FYL2X)) 16219 (clobber (match_scratch:XF 3))])] 16220 "TARGET_USE_FANCY_MATH_387 16221 && flag_unsafe_math_optimizations" 16222{ 16223 operands[2] 16224 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */ 16225}) 16226 16227(define_expand "log10<mode>2" 16228 [(use (match_operand:MODEF 0 "register_operand")) 16229 (use (match_operand:MODEF 1 "general_operand"))] 16230 "TARGET_USE_FANCY_MATH_387 16231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16232 || TARGET_MIX_SSE_I387) 16233 && flag_unsafe_math_optimizations" 16234{ 16235 rtx op0 = gen_reg_rtx (XFmode); 16236 rtx op1 = gen_reg_rtx (XFmode); 16237 16238 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16239 emit_insn (gen_log10xf2 (op0, op1)); 16240 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16241 DONE; 16242}) 16243 16244(define_expand "log2xf2" 16245 [(parallel [(set (match_operand:XF 0 "register_operand") 16246 (unspec:XF [(match_operand:XF 1 "register_operand") 16247 (match_dup 2)] UNSPEC_FYL2X)) 16248 (clobber (match_scratch:XF 3))])] 16249 "TARGET_USE_FANCY_MATH_387 16250 && flag_unsafe_math_optimizations" 16251 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));") 16252 16253(define_expand "log2<mode>2" 16254 [(use (match_operand:MODEF 0 "register_operand")) 16255 (use (match_operand:MODEF 1 "general_operand"))] 16256 "TARGET_USE_FANCY_MATH_387 16257 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16258 || TARGET_MIX_SSE_I387) 16259 && flag_unsafe_math_optimizations" 16260{ 16261 rtx op0 = gen_reg_rtx (XFmode); 16262 rtx op1 = gen_reg_rtx (XFmode); 16263 16264 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16265 emit_insn (gen_log2xf2 (op0, op1)); 16266 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16267 DONE; 16268}) 16269 16270(define_insn "fyl2xp1xf3_i387" 16271 [(set (match_operand:XF 0 "register_operand" "=f") 16272 (unspec:XF [(match_operand:XF 1 "register_operand" "0") 16273 (match_operand:XF 2 "register_operand" "f")] 16274 UNSPEC_FYL2XP1)) 16275 (clobber (match_scratch:XF 3 "=2"))] 16276 "TARGET_USE_FANCY_MATH_387 16277 && flag_unsafe_math_optimizations" 16278 "fyl2xp1" 16279 [(set_attr "type" "fpspc") 16280 (set_attr "znver1_decode" "vector") 16281 (set_attr "mode" "XF")]) 16282 16283(define_expand "log1pxf2" 16284 [(use (match_operand:XF 0 "register_operand")) 16285 (use (match_operand:XF 1 "register_operand"))] 16286 "TARGET_USE_FANCY_MATH_387 16287 && flag_unsafe_math_optimizations" 16288{ 16289 ix86_emit_i387_log1p (operands[0], operands[1]); 16290 DONE; 16291}) 16292 16293(define_expand "log1p<mode>2" 16294 [(use (match_operand:MODEF 0 "register_operand")) 16295 (use (match_operand:MODEF 1 "general_operand"))] 16296 "TARGET_USE_FANCY_MATH_387 16297 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16298 || TARGET_MIX_SSE_I387) 16299 && flag_unsafe_math_optimizations" 16300{ 16301 rtx op0 = gen_reg_rtx (XFmode); 16302 rtx op1 = gen_reg_rtx (XFmode); 16303 16304 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16305 emit_insn (gen_log1pxf2 (op0, op1)); 16306 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16307 DONE; 16308}) 16309 16310(define_insn "fxtractxf3_i387" 16311 [(set (match_operand:XF 0 "register_operand" "=f") 16312 (unspec:XF [(match_operand:XF 2 "register_operand" "0")] 16313 UNSPEC_XTRACT_FRACT)) 16314 (set (match_operand:XF 1 "register_operand" "=f") 16315 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))] 16316 "TARGET_USE_FANCY_MATH_387 16317 && flag_unsafe_math_optimizations" 16318 "fxtract" 16319 [(set_attr "type" "fpspc") 16320 (set_attr "znver1_decode" "vector") 16321 (set_attr "mode" "XF")]) 16322 16323(define_expand "logbxf2" 16324 [(parallel [(set (match_dup 2) 16325 (unspec:XF [(match_operand:XF 1 "register_operand")] 16326 UNSPEC_XTRACT_FRACT)) 16327 (set (match_operand:XF 0 "register_operand") 16328 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16329 "TARGET_USE_FANCY_MATH_387 16330 && flag_unsafe_math_optimizations" 16331 "operands[2] = gen_reg_rtx (XFmode);") 16332 16333(define_expand "logb<mode>2" 16334 [(use (match_operand:MODEF 0 "register_operand")) 16335 (use (match_operand:MODEF 1 "general_operand"))] 16336 "TARGET_USE_FANCY_MATH_387 16337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16338 || TARGET_MIX_SSE_I387) 16339 && flag_unsafe_math_optimizations" 16340{ 16341 rtx op0 = gen_reg_rtx (XFmode); 16342 rtx op1 = gen_reg_rtx (XFmode); 16343 16344 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16345 emit_insn (gen_logbxf2 (op0, op1)); 16346 emit_insn (gen_truncxf<mode>2 (operands[0], op1)); 16347 DONE; 16348}) 16349 16350(define_expand "ilogbxf2" 16351 [(use (match_operand:SI 0 "register_operand")) 16352 (use (match_operand:XF 1 "register_operand"))] 16353 "TARGET_USE_FANCY_MATH_387 16354 && flag_unsafe_math_optimizations" 16355{ 16356 rtx op0, op1; 16357 16358 if (optimize_insn_for_size_p ()) 16359 FAIL; 16360 16361 op0 = gen_reg_rtx (XFmode); 16362 op1 = gen_reg_rtx (XFmode); 16363 16364 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1])); 16365 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 16366 DONE; 16367}) 16368 16369(define_expand "ilogb<mode>2" 16370 [(use (match_operand:SI 0 "register_operand")) 16371 (use (match_operand:MODEF 1 "general_operand"))] 16372 "TARGET_USE_FANCY_MATH_387 16373 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16374 || TARGET_MIX_SSE_I387) 16375 && flag_unsafe_math_optimizations" 16376{ 16377 rtx op0, op1, op2; 16378 16379 if (optimize_insn_for_size_p ()) 16380 FAIL; 16381 16382 op0 = gen_reg_rtx (XFmode); 16383 op1 = gen_reg_rtx (XFmode); 16384 op2 = gen_reg_rtx (XFmode); 16385 16386 emit_insn (gen_extend<mode>xf2 (op2, operands[1])); 16387 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2)); 16388 emit_insn (gen_fix_truncxfsi2 (operands[0], op1)); 16389 DONE; 16390}) 16391 16392(define_insn "*f2xm1xf2_i387" 16393 [(set (match_operand:XF 0 "register_operand" "=f") 16394 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16395 UNSPEC_F2XM1))] 16396 "TARGET_USE_FANCY_MATH_387 16397 && flag_unsafe_math_optimizations" 16398 "f2xm1" 16399 [(set_attr "type" "fpspc") 16400 (set_attr "znver1_decode" "vector") 16401 (set_attr "mode" "XF")]) 16402 16403(define_insn "fscalexf4_i387" 16404 [(set (match_operand:XF 0 "register_operand" "=f") 16405 (unspec:XF [(match_operand:XF 2 "register_operand" "0") 16406 (match_operand:XF 3 "register_operand" "1")] 16407 UNSPEC_FSCALE_FRACT)) 16408 (set (match_operand:XF 1 "register_operand" "=f") 16409 (unspec:XF [(match_dup 2) (match_dup 3)] 16410 UNSPEC_FSCALE_EXP))] 16411 "TARGET_USE_FANCY_MATH_387 16412 && flag_unsafe_math_optimizations" 16413 "fscale" 16414 [(set_attr "type" "fpspc") 16415 (set_attr "znver1_decode" "vector") 16416 (set_attr "mode" "XF")]) 16417 16418(define_expand "expNcorexf3" 16419 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 16420 (match_operand:XF 2 "register_operand"))) 16421 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16422 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16423 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16424 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7))) 16425 (parallel [(set (match_operand:XF 0 "register_operand") 16426 (unspec:XF [(match_dup 8) (match_dup 4)] 16427 UNSPEC_FSCALE_FRACT)) 16428 (set (match_dup 9) 16429 (unspec:XF [(match_dup 8) (match_dup 4)] 16430 UNSPEC_FSCALE_EXP))])] 16431 "TARGET_USE_FANCY_MATH_387 16432 && flag_unsafe_math_optimizations" 16433{ 16434 int i; 16435 16436 for (i = 3; i < 10; i++) 16437 operands[i] = gen_reg_rtx (XFmode); 16438 16439 emit_move_insn (operands[7], CONST1_RTX (XFmode)); 16440}) 16441 16442(define_expand "expxf2" 16443 [(use (match_operand:XF 0 "register_operand")) 16444 (use (match_operand:XF 1 "register_operand"))] 16445 "TARGET_USE_FANCY_MATH_387 16446 && flag_unsafe_math_optimizations" 16447{ 16448 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */ 16449 16450 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16451 DONE; 16452}) 16453 16454(define_expand "exp<mode>2" 16455 [(use (match_operand:MODEF 0 "register_operand")) 16456 (use (match_operand:MODEF 1 "general_operand"))] 16457 "TARGET_USE_FANCY_MATH_387 16458 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16459 || TARGET_MIX_SSE_I387) 16460 && flag_unsafe_math_optimizations" 16461{ 16462 rtx op0 = gen_reg_rtx (XFmode); 16463 rtx op1 = gen_reg_rtx (XFmode); 16464 16465 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16466 emit_insn (gen_expxf2 (op0, op1)); 16467 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16468 DONE; 16469}) 16470 16471(define_expand "exp10xf2" 16472 [(use (match_operand:XF 0 "register_operand")) 16473 (use (match_operand:XF 1 "register_operand"))] 16474 "TARGET_USE_FANCY_MATH_387 16475 && flag_unsafe_math_optimizations" 16476{ 16477 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */ 16478 16479 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16480 DONE; 16481}) 16482 16483(define_expand "exp10<mode>2" 16484 [(use (match_operand:MODEF 0 "register_operand")) 16485 (use (match_operand:MODEF 1 "general_operand"))] 16486 "TARGET_USE_FANCY_MATH_387 16487 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16488 || TARGET_MIX_SSE_I387) 16489 && flag_unsafe_math_optimizations" 16490{ 16491 rtx op0 = gen_reg_rtx (XFmode); 16492 rtx op1 = gen_reg_rtx (XFmode); 16493 16494 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16495 emit_insn (gen_exp10xf2 (op0, op1)); 16496 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16497 DONE; 16498}) 16499 16500(define_expand "exp2xf2" 16501 [(use (match_operand:XF 0 "register_operand")) 16502 (use (match_operand:XF 1 "register_operand"))] 16503 "TARGET_USE_FANCY_MATH_387 16504 && flag_unsafe_math_optimizations" 16505{ 16506 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode)); 16507 16508 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2)); 16509 DONE; 16510}) 16511 16512(define_expand "exp2<mode>2" 16513 [(use (match_operand:MODEF 0 "register_operand")) 16514 (use (match_operand:MODEF 1 "general_operand"))] 16515 "TARGET_USE_FANCY_MATH_387 16516 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16517 || TARGET_MIX_SSE_I387) 16518 && flag_unsafe_math_optimizations" 16519{ 16520 rtx op0 = gen_reg_rtx (XFmode); 16521 rtx op1 = gen_reg_rtx (XFmode); 16522 16523 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16524 emit_insn (gen_exp2xf2 (op0, op1)); 16525 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16526 DONE; 16527}) 16528 16529(define_expand "expm1xf2" 16530 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand") 16531 (match_dup 2))) 16532 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT)) 16533 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4))) 16534 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1)) 16535 (parallel [(set (match_dup 7) 16536 (unspec:XF [(match_dup 6) (match_dup 4)] 16537 UNSPEC_FSCALE_FRACT)) 16538 (set (match_dup 8) 16539 (unspec:XF [(match_dup 6) (match_dup 4)] 16540 UNSPEC_FSCALE_EXP))]) 16541 (parallel [(set (match_dup 10) 16542 (unspec:XF [(match_dup 9) (match_dup 8)] 16543 UNSPEC_FSCALE_FRACT)) 16544 (set (match_dup 11) 16545 (unspec:XF [(match_dup 9) (match_dup 8)] 16546 UNSPEC_FSCALE_EXP))]) 16547 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9))) 16548 (set (match_operand:XF 0 "register_operand") 16549 (plus:XF (match_dup 12) (match_dup 7)))] 16550 "TARGET_USE_FANCY_MATH_387 16551 && flag_unsafe_math_optimizations" 16552{ 16553 int i; 16554 16555 for (i = 2; i < 13; i++) 16556 operands[i] = gen_reg_rtx (XFmode); 16557 16558 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */ 16559 emit_move_insn (operands[9], CONST1_RTX (XFmode)); 16560}) 16561 16562(define_expand "expm1<mode>2" 16563 [(use (match_operand:MODEF 0 "register_operand")) 16564 (use (match_operand:MODEF 1 "general_operand"))] 16565 "TARGET_USE_FANCY_MATH_387 16566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16567 || TARGET_MIX_SSE_I387) 16568 && flag_unsafe_math_optimizations" 16569{ 16570 rtx op0 = gen_reg_rtx (XFmode); 16571 rtx op1 = gen_reg_rtx (XFmode); 16572 16573 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16574 emit_insn (gen_expm1xf2 (op0, op1)); 16575 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16576 DONE; 16577}) 16578 16579(define_expand "ldexpxf3" 16580 [(match_operand:XF 0 "register_operand") 16581 (match_operand:XF 1 "register_operand") 16582 (match_operand:SI 2 "register_operand")] 16583 "TARGET_USE_FANCY_MATH_387 16584 && flag_unsafe_math_optimizations" 16585{ 16586 rtx tmp1 = gen_reg_rtx (XFmode); 16587 rtx tmp2 = gen_reg_rtx (XFmode); 16588 16589 emit_insn (gen_floatsixf2 (tmp1, operands[2])); 16590 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2, 16591 operands[1], tmp1)); 16592 DONE; 16593}) 16594 16595(define_expand "ldexp<mode>3" 16596 [(use (match_operand:MODEF 0 "register_operand")) 16597 (use (match_operand:MODEF 1 "general_operand")) 16598 (use (match_operand:SI 2 "register_operand"))] 16599 "TARGET_USE_FANCY_MATH_387 16600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16601 || TARGET_MIX_SSE_I387) 16602 && flag_unsafe_math_optimizations" 16603{ 16604 rtx op0 = gen_reg_rtx (XFmode); 16605 rtx op1 = gen_reg_rtx (XFmode); 16606 16607 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16608 emit_insn (gen_ldexpxf3 (op0, op1, operands[2])); 16609 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16610 DONE; 16611}) 16612 16613(define_expand "scalbxf3" 16614 [(parallel [(set (match_operand:XF 0 " register_operand") 16615 (unspec:XF [(match_operand:XF 1 "register_operand") 16616 (match_operand:XF 2 "register_operand")] 16617 UNSPEC_FSCALE_FRACT)) 16618 (set (match_dup 3) 16619 (unspec:XF [(match_dup 1) (match_dup 2)] 16620 UNSPEC_FSCALE_EXP))])] 16621 "TARGET_USE_FANCY_MATH_387 16622 && flag_unsafe_math_optimizations" 16623 "operands[3] = gen_reg_rtx (XFmode);") 16624 16625(define_expand "scalb<mode>3" 16626 [(use (match_operand:MODEF 0 "register_operand")) 16627 (use (match_operand:MODEF 1 "general_operand")) 16628 (use (match_operand:MODEF 2 "general_operand"))] 16629 "TARGET_USE_FANCY_MATH_387 16630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16631 || TARGET_MIX_SSE_I387) 16632 && flag_unsafe_math_optimizations" 16633{ 16634 rtx op0 = gen_reg_rtx (XFmode); 16635 rtx op1 = gen_reg_rtx (XFmode); 16636 rtx op2 = gen_reg_rtx (XFmode); 16637 16638 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16639 emit_insn (gen_extend<mode>xf2 (op2, operands[2])); 16640 emit_insn (gen_scalbxf3 (op0, op1, op2)); 16641 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16642 DONE; 16643}) 16644 16645(define_expand "significandxf2" 16646 [(parallel [(set (match_operand:XF 0 "register_operand") 16647 (unspec:XF [(match_operand:XF 1 "register_operand")] 16648 UNSPEC_XTRACT_FRACT)) 16649 (set (match_dup 2) 16650 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])] 16651 "TARGET_USE_FANCY_MATH_387 16652 && flag_unsafe_math_optimizations" 16653 "operands[2] = gen_reg_rtx (XFmode);") 16654 16655(define_expand "significand<mode>2" 16656 [(use (match_operand:MODEF 0 "register_operand")) 16657 (use (match_operand:MODEF 1 "general_operand"))] 16658 "TARGET_USE_FANCY_MATH_387 16659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16660 || TARGET_MIX_SSE_I387) 16661 && flag_unsafe_math_optimizations" 16662{ 16663 rtx op0 = gen_reg_rtx (XFmode); 16664 rtx op1 = gen_reg_rtx (XFmode); 16665 16666 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16667 emit_insn (gen_significandxf2 (op0, op1)); 16668 emit_insn (gen_truncxf<mode>2 (operands[0], op0)); 16669 DONE; 16670}) 16671 16672 16673(define_insn "sse4_1_round<mode>2" 16674 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v,v") 16675 (unspec:MODEF 16676 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,v,m") 16677 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n,n")] 16678 UNSPEC_ROUND))] 16679 "TARGET_SSE4_1" 16680 "@ 16681 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2} 16682 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2} 16683 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2} 16684 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2} 16685 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}" 16686 [(set_attr "type" "ssecvt") 16687 (set_attr "prefix_extra" "1,1,1,*,*") 16688 (set_attr "length_immediate" "*,*,*,1,1") 16689 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex") 16690 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f") 16691 (set_attr "avx_partial_xmm_update" "false,false,true,false,true") 16692 (set_attr "mode" "<MODE>") 16693 (set (attr "preferred_for_speed") 16694 (cond [(match_test "TARGET_AVX") 16695 (symbol_ref "true") 16696 (eq_attr "alternative" "1,2") 16697 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY") 16698 ] 16699 (symbol_ref "true")))]) 16700 16701(define_insn "rintxf2" 16702 [(set (match_operand:XF 0 "register_operand" "=f") 16703 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16704 UNSPEC_FRNDINT))] 16705 "TARGET_USE_FANCY_MATH_387" 16706 "frndint" 16707 [(set_attr "type" "fpspc") 16708 (set_attr "znver1_decode" "vector") 16709 (set_attr "mode" "XF")]) 16710 16711(define_expand "rint<mode>2" 16712 [(use (match_operand:MODEF 0 "register_operand")) 16713 (use (match_operand:MODEF 1 "nonimmediate_operand"))] 16714 "TARGET_USE_FANCY_MATH_387 16715 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 16716{ 16717 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16718 { 16719 if (TARGET_SSE4_1) 16720 emit_insn (gen_sse4_1_round<mode>2 16721 (operands[0], operands[1], GEN_INT (ROUND_MXCSR))); 16722 else 16723 ix86_expand_rint (operands[0], operands[1]); 16724 } 16725 else 16726 { 16727 rtx op0 = gen_reg_rtx (XFmode); 16728 rtx op1 = gen_reg_rtx (XFmode); 16729 16730 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16731 emit_insn (gen_rintxf2 (op0, op1)); 16732 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 16733 } 16734 DONE; 16735}) 16736 16737(define_expand "nearbyintxf2" 16738 [(set (match_operand:XF 0 "register_operand") 16739 (unspec:XF [(match_operand:XF 1 "register_operand")] 16740 UNSPEC_FRNDINT))] 16741 "TARGET_USE_FANCY_MATH_387 16742 && !flag_trapping_math") 16743 16744(define_expand "nearbyint<mode>2" 16745 [(use (match_operand:MODEF 0 "register_operand")) 16746 (use (match_operand:MODEF 1 "nonimmediate_operand"))] 16747 "(TARGET_USE_FANCY_MATH_387 16748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16749 || TARGET_MIX_SSE_I387) 16750 && !flag_trapping_math) 16751 || (TARGET_SSE4_1 && TARGET_SSE_MATH)" 16752{ 16753 if (TARGET_SSE4_1 && TARGET_SSE_MATH) 16754 emit_insn (gen_sse4_1_round<mode>2 16755 (operands[0], operands[1], GEN_INT (ROUND_MXCSR 16756 | ROUND_NO_EXC))); 16757 else 16758 { 16759 rtx op0 = gen_reg_rtx (XFmode); 16760 rtx op1 = gen_reg_rtx (XFmode); 16761 16762 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16763 emit_insn (gen_nearbyintxf2 (op0, op1)); 16764 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 16765 } 16766 DONE; 16767}) 16768 16769(define_expand "round<mode>2" 16770 [(match_operand:X87MODEF 0 "register_operand") 16771 (match_operand:X87MODEF 1 "nonimmediate_operand")] 16772 "(TARGET_USE_FANCY_MATH_387 16773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16774 || TARGET_MIX_SSE_I387) 16775 && flag_unsafe_math_optimizations 16776 && (flag_fp_int_builtin_inexact || !flag_trapping_math)) 16777 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16778 && !flag_trapping_math && !flag_rounding_math)" 16779{ 16780 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16781 && !flag_trapping_math && !flag_rounding_math) 16782 { 16783 if (TARGET_SSE4_1) 16784 { 16785 operands[1] = force_reg (<MODE>mode, operands[1]); 16786 ix86_expand_round_sse4 (operands[0], operands[1]); 16787 } 16788 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 16789 ix86_expand_round (operands[0], operands[1]); 16790 else 16791 ix86_expand_rounddf_32 (operands[0], operands[1]); 16792 } 16793 else 16794 { 16795 operands[1] = force_reg (<MODE>mode, operands[1]); 16796 ix86_emit_i387_round (operands[0], operands[1]); 16797 } 16798 DONE; 16799}) 16800 16801(define_insn "lrintxfdi2" 16802 [(set (match_operand:DI 0 "nonimmediate_operand" "=m") 16803 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 16804 UNSPEC_FIST)) 16805 (clobber (match_scratch:XF 2 "=&f"))] 16806 "TARGET_USE_FANCY_MATH_387" 16807 "* return output_fix_trunc (insn, operands, false);" 16808 [(set_attr "type" "fpspc") 16809 (set_attr "mode" "DI")]) 16810 16811(define_insn "lrintxf<mode>2" 16812 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m") 16813 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 16814 UNSPEC_FIST))] 16815 "TARGET_USE_FANCY_MATH_387" 16816 "* return output_fix_trunc (insn, operands, false);" 16817 [(set_attr "type" "fpspc") 16818 (set_attr "mode" "<MODE>")]) 16819 16820(define_expand "lrint<MODEF:mode><SWI48:mode>2" 16821 [(set (match_operand:SWI48 0 "nonimmediate_operand") 16822 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 16823 UNSPEC_FIX_NOTRUNC))] 16824 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH") 16825 16826(define_expand "lround<X87MODEF:mode><SWI248x:mode>2" 16827 [(match_operand:SWI248x 0 "nonimmediate_operand") 16828 (match_operand:X87MODEF 1 "register_operand")] 16829 "(TARGET_USE_FANCY_MATH_387 16830 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH) 16831 || TARGET_MIX_SSE_I387) 16832 && flag_unsafe_math_optimizations) 16833 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 16834 && <SWI248x:MODE>mode != HImode 16835 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 16836 && !flag_trapping_math && !flag_rounding_math)" 16837{ 16838 if (optimize_insn_for_size_p ()) 16839 FAIL; 16840 16841 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH 16842 && <SWI248x:MODE>mode != HImode 16843 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT) 16844 && !flag_trapping_math && !flag_rounding_math) 16845 ix86_expand_lround (operands[0], operands[1]); 16846 else 16847 ix86_emit_i387_round (operands[0], operands[1]); 16848 DONE; 16849}) 16850 16851(define_int_iterator FRNDINT_ROUNDING 16852 [UNSPEC_FRNDINT_ROUNDEVEN 16853 UNSPEC_FRNDINT_FLOOR 16854 UNSPEC_FRNDINT_CEIL 16855 UNSPEC_FRNDINT_TRUNC]) 16856 16857(define_int_iterator FIST_ROUNDING 16858 [UNSPEC_FIST_FLOOR 16859 UNSPEC_FIST_CEIL]) 16860 16861;; Base name for define_insn 16862(define_int_attr rounding_insn 16863 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven") 16864 (UNSPEC_FRNDINT_FLOOR "floor") 16865 (UNSPEC_FRNDINT_CEIL "ceil") 16866 (UNSPEC_FRNDINT_TRUNC "btrunc") 16867 (UNSPEC_FIST_FLOOR "floor") 16868 (UNSPEC_FIST_CEIL "ceil")]) 16869 16870(define_int_attr rounding 16871 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven") 16872 (UNSPEC_FRNDINT_FLOOR "floor") 16873 (UNSPEC_FRNDINT_CEIL "ceil") 16874 (UNSPEC_FRNDINT_TRUNC "trunc") 16875 (UNSPEC_FIST_FLOOR "floor") 16876 (UNSPEC_FIST_CEIL "ceil")]) 16877 16878(define_int_attr ROUNDING 16879 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN") 16880 (UNSPEC_FRNDINT_FLOOR "FLOOR") 16881 (UNSPEC_FRNDINT_CEIL "CEIL") 16882 (UNSPEC_FRNDINT_TRUNC "TRUNC") 16883 (UNSPEC_FIST_FLOOR "FLOOR") 16884 (UNSPEC_FIST_CEIL "CEIL")]) 16885 16886;; Rounding mode control word calculation could clobber FLAGS_REG. 16887(define_insn_and_split "frndintxf2_<rounding>" 16888 [(set (match_operand:XF 0 "register_operand") 16889 (unspec:XF [(match_operand:XF 1 "register_operand")] 16890 FRNDINT_ROUNDING)) 16891 (clobber (reg:CC FLAGS_REG))] 16892 "TARGET_USE_FANCY_MATH_387 16893 && (flag_fp_int_builtin_inexact || !flag_trapping_math) 16894 && ix86_pre_reload_split ()" 16895 "#" 16896 "&& 1" 16897 [(const_int 0)] 16898{ 16899 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 16900 16901 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 16902 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 16903 16904 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1], 16905 operands[2], operands[3])); 16906 DONE; 16907} 16908 [(set_attr "type" "frndint") 16909 (set_attr "i387_cw" "<rounding>") 16910 (set_attr "mode" "XF")]) 16911 16912(define_insn "frndintxf2_<rounding>_i387" 16913 [(set (match_operand:XF 0 "register_operand" "=f") 16914 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 16915 FRNDINT_ROUNDING)) 16916 (use (match_operand:HI 2 "memory_operand" "m")) 16917 (use (match_operand:HI 3 "memory_operand" "m"))] 16918 "TARGET_USE_FANCY_MATH_387 16919 && (flag_fp_int_builtin_inexact || !flag_trapping_math)" 16920 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2" 16921 [(set_attr "type" "frndint") 16922 (set_attr "i387_cw" "<rounding>") 16923 (set_attr "mode" "XF")]) 16924 16925(define_expand "<rounding_insn>xf2" 16926 [(parallel [(set (match_operand:XF 0 "register_operand") 16927 (unspec:XF [(match_operand:XF 1 "register_operand")] 16928 FRNDINT_ROUNDING)) 16929 (clobber (reg:CC FLAGS_REG))])] 16930 "TARGET_USE_FANCY_MATH_387 16931 && (flag_fp_int_builtin_inexact || !flag_trapping_math)") 16932 16933(define_expand "<rounding_insn><mode>2" 16934 [(parallel [(set (match_operand:MODEF 0 "register_operand") 16935 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")] 16936 FRNDINT_ROUNDING)) 16937 (clobber (reg:CC FLAGS_REG))])] 16938 "(TARGET_USE_FANCY_MATH_387 16939 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) 16940 || TARGET_MIX_SSE_I387) 16941 && (flag_fp_int_builtin_inexact || !flag_trapping_math)) 16942 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16943 && (TARGET_SSE4_1 16944 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN 16945 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))" 16946{ 16947 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH 16948 && (TARGET_SSE4_1 16949 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN 16950 && (flag_fp_int_builtin_inexact || !flag_trapping_math)))) 16951 { 16952 if (TARGET_SSE4_1) 16953 emit_insn (gen_sse4_1_round<mode>2 16954 (operands[0], operands[1], 16955 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC))); 16956 else if (TARGET_64BIT || (<MODE>mode != DFmode)) 16957 { 16958 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16959 ix86_expand_floorceil (operands[0], operands[1], true); 16960 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16961 ix86_expand_floorceil (operands[0], operands[1], false); 16962 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 16963 ix86_expand_trunc (operands[0], operands[1]); 16964 else 16965 gcc_unreachable (); 16966 } 16967 else 16968 { 16969 if (ROUND_<ROUNDING> == ROUND_FLOOR) 16970 ix86_expand_floorceildf_32 (operands[0], operands[1], true); 16971 else if (ROUND_<ROUNDING> == ROUND_CEIL) 16972 ix86_expand_floorceildf_32 (operands[0], operands[1], false); 16973 else if (ROUND_<ROUNDING> == ROUND_TRUNC) 16974 ix86_expand_truncdf_32 (operands[0], operands[1]); 16975 else 16976 gcc_unreachable (); 16977 } 16978 } 16979 else 16980 { 16981 rtx op0 = gen_reg_rtx (XFmode); 16982 rtx op1 = gen_reg_rtx (XFmode); 16983 16984 emit_insn (gen_extend<mode>xf2 (op1, operands[1])); 16985 emit_insn (gen_frndintxf2_<rounding> (op0, op1)); 16986 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0)); 16987 } 16988 DONE; 16989}) 16990 16991;; Rounding mode control word calculation could clobber FLAGS_REG. 16992(define_insn_and_split "*fist<mode>2_<rounding>_1" 16993 [(set (match_operand:SWI248x 0 "nonimmediate_operand") 16994 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 16995 FIST_ROUNDING)) 16996 (clobber (reg:CC FLAGS_REG))] 16997 "TARGET_USE_FANCY_MATH_387 16998 && flag_unsafe_math_optimizations 16999 && ix86_pre_reload_split ()" 17000 "#" 17001 "&& 1" 17002 [(const_int 0)] 17003{ 17004 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; 17005 17006 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); 17007 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); 17008 17009 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1], 17010 operands[2], operands[3])); 17011 DONE; 17012} 17013 [(set_attr "type" "fistp") 17014 (set_attr "i387_cw" "<rounding>") 17015 (set_attr "mode" "<MODE>")]) 17016 17017(define_insn "fistdi2_<rounding>" 17018 [(set (match_operand:DI 0 "nonimmediate_operand" "=m") 17019 (unspec:DI [(match_operand:XF 1 "register_operand" "f")] 17020 FIST_ROUNDING)) 17021 (use (match_operand:HI 2 "memory_operand" "m")) 17022 (use (match_operand:HI 3 "memory_operand" "m")) 17023 (clobber (match_scratch:XF 4 "=&f"))] 17024 "TARGET_USE_FANCY_MATH_387 17025 && flag_unsafe_math_optimizations" 17026 "* return output_fix_trunc (insn, operands, false);" 17027 [(set_attr "type" "fistp") 17028 (set_attr "i387_cw" "<rounding>") 17029 (set_attr "mode" "DI")]) 17030 17031(define_insn "fist<mode>2_<rounding>" 17032 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m") 17033 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] 17034 FIST_ROUNDING)) 17035 (use (match_operand:HI 2 "memory_operand" "m")) 17036 (use (match_operand:HI 3 "memory_operand" "m"))] 17037 "TARGET_USE_FANCY_MATH_387 17038 && flag_unsafe_math_optimizations" 17039 "* return output_fix_trunc (insn, operands, false);" 17040 [(set_attr "type" "fistp") 17041 (set_attr "i387_cw" "<rounding>") 17042 (set_attr "mode" "<MODE>")]) 17043 17044(define_expand "l<rounding_insn>xf<mode>2" 17045 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand") 17046 (unspec:SWI248x [(match_operand:XF 1 "register_operand")] 17047 FIST_ROUNDING)) 17048 (clobber (reg:CC FLAGS_REG))])] 17049 "TARGET_USE_FANCY_MATH_387 17050 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) 17051 && flag_unsafe_math_optimizations") 17052 17053(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2" 17054 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand") 17055 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] 17056 FIST_ROUNDING)) 17057 (clobber (reg:CC FLAGS_REG))])] 17058 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH 17059 && (TARGET_SSE4_1 || !flag_trapping_math)" 17060{ 17061 if (TARGET_SSE4_1) 17062 { 17063 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode); 17064 17065 emit_insn (gen_sse4_1_round<MODEF:mode>2 17066 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING> 17067 | ROUND_NO_EXC))); 17068 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2 17069 (operands[0], tmp)); 17070 } 17071 else if (ROUND_<ROUNDING> == ROUND_FLOOR) 17072 ix86_expand_lfloorceil (operands[0], operands[1], true); 17073 else if (ROUND_<ROUNDING> == ROUND_CEIL) 17074 ix86_expand_lfloorceil (operands[0], operands[1], false); 17075 else 17076 gcc_unreachable (); 17077 17078 DONE; 17079}) 17080 17081(define_insn "fxam<mode>2_i387" 17082 [(set (match_operand:HI 0 "register_operand" "=a") 17083 (unspec:HI 17084 [(match_operand:X87MODEF 1 "register_operand" "f")] 17085 UNSPEC_FXAM))] 17086 "TARGET_USE_FANCY_MATH_387" 17087 "fxam\n\tfnstsw\t%0" 17088 [(set_attr "type" "multi") 17089 (set_attr "length" "4") 17090 (set_attr "unit" "i387") 17091 (set_attr "mode" "<MODE>")]) 17092 17093(define_expand "signbittf2" 17094 [(use (match_operand:SI 0 "register_operand")) 17095 (use (match_operand:TF 1 "register_operand"))] 17096 "TARGET_SSE" 17097{ 17098 if (TARGET_SSE4_1) 17099 { 17100 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0); 17101 rtx scratch = gen_reg_rtx (QImode); 17102 17103 emit_insn (gen_ptesttf2 (operands[1], mask)); 17104 ix86_expand_setcc (scratch, NE, 17105 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 17106 17107 emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); 17108 } 17109 else 17110 { 17111 emit_insn (gen_sse_movmskps (operands[0], 17112 gen_lowpart (V4SFmode, operands[1]))); 17113 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8))); 17114 } 17115 DONE; 17116}) 17117 17118(define_expand "signbitxf2" 17119 [(use (match_operand:SI 0 "register_operand")) 17120 (use (match_operand:XF 1 "register_operand"))] 17121 "TARGET_USE_FANCY_MATH_387" 17122{ 17123 rtx scratch = gen_reg_rtx (HImode); 17124 17125 emit_insn (gen_fxamxf2_i387 (scratch, operands[1])); 17126 emit_insn (gen_andsi3 (operands[0], 17127 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17128 DONE; 17129}) 17130 17131(define_insn "movmsk_df" 17132 [(set (match_operand:SI 0 "register_operand" "=r") 17133 (unspec:SI 17134 [(match_operand:DF 1 "register_operand" "x")] 17135 UNSPEC_MOVMSK))] 17136 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH" 17137 "%vmovmskpd\t{%1, %0|%0, %1}" 17138 [(set_attr "type" "ssemov") 17139 (set_attr "prefix" "maybe_vex") 17140 (set_attr "mode" "DF")]) 17141 17142;; Use movmskpd in SSE mode to avoid store forwarding stall 17143;; for 32bit targets and movq+shrq sequence for 64bit targets. 17144(define_expand "signbitdf2" 17145 [(use (match_operand:SI 0 "register_operand")) 17146 (use (match_operand:DF 1 "register_operand"))] 17147 "TARGET_USE_FANCY_MATH_387 17148 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)" 17149{ 17150 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH) 17151 { 17152 emit_insn (gen_movmsk_df (operands[0], operands[1])); 17153 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx)); 17154 } 17155 else 17156 { 17157 rtx scratch = gen_reg_rtx (HImode); 17158 17159 emit_insn (gen_fxamdf2_i387 (scratch, operands[1])); 17160 emit_insn (gen_andsi3 (operands[0], 17161 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17162 } 17163 DONE; 17164}) 17165 17166(define_expand "signbitsf2" 17167 [(use (match_operand:SI 0 "register_operand")) 17168 (use (match_operand:SF 1 "register_operand"))] 17169 "TARGET_USE_FANCY_MATH_387 17170 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)" 17171{ 17172 rtx scratch = gen_reg_rtx (HImode); 17173 17174 emit_insn (gen_fxamsf2_i387 (scratch, operands[1])); 17175 emit_insn (gen_andsi3 (operands[0], 17176 gen_lowpart (SImode, scratch), GEN_INT (0x200))); 17177 DONE; 17178}) 17179 17180;; Block operation instructions 17181 17182(define_insn "cld" 17183 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)] 17184 "" 17185 "cld" 17186 [(set_attr "length" "1") 17187 (set_attr "length_immediate" "0") 17188 (set_attr "modrm" "0")]) 17189 17190(define_expand "cpymem<mode>" 17191 [(use (match_operand:BLK 0 "memory_operand")) 17192 (use (match_operand:BLK 1 "memory_operand")) 17193 (use (match_operand:SWI48 2 "nonmemory_operand")) 17194 (use (match_operand:SWI48 3 "const_int_operand")) 17195 (use (match_operand:SI 4 "const_int_operand")) 17196 (use (match_operand:SI 5 "const_int_operand")) 17197 (use (match_operand:SI 6 "")) 17198 (use (match_operand:SI 7 "")) 17199 (use (match_operand:SI 8 ""))] 17200 "" 17201{ 17202 if (ix86_expand_set_or_cpymem (operands[0], operands[1], 17203 operands[2], NULL, operands[3], 17204 operands[4], operands[5], 17205 operands[6], operands[7], 17206 operands[8], false)) 17207 DONE; 17208 else 17209 FAIL; 17210}) 17211 17212;; Most CPUs don't like single string operations 17213;; Handle this case here to simplify previous expander. 17214 17215(define_expand "strmov" 17216 [(set (match_dup 4) (match_operand 3 "memory_operand")) 17217 (set (match_operand 1 "memory_operand") (match_dup 4)) 17218 (parallel [(set (match_operand 0 "register_operand") (match_dup 5)) 17219 (clobber (reg:CC FLAGS_REG))]) 17220 (parallel [(set (match_operand 2 "register_operand") (match_dup 6)) 17221 (clobber (reg:CC FLAGS_REG))])] 17222 "" 17223{ 17224 /* Can't use this for non-default address spaces. */ 17225 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3]))) 17226 FAIL; 17227 17228 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1]))); 17229 17230 /* If .md ever supports :P for Pmode, these can be directly 17231 in the pattern above. */ 17232 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust); 17233 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust); 17234 17235 /* Can't use this if the user has appropriated esi or edi. */ 17236 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 17237 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])) 17238 { 17239 emit_insn (gen_strmov_singleop (operands[0], operands[1], 17240 operands[2], operands[3], 17241 operands[5], operands[6])); 17242 DONE; 17243 } 17244 17245 operands[4] = gen_reg_rtx (GET_MODE (operands[1])); 17246}) 17247 17248(define_expand "strmov_singleop" 17249 [(parallel [(set (match_operand 1 "memory_operand") 17250 (match_operand 3 "memory_operand")) 17251 (set (match_operand 0 "register_operand") 17252 (match_operand 4)) 17253 (set (match_operand 2 "register_operand") 17254 (match_operand 5))])] 17255 "" 17256{ 17257 if (TARGET_CLD) 17258 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17259}) 17260 17261(define_insn "*strmovdi_rex_1" 17262 [(set (mem:DI (match_operand:P 2 "register_operand" "0")) 17263 (mem:DI (match_operand:P 3 "register_operand" "1"))) 17264 (set (match_operand:P 0 "register_operand" "=D") 17265 (plus:P (match_dup 2) 17266 (const_int 8))) 17267 (set (match_operand:P 1 "register_operand" "=S") 17268 (plus:P (match_dup 3) 17269 (const_int 8)))] 17270 "TARGET_64BIT 17271 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17272 && ix86_check_no_addr_space (insn)" 17273 "%^movsq" 17274 [(set_attr "type" "str") 17275 (set_attr "memory" "both") 17276 (set_attr "mode" "DI")]) 17277 17278(define_insn "*strmovsi_1" 17279 [(set (mem:SI (match_operand:P 2 "register_operand" "0")) 17280 (mem:SI (match_operand:P 3 "register_operand" "1"))) 17281 (set (match_operand:P 0 "register_operand" "=D") 17282 (plus:P (match_dup 2) 17283 (const_int 4))) 17284 (set (match_operand:P 1 "register_operand" "=S") 17285 (plus:P (match_dup 3) 17286 (const_int 4)))] 17287 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17288 && ix86_check_no_addr_space (insn)" 17289 "%^movs{l|d}" 17290 [(set_attr "type" "str") 17291 (set_attr "memory" "both") 17292 (set_attr "mode" "SI")]) 17293 17294(define_insn "*strmovhi_1" 17295 [(set (mem:HI (match_operand:P 2 "register_operand" "0")) 17296 (mem:HI (match_operand:P 3 "register_operand" "1"))) 17297 (set (match_operand:P 0 "register_operand" "=D") 17298 (plus:P (match_dup 2) 17299 (const_int 2))) 17300 (set (match_operand:P 1 "register_operand" "=S") 17301 (plus:P (match_dup 3) 17302 (const_int 2)))] 17303 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17304 && ix86_check_no_addr_space (insn)" 17305 "%^movsw" 17306 [(set_attr "type" "str") 17307 (set_attr "memory" "both") 17308 (set_attr "mode" "HI")]) 17309 17310(define_insn "*strmovqi_1" 17311 [(set (mem:QI (match_operand:P 2 "register_operand" "0")) 17312 (mem:QI (match_operand:P 3 "register_operand" "1"))) 17313 (set (match_operand:P 0 "register_operand" "=D") 17314 (plus:P (match_dup 2) 17315 (const_int 1))) 17316 (set (match_operand:P 1 "register_operand" "=S") 17317 (plus:P (match_dup 3) 17318 (const_int 1)))] 17319 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17320 && ix86_check_no_addr_space (insn)" 17321 "%^movsb" 17322 [(set_attr "type" "str") 17323 (set_attr "memory" "both") 17324 (set (attr "prefix_rex") 17325 (if_then_else 17326 (match_test "<P:MODE>mode == DImode") 17327 (const_string "0") 17328 (const_string "*"))) 17329 (set_attr "mode" "QI")]) 17330 17331(define_expand "rep_mov" 17332 [(parallel [(set (match_operand 4 "register_operand") (const_int 0)) 17333 (set (match_operand 0 "register_operand") 17334 (match_operand 5)) 17335 (set (match_operand 2 "register_operand") 17336 (match_operand 6)) 17337 (set (match_operand 1 "memory_operand") 17338 (match_operand 3 "memory_operand")) 17339 (use (match_dup 4))])] 17340 "" 17341{ 17342 if (TARGET_CLD) 17343 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17344}) 17345 17346(define_insn "*rep_movdi_rex64" 17347 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17348 (set (match_operand:P 0 "register_operand" "=D") 17349 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 17350 (const_int 3)) 17351 (match_operand:P 3 "register_operand" "0"))) 17352 (set (match_operand:P 1 "register_operand" "=S") 17353 (plus:P (ashift:P (match_dup 5) (const_int 3)) 17354 (match_operand:P 4 "register_operand" "1"))) 17355 (set (mem:BLK (match_dup 3)) 17356 (mem:BLK (match_dup 4))) 17357 (use (match_dup 5))] 17358 "TARGET_64BIT 17359 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17360 && ix86_check_no_addr_space (insn)" 17361 "%^rep{%;} movsq" 17362 [(set_attr "type" "str") 17363 (set_attr "prefix_rep" "1") 17364 (set_attr "memory" "both") 17365 (set_attr "mode" "DI")]) 17366 17367(define_insn "*rep_movsi" 17368 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17369 (set (match_operand:P 0 "register_operand" "=D") 17370 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2") 17371 (const_int 2)) 17372 (match_operand:P 3 "register_operand" "0"))) 17373 (set (match_operand:P 1 "register_operand" "=S") 17374 (plus:P (ashift:P (match_dup 5) (const_int 2)) 17375 (match_operand:P 4 "register_operand" "1"))) 17376 (set (mem:BLK (match_dup 3)) 17377 (mem:BLK (match_dup 4))) 17378 (use (match_dup 5))] 17379 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17380 && ix86_check_no_addr_space (insn)" 17381 "%^rep{%;} movs{l|d}" 17382 [(set_attr "type" "str") 17383 (set_attr "prefix_rep" "1") 17384 (set_attr "memory" "both") 17385 (set_attr "mode" "SI")]) 17386 17387(define_insn "*rep_movqi" 17388 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0)) 17389 (set (match_operand:P 0 "register_operand" "=D") 17390 (plus:P (match_operand:P 3 "register_operand" "0") 17391 (match_operand:P 5 "register_operand" "2"))) 17392 (set (match_operand:P 1 "register_operand" "=S") 17393 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5))) 17394 (set (mem:BLK (match_dup 3)) 17395 (mem:BLK (match_dup 4))) 17396 (use (match_dup 5))] 17397 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17398 && ix86_check_no_addr_space (insn)" 17399 "%^rep{%;} movsb" 17400 [(set_attr "type" "str") 17401 (set_attr "prefix_rep" "1") 17402 (set_attr "memory" "both") 17403 (set_attr "mode" "QI")]) 17404 17405(define_expand "setmem<mode>" 17406 [(use (match_operand:BLK 0 "memory_operand")) 17407 (use (match_operand:SWI48 1 "nonmemory_operand")) 17408 (use (match_operand:QI 2 "nonmemory_operand")) 17409 (use (match_operand 3 "const_int_operand")) 17410 (use (match_operand:SI 4 "const_int_operand")) 17411 (use (match_operand:SI 5 "const_int_operand")) 17412 (use (match_operand:SI 6 "")) 17413 (use (match_operand:SI 7 "")) 17414 (use (match_operand:SI 8 ""))] 17415 "" 17416{ 17417 if (ix86_expand_set_or_cpymem (operands[0], NULL, 17418 operands[1], operands[2], 17419 operands[3], operands[4], 17420 operands[5], operands[6], 17421 operands[7], operands[8], true)) 17422 DONE; 17423 else 17424 FAIL; 17425}) 17426 17427;; Most CPUs don't like single string operations 17428;; Handle this case here to simplify previous expander. 17429 17430(define_expand "strset" 17431 [(set (match_operand 1 "memory_operand") 17432 (match_operand 2 "register_operand")) 17433 (parallel [(set (match_operand 0 "register_operand") 17434 (match_dup 3)) 17435 (clobber (reg:CC FLAGS_REG))])] 17436 "" 17437{ 17438 /* Can't use this for non-default address spaces. */ 17439 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1]))) 17440 FAIL; 17441 17442 if (GET_MODE (operands[1]) != GET_MODE (operands[2])) 17443 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0); 17444 17445 /* If .md ever supports :P for Pmode, this can be directly 17446 in the pattern above. */ 17447 operands[3] = gen_rtx_PLUS (Pmode, operands[0], 17448 GEN_INT (GET_MODE_SIZE (GET_MODE 17449 (operands[2])))); 17450 /* Can't use this if the user has appropriated eax or edi. */ 17451 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ()) 17452 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])) 17453 { 17454 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2], 17455 operands[3])); 17456 DONE; 17457 } 17458}) 17459 17460(define_expand "strset_singleop" 17461 [(parallel [(set (match_operand 1 "memory_operand") 17462 (match_operand 2 "register_operand")) 17463 (set (match_operand 0 "register_operand") 17464 (match_operand 3)) 17465 (unspec [(const_int 0)] UNSPEC_STOS)])] 17466 "" 17467{ 17468 if (TARGET_CLD) 17469 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17470}) 17471 17472(define_insn "*strsetdi_rex_1" 17473 [(set (mem:DI (match_operand:P 1 "register_operand" "0")) 17474 (match_operand:DI 2 "register_operand" "a")) 17475 (set (match_operand:P 0 "register_operand" "=D") 17476 (plus:P (match_dup 1) 17477 (const_int 8))) 17478 (unspec [(const_int 0)] UNSPEC_STOS)] 17479 "TARGET_64BIT 17480 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17481 && ix86_check_no_addr_space (insn)" 17482 "%^stosq" 17483 [(set_attr "type" "str") 17484 (set_attr "memory" "store") 17485 (set_attr "mode" "DI")]) 17486 17487(define_insn "*strsetsi_1" 17488 [(set (mem:SI (match_operand:P 1 "register_operand" "0")) 17489 (match_operand:SI 2 "register_operand" "a")) 17490 (set (match_operand:P 0 "register_operand" "=D") 17491 (plus:P (match_dup 1) 17492 (const_int 4))) 17493 (unspec [(const_int 0)] UNSPEC_STOS)] 17494 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17495 && ix86_check_no_addr_space (insn)" 17496 "%^stos{l|d}" 17497 [(set_attr "type" "str") 17498 (set_attr "memory" "store") 17499 (set_attr "mode" "SI")]) 17500 17501(define_insn "*strsethi_1" 17502 [(set (mem:HI (match_operand:P 1 "register_operand" "0")) 17503 (match_operand:HI 2 "register_operand" "a")) 17504 (set (match_operand:P 0 "register_operand" "=D") 17505 (plus:P (match_dup 1) 17506 (const_int 2))) 17507 (unspec [(const_int 0)] UNSPEC_STOS)] 17508 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17509 && ix86_check_no_addr_space (insn)" 17510 "%^stosw" 17511 [(set_attr "type" "str") 17512 (set_attr "memory" "store") 17513 (set_attr "mode" "HI")]) 17514 17515(define_insn "*strsetqi_1" 17516 [(set (mem:QI (match_operand:P 1 "register_operand" "0")) 17517 (match_operand:QI 2 "register_operand" "a")) 17518 (set (match_operand:P 0 "register_operand" "=D") 17519 (plus:P (match_dup 1) 17520 (const_int 1))) 17521 (unspec [(const_int 0)] UNSPEC_STOS)] 17522 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG]) 17523 && ix86_check_no_addr_space (insn)" 17524 "%^stosb" 17525 [(set_attr "type" "str") 17526 (set_attr "memory" "store") 17527 (set (attr "prefix_rex") 17528 (if_then_else 17529 (match_test "<P:MODE>mode == DImode") 17530 (const_string "0") 17531 (const_string "*"))) 17532 (set_attr "mode" "QI")]) 17533 17534(define_expand "rep_stos" 17535 [(parallel [(set (match_operand 1 "register_operand") (const_int 0)) 17536 (set (match_operand 0 "register_operand") 17537 (match_operand 4)) 17538 (set (match_operand 2 "memory_operand") (const_int 0)) 17539 (use (match_operand 3 "register_operand")) 17540 (use (match_dup 1))])] 17541 "" 17542{ 17543 if (TARGET_CLD) 17544 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17545}) 17546 17547(define_insn "*rep_stosdi_rex64" 17548 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17549 (set (match_operand:P 0 "register_operand" "=D") 17550 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 17551 (const_int 3)) 17552 (match_operand:P 3 "register_operand" "0"))) 17553 (set (mem:BLK (match_dup 3)) 17554 (const_int 0)) 17555 (use (match_operand:DI 2 "register_operand" "a")) 17556 (use (match_dup 4))] 17557 "TARGET_64BIT 17558 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17559 && ix86_check_no_addr_space (insn)" 17560 "%^rep{%;} stosq" 17561 [(set_attr "type" "str") 17562 (set_attr "prefix_rep" "1") 17563 (set_attr "memory" "store") 17564 (set_attr "mode" "DI")]) 17565 17566(define_insn "*rep_stossi" 17567 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17568 (set (match_operand:P 0 "register_operand" "=D") 17569 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1") 17570 (const_int 2)) 17571 (match_operand:P 3 "register_operand" "0"))) 17572 (set (mem:BLK (match_dup 3)) 17573 (const_int 0)) 17574 (use (match_operand:SI 2 "register_operand" "a")) 17575 (use (match_dup 4))] 17576 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17577 && ix86_check_no_addr_space (insn)" 17578 "%^rep{%;} stos{l|d}" 17579 [(set_attr "type" "str") 17580 (set_attr "prefix_rep" "1") 17581 (set_attr "memory" "store") 17582 (set_attr "mode" "SI")]) 17583 17584(define_insn "*rep_stosqi" 17585 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0)) 17586 (set (match_operand:P 0 "register_operand" "=D") 17587 (plus:P (match_operand:P 3 "register_operand" "0") 17588 (match_operand:P 4 "register_operand" "1"))) 17589 (set (mem:BLK (match_dup 3)) 17590 (const_int 0)) 17591 (use (match_operand:QI 2 "register_operand" "a")) 17592 (use (match_dup 4))] 17593 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17594 && ix86_check_no_addr_space (insn)" 17595 "%^rep{%;} stosb" 17596 [(set_attr "type" "str") 17597 (set_attr "prefix_rep" "1") 17598 (set_attr "memory" "store") 17599 (set (attr "prefix_rex") 17600 (if_then_else 17601 (match_test "<P:MODE>mode == DImode") 17602 (const_string "0") 17603 (const_string "*"))) 17604 (set_attr "mode" "QI")]) 17605 17606(define_expand "cmpstrnsi" 17607 [(set (match_operand:SI 0 "register_operand") 17608 (compare:SI (match_operand:BLK 1 "general_operand") 17609 (match_operand:BLK 2 "general_operand"))) 17610 (use (match_operand 3 "general_operand")) 17611 (use (match_operand 4 "immediate_operand"))] 17612 "" 17613{ 17614 rtx addr1, addr2, countreg, align, out; 17615 17616 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS) 17617 FAIL; 17618 17619 /* Can't use this if the user has appropriated ecx, esi or edi. */ 17620 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17621 FAIL; 17622 17623 /* One of the strings must be a constant. If so, expand_builtin_strncmp() 17624 will have rewritten the length arg to be the minimum of the const string 17625 length and the actual length arg. If both strings are the same and 17626 shorter than the length arg, repz cmpsb will not stop at the 0 byte and 17627 will incorrectly base the results on chars past the 0 byte. */ 17628 tree t1 = MEM_EXPR (operands[1]); 17629 tree t2 = MEM_EXPR (operands[2]); 17630 if (!((t1 && TREE_CODE (t1) == MEM_REF 17631 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR 17632 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST) 17633 || (t2 && TREE_CODE (t2) == MEM_REF 17634 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR 17635 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST))) 17636 FAIL; 17637 17638 addr1 = copy_addr_to_reg (XEXP (operands[1], 0)); 17639 addr2 = copy_addr_to_reg (XEXP (operands[2], 0)); 17640 if (addr1 != XEXP (operands[1], 0)) 17641 operands[1] = replace_equiv_address_nv (operands[1], addr1); 17642 if (addr2 != XEXP (operands[2], 0)) 17643 operands[2] = replace_equiv_address_nv (operands[2], addr2); 17644 17645 countreg = ix86_zero_extend_to_Pmode (operands[3]); 17646 17647 /* %%% Iff we are testing strict equality, we can use known alignment 17648 to good advantage. This may be possible with combine, particularly 17649 once cc0 is dead. */ 17650 align = operands[4]; 17651 17652 if (CONST_INT_P (operands[3])) 17653 { 17654 if (operands[3] == const0_rtx) 17655 { 17656 emit_move_insn (operands[0], const0_rtx); 17657 DONE; 17658 } 17659 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align, 17660 operands[1], operands[2])); 17661 } 17662 else 17663 { 17664 emit_insn (gen_cmp_1 (Pmode, countreg, countreg)); 17665 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align, 17666 operands[1], operands[2])); 17667 } 17668 17669 out = gen_lowpart (QImode, operands[0]); 17670 emit_insn (gen_cmpintqi (out)); 17671 emit_move_insn (operands[0], gen_rtx_SIGN_EXTEND (SImode, out)); 17672 17673 DONE; 17674}) 17675 17676;; Produce a tri-state integer (-1, 0, 1) from condition codes. 17677 17678(define_expand "cmpintqi" 17679 [(set (match_dup 1) 17680 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17681 (set (match_dup 2) 17682 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17683 (parallel [(set (match_operand:QI 0 "register_operand") 17684 (minus:QI (match_dup 1) 17685 (match_dup 2))) 17686 (clobber (reg:CC FLAGS_REG))])] 17687 "" 17688{ 17689 operands[1] = gen_reg_rtx (QImode); 17690 operands[2] = gen_reg_rtx (QImode); 17691}) 17692 17693;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is 17694;; zero. Emit extra code to make sure that a zero-length compare is EQ. 17695 17696(define_expand "cmpstrnqi_nz_1" 17697 [(parallel [(set (reg:CC FLAGS_REG) 17698 (compare:CC (match_operand 4 "memory_operand") 17699 (match_operand 5 "memory_operand"))) 17700 (use (match_operand 2 "register_operand")) 17701 (use (match_operand:SI 3 "immediate_operand")) 17702 (clobber (match_operand 0 "register_operand")) 17703 (clobber (match_operand 1 "register_operand")) 17704 (clobber (match_dup 2))])] 17705 "" 17706{ 17707 if (TARGET_CLD) 17708 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17709}) 17710 17711(define_insn "*cmpstrnqi_nz_1" 17712 [(set (reg:CC FLAGS_REG) 17713 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 17714 (mem:BLK (match_operand:P 5 "register_operand" "1")))) 17715 (use (match_operand:P 6 "register_operand" "2")) 17716 (use (match_operand:SI 3 "immediate_operand" "i")) 17717 (clobber (match_operand:P 0 "register_operand" "=S")) 17718 (clobber (match_operand:P 1 "register_operand" "=D")) 17719 (clobber (match_operand:P 2 "register_operand" "=c"))] 17720 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17721 && ix86_check_no_addr_space (insn)" 17722 "%^repz{%;} cmpsb" 17723 [(set_attr "type" "str") 17724 (set_attr "mode" "QI") 17725 (set (attr "prefix_rex") 17726 (if_then_else 17727 (match_test "<P:MODE>mode == DImode") 17728 (const_string "0") 17729 (const_string "*"))) 17730 (set_attr "prefix_rep" "1")]) 17731 17732;; The same, but the count is not known to not be zero. 17733 17734(define_expand "cmpstrnqi_1" 17735 [(parallel [(set (reg:CC FLAGS_REG) 17736 (if_then_else:CC (ne (match_operand 2 "register_operand") 17737 (const_int 0)) 17738 (compare:CC (match_operand 4 "memory_operand") 17739 (match_operand 5 "memory_operand")) 17740 (const_int 0))) 17741 (use (match_operand:SI 3 "immediate_operand")) 17742 (use (reg:CC FLAGS_REG)) 17743 (clobber (match_operand 0 "register_operand")) 17744 (clobber (match_operand 1 "register_operand")) 17745 (clobber (match_dup 2))])] 17746 "" 17747{ 17748 if (TARGET_CLD) 17749 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17750}) 17751 17752(define_insn "*cmpstrnqi_1" 17753 [(set (reg:CC FLAGS_REG) 17754 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2") 17755 (const_int 0)) 17756 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0")) 17757 (mem:BLK (match_operand:P 5 "register_operand" "1"))) 17758 (const_int 0))) 17759 (use (match_operand:SI 3 "immediate_operand" "i")) 17760 (use (reg:CC FLAGS_REG)) 17761 (clobber (match_operand:P 0 "register_operand" "=S")) 17762 (clobber (match_operand:P 1 "register_operand" "=D")) 17763 (clobber (match_operand:P 2 "register_operand" "=c"))] 17764 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG]) 17765 && ix86_check_no_addr_space (insn)" 17766 "%^repz{%;} cmpsb" 17767 [(set_attr "type" "str") 17768 (set_attr "mode" "QI") 17769 (set (attr "prefix_rex") 17770 (if_then_else 17771 (match_test "<P:MODE>mode == DImode") 17772 (const_string "0") 17773 (const_string "*"))) 17774 (set_attr "prefix_rep" "1")]) 17775 17776(define_expand "strlen<mode>" 17777 [(set (match_operand:P 0 "register_operand") 17778 (unspec:P [(match_operand:BLK 1 "general_operand") 17779 (match_operand:QI 2 "immediate_operand") 17780 (match_operand 3 "immediate_operand")] 17781 UNSPEC_SCAS))] 17782 "" 17783{ 17784 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3])) 17785 DONE; 17786 else 17787 FAIL; 17788}) 17789 17790(define_expand "strlenqi_1" 17791 [(parallel [(set (match_operand 0 "register_operand") 17792 (match_operand 2)) 17793 (clobber (match_operand 1 "register_operand")) 17794 (clobber (reg:CC FLAGS_REG))])] 17795 "" 17796{ 17797 if (TARGET_CLD) 17798 ix86_optimize_mode_switching[X86_DIRFLAG] = 1; 17799}) 17800 17801(define_insn "*strlenqi_1" 17802 [(set (match_operand:P 0 "register_operand" "=&c") 17803 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1")) 17804 (match_operand:QI 2 "register_operand" "a") 17805 (match_operand:P 3 "immediate_operand" "i") 17806 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS)) 17807 (clobber (match_operand:P 1 "register_operand" "=D")) 17808 (clobber (reg:CC FLAGS_REG))] 17809 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG]) 17810 && ix86_check_no_addr_space (insn)" 17811 "%^repnz{%;} scasb" 17812 [(set_attr "type" "str") 17813 (set_attr "mode" "QI") 17814 (set (attr "prefix_rex") 17815 (if_then_else 17816 (match_test "<P:MODE>mode == DImode") 17817 (const_string "0") 17818 (const_string "*"))) 17819 (set_attr "prefix_rep" "1")]) 17820 17821;; Peephole optimizations to clean up after cmpstrn*. This should be 17822;; handled in combine, but it is not currently up to the task. 17823;; When used for their truth value, the cmpstrn* expanders generate 17824;; code like this: 17825;; 17826;; repz cmpsb 17827;; seta %al 17828;; setb %dl 17829;; cmpb %al, %dl 17830;; jcc label 17831;; 17832;; The intermediate three instructions are unnecessary. 17833 17834;; This one handles cmpstrn*_nz_1... 17835(define_peephole2 17836 [(parallel[ 17837 (set (reg:CC FLAGS_REG) 17838 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 17839 (mem:BLK (match_operand 5 "register_operand")))) 17840 (use (match_operand 6 "register_operand")) 17841 (use (match_operand:SI 3 "immediate_operand")) 17842 (clobber (match_operand 0 "register_operand")) 17843 (clobber (match_operand 1 "register_operand")) 17844 (clobber (match_operand 2 "register_operand"))]) 17845 (set (match_operand:QI 7 "register_operand") 17846 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17847 (set (match_operand:QI 8 "register_operand") 17848 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17849 (set (reg FLAGS_REG) 17850 (compare (match_dup 7) (match_dup 8))) 17851 ] 17852 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 17853 [(parallel[ 17854 (set (reg:CC FLAGS_REG) 17855 (compare:CC (mem:BLK (match_dup 4)) 17856 (mem:BLK (match_dup 5)))) 17857 (use (match_dup 6)) 17858 (use (match_dup 3)) 17859 (clobber (match_dup 0)) 17860 (clobber (match_dup 1)) 17861 (clobber (match_dup 2))])]) 17862 17863;; ...and this one handles cmpstrn*_1. 17864(define_peephole2 17865 [(parallel[ 17866 (set (reg:CC FLAGS_REG) 17867 (if_then_else:CC (ne (match_operand 6 "register_operand") 17868 (const_int 0)) 17869 (compare:CC (mem:BLK (match_operand 4 "register_operand")) 17870 (mem:BLK (match_operand 5 "register_operand"))) 17871 (const_int 0))) 17872 (use (match_operand:SI 3 "immediate_operand")) 17873 (use (reg:CC FLAGS_REG)) 17874 (clobber (match_operand 0 "register_operand")) 17875 (clobber (match_operand 1 "register_operand")) 17876 (clobber (match_operand 2 "register_operand"))]) 17877 (set (match_operand:QI 7 "register_operand") 17878 (gtu:QI (reg:CC FLAGS_REG) (const_int 0))) 17879 (set (match_operand:QI 8 "register_operand") 17880 (ltu:QI (reg:CC FLAGS_REG) (const_int 0))) 17881 (set (reg FLAGS_REG) 17882 (compare (match_dup 7) (match_dup 8))) 17883 ] 17884 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])" 17885 [(parallel[ 17886 (set (reg:CC FLAGS_REG) 17887 (if_then_else:CC (ne (match_dup 6) 17888 (const_int 0)) 17889 (compare:CC (mem:BLK (match_dup 4)) 17890 (mem:BLK (match_dup 5))) 17891 (const_int 0))) 17892 (use (match_dup 3)) 17893 (use (reg:CC FLAGS_REG)) 17894 (clobber (match_dup 0)) 17895 (clobber (match_dup 1)) 17896 (clobber (match_dup 2))])]) 17897 17898;; Conditional move instructions. 17899 17900(define_expand "mov<mode>cc" 17901 [(set (match_operand:SWIM 0 "register_operand") 17902 (if_then_else:SWIM (match_operand 1 "comparison_operator") 17903 (match_operand:SWIM 2 "<general_operand>") 17904 (match_operand:SWIM 3 "<general_operand>")))] 17905 "" 17906 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;") 17907 17908;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing 17909;; the register first winds up with `sbbl $0,reg', which is also weird. 17910;; So just document what we're doing explicitly. 17911 17912(define_expand "x86_mov<mode>cc_0_m1" 17913 [(parallel 17914 [(set (match_operand:SWI48 0 "register_operand") 17915 (if_then_else:SWI48 17916 (match_operator:SWI48 2 "ix86_carry_flag_operator" 17917 [(match_operand 1 "flags_reg_operand") 17918 (const_int 0)]) 17919 (const_int -1) 17920 (const_int 0))) 17921 (clobber (reg:CC FLAGS_REG))])]) 17922 17923(define_insn "*x86_mov<mode>cc_0_m1" 17924 [(set (match_operand:SWI48 0 "register_operand" "=r") 17925 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17926 [(reg FLAGS_REG) (const_int 0)]) 17927 (const_int -1) 17928 (const_int 0))) 17929 (clobber (reg:CC FLAGS_REG))] 17930 "" 17931 "sbb{<imodesuffix>}\t%0, %0" 17932 [(set_attr "type" "alu1") 17933 (set_attr "use_carry" "1") 17934 (set_attr "pent_pair" "pu") 17935 (set_attr "mode" "<MODE>") 17936 (set_attr "length_immediate" "0")]) 17937 17938(define_insn "*x86_mov<mode>cc_0_m1_se" 17939 [(set (match_operand:SWI48 0 "register_operand" "=r") 17940 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17941 [(reg FLAGS_REG) (const_int 0)]) 17942 (const_int 1) 17943 (const_int 0))) 17944 (clobber (reg:CC FLAGS_REG))] 17945 "" 17946 "sbb{<imodesuffix>}\t%0, %0" 17947 [(set_attr "type" "alu1") 17948 (set_attr "use_carry" "1") 17949 (set_attr "pent_pair" "pu") 17950 (set_attr "mode" "<MODE>") 17951 (set_attr "length_immediate" "0")]) 17952 17953(define_insn "*x86_mov<mode>cc_0_m1_neg" 17954 [(set (match_operand:SWI48 0 "register_operand" "=r") 17955 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator" 17956 [(reg FLAGS_REG) (const_int 0)]))) 17957 (clobber (reg:CC FLAGS_REG))] 17958 "" 17959 "sbb{<imodesuffix>}\t%0, %0" 17960 [(set_attr "type" "alu1") 17961 (set_attr "use_carry" "1") 17962 (set_attr "pent_pair" "pu") 17963 (set_attr "mode" "<MODE>") 17964 (set_attr "length_immediate" "0")]) 17965 17966(define_insn_and_split "*x86_mov<SWI48:mode>cc_0_m1_neg_leu<SWI:mode>" 17967 [(set (match_operand:SWI48 0 "register_operand" "=r") 17968 (neg:SWI48 17969 (leu:SWI48 17970 (match_operand:SWI 1 "nonimmediate_operand" "<SWI:r>m") 17971 (match_operand:SWI 2 "<SWI:immediate_operand>" "<SWI:i>")))) 17972 (clobber (reg:CC FLAGS_REG))] 17973 "CONST_INT_P (operands[2]) 17974 && INTVAL (operands[2]) != -1 17975 && INTVAL (operands[2]) != 2147483647" 17976 "#" 17977 "" 17978 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2))) 17979 (parallel [(set (match_dup 0) 17980 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))) 17981 (clobber (reg:CC FLAGS_REG))])] 17982 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);") 17983 17984(define_insn "*mov<mode>cc_noc" 17985 [(set (match_operand:SWI248 0 "register_operand" "=r,r") 17986 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 17987 [(reg FLAGS_REG) (const_int 0)]) 17988 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0") 17989 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))] 17990 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 17991 "@ 17992 cmov%O2%C1\t{%2, %0|%0, %2} 17993 cmov%O2%c1\t{%3, %0|%0, %3}" 17994 [(set_attr "type" "icmov") 17995 (set_attr "mode" "<MODE>")]) 17996 17997(define_insn "*movsicc_noc_zext" 17998 [(set (match_operand:DI 0 "register_operand" "=r,r") 17999 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 18000 [(reg FLAGS_REG) (const_int 0)]) 18001 (zero_extend:DI 18002 (match_operand:SI 2 "nonimmediate_operand" "rm,0")) 18003 (zero_extend:DI 18004 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))] 18005 "TARGET_64BIT 18006 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18007 "@ 18008 cmov%O2%C1\t{%2, %k0|%k0, %2} 18009 cmov%O2%c1\t{%3, %k0|%k0, %3}" 18010 [(set_attr "type" "icmov") 18011 (set_attr "mode" "SI")]) 18012 18013;; Don't do conditional moves with memory inputs. This splitter helps 18014;; register starved x86_32 by forcing inputs into registers before reload. 18015(define_split 18016 [(set (match_operand:SWI248 0 "register_operand") 18017 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 18018 [(reg FLAGS_REG) (const_int 0)]) 18019 (match_operand:SWI248 2 "nonimmediate_operand") 18020 (match_operand:SWI248 3 "nonimmediate_operand")))] 18021 "!TARGET_64BIT && TARGET_CMOVE 18022 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18023 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18024 && can_create_pseudo_p () 18025 && optimize_insn_for_speed_p ()" 18026 [(set (match_dup 0) 18027 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 18028{ 18029 if (MEM_P (operands[2])) 18030 operands[2] = force_reg (<MODE>mode, operands[2]); 18031 if (MEM_P (operands[3])) 18032 operands[3] = force_reg (<MODE>mode, operands[3]); 18033}) 18034 18035(define_insn "*movqicc_noc" 18036 [(set (match_operand:QI 0 "register_operand" "=r,r") 18037 (if_then_else:QI (match_operator 1 "ix86_comparison_operator" 18038 [(reg FLAGS_REG) (const_int 0)]) 18039 (match_operand:QI 2 "register_operand" "r,0") 18040 (match_operand:QI 3 "register_operand" "0,r")))] 18041 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL" 18042 "#" 18043 [(set_attr "type" "icmov") 18044 (set_attr "mode" "QI")]) 18045 18046(define_split 18047 [(set (match_operand:SWI12 0 "register_operand") 18048 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator" 18049 [(reg FLAGS_REG) (const_int 0)]) 18050 (match_operand:SWI12 2 "register_operand") 18051 (match_operand:SWI12 3 "register_operand")))] 18052 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL 18053 && reload_completed" 18054 [(set (match_dup 0) 18055 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))] 18056{ 18057 operands[0] = gen_lowpart (SImode, operands[0]); 18058 operands[2] = gen_lowpart (SImode, operands[2]); 18059 operands[3] = gen_lowpart (SImode, operands[3]); 18060}) 18061 18062;; Don't do conditional moves with memory inputs 18063(define_peephole2 18064 [(match_scratch:SWI248 4 "r") 18065 (set (match_operand:SWI248 0 "register_operand") 18066 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator" 18067 [(reg FLAGS_REG) (const_int 0)]) 18068 (match_operand:SWI248 2 "nonimmediate_operand") 18069 (match_operand:SWI248 3 "nonimmediate_operand")))] 18070 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18071 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18072 && optimize_insn_for_speed_p ()" 18073 [(set (match_dup 4) (match_dup 5)) 18074 (set (match_dup 0) 18075 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))] 18076{ 18077 if (MEM_P (operands[2])) 18078 { 18079 operands[5] = operands[2]; 18080 operands[2] = operands[4]; 18081 } 18082 else if (MEM_P (operands[3])) 18083 { 18084 operands[5] = operands[3]; 18085 operands[3] = operands[4]; 18086 } 18087 else 18088 gcc_unreachable (); 18089}) 18090 18091(define_peephole2 18092 [(match_scratch:SI 4 "r") 18093 (set (match_operand:DI 0 "register_operand") 18094 (if_then_else:DI (match_operator 1 "ix86_comparison_operator" 18095 [(reg FLAGS_REG) (const_int 0)]) 18096 (zero_extend:DI 18097 (match_operand:SI 2 "nonimmediate_operand")) 18098 (zero_extend:DI 18099 (match_operand:SI 3 "nonimmediate_operand"))))] 18100 "TARGET_64BIT 18101 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18102 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18103 && optimize_insn_for_speed_p ()" 18104 [(set (match_dup 4) (match_dup 5)) 18105 (set (match_dup 0) 18106 (if_then_else:DI (match_dup 1) 18107 (zero_extend:DI (match_dup 2)) 18108 (zero_extend:DI (match_dup 3))))] 18109{ 18110 if (MEM_P (operands[2])) 18111 { 18112 operands[5] = operands[2]; 18113 operands[2] = operands[4]; 18114 } 18115 else if (MEM_P (operands[3])) 18116 { 18117 operands[5] = operands[3]; 18118 operands[3] = operands[4]; 18119 } 18120 else 18121 gcc_unreachable (); 18122}) 18123 18124(define_expand "mov<mode>cc" 18125 [(set (match_operand:X87MODEF 0 "register_operand") 18126 (if_then_else:X87MODEF 18127 (match_operand 1 "comparison_operator") 18128 (match_operand:X87MODEF 2 "register_operand") 18129 (match_operand:X87MODEF 3 "register_operand")))] 18130 "(TARGET_80387 && TARGET_CMOVE) 18131 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)" 18132 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;") 18133 18134(define_insn "*movxfcc_1" 18135 [(set (match_operand:XF 0 "register_operand" "=f,f") 18136 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator" 18137 [(reg FLAGS_REG) (const_int 0)]) 18138 (match_operand:XF 2 "register_operand" "f,0") 18139 (match_operand:XF 3 "register_operand" "0,f")))] 18140 "TARGET_80387 && TARGET_CMOVE" 18141 "@ 18142 fcmov%F1\t{%2, %0|%0, %2} 18143 fcmov%f1\t{%3, %0|%0, %3}" 18144 [(set_attr "type" "fcmov") 18145 (set_attr "mode" "XF")]) 18146 18147(define_insn "*movdfcc_1" 18148 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r") 18149 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18150 [(reg FLAGS_REG) (const_int 0)]) 18151 (match_operand:DF 2 "nonimmediate_operand" 18152 "f ,0,rm,0 ,rm,0") 18153 (match_operand:DF 3 "nonimmediate_operand" 18154 "0 ,f,0 ,rm,0, rm")))] 18155 "TARGET_80387 && TARGET_CMOVE 18156 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18157 "@ 18158 fcmov%F1\t{%2, %0|%0, %2} 18159 fcmov%f1\t{%3, %0|%0, %3} 18160 # 18161 # 18162 cmov%O2%C1\t{%2, %0|%0, %2} 18163 cmov%O2%c1\t{%3, %0|%0, %3}" 18164 [(set_attr "isa" "*,*,nox64,nox64,x64,x64") 18165 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov") 18166 (set_attr "mode" "DF,DF,DI,DI,DI,DI")]) 18167 18168(define_split 18169 [(set (match_operand:DF 0 "general_reg_operand") 18170 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" 18171 [(reg FLAGS_REG) (const_int 0)]) 18172 (match_operand:DF 2 "nonimmediate_operand") 18173 (match_operand:DF 3 "nonimmediate_operand")))] 18174 "!TARGET_64BIT && reload_completed" 18175 [(set (match_dup 2) 18176 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5))) 18177 (set (match_dup 3) 18178 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))] 18179{ 18180 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]); 18181 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]); 18182}) 18183 18184(define_insn "*movsfcc_1_387" 18185 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") 18186 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" 18187 [(reg FLAGS_REG) (const_int 0)]) 18188 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") 18189 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] 18190 "TARGET_80387 && TARGET_CMOVE 18191 && !(MEM_P (operands[2]) && MEM_P (operands[3]))" 18192 "@ 18193 fcmov%F1\t{%2, %0|%0, %2} 18194 fcmov%f1\t{%3, %0|%0, %3} 18195 cmov%O2%C1\t{%2, %0|%0, %2} 18196 cmov%O2%c1\t{%3, %0|%0, %3}" 18197 [(set_attr "type" "fcmov,fcmov,icmov,icmov") 18198 (set_attr "mode" "SF,SF,SI,SI")]) 18199 18200;; Don't do conditional moves with memory inputs. This splitter helps 18201;; register starved x86_32 by forcing inputs into registers before reload. 18202(define_split 18203 [(set (match_operand:MODEF 0 "register_operand") 18204 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator" 18205 [(reg FLAGS_REG) (const_int 0)]) 18206 (match_operand:MODEF 2 "nonimmediate_operand") 18207 (match_operand:MODEF 3 "nonimmediate_operand")))] 18208 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE 18209 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18210 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18211 && can_create_pseudo_p () 18212 && optimize_insn_for_speed_p ()" 18213 [(set (match_dup 0) 18214 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 18215{ 18216 if (MEM_P (operands[2])) 18217 operands[2] = force_reg (<MODE>mode, operands[2]); 18218 if (MEM_P (operands[3])) 18219 operands[3] = force_reg (<MODE>mode, operands[3]); 18220}) 18221 18222;; Don't do conditional moves with memory inputs 18223(define_peephole2 18224 [(match_scratch:MODEF 4 "r") 18225 (set (match_operand:MODEF 0 "general_reg_operand") 18226 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator" 18227 [(reg FLAGS_REG) (const_int 0)]) 18228 (match_operand:MODEF 2 "nonimmediate_operand") 18229 (match_operand:MODEF 3 "nonimmediate_operand")))] 18230 "(<MODE>mode != DFmode || TARGET_64BIT) 18231 && TARGET_80387 && TARGET_CMOVE 18232 && TARGET_AVOID_MEM_OPND_FOR_CMOVE 18233 && (MEM_P (operands[2]) || MEM_P (operands[3])) 18234 && optimize_insn_for_speed_p ()" 18235 [(set (match_dup 4) (match_dup 5)) 18236 (set (match_dup 0) 18237 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))] 18238{ 18239 if (MEM_P (operands[2])) 18240 { 18241 operands[5] = operands[2]; 18242 operands[2] = operands[4]; 18243 } 18244 else if (MEM_P (operands[3])) 18245 { 18246 operands[5] = operands[3]; 18247 operands[3] = operands[4]; 18248 } 18249 else 18250 gcc_unreachable (); 18251}) 18252 18253;; All moves in XOP pcmov instructions are 128 bits and hence we restrict 18254;; the scalar versions to have only XMM registers as operands. 18255 18256;; XOP conditional move 18257(define_insn "*xop_pcmov_<mode>" 18258 [(set (match_operand:MODEF 0 "register_operand" "=x") 18259 (if_then_else:MODEF 18260 (match_operand:MODEF 1 "register_operand" "x") 18261 (match_operand:MODEF 2 "register_operand" "x") 18262 (match_operand:MODEF 3 "register_operand" "x")))] 18263 "TARGET_XOP" 18264 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}" 18265 [(set_attr "type" "sse4arg")]) 18266 18267;; These versions of the min/max patterns are intentionally ignorant of 18268;; their behavior wrt -0.0 and NaN (via the commutative operand mark). 18269;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator 18270;; are undefined in this condition, we're certain this is correct. 18271 18272(define_insn "<code><mode>3" 18273 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 18274 (smaxmin:MODEF 18275 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v") 18276 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))] 18277 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 18278 "@ 18279 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2} 18280 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 18281 [(set_attr "isa" "noavx,avx") 18282 (set_attr "prefix" "orig,vex") 18283 (set_attr "type" "sseadd") 18284 (set_attr "mode" "<MODE>")]) 18285 18286;; These versions of the min/max patterns implement exactly the operations 18287;; min = (op1 < op2 ? op1 : op2) 18288;; max = (!(op1 < op2) ? op1 : op2) 18289;; Their operands are not commutative, and thus they may be used in the 18290;; presence of -0.0 and NaN. 18291 18292(define_insn "*ieee_s<ieee_maxmin><mode>3" 18293 [(set (match_operand:MODEF 0 "register_operand" "=x,v") 18294 (unspec:MODEF 18295 [(match_operand:MODEF 1 "register_operand" "0,v") 18296 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")] 18297 IEEE_MAXMIN))] 18298 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" 18299 "@ 18300 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2} 18301 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" 18302 [(set_attr "isa" "noavx,avx") 18303 (set_attr "prefix" "orig,maybe_evex") 18304 (set_attr "type" "sseadd") 18305 (set_attr "mode" "<MODE>")]) 18306 18307;; Make two stack loads independent: 18308;; fld aa fld aa 18309;; fld %st(0) -> fld bb 18310;; fmul bb fmul %st(1), %st 18311;; 18312;; Actually we only match the last two instructions for simplicity. 18313 18314(define_peephole2 18315 [(set (match_operand 0 "fp_register_operand") 18316 (match_operand 1 "fp_register_operand")) 18317 (set (match_dup 0) 18318 (match_operator 2 "binary_fp_operator" 18319 [(match_dup 0) 18320 (match_operand 3 "memory_operand")]))] 18321 "REGNO (operands[0]) != REGNO (operands[1])" 18322 [(set (match_dup 0) (match_dup 3)) 18323 (set (match_dup 0) 18324 (match_op_dup 2 18325 [(match_dup 5) (match_dup 4)]))] 18326{ 18327 operands[4] = operands[0]; 18328 operands[5] = operands[1]; 18329 18330 /* The % modifier is not operational anymore in peephole2's, so we have to 18331 swap the operands manually in the case of addition and multiplication. */ 18332 if (COMMUTATIVE_ARITH_P (operands[2])) 18333 std::swap (operands[4], operands[5]); 18334}) 18335 18336(define_peephole2 18337 [(set (match_operand 0 "fp_register_operand") 18338 (match_operand 1 "fp_register_operand")) 18339 (set (match_dup 0) 18340 (match_operator 2 "binary_fp_operator" 18341 [(match_operand 3 "memory_operand") 18342 (match_dup 0)]))] 18343 "REGNO (operands[0]) != REGNO (operands[1])" 18344 [(set (match_dup 0) (match_dup 3)) 18345 (set (match_dup 0) 18346 (match_op_dup 2 18347 [(match_dup 4) (match_dup 5)]))] 18348{ 18349 operands[4] = operands[0]; 18350 operands[5] = operands[1]; 18351 18352 /* The % modifier is not operational anymore in peephole2's, so we have to 18353 swap the operands manually in the case of addition and multiplication. */ 18354 if (COMMUTATIVE_ARITH_P (operands[2])) 18355 std::swap (operands[4], operands[5]); 18356}) 18357 18358;; Conditional addition patterns 18359(define_expand "add<mode>cc" 18360 [(match_operand:SWI 0 "register_operand") 18361 (match_operand 1 "ordered_comparison_operator") 18362 (match_operand:SWI 2 "register_operand") 18363 (match_operand:SWI 3 "const_int_operand")] 18364 "" 18365 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;") 18366 18367;; min/max patterns 18368 18369(define_mode_iterator MAXMIN_IMODE 18370 [(SI "TARGET_SSE4_1") (DI "TARGET_AVX512VL")]) 18371(define_code_attr maxmin_rel 18372 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")]) 18373 18374(define_expand "<code><mode>3" 18375 [(parallel 18376 [(set (match_operand:MAXMIN_IMODE 0 "register_operand") 18377 (maxmin:MAXMIN_IMODE 18378 (match_operand:MAXMIN_IMODE 1 "register_operand") 18379 (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand"))) 18380 (clobber (reg:CC FLAGS_REG))])] 18381 "TARGET_STV") 18382 18383(define_insn_and_split "*<code><mode>3_1" 18384 [(set (match_operand:MAXMIN_IMODE 0 "register_operand") 18385 (maxmin:MAXMIN_IMODE 18386 (match_operand:MAXMIN_IMODE 1 "register_operand") 18387 (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand"))) 18388 (clobber (reg:CC FLAGS_REG))] 18389 "(TARGET_64BIT || <MODE>mode != DImode) && TARGET_STV 18390 && ix86_pre_reload_split ()" 18391 "#" 18392 "&& 1" 18393 [(set (match_dup 0) 18394 (if_then_else:MAXMIN_IMODE (match_dup 3) 18395 (match_dup 1) 18396 (match_dup 2)))] 18397{ 18398 machine_mode mode = <MODE>mode; 18399 18400 if (!register_operand (operands[2], mode)) 18401 operands[2] = force_reg (mode, operands[2]); 18402 18403 enum rtx_code code = <maxmin_rel>; 18404 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], operands[2]); 18405 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG); 18406 18407 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], operands[2]); 18408 emit_insn (gen_rtx_SET (flags, tmp)); 18409 18410 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx); 18411}) 18412 18413(define_insn_and_split "*<code>di3_doubleword" 18414 [(set (match_operand:DI 0 "register_operand") 18415 (maxmin:DI (match_operand:DI 1 "register_operand") 18416 (match_operand:DI 2 "nonimmediate_operand"))) 18417 (clobber (reg:CC FLAGS_REG))] 18418 "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL 18419 && ix86_pre_reload_split ()" 18420 "#" 18421 "&& 1" 18422 [(set (match_dup 0) 18423 (if_then_else:SI (match_dup 6) 18424 (match_dup 1) 18425 (match_dup 2))) 18426 (set (match_dup 3) 18427 (if_then_else:SI (match_dup 6) 18428 (match_dup 4) 18429 (match_dup 5)))] 18430{ 18431 if (!register_operand (operands[2], DImode)) 18432 operands[2] = force_reg (DImode, operands[2]); 18433 18434 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]); 18435 18436 rtx cmplo[2] = { operands[1], operands[2] }; 18437 rtx cmphi[2] = { operands[4], operands[5] }; 18438 18439 enum rtx_code code = <maxmin_rel>; 18440 18441 switch (code) 18442 { 18443 case LE: case LEU: 18444 std::swap (cmplo[0], cmplo[1]); 18445 std::swap (cmphi[0], cmphi[1]); 18446 code = swap_condition (code); 18447 /* FALLTHRU */ 18448 18449 case GE: case GEU: 18450 { 18451 bool uns = (code == GEU); 18452 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx) 18453 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz; 18454 18455 emit_insn (gen_cmp_1 (SImode, cmplo[0], cmplo[1])); 18456 18457 rtx tmp = gen_rtx_SCRATCH (SImode); 18458 emit_insn (sbb_insn (SImode, tmp, cmphi[0], cmphi[1])); 18459 18460 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG); 18461 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx); 18462 18463 break; 18464 } 18465 18466 default: 18467 gcc_unreachable (); 18468 } 18469}) 18470 18471;; Misc patterns (?) 18472 18473;; This pattern exists to put a dependency on all ebp-based memory accesses. 18474;; Otherwise there will be nothing to keep 18475;; 18476;; [(set (reg ebp) (reg esp))] 18477;; [(set (reg esp) (plus (reg esp) (const_int -160000))) 18478;; (clobber (eflags)] 18479;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))] 18480;; 18481;; in proper program order. 18482 18483(define_insn "@pro_epilogue_adjust_stack_add_<mode>" 18484 [(set (match_operand:P 0 "register_operand" "=r,r") 18485 (plus:P (match_operand:P 1 "register_operand" "0,r") 18486 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>"))) 18487 (clobber (reg:CC FLAGS_REG)) 18488 (clobber (mem:BLK (scratch)))] 18489 "" 18490{ 18491 switch (get_attr_type (insn)) 18492 { 18493 case TYPE_IMOV: 18494 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}"; 18495 18496 case TYPE_ALU: 18497 gcc_assert (rtx_equal_p (operands[0], operands[1])); 18498 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode)) 18499 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}"; 18500 18501 return "add{<imodesuffix>}\t{%2, %0|%0, %2}"; 18502 18503 default: 18504 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0)); 18505 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}"; 18506 } 18507} 18508 [(set (attr "type") 18509 (cond [(and (eq_attr "alternative" "0") 18510 (not (match_test "TARGET_OPT_AGU"))) 18511 (const_string "alu") 18512 (match_operand:<MODE> 2 "const0_operand") 18513 (const_string "imov") 18514 ] 18515 (const_string "lea"))) 18516 (set (attr "length_immediate") 18517 (cond [(eq_attr "type" "imov") 18518 (const_string "0") 18519 (and (eq_attr "type" "alu") 18520 (match_operand 2 "const128_operand")) 18521 (const_string "1") 18522 ] 18523 (const_string "*"))) 18524 (set_attr "mode" "<MODE>")]) 18525 18526(define_insn "@pro_epilogue_adjust_stack_sub_<mode>" 18527 [(set (match_operand:P 0 "register_operand" "=r") 18528 (minus:P (match_operand:P 1 "register_operand" "0") 18529 (match_operand:P 2 "register_operand" "r"))) 18530 (clobber (reg:CC FLAGS_REG)) 18531 (clobber (mem:BLK (scratch)))] 18532 "" 18533 "sub{<imodesuffix>}\t{%2, %0|%0, %2}" 18534 [(set_attr "type" "alu") 18535 (set_attr "mode" "<MODE>")]) 18536 18537(define_insn "@allocate_stack_worker_probe_<mode>" 18538 [(set (match_operand:P 0 "register_operand" "=a") 18539 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 18540 UNSPECV_STACK_PROBE)) 18541 (clobber (reg:CC FLAGS_REG))] 18542 "ix86_target_stack_probe ()" 18543 "call\t___chkstk_ms" 18544 [(set_attr "type" "multi") 18545 (set_attr "length" "5")]) 18546 18547(define_expand "allocate_stack" 18548 [(match_operand 0 "register_operand") 18549 (match_operand 1 "general_operand")] 18550 "ix86_target_stack_probe ()" 18551{ 18552 rtx x; 18553 18554#ifndef CHECK_STACK_LIMIT 18555#define CHECK_STACK_LIMIT 0 18556#endif 18557 18558 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1]) 18559 && INTVAL (operands[1]) < CHECK_STACK_LIMIT) 18560 x = operands[1]; 18561 else 18562 { 18563 x = copy_to_mode_reg (Pmode, operands[1]); 18564 18565 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x)); 18566 } 18567 18568 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x, 18569 stack_pointer_rtx, 0, OPTAB_DIRECT); 18570 18571 if (x != stack_pointer_rtx) 18572 emit_move_insn (stack_pointer_rtx, x); 18573 18574 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 18575 DONE; 18576}) 18577 18578(define_expand "probe_stack" 18579 [(match_operand 0 "memory_operand")] 18580 "" 18581{ 18582 emit_insn (gen_probe_stack_1 18583 (word_mode, operands[0], const0_rtx)); 18584 DONE; 18585}) 18586 18587;; Use OR for stack probes, this is shorter. 18588(define_insn "@probe_stack_1_<mode>" 18589 [(set (match_operand:W 0 "memory_operand" "=m") 18590 (unspec:W [(match_operand:W 1 "const0_operand")] 18591 UNSPEC_PROBE_STACK)) 18592 (clobber (reg:CC FLAGS_REG))] 18593 "" 18594 "or{<imodesuffix>}\t{%1, %0|%0, %1}" 18595 [(set_attr "type" "alu1") 18596 (set_attr "mode" "<MODE>") 18597 (set_attr "length_immediate" "1")]) 18598 18599(define_insn "@adjust_stack_and_probe_<mode>" 18600 [(set (match_operand:P 0 "register_operand" "=r") 18601 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")] 18602 UNSPECV_PROBE_STACK_RANGE)) 18603 (set (reg:P SP_REG) 18604 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n"))) 18605 (clobber (reg:CC FLAGS_REG)) 18606 (clobber (mem:BLK (scratch)))] 18607 "" 18608 "* return output_adjust_stack_and_probe (operands[0]);" 18609 [(set_attr "type" "multi")]) 18610 18611(define_insn "@probe_stack_range_<mode>" 18612 [(set (match_operand:P 0 "register_operand" "=r") 18613 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 18614 (match_operand:P 2 "const_int_operand" "n")] 18615 UNSPECV_PROBE_STACK_RANGE)) 18616 (clobber (reg:CC FLAGS_REG))] 18617 "" 18618 "* return output_probe_stack_range (operands[0], operands[2]);" 18619 [(set_attr "type" "multi")]) 18620 18621(define_expand "builtin_setjmp_receiver" 18622 [(label_ref (match_operand 0))] 18623 "!TARGET_64BIT && flag_pic" 18624{ 18625#if TARGET_MACHO 18626 if (TARGET_MACHO) 18627 { 18628 rtx xops[3]; 18629 rtx_code_label *label_rtx = gen_label_rtx (); 18630 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx)); 18631 xops[0] = xops[1] = pic_offset_table_rtx; 18632 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx)); 18633 ix86_expand_binary_operator (MINUS, SImode, xops); 18634 } 18635 else 18636#endif 18637 emit_insn (gen_set_got (pic_offset_table_rtx)); 18638 DONE; 18639}) 18640 18641(define_expand "save_stack_nonlocal" 18642 [(set (match_operand 0 "memory_operand") 18643 (match_operand 1 "register_operand"))] 18644 "" 18645{ 18646 rtx stack_slot; 18647 if ((flag_cf_protection & CF_RETURN)) 18648 { 18649 /* Copy shadow stack pointer to the first slot and stack ppointer 18650 to the second slot. */ 18651 rtx ssp_slot = adjust_address (operands[0], word_mode, 0); 18652 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD); 18653 rtx ssp = gen_reg_rtx (word_mode); 18654 emit_insn ((word_mode == SImode) 18655 ? gen_rdsspsi (ssp) 18656 : gen_rdsspdi (ssp)); 18657 emit_move_insn (ssp_slot, ssp); 18658 } 18659 else 18660 stack_slot = adjust_address (operands[0], Pmode, 0); 18661 emit_move_insn (stack_slot, operands[1]); 18662 DONE; 18663}) 18664 18665(define_expand "restore_stack_nonlocal" 18666 [(set (match_operand 0 "register_operand" "") 18667 (match_operand 1 "memory_operand" ""))] 18668 "" 18669{ 18670 rtx stack_slot; 18671 if ((flag_cf_protection & CF_RETURN)) 18672 { 18673 /* Restore shadow stack pointer from the first slot and stack 18674 pointer from the second slot. */ 18675 rtx ssp_slot = adjust_address (operands[1], word_mode, 0); 18676 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD); 18677 18678 rtx flags, jump, noadj_label, inc_label, loop_label; 18679 rtx reg_adj, reg_ssp, tmp, clob; 18680 18681 /* Get the current shadow stack pointer. The code below will check if 18682 SHSTK feature is enabled. If it is not enabled the RDSSP instruction 18683 is a NOP. */ 18684 reg_ssp = gen_reg_rtx (word_mode); 18685 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx)); 18686 emit_insn ((word_mode == SImode) 18687 ? gen_rdsspsi (reg_ssp) 18688 : gen_rdsspdi (reg_ssp)); 18689 18690 /* Compare through substraction the saved and the current ssp to decide 18691 if ssp has to be adjusted. */ 18692 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp, 18693 ssp_slot)); 18694 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18695 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18696 emit_insn (tmp); 18697 18698 /* Compare and jump over adjustment code. */ 18699 tmp = gen_rtx_COMPARE (CCZmode, reg_ssp, const0_rtx); 18700 flags = gen_rtx_REG (CCZmode, FLAGS_REG); 18701 emit_insn (gen_rtx_SET (flags, tmp)); 18702 18703 noadj_label = gen_label_rtx (); 18704 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx); 18705 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18706 gen_rtx_LABEL_REF (VOIDmode, noadj_label), 18707 pc_rtx); 18708 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18709 JUMP_LABEL (jump) = noadj_label; 18710 18711 /* Compute the numebr of frames to adjust. */ 18712 reg_adj = gen_lowpart (ptr_mode, reg_ssp); 18713 tmp = gen_rtx_SET (reg_adj, 18714 gen_rtx_LSHIFTRT (ptr_mode, 18715 negate_rtx (ptr_mode, reg_adj), 18716 GEN_INT ((word_mode == SImode) 18717 ? 2 18718 : 3))); 18719 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18720 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18721 emit_insn (tmp); 18722 18723 /* Check if number of frames <= 255 so no loop is needed. */ 18724 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255)); 18725 flags = gen_rtx_REG (CCmode, FLAGS_REG); 18726 emit_insn (gen_rtx_SET (flags, tmp)); 18727 18728 inc_label = gen_label_rtx (); 18729 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx); 18730 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18731 gen_rtx_LABEL_REF (VOIDmode, inc_label), 18732 pc_rtx); 18733 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18734 JUMP_LABEL (jump) = inc_label; 18735 18736 rtx reg_255 = gen_reg_rtx (word_mode); 18737 emit_move_insn (reg_255, GEN_INT (255)); 18738 18739 /* Adjust the ssp in a loop. */ 18740 loop_label = gen_label_rtx (); 18741 emit_label (loop_label); 18742 LABEL_NUSES (loop_label) = 1; 18743 18744 emit_insn ((word_mode == SImode) 18745 ? gen_incsspsi (reg_255) 18746 : gen_incsspdi (reg_255)); 18747 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode, 18748 reg_adj, 18749 GEN_INT (255))); 18750 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG)); 18751 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob)); 18752 emit_insn (tmp); 18753 18754 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255)); 18755 flags = gen_rtx_REG (CCmode, FLAGS_REG); 18756 emit_insn (gen_rtx_SET (flags, tmp)); 18757 18758 /* Jump to the loop label. */ 18759 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx); 18760 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp, 18761 gen_rtx_LABEL_REF (VOIDmode, loop_label), 18762 pc_rtx); 18763 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp)); 18764 JUMP_LABEL (jump) = loop_label; 18765 18766 emit_label (inc_label); 18767 LABEL_NUSES (inc_label) = 1; 18768 emit_insn ((word_mode == SImode) 18769 ? gen_incsspsi (reg_ssp) 18770 : gen_incsspdi (reg_ssp)); 18771 18772 emit_label (noadj_label); 18773 LABEL_NUSES (noadj_label) = 1; 18774 } 18775 else 18776 stack_slot = adjust_address (operands[1], Pmode, 0); 18777 emit_move_insn (operands[0], stack_slot); 18778 DONE; 18779}) 18780 18781 18782;; Avoid redundant prefixes by splitting HImode arithmetic to SImode. 18783;; Do not split instructions with mask registers. 18784(define_split 18785 [(set (match_operand 0 "general_reg_operand") 18786 (match_operator 3 "promotable_binary_operator" 18787 [(match_operand 1 "general_reg_operand") 18788 (match_operand 2 "aligned_operand")])) 18789 (clobber (reg:CC FLAGS_REG))] 18790 "! TARGET_PARTIAL_REG_STALL && reload_completed 18791 && ((GET_MODE (operands[0]) == HImode 18792 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX) 18793 /* ??? next two lines just !satisfies_constraint_K (...) */ 18794 || !CONST_INT_P (operands[2]) 18795 || satisfies_constraint_K (operands[2]))) 18796 || (GET_MODE (operands[0]) == QImode 18797 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))" 18798 [(parallel [(set (match_dup 0) 18799 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 18800 (clobber (reg:CC FLAGS_REG))])] 18801{ 18802 operands[0] = gen_lowpart (SImode, operands[0]); 18803 operands[1] = gen_lowpart (SImode, operands[1]); 18804 if (GET_CODE (operands[3]) != ASHIFT) 18805 operands[2] = gen_lowpart (SImode, operands[2]); 18806 operands[3] = shallow_copy_rtx (operands[3]); 18807 PUT_MODE (operands[3], SImode); 18808}) 18809 18810; Promote the QImode tests, as i386 has encoding of the AND 18811; instruction with 32-bit sign-extended immediate and thus the 18812; instruction size is unchanged, except in the %eax case for 18813; which it is increased by one byte, hence the ! optimize_size. 18814(define_split 18815 [(set (match_operand 0 "flags_reg_operand") 18816 (match_operator 2 "compare_operator" 18817 [(and (match_operand 3 "aligned_operand") 18818 (match_operand 4 "const_int_operand")) 18819 (const_int 0)])) 18820 (set (match_operand 1 "register_operand") 18821 (and (match_dup 3) (match_dup 4)))] 18822 "! TARGET_PARTIAL_REG_STALL && reload_completed 18823 && optimize_insn_for_speed_p () 18824 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX) 18825 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode)) 18826 /* Ensure that the operand will remain sign-extended immediate. */ 18827 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)" 18828 [(parallel [(set (match_dup 0) 18829 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4)) 18830 (const_int 0)])) 18831 (set (match_dup 1) 18832 (and:SI (match_dup 3) (match_dup 4)))])] 18833{ 18834 operands[4] 18835 = gen_int_mode (INTVAL (operands[4]) 18836 & GET_MODE_MASK (GET_MODE (operands[1])), SImode); 18837 operands[1] = gen_lowpart (SImode, operands[1]); 18838 operands[3] = gen_lowpart (SImode, operands[3]); 18839}) 18840 18841; Don't promote the QImode tests, as i386 doesn't have encoding of 18842; the TEST instruction with 32-bit sign-extended immediate and thus 18843; the instruction size would at least double, which is not what we 18844; want even with ! optimize_size. 18845(define_split 18846 [(set (match_operand 0 "flags_reg_operand") 18847 (match_operator 1 "compare_operator" 18848 [(and (match_operand:HI 2 "aligned_operand") 18849 (match_operand:HI 3 "const_int_operand")) 18850 (const_int 0)]))] 18851 "! TARGET_PARTIAL_REG_STALL && reload_completed 18852 && ! TARGET_FAST_PREFIX 18853 && optimize_insn_for_speed_p () 18854 /* Ensure that the operand will remain sign-extended immediate. */ 18855 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)" 18856 [(set (match_dup 0) 18857 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 18858 (const_int 0)]))] 18859{ 18860 operands[3] 18861 = gen_int_mode (INTVAL (operands[3]) 18862 & GET_MODE_MASK (GET_MODE (operands[2])), SImode); 18863 operands[2] = gen_lowpart (SImode, operands[2]); 18864}) 18865 18866(define_split 18867 [(set (match_operand 0 "register_operand") 18868 (neg (match_operand 1 "register_operand"))) 18869 (clobber (reg:CC FLAGS_REG))] 18870 "! TARGET_PARTIAL_REG_STALL && reload_completed 18871 && (GET_MODE (operands[0]) == HImode 18872 || (GET_MODE (operands[0]) == QImode 18873 && (TARGET_PROMOTE_QImode 18874 || optimize_insn_for_size_p ())))" 18875 [(parallel [(set (match_dup 0) 18876 (neg:SI (match_dup 1))) 18877 (clobber (reg:CC FLAGS_REG))])] 18878{ 18879 operands[0] = gen_lowpart (SImode, operands[0]); 18880 operands[1] = gen_lowpart (SImode, operands[1]); 18881}) 18882 18883;; Do not split instructions with mask regs. 18884(define_split 18885 [(set (match_operand 0 "general_reg_operand") 18886 (not (match_operand 1 "general_reg_operand")))] 18887 "! TARGET_PARTIAL_REG_STALL && reload_completed 18888 && (GET_MODE (operands[0]) == HImode 18889 || (GET_MODE (operands[0]) == QImode 18890 && (TARGET_PROMOTE_QImode 18891 || optimize_insn_for_size_p ())))" 18892 [(set (match_dup 0) 18893 (not:SI (match_dup 1)))] 18894{ 18895 operands[0] = gen_lowpart (SImode, operands[0]); 18896 operands[1] = gen_lowpart (SImode, operands[1]); 18897}) 18898 18899;; RTL Peephole optimizations, run before sched2. These primarily look to 18900;; transform a complex memory operation into two memory to register operations. 18901 18902;; Don't push memory operands 18903(define_peephole2 18904 [(set (match_operand:SWI 0 "push_operand") 18905 (match_operand:SWI 1 "memory_operand")) 18906 (match_scratch:SWI 2 "<r>")] 18907 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 18908 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 18909 [(set (match_dup 2) (match_dup 1)) 18910 (set (match_dup 0) (match_dup 2))]) 18911 18912;; We need to handle SFmode only, because DFmode and XFmode are split to 18913;; SImode pushes. 18914(define_peephole2 18915 [(set (match_operand:SF 0 "push_operand") 18916 (match_operand:SF 1 "memory_operand")) 18917 (match_scratch:SF 2 "r")] 18918 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ()) 18919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))" 18920 [(set (match_dup 2) (match_dup 1)) 18921 (set (match_dup 0) (match_dup 2))]) 18922 18923;; Don't move an immediate directly to memory when the instruction 18924;; gets too big, or if LCP stalls are a problem for 16-bit moves. 18925(define_peephole2 18926 [(match_scratch:SWI124 1 "<r>") 18927 (set (match_operand:SWI124 0 "memory_operand") 18928 (const_int 0))] 18929 "optimize_insn_for_speed_p () 18930 && ((<MODE>mode == HImode 18931 && TARGET_LCP_STALL) 18932 || (!TARGET_USE_MOV0 18933 && TARGET_SPLIT_LONG_MOVES 18934 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn)) 18935 && peep2_regno_dead_p (0, FLAGS_REG)" 18936 [(parallel [(set (match_dup 2) (const_int 0)) 18937 (clobber (reg:CC FLAGS_REG))]) 18938 (set (match_dup 0) (match_dup 1))] 18939 "operands[2] = gen_lowpart (SImode, operands[1]);") 18940 18941(define_peephole2 18942 [(match_scratch:SWI124 2 "<r>") 18943 (set (match_operand:SWI124 0 "memory_operand") 18944 (match_operand:SWI124 1 "immediate_operand"))] 18945 "optimize_insn_for_speed_p () 18946 && ((<MODE>mode == HImode 18947 && TARGET_LCP_STALL) 18948 || (TARGET_SPLIT_LONG_MOVES 18949 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))" 18950 [(set (match_dup 2) (match_dup 1)) 18951 (set (match_dup 0) (match_dup 2))]) 18952 18953;; Don't compare memory with zero, load and use a test instead. 18954(define_peephole2 18955 [(set (match_operand 0 "flags_reg_operand") 18956 (match_operator 1 "compare_operator" 18957 [(match_operand:SI 2 "memory_operand") 18958 (const_int 0)])) 18959 (match_scratch:SI 3 "r")] 18960 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)" 18961 [(set (match_dup 3) (match_dup 2)) 18962 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]) 18963 18964;; NOT is not pairable on Pentium, while XOR is, but one byte longer. 18965;; Don't split NOTs with a displacement operand, because resulting XOR 18966;; will not be pairable anyway. 18967;; 18968;; On AMD K6, NOT is vector decoded with memory operand that cannot be 18969;; represented using a modRM byte. The XOR replacement is long decoded, 18970;; so this split helps here as well. 18971;; 18972;; Note: Can't do this as a regular split because we can't get proper 18973;; lifetime information then. 18974 18975(define_peephole2 18976 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand") 18977 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))] 18978 "optimize_insn_for_speed_p () 18979 && ((TARGET_NOT_UNPAIRABLE 18980 && (!MEM_P (operands[0]) 18981 || !memory_displacement_operand (operands[0], <MODE>mode))) 18982 || (TARGET_NOT_VECTORMODE 18983 && long_memory_operand (operands[0], <MODE>mode))) 18984 && peep2_regno_dead_p (0, FLAGS_REG)" 18985 [(parallel [(set (match_dup 0) 18986 (xor:SWI124 (match_dup 1) (const_int -1))) 18987 (clobber (reg:CC FLAGS_REG))])]) 18988 18989;; Non pairable "test imm, reg" instructions can be translated to 18990;; "and imm, reg" if reg dies. The "and" form is also shorter (one 18991;; byte opcode instead of two, have a short form for byte operands), 18992;; so do it for other CPUs as well. Given that the value was dead, 18993;; this should not create any new dependencies. Pass on the sub-word 18994;; versions if we're concerned about partial register stalls. 18995 18996(define_peephole2 18997 [(set (match_operand 0 "flags_reg_operand") 18998 (match_operator 1 "compare_operator" 18999 [(and:SI (match_operand:SI 2 "register_operand") 19000 (match_operand:SI 3 "immediate_operand")) 19001 (const_int 0)]))] 19002 "ix86_match_ccmode (insn, CCNOmode) 19003 && (REGNO (operands[2]) != AX_REG 19004 || satisfies_constraint_K (operands[3])) 19005 && peep2_reg_dead_p (1, operands[2])" 19006 [(parallel 19007 [(set (match_dup 0) 19008 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3)) 19009 (const_int 0)])) 19010 (set (match_dup 2) 19011 (and:SI (match_dup 2) (match_dup 3)))])]) 19012 19013;; We don't need to handle HImode case, because it will be promoted to SImode 19014;; on ! TARGET_PARTIAL_REG_STALL 19015 19016(define_peephole2 19017 [(set (match_operand 0 "flags_reg_operand") 19018 (match_operator 1 "compare_operator" 19019 [(and:QI (match_operand:QI 2 "register_operand") 19020 (match_operand:QI 3 "immediate_operand")) 19021 (const_int 0)]))] 19022 "! TARGET_PARTIAL_REG_STALL 19023 && ix86_match_ccmode (insn, CCNOmode) 19024 && REGNO (operands[2]) != AX_REG 19025 && peep2_reg_dead_p (1, operands[2])" 19026 [(parallel 19027 [(set (match_dup 0) 19028 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3)) 19029 (const_int 0)])) 19030 (set (match_dup 2) 19031 (and:QI (match_dup 2) (match_dup 3)))])]) 19032 19033(define_peephole2 19034 [(set (match_operand 0 "flags_reg_operand") 19035 (match_operator 1 "compare_operator" 19036 [(and:QI 19037 (subreg:QI 19038 (zero_extract:SI (match_operand 2 "QIreg_operand") 19039 (const_int 8) 19040 (const_int 8)) 0) 19041 (match_operand 3 "const_int_operand")) 19042 (const_int 0)]))] 19043 "! TARGET_PARTIAL_REG_STALL 19044 && ix86_match_ccmode (insn, CCNOmode) 19045 && REGNO (operands[2]) != AX_REG 19046 && peep2_reg_dead_p (1, operands[2])" 19047 [(parallel 19048 [(set (match_dup 0) 19049 (match_op_dup 1 19050 [(and:QI 19051 (subreg:QI 19052 (zero_extract:SI (match_dup 2) 19053 (const_int 8) 19054 (const_int 8)) 0) 19055 (match_dup 3)) 19056 (const_int 0)])) 19057 (set (zero_extract:SI (match_dup 2) 19058 (const_int 8) 19059 (const_int 8)) 19060 (subreg:SI 19061 (and:QI 19062 (subreg:QI 19063 (zero_extract:SI (match_dup 2) 19064 (const_int 8) 19065 (const_int 8)) 0) 19066 (match_dup 3)) 0))])]) 19067 19068;; Don't do logical operations with memory inputs. 19069(define_peephole2 19070 [(match_scratch:SWI 2 "<r>") 19071 (parallel [(set (match_operand:SWI 0 "register_operand") 19072 (match_operator:SWI 3 "arith_or_logical_operator" 19073 [(match_dup 0) 19074 (match_operand:SWI 1 "memory_operand")])) 19075 (clobber (reg:CC FLAGS_REG))])] 19076 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 19077 [(set (match_dup 2) (match_dup 1)) 19078 (parallel [(set (match_dup 0) 19079 (match_op_dup 3 [(match_dup 0) (match_dup 2)])) 19080 (clobber (reg:CC FLAGS_REG))])]) 19081 19082(define_peephole2 19083 [(match_scratch:SWI 2 "<r>") 19084 (parallel [(set (match_operand:SWI 0 "register_operand") 19085 (match_operator:SWI 3 "arith_or_logical_operator" 19086 [(match_operand:SWI 1 "memory_operand") 19087 (match_dup 0)])) 19088 (clobber (reg:CC FLAGS_REG))])] 19089 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())" 19090 [(set (match_dup 2) (match_dup 1)) 19091 (parallel [(set (match_dup 0) 19092 (match_op_dup 3 [(match_dup 2) (match_dup 0)])) 19093 (clobber (reg:CC FLAGS_REG))])]) 19094 19095;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when 19096;; the memory address refers to the destination of the load! 19097 19098(define_peephole2 19099 [(set (match_operand:SWI 0 "general_reg_operand") 19100 (match_operand:SWI 1 "general_reg_operand")) 19101 (parallel [(set (match_dup 0) 19102 (match_operator:SWI 3 "commutative_operator" 19103 [(match_dup 0) 19104 (match_operand:SWI 2 "memory_operand")])) 19105 (clobber (reg:CC FLAGS_REG))])] 19106 "REGNO (operands[0]) != REGNO (operands[1]) 19107 && (<MODE>mode != QImode 19108 || any_QIreg_operand (operands[1], QImode))" 19109 [(set (match_dup 0) (match_dup 4)) 19110 (parallel [(set (match_dup 0) 19111 (match_op_dup 3 [(match_dup 0) (match_dup 1)])) 19112 (clobber (reg:CC FLAGS_REG))])] 19113 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);") 19114 19115(define_peephole2 19116 [(set (match_operand 0 "mmx_reg_operand") 19117 (match_operand 1 "mmx_reg_operand")) 19118 (set (match_dup 0) 19119 (match_operator 3 "commutative_operator" 19120 [(match_dup 0) 19121 (match_operand 2 "memory_operand")]))] 19122 "REGNO (operands[0]) != REGNO (operands[1])" 19123 [(set (match_dup 0) (match_dup 2)) 19124 (set (match_dup 0) 19125 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 19126 19127(define_peephole2 19128 [(set (match_operand 0 "sse_reg_operand") 19129 (match_operand 1 "sse_reg_operand")) 19130 (set (match_dup 0) 19131 (match_operator 3 "commutative_operator" 19132 [(match_dup 0) 19133 (match_operand 2 "memory_operand")]))] 19134 "REGNO (operands[0]) != REGNO (operands[1])" 19135 [(set (match_dup 0) (match_dup 2)) 19136 (set (match_dup 0) 19137 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) 19138 19139; Don't do logical operations with memory outputs 19140; 19141; These two don't make sense for PPro/PII -- we're expanding a 4-uop 19142; instruction into two 1-uop insns plus a 2-uop insn. That last has 19143; the same decoder scheduling characteristics as the original. 19144 19145(define_peephole2 19146 [(match_scratch:SWI 2 "<r>") 19147 (parallel [(set (match_operand:SWI 0 "memory_operand") 19148 (match_operator:SWI 3 "arith_or_logical_operator" 19149 [(match_dup 0) 19150 (match_operand:SWI 1 "<nonmemory_operand>")])) 19151 (clobber (reg:CC FLAGS_REG))])] 19152 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())" 19153 [(set (match_dup 2) (match_dup 0)) 19154 (parallel [(set (match_dup 2) 19155 (match_op_dup 3 [(match_dup 2) (match_dup 1)])) 19156 (clobber (reg:CC FLAGS_REG))]) 19157 (set (match_dup 0) (match_dup 2))]) 19158 19159(define_peephole2 19160 [(match_scratch:SWI 2 "<r>") 19161 (parallel [(set (match_operand:SWI 0 "memory_operand") 19162 (match_operator:SWI 3 "arith_or_logical_operator" 19163 [(match_operand:SWI 1 "<nonmemory_operand>") 19164 (match_dup 0)])) 19165 (clobber (reg:CC FLAGS_REG))])] 19166 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())" 19167 [(set (match_dup 2) (match_dup 0)) 19168 (parallel [(set (match_dup 2) 19169 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 19170 (clobber (reg:CC FLAGS_REG))]) 19171 (set (match_dup 0) (match_dup 2))]) 19172 19173;; Attempt to use arith or logical operations with memory outputs with 19174;; setting of flags. 19175(define_peephole2 19176 [(set (match_operand:SWI 0 "register_operand") 19177 (match_operand:SWI 1 "memory_operand")) 19178 (parallel [(set (match_dup 0) 19179 (match_operator:SWI 3 "plusminuslogic_operator" 19180 [(match_dup 0) 19181 (match_operand:SWI 2 "<nonmemory_operand>")])) 19182 (clobber (reg:CC FLAGS_REG))]) 19183 (set (match_dup 1) (match_dup 0)) 19184 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19185 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19186 && peep2_reg_dead_p (4, operands[0]) 19187 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19188 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19189 && (<MODE>mode != QImode 19190 || immediate_operand (operands[2], QImode) 19191 || any_QIreg_operand (operands[2], QImode)) 19192 && ix86_match_ccmode (peep2_next_insn (3), 19193 (GET_CODE (operands[3]) == PLUS 19194 || GET_CODE (operands[3]) == MINUS) 19195 ? CCGOCmode : CCNOmode)" 19196 [(parallel [(set (match_dup 4) (match_dup 6)) 19197 (set (match_dup 1) (match_dup 5))])] 19198{ 19199 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3))); 19200 operands[5] 19201 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19202 copy_rtx (operands[1]), 19203 operands[2]); 19204 operands[6] 19205 = gen_rtx_COMPARE (GET_MODE (operands[4]), 19206 copy_rtx (operands[5]), 19207 const0_rtx); 19208}) 19209 19210;; Likewise for cmpelim optimized pattern. 19211(define_peephole2 19212 [(set (match_operand:SWI 0 "register_operand") 19213 (match_operand:SWI 1 "memory_operand")) 19214 (parallel [(set (reg FLAGS_REG) 19215 (compare (match_operator:SWI 3 "plusminuslogic_operator" 19216 [(match_dup 0) 19217 (match_operand:SWI 2 "<nonmemory_operand>")]) 19218 (const_int 0))) 19219 (set (match_dup 0) (match_dup 3))]) 19220 (set (match_dup 1) (match_dup 0))] 19221 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19222 && peep2_reg_dead_p (3, operands[0]) 19223 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19224 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19225 && ix86_match_ccmode (peep2_next_insn (1), 19226 (GET_CODE (operands[3]) == PLUS 19227 || GET_CODE (operands[3]) == MINUS) 19228 ? CCGOCmode : CCNOmode)" 19229 [(parallel [(set (match_dup 4) (match_dup 6)) 19230 (set (match_dup 1) (match_dup 5))])] 19231{ 19232 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0)); 19233 operands[5] 19234 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19235 copy_rtx (operands[1]), operands[2]); 19236 operands[6] 19237 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]), 19238 const0_rtx); 19239}) 19240 19241;; Likewise for instances where we have a lea pattern. 19242(define_peephole2 19243 [(set (match_operand:SWI 0 "register_operand") 19244 (match_operand:SWI 1 "memory_operand")) 19245 (set (match_operand:<LEAMODE> 3 "register_operand") 19246 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand") 19247 (match_operand:<LEAMODE> 2 "<nonmemory_operand>"))) 19248 (set (match_dup 1) (match_operand:SWI 5 "register_operand")) 19249 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))] 19250 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19251 && REGNO (operands[4]) == REGNO (operands[0]) 19252 && REGNO (operands[5]) == REGNO (operands[3]) 19253 && peep2_reg_dead_p (4, operands[3]) 19254 && ((REGNO (operands[0]) == REGNO (operands[3])) 19255 || peep2_reg_dead_p (2, operands[0])) 19256 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19257 && !reg_overlap_mentioned_p (operands[3], operands[1]) 19258 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19259 && (<MODE>mode != QImode 19260 || immediate_operand (operands[2], QImode) 19261 || any_QIreg_operand (operands[2], QImode)) 19262 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)" 19263 [(parallel [(set (match_dup 6) (match_dup 8)) 19264 (set (match_dup 1) (match_dup 7))])] 19265{ 19266 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3))); 19267 operands[7] 19268 = gen_rtx_PLUS (<MODE>mode, 19269 copy_rtx (operands[1]), 19270 gen_lowpart (<MODE>mode, operands[2])); 19271 operands[8] 19272 = gen_rtx_COMPARE (GET_MODE (operands[6]), 19273 copy_rtx (operands[7]), 19274 const0_rtx); 19275}) 19276 19277(define_peephole2 19278 [(parallel [(set (match_operand:SWI 0 "register_operand") 19279 (match_operator:SWI 2 "plusminuslogic_operator" 19280 [(match_dup 0) 19281 (match_operand:SWI 1 "memory_operand")])) 19282 (clobber (reg:CC FLAGS_REG))]) 19283 (set (match_dup 1) (match_dup 0)) 19284 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19285 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19286 && COMMUTATIVE_ARITH_P (operands[2]) 19287 && peep2_reg_dead_p (3, operands[0]) 19288 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19289 && ix86_match_ccmode (peep2_next_insn (2), 19290 GET_CODE (operands[2]) == PLUS 19291 ? CCGOCmode : CCNOmode)" 19292 [(parallel [(set (match_dup 3) (match_dup 5)) 19293 (set (match_dup 1) (match_dup 4))])] 19294{ 19295 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2))); 19296 operands[4] 19297 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19298 copy_rtx (operands[1]), 19299 operands[0]); 19300 operands[5] 19301 = gen_rtx_COMPARE (GET_MODE (operands[3]), 19302 copy_rtx (operands[4]), 19303 const0_rtx); 19304}) 19305 19306;; Likewise for cmpelim optimized pattern. 19307(define_peephole2 19308 [(parallel [(set (reg FLAGS_REG) 19309 (compare (match_operator:SWI 2 "plusminuslogic_operator" 19310 [(match_operand:SWI 0 "register_operand") 19311 (match_operand:SWI 1 "memory_operand")]) 19312 (const_int 0))) 19313 (set (match_dup 0) (match_dup 2))]) 19314 (set (match_dup 1) (match_dup 0))] 19315 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19316 && COMMUTATIVE_ARITH_P (operands[2]) 19317 && peep2_reg_dead_p (2, operands[0]) 19318 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19319 && ix86_match_ccmode (peep2_next_insn (0), 19320 GET_CODE (operands[2]) == PLUS 19321 ? CCGOCmode : CCNOmode)" 19322 [(parallel [(set (match_dup 3) (match_dup 5)) 19323 (set (match_dup 1) (match_dup 4))])] 19324{ 19325 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0)); 19326 operands[4] 19327 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]), 19328 copy_rtx (operands[1]), operands[0]); 19329 operands[5] 19330 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]), 19331 const0_rtx); 19332}) 19333 19334(define_peephole2 19335 [(set (match_operand:SWI12 0 "register_operand") 19336 (match_operand:SWI12 1 "memory_operand")) 19337 (parallel [(set (match_operand:SI 4 "register_operand") 19338 (match_operator:SI 3 "plusminuslogic_operator" 19339 [(match_dup 4) 19340 (match_operand:SI 2 "nonmemory_operand")])) 19341 (clobber (reg:CC FLAGS_REG))]) 19342 (set (match_dup 1) (match_dup 0)) 19343 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))] 19344 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19345 && REGNO (operands[0]) == REGNO (operands[4]) 19346 && peep2_reg_dead_p (4, operands[0]) 19347 && (<MODE>mode != QImode 19348 || immediate_operand (operands[2], SImode) 19349 || any_QIreg_operand (operands[2], SImode)) 19350 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19351 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19352 && ix86_match_ccmode (peep2_next_insn (3), 19353 (GET_CODE (operands[3]) == PLUS 19354 || GET_CODE (operands[3]) == MINUS) 19355 ? CCGOCmode : CCNOmode)" 19356 [(parallel [(set (match_dup 5) (match_dup 7)) 19357 (set (match_dup 1) (match_dup 6))])] 19358{ 19359 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3))); 19360 operands[6] 19361 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 19362 copy_rtx (operands[1]), 19363 gen_lowpart (<MODE>mode, operands[2])); 19364 operands[7] 19365 = gen_rtx_COMPARE (GET_MODE (operands[5]), 19366 copy_rtx (operands[6]), 19367 const0_rtx); 19368}) 19369 19370;; peephole2 comes before regcprop, so deal also with a case that 19371;; would be cleaned up by regcprop. 19372(define_peephole2 19373 [(set (match_operand:SWI 0 "register_operand") 19374 (match_operand:SWI 1 "memory_operand")) 19375 (parallel [(set (match_dup 0) 19376 (match_operator:SWI 3 "plusminuslogic_operator" 19377 [(match_dup 0) 19378 (match_operand:SWI 2 "<nonmemory_operand>")])) 19379 (clobber (reg:CC FLAGS_REG))]) 19380 (set (match_operand:SWI 4 "register_operand") (match_dup 0)) 19381 (set (match_dup 1) (match_dup 4)) 19382 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))] 19383 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19384 && peep2_reg_dead_p (3, operands[0]) 19385 && peep2_reg_dead_p (5, operands[4]) 19386 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19387 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19388 && !reg_overlap_mentioned_p (operands[4], operands[1]) 19389 && (<MODE>mode != QImode 19390 || immediate_operand (operands[2], QImode) 19391 || any_QIreg_operand (operands[2], QImode)) 19392 && ix86_match_ccmode (peep2_next_insn (4), 19393 (GET_CODE (operands[3]) == PLUS 19394 || GET_CODE (operands[3]) == MINUS) 19395 ? CCGOCmode : CCNOmode)" 19396 [(parallel [(set (match_dup 5) (match_dup 7)) 19397 (set (match_dup 1) (match_dup 6))])] 19398{ 19399 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4))); 19400 operands[6] 19401 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19402 copy_rtx (operands[1]), 19403 operands[2]); 19404 operands[7] 19405 = gen_rtx_COMPARE (GET_MODE (operands[5]), 19406 copy_rtx (operands[6]), 19407 const0_rtx); 19408}) 19409 19410(define_peephole2 19411 [(set (match_operand:SWI12 0 "register_operand") 19412 (match_operand:SWI12 1 "memory_operand")) 19413 (parallel [(set (match_operand:SI 4 "register_operand") 19414 (match_operator:SI 3 "plusminuslogic_operator" 19415 [(match_dup 4) 19416 (match_operand:SI 2 "nonmemory_operand")])) 19417 (clobber (reg:CC FLAGS_REG))]) 19418 (set (match_operand:SWI12 5 "register_operand") (match_dup 0)) 19419 (set (match_dup 1) (match_dup 5)) 19420 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))] 19421 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19422 && REGNO (operands[0]) == REGNO (operands[4]) 19423 && peep2_reg_dead_p (3, operands[0]) 19424 && peep2_reg_dead_p (5, operands[5]) 19425 && (<MODE>mode != QImode 19426 || immediate_operand (operands[2], SImode) 19427 || any_QIreg_operand (operands[2], SImode)) 19428 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19429 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19430 && !reg_overlap_mentioned_p (operands[5], operands[1]) 19431 && ix86_match_ccmode (peep2_next_insn (4), 19432 (GET_CODE (operands[3]) == PLUS 19433 || GET_CODE (operands[3]) == MINUS) 19434 ? CCGOCmode : CCNOmode)" 19435 [(parallel [(set (match_dup 6) (match_dup 8)) 19436 (set (match_dup 1) (match_dup 7))])] 19437{ 19438 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4))); 19439 operands[7] 19440 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode, 19441 copy_rtx (operands[1]), 19442 gen_lowpart (<MODE>mode, operands[2])); 19443 operands[8] 19444 = gen_rtx_COMPARE (GET_MODE (operands[6]), 19445 copy_rtx (operands[7]), 19446 const0_rtx); 19447}) 19448 19449;; Likewise for cmpelim optimized pattern. 19450(define_peephole2 19451 [(set (match_operand:SWI 0 "register_operand") 19452 (match_operand:SWI 1 "memory_operand")) 19453 (parallel [(set (reg FLAGS_REG) 19454 (compare (match_operator:SWI 3 "plusminuslogic_operator" 19455 [(match_dup 0) 19456 (match_operand:SWI 2 "<nonmemory_operand>")]) 19457 (const_int 0))) 19458 (set (match_dup 0) (match_dup 3))]) 19459 (set (match_operand:SWI 4 "register_operand") (match_dup 0)) 19460 (set (match_dup 1) (match_dup 4))] 19461 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19462 && peep2_reg_dead_p (3, operands[0]) 19463 && peep2_reg_dead_p (4, operands[4]) 19464 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19465 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19466 && !reg_overlap_mentioned_p (operands[4], operands[1]) 19467 && ix86_match_ccmode (peep2_next_insn (1), 19468 (GET_CODE (operands[3]) == PLUS 19469 || GET_CODE (operands[3]) == MINUS) 19470 ? CCGOCmode : CCNOmode)" 19471 [(parallel [(set (match_dup 5) (match_dup 7)) 19472 (set (match_dup 1) (match_dup 6))])] 19473{ 19474 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0)); 19475 operands[6] 19476 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]), 19477 copy_rtx (operands[1]), operands[2]); 19478 operands[7] 19479 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]), 19480 const0_rtx); 19481}) 19482 19483;; Special cases for xor, where (x ^= y) != 0 is (misoptimized) 19484;; into x = z; x ^= y; x != z 19485(define_peephole2 19486 [(set (match_operand:SWI 0 "register_operand") 19487 (match_operand:SWI 1 "memory_operand")) 19488 (set (match_operand:SWI 3 "register_operand") (match_dup 0)) 19489 (parallel [(set (match_operand:SWI 4 "register_operand") 19490 (xor:SWI (match_dup 4) 19491 (match_operand:SWI 2 "<nonmemory_operand>"))) 19492 (clobber (reg:CC FLAGS_REG))]) 19493 (set (match_dup 1) (match_dup 4)) 19494 (set (reg:CCZ FLAGS_REG) 19495 (compare:CCZ (match_operand:SWI 5 "register_operand") 19496 (match_operand:SWI 6 "<nonmemory_operand>")))] 19497 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19498 && (REGNO (operands[4]) == REGNO (operands[0]) 19499 || REGNO (operands[4]) == REGNO (operands[3])) 19500 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0]) 19501 ? 3 : 0], operands[5]) 19502 ? rtx_equal_p (operands[2], operands[6]) 19503 : rtx_equal_p (operands[2], operands[5]) 19504 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0]) 19505 ? 3 : 0], operands[6])) 19506 && peep2_reg_dead_p (4, operands[4]) 19507 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0]) 19508 ? 3 : 0]) 19509 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19510 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19511 && !reg_overlap_mentioned_p (operands[3], operands[0]) 19512 && !reg_overlap_mentioned_p (operands[3], operands[1]) 19513 && !reg_overlap_mentioned_p (operands[3], operands[2]) 19514 && (<MODE>mode != QImode 19515 || immediate_operand (operands[2], QImode) 19516 || any_QIreg_operand (operands[2], QImode))" 19517 [(parallel [(set (match_dup 7) (match_dup 9)) 19518 (set (match_dup 1) (match_dup 8))])] 19519{ 19520 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4))); 19521 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]), 19522 operands[2]); 19523 operands[9] 19524 = gen_rtx_COMPARE (GET_MODE (operands[7]), 19525 copy_rtx (operands[8]), 19526 const0_rtx); 19527}) 19528 19529(define_peephole2 19530 [(set (match_operand:SWI12 0 "register_operand") 19531 (match_operand:SWI12 1 "memory_operand")) 19532 (set (match_operand:SWI12 3 "register_operand") (match_dup 0)) 19533 (parallel [(set (match_operand:SI 4 "register_operand") 19534 (xor:SI (match_dup 4) 19535 (match_operand:SI 2 "<nonmemory_operand>"))) 19536 (clobber (reg:CC FLAGS_REG))]) 19537 (set (match_dup 1) (match_operand:SWI12 5 "register_operand")) 19538 (set (reg:CCZ FLAGS_REG) 19539 (compare:CCZ (match_operand:SWI12 6 "register_operand") 19540 (match_operand:SWI12 7 "<nonmemory_operand>")))] 19541 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ()) 19542 && (REGNO (operands[5]) == REGNO (operands[0]) 19543 || REGNO (operands[5]) == REGNO (operands[3])) 19544 && REGNO (operands[5]) == REGNO (operands[4]) 19545 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0]) 19546 ? 3 : 0], operands[6]) 19547 ? (REG_P (operands[2]) 19548 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7]) 19549 : rtx_equal_p (operands[2], operands[7])) 19550 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0]) 19551 ? 3 : 0], operands[7]) 19552 && REG_P (operands[2]) 19553 && REGNO (operands[2]) == REGNO (operands[6]))) 19554 && peep2_reg_dead_p (4, operands[5]) 19555 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0]) 19556 ? 3 : 0]) 19557 && !reg_overlap_mentioned_p (operands[0], operands[1]) 19558 && !reg_overlap_mentioned_p (operands[0], operands[2]) 19559 && !reg_overlap_mentioned_p (operands[3], operands[0]) 19560 && !reg_overlap_mentioned_p (operands[3], operands[1]) 19561 && !reg_overlap_mentioned_p (operands[3], operands[2]) 19562 && (<MODE>mode != QImode 19563 || immediate_operand (operands[2], SImode) 19564 || any_QIreg_operand (operands[2], SImode))" 19565 [(parallel [(set (match_dup 8) (match_dup 10)) 19566 (set (match_dup 1) (match_dup 9))])] 19567{ 19568 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4))); 19569 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]), 19570 gen_lowpart (<MODE>mode, operands[2])); 19571 operands[10] 19572 = gen_rtx_COMPARE (GET_MODE (operands[8]), 19573 copy_rtx (operands[9]), 19574 const0_rtx); 19575}) 19576 19577;; Attempt to optimize away memory stores of values the memory already 19578;; has. See PR79593. 19579(define_peephole2 19580 [(set (match_operand 0 "register_operand") 19581 (match_operand 1 "memory_operand")) 19582 (set (match_operand 2 "memory_operand") (match_dup 0))] 19583 "!MEM_VOLATILE_P (operands[1]) 19584 && !MEM_VOLATILE_P (operands[2]) 19585 && rtx_equal_p (operands[1], operands[2]) 19586 && !reg_overlap_mentioned_p (operands[0], operands[2])" 19587 [(set (match_dup 0) (match_dup 1))]) 19588 19589;; Attempt to always use XOR for zeroing registers (including FP modes). 19590(define_peephole2 19591 [(set (match_operand 0 "general_reg_operand") 19592 (match_operand 1 "const0_operand"))] 19593 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD 19594 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 19595 && peep2_regno_dead_p (0, FLAGS_REG)" 19596 [(parallel [(set (match_dup 0) (const_int 0)) 19597 (clobber (reg:CC FLAGS_REG))])] 19598 "operands[0] = gen_lowpart (word_mode, operands[0]);") 19599 19600(define_peephole2 19601 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand")) 19602 (const_int 0))] 19603 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) 19604 && peep2_regno_dead_p (0, FLAGS_REG)" 19605 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0)) 19606 (clobber (reg:CC FLAGS_REG))])]) 19607 19608;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg. 19609(define_peephole2 19610 [(set (match_operand:SWI248 0 "general_reg_operand") 19611 (const_int -1))] 19612 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ()) 19613 && peep2_regno_dead_p (0, FLAGS_REG)" 19614 [(parallel [(set (match_dup 0) (const_int -1)) 19615 (clobber (reg:CC FLAGS_REG))])] 19616{ 19617 if (<MODE_SIZE> < GET_MODE_SIZE (SImode)) 19618 operands[0] = gen_lowpart (SImode, operands[0]); 19619}) 19620 19621;; Attempt to convert simple lea to add/shift. 19622;; These can be created by move expanders. 19623;; Disable PLUS peepholes on TARGET_OPT_AGU, since all 19624;; relevant lea instructions were already split. 19625 19626(define_peephole2 19627 [(set (match_operand:SWI48 0 "register_operand") 19628 (plus:SWI48 (match_dup 0) 19629 (match_operand:SWI48 1 "<nonmemory_operand>")))] 19630 "!TARGET_OPT_AGU 19631 && peep2_regno_dead_p (0, FLAGS_REG)" 19632 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 19633 (clobber (reg:CC FLAGS_REG))])]) 19634 19635(define_peephole2 19636 [(set (match_operand:SWI48 0 "register_operand") 19637 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>") 19638 (match_dup 0)))] 19639 "!TARGET_OPT_AGU 19640 && peep2_regno_dead_p (0, FLAGS_REG)" 19641 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1))) 19642 (clobber (reg:CC FLAGS_REG))])]) 19643 19644(define_peephole2 19645 [(set (match_operand:DI 0 "register_operand") 19646 (zero_extend:DI 19647 (plus:SI (match_operand:SI 1 "register_operand") 19648 (match_operand:SI 2 "nonmemory_operand"))))] 19649 "TARGET_64BIT && !TARGET_OPT_AGU 19650 && REGNO (operands[0]) == REGNO (operands[1]) 19651 && peep2_regno_dead_p (0, FLAGS_REG)" 19652 [(parallel [(set (match_dup 0) 19653 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2)))) 19654 (clobber (reg:CC FLAGS_REG))])]) 19655 19656(define_peephole2 19657 [(set (match_operand:DI 0 "register_operand") 19658 (zero_extend:DI 19659 (plus:SI (match_operand:SI 1 "nonmemory_operand") 19660 (match_operand:SI 2 "register_operand"))))] 19661 "TARGET_64BIT && !TARGET_OPT_AGU 19662 && REGNO (operands[0]) == REGNO (operands[2]) 19663 && peep2_regno_dead_p (0, FLAGS_REG)" 19664 [(parallel [(set (match_dup 0) 19665 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1)))) 19666 (clobber (reg:CC FLAGS_REG))])]) 19667 19668(define_peephole2 19669 [(set (match_operand:SWI48 0 "register_operand") 19670 (mult:SWI48 (match_dup 0) 19671 (match_operand:SWI48 1 "const_int_operand")))] 19672 "pow2p_hwi (INTVAL (operands[1])) 19673 && peep2_regno_dead_p (0, FLAGS_REG)" 19674 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1))) 19675 (clobber (reg:CC FLAGS_REG))])] 19676 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));") 19677 19678(define_peephole2 19679 [(set (match_operand:DI 0 "register_operand") 19680 (zero_extend:DI 19681 (mult:SI (match_operand:SI 1 "register_operand") 19682 (match_operand:SI 2 "const_int_operand"))))] 19683 "TARGET_64BIT 19684 && pow2p_hwi (INTVAL (operands[2])) 19685 && REGNO (operands[0]) == REGNO (operands[1]) 19686 && peep2_regno_dead_p (0, FLAGS_REG)" 19687 [(parallel [(set (match_dup 0) 19688 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2)))) 19689 (clobber (reg:CC FLAGS_REG))])] 19690 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));") 19691 19692;; The ESP adjustments can be done by the push and pop instructions. Resulting 19693;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes. 19694;; On many CPUs it is also faster, since special hardware to avoid esp 19695;; dependencies is present. 19696 19697;; While some of these conversions may be done using splitters, we use 19698;; peepholes in order to allow combine_stack_adjustments pass to see 19699;; nonobfuscated RTL. 19700 19701;; Convert prologue esp subtractions to push. 19702;; We need register to push. In order to keep verify_flow_info happy we have 19703;; two choices 19704;; - use scratch and clobber it in order to avoid dependencies 19705;; - use already live register 19706;; We can't use the second way right now, since there is no reliable way how to 19707;; verify that given register is live. First choice will also most likely in 19708;; fewer dependencies. On the place of esp adjustments it is very likely that 19709;; call clobbered registers are dead. We may want to use base pointer as an 19710;; alternative when no register is available later. 19711 19712(define_peephole2 19713 [(match_scratch:W 1 "r") 19714 (parallel [(set (reg:P SP_REG) 19715 (plus:P (reg:P SP_REG) 19716 (match_operand:P 0 "const_int_operand"))) 19717 (clobber (reg:CC FLAGS_REG)) 19718 (clobber (mem:BLK (scratch)))])] 19719 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 19720 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) 19721 && ix86_red_zone_size == 0" 19722 [(clobber (match_dup 1)) 19723 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19724 (clobber (mem:BLK (scratch)))])]) 19725 19726(define_peephole2 19727 [(match_scratch:W 1 "r") 19728 (parallel [(set (reg:P SP_REG) 19729 (plus:P (reg:P SP_REG) 19730 (match_operand:P 0 "const_int_operand"))) 19731 (clobber (reg:CC FLAGS_REG)) 19732 (clobber (mem:BLK (scratch)))])] 19733 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 19734 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) 19735 && ix86_red_zone_size == 0" 19736 [(clobber (match_dup 1)) 19737 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19738 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19739 (clobber (mem:BLK (scratch)))])]) 19740 19741;; Convert esp subtractions to push. 19742(define_peephole2 19743 [(match_scratch:W 1 "r") 19744 (parallel [(set (reg:P SP_REG) 19745 (plus:P (reg:P SP_REG) 19746 (match_operand:P 0 "const_int_operand"))) 19747 (clobber (reg:CC FLAGS_REG))])] 19748 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ()) 19749 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode) 19750 && ix86_red_zone_size == 0" 19751 [(clobber (match_dup 1)) 19752 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 19753 19754(define_peephole2 19755 [(match_scratch:W 1 "r") 19756 (parallel [(set (reg:P SP_REG) 19757 (plus:P (reg:P SP_REG) 19758 (match_operand:P 0 "const_int_operand"))) 19759 (clobber (reg:CC FLAGS_REG))])] 19760 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ()) 19761 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode) 19762 && ix86_red_zone_size == 0" 19763 [(clobber (match_dup 1)) 19764 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1)) 19765 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))]) 19766 19767;; Convert epilogue deallocator to pop. 19768(define_peephole2 19769 [(match_scratch:W 1 "r") 19770 (parallel [(set (reg:P SP_REG) 19771 (plus:P (reg:P SP_REG) 19772 (match_operand:P 0 "const_int_operand"))) 19773 (clobber (reg:CC FLAGS_REG)) 19774 (clobber (mem:BLK (scratch)))])] 19775 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ()) 19776 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 19777 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19778 (clobber (mem:BLK (scratch)))])]) 19779 19780;; Two pops case is tricky, since pop causes dependency 19781;; on destination register. We use two registers if available. 19782(define_peephole2 19783 [(match_scratch:W 1 "r") 19784 (match_scratch:W 2 "r") 19785 (parallel [(set (reg:P SP_REG) 19786 (plus:P (reg:P SP_REG) 19787 (match_operand:P 0 "const_int_operand"))) 19788 (clobber (reg:CC FLAGS_REG)) 19789 (clobber (mem:BLK (scratch)))])] 19790 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ()) 19791 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19792 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19793 (clobber (mem:BLK (scratch)))]) 19794 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 19795 19796(define_peephole2 19797 [(match_scratch:W 1 "r") 19798 (parallel [(set (reg:P SP_REG) 19799 (plus:P (reg:P SP_REG) 19800 (match_operand:P 0 "const_int_operand"))) 19801 (clobber (reg:CC FLAGS_REG)) 19802 (clobber (mem:BLK (scratch)))])] 19803 "optimize_insn_for_size_p () 19804 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19805 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19806 (clobber (mem:BLK (scratch)))]) 19807 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19808 19809;; Convert esp additions to pop. 19810(define_peephole2 19811 [(match_scratch:W 1 "r") 19812 (parallel [(set (reg:P SP_REG) 19813 (plus:P (reg:P SP_REG) 19814 (match_operand:P 0 "const_int_operand"))) 19815 (clobber (reg:CC FLAGS_REG))])] 19816 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)" 19817 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19818 19819;; Two pops case is tricky, since pop causes dependency 19820;; on destination register. We use two registers if available. 19821(define_peephole2 19822 [(match_scratch:W 1 "r") 19823 (match_scratch:W 2 "r") 19824 (parallel [(set (reg:P SP_REG) 19825 (plus:P (reg:P SP_REG) 19826 (match_operand:P 0 "const_int_operand"))) 19827 (clobber (reg:CC FLAGS_REG))])] 19828 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19829 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19830 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))]) 19831 19832(define_peephole2 19833 [(match_scratch:W 1 "r") 19834 (parallel [(set (reg:P SP_REG) 19835 (plus:P (reg:P SP_REG) 19836 (match_operand:P 0 "const_int_operand"))) 19837 (clobber (reg:CC FLAGS_REG))])] 19838 "optimize_insn_for_size_p () 19839 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)" 19840 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG)))) 19841 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))]) 19842 19843;; Convert compares with 1 to shorter inc/dec operations when CF is not 19844;; required and register dies. Similarly for 128 to -128. 19845(define_peephole2 19846 [(set (match_operand 0 "flags_reg_operand") 19847 (match_operator 1 "compare_operator" 19848 [(match_operand 2 "register_operand") 19849 (match_operand 3 "const_int_operand")]))] 19850 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ()) 19851 && incdec_operand (operands[3], GET_MODE (operands[3]))) 19852 || (!TARGET_FUSE_CMP_AND_BRANCH 19853 && INTVAL (operands[3]) == 128)) 19854 && ix86_match_ccmode (insn, CCGCmode) 19855 && peep2_reg_dead_p (1, operands[2])" 19856 [(parallel [(set (match_dup 0) 19857 (match_op_dup 1 [(match_dup 2) (match_dup 3)])) 19858 (clobber (match_dup 2))])]) 19859 19860;; Convert imul by three, five and nine into lea 19861(define_peephole2 19862 [(parallel 19863 [(set (match_operand:SWI48 0 "register_operand") 19864 (mult:SWI48 (match_operand:SWI48 1 "register_operand") 19865 (match_operand:SWI48 2 "const359_operand"))) 19866 (clobber (reg:CC FLAGS_REG))])] 19867 "!TARGET_PARTIAL_REG_STALL 19868 || <MODE>mode == SImode 19869 || optimize_function_for_size_p (cfun)" 19870 [(set (match_dup 0) 19871 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2)) 19872 (match_dup 1)))] 19873 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 19874 19875(define_peephole2 19876 [(parallel 19877 [(set (match_operand:SWI48 0 "register_operand") 19878 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand") 19879 (match_operand:SWI48 2 "const359_operand"))) 19880 (clobber (reg:CC FLAGS_REG))])] 19881 "optimize_insn_for_speed_p () 19882 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)" 19883 [(set (match_dup 0) (match_dup 1)) 19884 (set (match_dup 0) 19885 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2)) 19886 (match_dup 0)))] 19887 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);") 19888 19889;; imul $32bit_imm, mem, reg is vector decoded, while 19890;; imul $32bit_imm, reg, reg is direct decoded. 19891(define_peephole2 19892 [(match_scratch:SWI48 3 "r") 19893 (parallel [(set (match_operand:SWI48 0 "register_operand") 19894 (mult:SWI48 (match_operand:SWI48 1 "memory_operand") 19895 (match_operand:SWI48 2 "immediate_operand"))) 19896 (clobber (reg:CC FLAGS_REG))])] 19897 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 19898 && !satisfies_constraint_K (operands[2])" 19899 [(set (match_dup 3) (match_dup 1)) 19900 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2))) 19901 (clobber (reg:CC FLAGS_REG))])]) 19902 19903(define_peephole2 19904 [(match_scratch:SI 3 "r") 19905 (parallel [(set (match_operand:DI 0 "register_operand") 19906 (zero_extend:DI 19907 (mult:SI (match_operand:SI 1 "memory_operand") 19908 (match_operand:SI 2 "immediate_operand")))) 19909 (clobber (reg:CC FLAGS_REG))])] 19910 "TARGET_64BIT 19911 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p () 19912 && !satisfies_constraint_K (operands[2])" 19913 [(set (match_dup 3) (match_dup 1)) 19914 (parallel [(set (match_dup 0) 19915 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2)))) 19916 (clobber (reg:CC FLAGS_REG))])]) 19917 19918;; imul $8/16bit_imm, regmem, reg is vector decoded. 19919;; Convert it into imul reg, reg 19920;; It would be better to force assembler to encode instruction using long 19921;; immediate, but there is apparently no way to do so. 19922(define_peephole2 19923 [(parallel [(set (match_operand:SWI248 0 "register_operand") 19924 (mult:SWI248 19925 (match_operand:SWI248 1 "nonimmediate_operand") 19926 (match_operand:SWI248 2 "const_int_operand"))) 19927 (clobber (reg:CC FLAGS_REG))]) 19928 (match_scratch:SWI248 3 "r")] 19929 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p () 19930 && satisfies_constraint_K (operands[2])" 19931 [(set (match_dup 3) (match_dup 2)) 19932 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3))) 19933 (clobber (reg:CC FLAGS_REG))])] 19934{ 19935 if (!rtx_equal_p (operands[0], operands[1])) 19936 emit_move_insn (operands[0], operands[1]); 19937}) 19938 19939;; After splitting up read-modify operations, array accesses with memory 19940;; operands might end up in form: 19941;; sall $2, %eax 19942;; movl 4(%esp), %edx 19943;; addl %edx, %eax 19944;; instead of pre-splitting: 19945;; sall $2, %eax 19946;; addl 4(%esp), %eax 19947;; Turn it into: 19948;; movl 4(%esp), %edx 19949;; leal (%edx,%eax,4), %eax 19950 19951(define_peephole2 19952 [(match_scratch:W 5 "r") 19953 (parallel [(set (match_operand 0 "register_operand") 19954 (ashift (match_operand 1 "register_operand") 19955 (match_operand 2 "const_int_operand"))) 19956 (clobber (reg:CC FLAGS_REG))]) 19957 (parallel [(set (match_operand 3 "register_operand") 19958 (plus (match_dup 0) 19959 (match_operand 4 "x86_64_general_operand"))) 19960 (clobber (reg:CC FLAGS_REG))])] 19961 "IN_RANGE (INTVAL (operands[2]), 1, 3) 19962 /* Validate MODE for lea. */ 19963 && ((!TARGET_PARTIAL_REG_STALL 19964 && (GET_MODE (operands[0]) == QImode 19965 || GET_MODE (operands[0]) == HImode)) 19966 || GET_MODE (operands[0]) == SImode 19967 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)) 19968 && (rtx_equal_p (operands[0], operands[3]) 19969 || peep2_reg_dead_p (2, operands[0])) 19970 /* We reorder load and the shift. */ 19971 && !reg_overlap_mentioned_p (operands[0], operands[4])" 19972 [(set (match_dup 5) (match_dup 4)) 19973 (set (match_dup 0) (match_dup 1))] 19974{ 19975 machine_mode op1mode = GET_MODE (operands[1]); 19976 machine_mode mode = op1mode == DImode ? DImode : SImode; 19977 int scale = 1 << INTVAL (operands[2]); 19978 rtx index = gen_lowpart (word_mode, operands[1]); 19979 rtx base = gen_lowpart (word_mode, operands[5]); 19980 rtx dest = gen_lowpart (mode, operands[3]); 19981 19982 operands[1] = gen_rtx_PLUS (word_mode, base, 19983 gen_rtx_MULT (word_mode, index, GEN_INT (scale))); 19984 if (mode != word_mode) 19985 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); 19986 19987 operands[5] = base; 19988 if (op1mode != word_mode) 19989 operands[5] = gen_lowpart (op1mode, operands[5]); 19990 19991 operands[0] = dest; 19992}) 19993 19994;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5. 19995;; That, however, is usually mapped by the OS to SIGSEGV, which is often 19996;; caught for use by garbage collectors and the like. Using an insn that 19997;; maps to SIGILL makes it more likely the program will rightfully die. 19998;; Keeping with tradition, "6" is in honor of #UD. 19999(define_insn "trap" 20000 [(trap_if (const_int 1) (const_int 6))] 20001 "" 20002{ 20003#ifdef HAVE_AS_IX86_UD2 20004 return "ud2"; 20005#else 20006 return ASM_SHORT "0x0b0f"; 20007#endif 20008} 20009 [(set_attr "length" "2")]) 20010 20011(define_insn "ud2" 20012 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)] 20013 "" 20014{ 20015#ifdef HAVE_AS_IX86_UD2 20016 return "ud2"; 20017#else 20018 return ASM_SHORT "0x0b0f"; 20019#endif 20020} 20021 [(set_attr "length" "2")]) 20022 20023(define_expand "prefetch" 20024 [(prefetch (match_operand 0 "address_operand") 20025 (match_operand:SI 1 "const_int_operand") 20026 (match_operand:SI 2 "const_int_operand"))] 20027 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1" 20028{ 20029 bool write = operands[1] != const0_rtx; 20030 int locality = INTVAL (operands[2]); 20031 20032 gcc_assert (IN_RANGE (locality, 0, 3)); 20033 20034 /* Use 3dNOW prefetch in case we are asking for write prefetch not 20035 supported by SSE counterpart (non-SSE2 athlon machines) or the 20036 SSE prefetch is not available (K6 machines). Otherwise use SSE 20037 prefetch as it allows specifying of locality. */ 20038 20039 if (write) 20040 { 20041 if (TARGET_PREFETCHWT1) 20042 operands[2] = GEN_INT (MAX (locality, 2)); 20043 else if (TARGET_PRFCHW) 20044 operands[2] = GEN_INT (3); 20045 else if (TARGET_3DNOW && !TARGET_SSE2) 20046 operands[2] = GEN_INT (3); 20047 else if (TARGET_PREFETCH_SSE) 20048 operands[1] = const0_rtx; 20049 else 20050 { 20051 gcc_assert (TARGET_3DNOW); 20052 operands[2] = GEN_INT (3); 20053 } 20054 } 20055 else 20056 { 20057 if (TARGET_PREFETCH_SSE) 20058 ; 20059 else 20060 { 20061 gcc_assert (TARGET_3DNOW); 20062 operands[2] = GEN_INT (3); 20063 } 20064 } 20065}) 20066 20067(define_insn "*prefetch_sse" 20068 [(prefetch (match_operand 0 "address_operand" "p") 20069 (const_int 0) 20070 (match_operand:SI 1 "const_int_operand"))] 20071 "TARGET_PREFETCH_SSE" 20072{ 20073 static const char * const patterns[4] = { 20074 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0" 20075 }; 20076 20077 int locality = INTVAL (operands[1]); 20078 gcc_assert (IN_RANGE (locality, 0, 3)); 20079 20080 return patterns[locality]; 20081} 20082 [(set_attr "type" "sse") 20083 (set_attr "atom_sse_attr" "prefetch") 20084 (set (attr "length_address") 20085 (symbol_ref "memory_address_length (operands[0], false)")) 20086 (set_attr "memory" "none")]) 20087 20088(define_insn "*prefetch_3dnow" 20089 [(prefetch (match_operand 0 "address_operand" "p") 20090 (match_operand:SI 1 "const_int_operand" "n") 20091 (const_int 3))] 20092 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1" 20093{ 20094 if (operands[1] == const0_rtx) 20095 return "prefetch\t%a0"; 20096 else 20097 return "prefetchw\t%a0"; 20098} 20099 [(set_attr "type" "mmx") 20100 (set (attr "length_address") 20101 (symbol_ref "memory_address_length (operands[0], false)")) 20102 (set_attr "memory" "none")]) 20103 20104(define_insn "*prefetch_prefetchwt1" 20105 [(prefetch (match_operand 0 "address_operand" "p") 20106 (const_int 1) 20107 (const_int 2))] 20108 "TARGET_PREFETCHWT1" 20109 "prefetchwt1\t%a0"; 20110 [(set_attr "type" "sse") 20111 (set (attr "length_address") 20112 (symbol_ref "memory_address_length (operands[0], false)")) 20113 (set_attr "memory" "none")]) 20114 20115(define_expand "stack_protect_set" 20116 [(match_operand 0 "memory_operand") 20117 (match_operand 1 "memory_operand")] 20118 "" 20119{ 20120 emit_insn (gen_stack_protect_set_1 20121 (ptr_mode, operands[0], operands[1])); 20122 DONE; 20123}) 20124 20125(define_insn "@stack_protect_set_1_<mode>" 20126 [(set (match_operand:PTR 0 "memory_operand" "=m") 20127 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")] 20128 UNSPEC_SP_SET)) 20129 (set (match_scratch:PTR 2 "=&r") (const_int 0)) 20130 (clobber (reg:CC FLAGS_REG))] 20131 "" 20132{ 20133 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands); 20134 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands); 20135 return "xor{l}\t%k2, %k2"; 20136} 20137 [(set_attr "type" "multi")]) 20138 20139;; Patterns and peephole2s to optimize stack_protect_set_1_<mode> 20140;; immediately followed by *mov{s,d}i_internal to the same register, 20141;; where we can avoid the xor{l} above. We don't split this, so that 20142;; scheduling or anything else doesn't separate the *stack_protect_set* 20143;; pattern from the set of the register that overwrites the register 20144;; with a new value. 20145(define_insn "*stack_protect_set_2_<mode>" 20146 [(set (match_operand:PTR 0 "memory_operand" "=m") 20147 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")] 20148 UNSPEC_SP_SET)) 20149 (set (match_operand:SI 1 "register_operand" "=&r") 20150 (match_operand:SI 2 "general_operand" "g")) 20151 (clobber (reg:CC FLAGS_REG))] 20152 "reload_completed 20153 && !reg_overlap_mentioned_p (operands[1], operands[2])" 20154{ 20155 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands); 20156 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands); 20157 if (pic_32bit_operand (operands[2], SImode) 20158 || ix86_use_lea_for_mov (insn, operands + 1)) 20159 return "lea{l}\t{%E2, %1|%1, %E2}"; 20160 else 20161 return "mov{l}\t{%2, %1|%1, %2}"; 20162} 20163 [(set_attr "type" "multi") 20164 (set_attr "length" "24")]) 20165 20166(define_peephole2 20167 [(parallel [(set (match_operand:PTR 0 "memory_operand") 20168 (unspec:PTR [(match_operand:PTR 1 "memory_operand")] 20169 UNSPEC_SP_SET)) 20170 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0)) 20171 (clobber (reg:CC FLAGS_REG))]) 20172 (set (match_operand:SI 3 "general_reg_operand") 20173 (match_operand:SI 4))] 20174 "REGNO (operands[2]) == REGNO (operands[3]) 20175 && general_operand (operands[4], SImode) 20176 && (general_reg_operand (operands[4], SImode) 20177 || memory_operand (operands[4], SImode) 20178 || immediate_operand (operands[4], SImode)) 20179 && !reg_overlap_mentioned_p (operands[3], operands[4])" 20180 [(parallel [(set (match_dup 0) 20181 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET)) 20182 (set (match_dup 3) (match_dup 4)) 20183 (clobber (reg:CC FLAGS_REG))])]) 20184 20185(define_insn "*stack_protect_set_3" 20186 [(set (match_operand:DI 0 "memory_operand" "=m,m,m") 20187 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")] 20188 UNSPEC_SP_SET)) 20189 (set (match_operand:DI 1 "register_operand" "=&r,r,r") 20190 (match_operand:DI 2 "general_operand" "Z,rem,i")) 20191 (clobber (reg:CC FLAGS_REG))] 20192 "TARGET_64BIT 20193 && reload_completed 20194 && !reg_overlap_mentioned_p (operands[1], operands[2])" 20195{ 20196 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands); 20197 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands); 20198 if (pic_32bit_operand (operands[2], DImode)) 20199 return "lea{q}\t{%E2, %1|%1, %E2}"; 20200 else if (which_alternative == 0) 20201 return "mov{l}\t{%k2, %k1|%k1, %k2}"; 20202 else if (which_alternative == 2) 20203 return "movabs{q}\t{%2, %1|%1, %2}"; 20204 else if (ix86_use_lea_for_mov (insn, operands + 1)) 20205 return "lea{q}\t{%E2, %1|%1, %E2}"; 20206 else 20207 return "mov{q}\t{%2, %1|%1, %2}"; 20208} 20209 [(set_attr "type" "multi") 20210 (set_attr "length" "24")]) 20211 20212(define_peephole2 20213 [(parallel [(set (match_operand:DI 0 "memory_operand") 20214 (unspec:DI [(match_operand:DI 1 "memory_operand")] 20215 UNSPEC_SP_SET)) 20216 (set (match_operand:DI 2 "general_reg_operand") (const_int 0)) 20217 (clobber (reg:CC FLAGS_REG))]) 20218 (set (match_dup 2) (match_operand:DI 3))] 20219 "TARGET_64BIT 20220 && general_operand (operands[3], DImode) 20221 && (general_reg_operand (operands[3], DImode) 20222 || memory_operand (operands[3], DImode) 20223 || x86_64_zext_immediate_operand (operands[3], DImode) 20224 || x86_64_immediate_operand (operands[3], DImode) 20225 || (CONSTANT_P (operands[3]) 20226 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3])))) 20227 && !reg_overlap_mentioned_p (operands[2], operands[3])" 20228 [(parallel [(set (match_dup 0) 20229 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET)) 20230 (set (match_dup 2) (match_dup 3)) 20231 (clobber (reg:CC FLAGS_REG))])]) 20232 20233(define_expand "stack_protect_test" 20234 [(match_operand 0 "memory_operand") 20235 (match_operand 1 "memory_operand") 20236 (match_operand 2)] 20237 "" 20238{ 20239 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG); 20240 20241 emit_insn (gen_stack_protect_test_1 20242 (ptr_mode, flags, operands[0], operands[1])); 20243 20244 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx), 20245 flags, const0_rtx, operands[2])); 20246 DONE; 20247}) 20248 20249(define_insn "@stack_protect_test_1_<mode>" 20250 [(set (match_operand:CCZ 0 "flags_reg_operand") 20251 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m") 20252 (match_operand:PTR 2 "memory_operand" "m")] 20253 UNSPEC_SP_TEST)) 20254 (clobber (match_scratch:PTR 3 "=&r"))] 20255 "" 20256{ 20257 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands); 20258 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}"; 20259} 20260 [(set_attr "type" "multi")]) 20261 20262(define_insn "sse4_2_crc32<mode>" 20263 [(set (match_operand:SI 0 "register_operand" "=r") 20264 (unspec:SI 20265 [(match_operand:SI 1 "register_operand" "0") 20266 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")] 20267 UNSPEC_CRC32))] 20268 "TARGET_SSE4_2 || TARGET_CRC32" 20269 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}" 20270 [(set_attr "type" "sselog1") 20271 (set_attr "prefix_rep" "1") 20272 (set_attr "prefix_extra" "1") 20273 (set (attr "prefix_data16") 20274 (if_then_else (match_operand:HI 2) 20275 (const_string "1") 20276 (const_string "*"))) 20277 (set (attr "prefix_rex") 20278 (if_then_else (match_operand:QI 2 "ext_QIreg_operand") 20279 (const_string "1") 20280 (const_string "*"))) 20281 (set_attr "mode" "SI")]) 20282 20283(define_insn "sse4_2_crc32di" 20284 [(set (match_operand:DI 0 "register_operand" "=r") 20285 (unspec:DI 20286 [(match_operand:DI 1 "register_operand" "0") 20287 (match_operand:DI 2 "nonimmediate_operand" "rm")] 20288 UNSPEC_CRC32))] 20289 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)" 20290 "crc32{q}\t{%2, %0|%0, %2}" 20291 [(set_attr "type" "sselog1") 20292 (set_attr "prefix_rep" "1") 20293 (set_attr "prefix_extra" "1") 20294 (set_attr "mode" "DI")]) 20295 20296(define_insn "rdpmc" 20297 [(set (match_operand:DI 0 "register_operand" "=A") 20298 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 20299 UNSPECV_RDPMC))] 20300 "!TARGET_64BIT" 20301 "rdpmc" 20302 [(set_attr "type" "other") 20303 (set_attr "length" "2")]) 20304 20305(define_insn "rdpmc_rex64" 20306 [(set (match_operand:DI 0 "register_operand" "=a") 20307 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 20308 UNSPECV_RDPMC)) 20309 (set (match_operand:DI 1 "register_operand" "=d") 20310 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))] 20311 "TARGET_64BIT" 20312 "rdpmc" 20313 [(set_attr "type" "other") 20314 (set_attr "length" "2")]) 20315 20316(define_insn "rdtsc" 20317 [(set (match_operand:DI 0 "register_operand" "=A") 20318 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 20319 "!TARGET_64BIT" 20320 "rdtsc" 20321 [(set_attr "type" "other") 20322 (set_attr "length" "2")]) 20323 20324(define_insn "rdtsc_rex64" 20325 [(set (match_operand:DI 0 "register_operand" "=a") 20326 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC)) 20327 (set (match_operand:DI 1 "register_operand" "=d") 20328 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))] 20329 "TARGET_64BIT" 20330 "rdtsc" 20331 [(set_attr "type" "other") 20332 (set_attr "length" "2")]) 20333 20334(define_insn "rdtscp" 20335 [(set (match_operand:DI 0 "register_operand" "=A") 20336 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 20337 (set (match_operand:SI 1 "register_operand" "=c") 20338 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 20339 "!TARGET_64BIT" 20340 "rdtscp" 20341 [(set_attr "type" "other") 20342 (set_attr "length" "3")]) 20343 20344(define_insn "rdtscp_rex64" 20345 [(set (match_operand:DI 0 "register_operand" "=a") 20346 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 20347 (set (match_operand:DI 1 "register_operand" "=d") 20348 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP)) 20349 (set (match_operand:SI 2 "register_operand" "=c") 20350 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))] 20351 "TARGET_64BIT" 20352 "rdtscp" 20353 [(set_attr "type" "other") 20354 (set_attr "length" "3")]) 20355 20356;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20357;; 20358;; FXSR, XSAVE and XSAVEOPT instructions 20359;; 20360;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20361 20362(define_insn "fxsave" 20363 [(set (match_operand:BLK 0 "memory_operand" "=m") 20364 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))] 20365 "TARGET_FXSR" 20366 "fxsave\t%0" 20367 [(set_attr "type" "other") 20368 (set_attr "memory" "store") 20369 (set (attr "length") 20370 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20371 20372(define_insn "fxsave64" 20373 [(set (match_operand:BLK 0 "memory_operand" "=m") 20374 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))] 20375 "TARGET_64BIT && TARGET_FXSR" 20376 "fxsave64\t%0" 20377 [(set_attr "type" "other") 20378 (set_attr "memory" "store") 20379 (set (attr "length") 20380 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20381 20382(define_insn "fxrstor" 20383 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 20384 UNSPECV_FXRSTOR)] 20385 "TARGET_FXSR" 20386 "fxrstor\t%0" 20387 [(set_attr "type" "other") 20388 (set_attr "memory" "load") 20389 (set (attr "length") 20390 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20391 20392(define_insn "fxrstor64" 20393 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 20394 UNSPECV_FXRSTOR64)] 20395 "TARGET_64BIT && TARGET_FXSR" 20396 "fxrstor64\t%0" 20397 [(set_attr "type" "other") 20398 (set_attr "memory" "load") 20399 (set (attr "length") 20400 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20401 20402(define_int_iterator ANY_XSAVE 20403 [UNSPECV_XSAVE 20404 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT") 20405 (UNSPECV_XSAVEC "TARGET_XSAVEC") 20406 (UNSPECV_XSAVES "TARGET_XSAVES")]) 20407 20408(define_int_iterator ANY_XSAVE64 20409 [UNSPECV_XSAVE64 20410 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT") 20411 (UNSPECV_XSAVEC64 "TARGET_XSAVEC") 20412 (UNSPECV_XSAVES64 "TARGET_XSAVES")]) 20413 20414(define_int_attr xsave 20415 [(UNSPECV_XSAVE "xsave") 20416 (UNSPECV_XSAVE64 "xsave64") 20417 (UNSPECV_XSAVEOPT "xsaveopt") 20418 (UNSPECV_XSAVEOPT64 "xsaveopt64") 20419 (UNSPECV_XSAVEC "xsavec") 20420 (UNSPECV_XSAVEC64 "xsavec64") 20421 (UNSPECV_XSAVES "xsaves") 20422 (UNSPECV_XSAVES64 "xsaves64")]) 20423 20424(define_int_iterator ANY_XRSTOR 20425 [UNSPECV_XRSTOR 20426 (UNSPECV_XRSTORS "TARGET_XSAVES")]) 20427 20428(define_int_iterator ANY_XRSTOR64 20429 [UNSPECV_XRSTOR64 20430 (UNSPECV_XRSTORS64 "TARGET_XSAVES")]) 20431 20432(define_int_attr xrstor 20433 [(UNSPECV_XRSTOR "xrstor") 20434 (UNSPECV_XRSTOR64 "xrstor") 20435 (UNSPECV_XRSTORS "xrstors") 20436 (UNSPECV_XRSTORS64 "xrstors")]) 20437 20438(define_insn "<xsave>" 20439 [(set (match_operand:BLK 0 "memory_operand" "=m") 20440 (unspec_volatile:BLK 20441 [(match_operand:DI 1 "register_operand" "A")] 20442 ANY_XSAVE))] 20443 "!TARGET_64BIT && TARGET_XSAVE" 20444 "<xsave>\t%0" 20445 [(set_attr "type" "other") 20446 (set_attr "memory" "store") 20447 (set (attr "length") 20448 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20449 20450(define_insn "<xsave>_rex64" 20451 [(set (match_operand:BLK 0 "memory_operand" "=m") 20452 (unspec_volatile:BLK 20453 [(match_operand:SI 1 "register_operand" "a") 20454 (match_operand:SI 2 "register_operand" "d")] 20455 ANY_XSAVE))] 20456 "TARGET_64BIT && TARGET_XSAVE" 20457 "<xsave>\t%0" 20458 [(set_attr "type" "other") 20459 (set_attr "memory" "store") 20460 (set (attr "length") 20461 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20462 20463(define_insn "<xsave>" 20464 [(set (match_operand:BLK 0 "memory_operand" "=m") 20465 (unspec_volatile:BLK 20466 [(match_operand:SI 1 "register_operand" "a") 20467 (match_operand:SI 2 "register_operand" "d")] 20468 ANY_XSAVE64))] 20469 "TARGET_64BIT && TARGET_XSAVE" 20470 "<xsave>\t%0" 20471 [(set_attr "type" "other") 20472 (set_attr "memory" "store") 20473 (set (attr "length") 20474 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20475 20476(define_insn "<xrstor>" 20477 [(unspec_volatile:BLK 20478 [(match_operand:BLK 0 "memory_operand" "m") 20479 (match_operand:DI 1 "register_operand" "A")] 20480 ANY_XRSTOR)] 20481 "!TARGET_64BIT && TARGET_XSAVE" 20482 "<xrstor>\t%0" 20483 [(set_attr "type" "other") 20484 (set_attr "memory" "load") 20485 (set (attr "length") 20486 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20487 20488(define_insn "<xrstor>_rex64" 20489 [(unspec_volatile:BLK 20490 [(match_operand:BLK 0 "memory_operand" "m") 20491 (match_operand:SI 1 "register_operand" "a") 20492 (match_operand:SI 2 "register_operand" "d")] 20493 ANY_XRSTOR)] 20494 "TARGET_64BIT && TARGET_XSAVE" 20495 "<xrstor>\t%0" 20496 [(set_attr "type" "other") 20497 (set_attr "memory" "load") 20498 (set (attr "length") 20499 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))]) 20500 20501(define_insn "<xrstor>64" 20502 [(unspec_volatile:BLK 20503 [(match_operand:BLK 0 "memory_operand" "m") 20504 (match_operand:SI 1 "register_operand" "a") 20505 (match_operand:SI 2 "register_operand" "d")] 20506 ANY_XRSTOR64)] 20507 "TARGET_64BIT && TARGET_XSAVE" 20508 "<xrstor>64\t%0" 20509 [(set_attr "type" "other") 20510 (set_attr "memory" "load") 20511 (set (attr "length") 20512 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))]) 20513 20514(define_insn "xsetbv" 20515 [(unspec_volatile:SI 20516 [(match_operand:SI 0 "register_operand" "c") 20517 (match_operand:DI 1 "register_operand" "A")] 20518 UNSPECV_XSETBV)] 20519 "!TARGET_64BIT && TARGET_XSAVE" 20520 "xsetbv" 20521 [(set_attr "type" "other")]) 20522 20523(define_insn "xsetbv_rex64" 20524 [(unspec_volatile:SI 20525 [(match_operand:SI 0 "register_operand" "c") 20526 (match_operand:SI 1 "register_operand" "a") 20527 (match_operand:SI 2 "register_operand" "d")] 20528 UNSPECV_XSETBV)] 20529 "TARGET_64BIT && TARGET_XSAVE" 20530 "xsetbv" 20531 [(set_attr "type" "other")]) 20532 20533(define_insn "xgetbv" 20534 [(set (match_operand:DI 0 "register_operand" "=A") 20535 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")] 20536 UNSPECV_XGETBV))] 20537 "!TARGET_64BIT && TARGET_XSAVE" 20538 "xgetbv" 20539 [(set_attr "type" "other")]) 20540 20541(define_insn "xgetbv_rex64" 20542 [(set (match_operand:DI 0 "register_operand" "=a") 20543 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")] 20544 UNSPECV_XGETBV)) 20545 (set (match_operand:DI 1 "register_operand" "=d") 20546 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))] 20547 "TARGET_64BIT && TARGET_XSAVE" 20548 "xgetbv" 20549 [(set_attr "type" "other")]) 20550 20551;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20552;; 20553;; Floating-point instructions for atomic compound assignments 20554;; 20555;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20556 20557; Clobber all floating-point registers on environment save and restore 20558; to ensure that the TOS value saved at fnstenv is valid after fldenv. 20559(define_insn "fnstenv" 20560 [(set (match_operand:BLK 0 "memory_operand" "=m") 20561 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV)) 20562 (clobber (reg:XF ST0_REG)) 20563 (clobber (reg:XF ST1_REG)) 20564 (clobber (reg:XF ST2_REG)) 20565 (clobber (reg:XF ST3_REG)) 20566 (clobber (reg:XF ST4_REG)) 20567 (clobber (reg:XF ST5_REG)) 20568 (clobber (reg:XF ST6_REG)) 20569 (clobber (reg:XF ST7_REG))] 20570 "TARGET_80387" 20571 "fnstenv\t%0" 20572 [(set_attr "type" "other") 20573 (set_attr "memory" "store") 20574 (set (attr "length") 20575 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20576 20577(define_insn "fldenv" 20578 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")] 20579 UNSPECV_FLDENV) 20580 (clobber (reg:XF ST0_REG)) 20581 (clobber (reg:XF ST1_REG)) 20582 (clobber (reg:XF ST2_REG)) 20583 (clobber (reg:XF ST3_REG)) 20584 (clobber (reg:XF ST4_REG)) 20585 (clobber (reg:XF ST5_REG)) 20586 (clobber (reg:XF ST6_REG)) 20587 (clobber (reg:XF ST7_REG))] 20588 "TARGET_80387" 20589 "fldenv\t%0" 20590 [(set_attr "type" "other") 20591 (set_attr "memory" "load") 20592 (set (attr "length") 20593 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20594 20595(define_insn "fnstsw" 20596 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m") 20597 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))] 20598 "TARGET_80387" 20599 "fnstsw\t%0" 20600 [(set_attr "type" "other,other") 20601 (set_attr "memory" "none,store") 20602 (set (attr "length") 20603 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))]) 20604 20605(define_insn "fnclex" 20606 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)] 20607 "TARGET_80387" 20608 "fnclex" 20609 [(set_attr "type" "other") 20610 (set_attr "memory" "none") 20611 (set_attr "length" "2")]) 20612 20613;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20614;; 20615;; LWP instructions 20616;; 20617;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 20618 20619(define_expand "lwp_llwpcb" 20620 [(unspec_volatile [(match_operand 0 "register_operand")] 20621 UNSPECV_LLWP_INTRINSIC)] 20622 "TARGET_LWP") 20623 20624(define_insn "*lwp_llwpcb<mode>_1" 20625 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 20626 UNSPECV_LLWP_INTRINSIC)] 20627 "TARGET_LWP" 20628 "llwpcb\t%0" 20629 [(set_attr "type" "lwp") 20630 (set_attr "mode" "<MODE>") 20631 (set_attr "length" "5")]) 20632 20633(define_expand "lwp_slwpcb" 20634 [(set (match_operand 0 "register_operand") 20635 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 20636 "TARGET_LWP" 20637 "emit_insn (gen_lwp_slwpcb_1 (Pmode, operands[0])); DONE;") 20638 20639(define_insn "@lwp_slwpcb<mode>_1" 20640 [(set (match_operand:P 0 "register_operand" "=r") 20641 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))] 20642 "TARGET_LWP" 20643 "slwpcb\t%0" 20644 [(set_attr "type" "lwp") 20645 (set_attr "mode" "<MODE>") 20646 (set_attr "length" "5")]) 20647 20648(define_expand "lwp_lwpval<mode>3" 20649 [(unspec_volatile [(match_operand:SWI48 1 "register_operand") 20650 (match_operand:SI 2 "nonimmediate_operand") 20651 (match_operand:SI 3 "const_int_operand")] 20652 UNSPECV_LWPVAL_INTRINSIC)] 20653 "TARGET_LWP" 20654 ;; Avoid unused variable warning. 20655 "(void) operands[0];") 20656 20657(define_insn "*lwp_lwpval<mode>3_1" 20658 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r") 20659 (match_operand:SI 1 "nonimmediate_operand" "rm") 20660 (match_operand:SI 2 "const_int_operand" "i")] 20661 UNSPECV_LWPVAL_INTRINSIC)] 20662 "TARGET_LWP" 20663 "lwpval\t{%2, %1, %0|%0, %1, %2}" 20664 [(set_attr "type" "lwp") 20665 (set_attr "mode" "<MODE>") 20666 (set (attr "length") 20667 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 20668 20669(define_expand "lwp_lwpins<mode>3" 20670 [(set (reg:CCC FLAGS_REG) 20671 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand") 20672 (match_operand:SI 2 "nonimmediate_operand") 20673 (match_operand:SI 3 "const_int_operand")] 20674 UNSPECV_LWPINS_INTRINSIC)) 20675 (set (match_operand:QI 0 "nonimmediate_operand") 20676 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))] 20677 "TARGET_LWP") 20678 20679(define_insn "*lwp_lwpins<mode>3_1" 20680 [(set (reg:CCC FLAGS_REG) 20681 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r") 20682 (match_operand:SI 1 "nonimmediate_operand" "rm") 20683 (match_operand:SI 2 "const_int_operand" "i")] 20684 UNSPECV_LWPINS_INTRINSIC))] 20685 "TARGET_LWP" 20686 "lwpins\t{%2, %1, %0|%0, %1, %2}" 20687 [(set_attr "type" "lwp") 20688 (set_attr "mode" "<MODE>") 20689 (set (attr "length") 20690 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))]) 20691 20692(define_int_iterator RDFSGSBASE 20693 [UNSPECV_RDFSBASE 20694 UNSPECV_RDGSBASE]) 20695 20696(define_int_iterator WRFSGSBASE 20697 [UNSPECV_WRFSBASE 20698 UNSPECV_WRGSBASE]) 20699 20700(define_int_attr fsgs 20701 [(UNSPECV_RDFSBASE "fs") 20702 (UNSPECV_RDGSBASE "gs") 20703 (UNSPECV_WRFSBASE "fs") 20704 (UNSPECV_WRGSBASE "gs")]) 20705 20706(define_insn "rd<fsgs>base<mode>" 20707 [(set (match_operand:SWI48 0 "register_operand" "=r") 20708 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))] 20709 "TARGET_64BIT && TARGET_FSGSBASE" 20710 "rd<fsgs>base\t%0" 20711 [(set_attr "type" "other") 20712 (set_attr "prefix_extra" "2")]) 20713 20714(define_insn "wr<fsgs>base<mode>" 20715 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")] 20716 WRFSGSBASE)] 20717 "TARGET_64BIT && TARGET_FSGSBASE" 20718 "wr<fsgs>base\t%0" 20719 [(set_attr "type" "other") 20720 (set_attr "prefix_extra" "2")]) 20721 20722(define_insn "ptwrite<mode>" 20723 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")] 20724 UNSPECV_PTWRITE)] 20725 "TARGET_PTWRITE" 20726 "ptwrite\t%0" 20727 [(set_attr "type" "other") 20728 (set_attr "prefix_extra" "2")]) 20729 20730(define_insn "rdrand<mode>_1" 20731 [(set (match_operand:SWI248 0 "register_operand" "=r") 20732 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND)) 20733 (set (reg:CCC FLAGS_REG) 20734 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))] 20735 "TARGET_RDRND" 20736 "rdrand\t%0" 20737 [(set_attr "type" "other") 20738 (set_attr "prefix_extra" "1")]) 20739 20740(define_insn "rdseed<mode>_1" 20741 [(set (match_operand:SWI248 0 "register_operand" "=r") 20742 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED)) 20743 (set (reg:CCC FLAGS_REG) 20744 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))] 20745 "TARGET_RDSEED" 20746 "rdseed\t%0" 20747 [(set_attr "type" "other") 20748 (set_attr "prefix_extra" "1")]) 20749 20750(define_expand "pause" 20751 [(set (match_dup 0) 20752 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 20753 "" 20754{ 20755 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode)); 20756 MEM_VOLATILE_P (operands[0]) = 1; 20757}) 20758 20759;; Use "rep; nop", instead of "pause", to support older assemblers. 20760;; They have the same encoding. 20761(define_insn "*pause" 20762 [(set (match_operand:BLK 0) 20763 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))] 20764 "" 20765 "rep%; nop" 20766 [(set_attr "length" "2") 20767 (set_attr "memory" "unknown")]) 20768 20769;; CET instructions 20770(define_insn "rdssp<mode>" 20771 [(set (match_operand:SWI48x 0 "register_operand" "=r") 20772 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))] 20773 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" 20774 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0" 20775 [(set_attr "length" "6") 20776 (set_attr "type" "other")]) 20777 20778(define_insn "incssp<mode>" 20779 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")] 20780 UNSPECV_INCSSP)] 20781 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)" 20782 "incssp<mskmodesuffix>\t%0" 20783 [(set_attr "length" "4") 20784 (set_attr "type" "other")]) 20785 20786(define_insn "saveprevssp" 20787 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)] 20788 "TARGET_SHSTK" 20789 "saveprevssp" 20790 [(set_attr "length" "5") 20791 (set_attr "type" "other")]) 20792 20793(define_expand "rstorssp" 20794 [(unspec_volatile [(match_operand 0 "memory_operand")] 20795 UNSPECV_RSTORSSP)] 20796 "TARGET_SHSTK") 20797 20798(define_insn "*rstorssp<mode>" 20799 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] 20800 UNSPECV_RSTORSSP)] 20801 "TARGET_SHSTK" 20802 "rstorssp\t%0" 20803 [(set_attr "length" "5") 20804 (set_attr "type" "other")]) 20805 20806(define_insn "wrss<mode>" 20807 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") 20808 (match_operand:SWI48x 1 "memory_operand" "m")] 20809 UNSPECV_WRSS)] 20810 "TARGET_SHSTK" 20811 "wrss<mskmodesuffix>\t%0, %1" 20812 [(set_attr "length" "3") 20813 (set_attr "type" "other")]) 20814 20815(define_insn "wruss<mode>" 20816 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r") 20817 (match_operand:SWI48x 1 "memory_operand" "m")] 20818 UNSPECV_WRUSS)] 20819 "TARGET_SHSTK" 20820 "wruss<mskmodesuffix>\t%0, %1" 20821 [(set_attr "length" "4") 20822 (set_attr "type" "other")]) 20823 20824(define_insn "setssbsy" 20825 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)] 20826 "TARGET_SHSTK" 20827 "setssbsy" 20828 [(set_attr "length" "4") 20829 (set_attr "type" "other")]) 20830 20831(define_expand "clrssbsy" 20832 [(unspec_volatile [(match_operand 0 "memory_operand")] 20833 UNSPECV_CLRSSBSY)] 20834 "TARGET_SHSTK") 20835 20836(define_insn "*clrssbsy<mode>" 20837 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")] 20838 UNSPECV_CLRSSBSY)] 20839 "TARGET_SHSTK" 20840 "clrssbsy\t%0" 20841 [(set_attr "length" "4") 20842 (set_attr "type" "other")]) 20843 20844(define_insn "nop_endbr" 20845 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)] 20846 "(flag_cf_protection & CF_BRANCH)" 20847{ 20848 return TARGET_64BIT ? "endbr64" : "endbr32"; 20849} 20850 [(set_attr "length" "4") 20851 (set_attr "length_immediate" "0") 20852 (set_attr "modrm" "0")]) 20853 20854;; For RTM support 20855(define_expand "xbegin" 20856 [(set (match_operand:SI 0 "register_operand") 20857 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))] 20858 "TARGET_RTM" 20859{ 20860 rtx_code_label *label = gen_label_rtx (); 20861 20862 /* xbegin is emitted as jump_insn, so reload won't be able 20863 to reload its operand. Force the value into AX hard register. */ 20864 rtx ax_reg = gen_rtx_REG (SImode, AX_REG); 20865 emit_move_insn (ax_reg, constm1_rtx); 20866 20867 emit_jump_insn (gen_xbegin_1 (ax_reg, label)); 20868 20869 emit_label (label); 20870 LABEL_NUSES (label) = 1; 20871 20872 emit_move_insn (operands[0], ax_reg); 20873 20874 DONE; 20875}) 20876 20877(define_insn "xbegin_1" 20878 [(set (pc) 20879 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT) 20880 (const_int 0)) 20881 (label_ref (match_operand 1)) 20882 (pc))) 20883 (set (match_operand:SI 0 "register_operand" "+a") 20884 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))] 20885 "TARGET_RTM" 20886 "xbegin\t%l1" 20887 [(set_attr "type" "other") 20888 (set_attr "length" "6")]) 20889 20890(define_insn "xend" 20891 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)] 20892 "TARGET_RTM" 20893 "xend" 20894 [(set_attr "type" "other") 20895 (set_attr "length" "3")]) 20896 20897(define_insn "xabort" 20898 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")] 20899 UNSPECV_XABORT)] 20900 "TARGET_RTM" 20901 "xabort\t%0" 20902 [(set_attr "type" "other") 20903 (set_attr "length" "3")]) 20904 20905(define_expand "xtest" 20906 [(set (match_operand:QI 0 "register_operand") 20907 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))] 20908 "TARGET_RTM" 20909{ 20910 emit_insn (gen_xtest_1 ()); 20911 20912 ix86_expand_setcc (operands[0], NE, 20913 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx); 20914 DONE; 20915}) 20916 20917(define_insn "xtest_1" 20918 [(set (reg:CCZ FLAGS_REG) 20919 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))] 20920 "TARGET_RTM" 20921 "xtest" 20922 [(set_attr "type" "other") 20923 (set_attr "length" "3")]) 20924 20925(define_insn "clwb" 20926 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 20927 UNSPECV_CLWB)] 20928 "TARGET_CLWB" 20929 "clwb\t%a0" 20930 [(set_attr "type" "sse") 20931 (set_attr "atom_sse_attr" "fence") 20932 (set_attr "memory" "unknown")]) 20933 20934(define_insn "clflushopt" 20935 [(unspec_volatile [(match_operand 0 "address_operand" "p")] 20936 UNSPECV_CLFLUSHOPT)] 20937 "TARGET_CLFLUSHOPT" 20938 "clflushopt\t%a0" 20939 [(set_attr "type" "sse") 20940 (set_attr "atom_sse_attr" "fence") 20941 (set_attr "memory" "unknown")]) 20942 20943;; MONITORX and MWAITX 20944(define_insn "mwaitx" 20945 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c") 20946 (match_operand:SI 1 "register_operand" "a") 20947 (match_operand:SI 2 "register_operand" "b")] 20948 UNSPECV_MWAITX)] 20949 "TARGET_MWAITX" 20950;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used. 20951;; Since 32bit register operands are implicitly zero extended to 64bit, 20952;; we only need to set up 32bit registers. 20953 "mwaitx" 20954 [(set_attr "length" "3")]) 20955 20956(define_insn "@monitorx_<mode>" 20957 [(unspec_volatile [(match_operand:P 0 "register_operand" "a") 20958 (match_operand:SI 1 "register_operand" "c") 20959 (match_operand:SI 2 "register_operand" "d")] 20960 UNSPECV_MONITORX)] 20961 "TARGET_MWAITX" 20962;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in 20963;; RCX and RDX are used. Since 32bit register operands are implicitly 20964;; zero extended to 64bit, we only need to set up 32bit registers. 20965 "%^monitorx" 20966 [(set (attr "length") 20967 (symbol_ref ("(Pmode != word_mode) + 3")))]) 20968 20969;; CLZERO 20970(define_insn "@clzero_<mode>" 20971 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")] 20972 UNSPECV_CLZERO)] 20973 "TARGET_CLZERO" 20974 "clzero" 20975 [(set_attr "length" "3") 20976 (set_attr "memory" "unknown")]) 20977 20978;; RDPKRU and WRPKRU 20979 20980(define_expand "rdpkru" 20981 [(parallel 20982 [(set (match_operand:SI 0 "register_operand") 20983 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU)) 20984 (set (match_dup 2) (const_int 0))])] 20985 "TARGET_PKU" 20986{ 20987 operands[1] = force_reg (SImode, const0_rtx); 20988 operands[2] = gen_reg_rtx (SImode); 20989}) 20990 20991(define_insn "*rdpkru" 20992 [(set (match_operand:SI 0 "register_operand" "=a") 20993 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")] 20994 UNSPECV_PKU)) 20995 (set (match_operand:SI 1 "register_operand" "=d") 20996 (const_int 0))] 20997 "TARGET_PKU" 20998 "rdpkru" 20999 [(set_attr "type" "other")]) 21000 21001(define_expand "wrpkru" 21002 [(unspec_volatile:SI 21003 [(match_operand:SI 0 "register_operand") 21004 (match_dup 1) (match_dup 2)] UNSPECV_PKU)] 21005 "TARGET_PKU" 21006{ 21007 operands[1] = force_reg (SImode, const0_rtx); 21008 operands[2] = force_reg (SImode, const0_rtx); 21009}) 21010 21011(define_insn "*wrpkru" 21012 [(unspec_volatile:SI 21013 [(match_operand:SI 0 "register_operand" "a") 21014 (match_operand:SI 1 "register_operand" "d") 21015 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)] 21016 "TARGET_PKU" 21017 "wrpkru" 21018 [(set_attr "type" "other")]) 21019 21020(define_insn "rdpid" 21021 [(set (match_operand:SI 0 "register_operand" "=r") 21022 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))] 21023 "!TARGET_64BIT && TARGET_RDPID" 21024 "rdpid\t%0" 21025 [(set_attr "type" "other")]) 21026 21027(define_insn "rdpid_rex64" 21028 [(set (match_operand:DI 0 "register_operand" "=r") 21029 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))] 21030 "TARGET_64BIT && TARGET_RDPID" 21031 "rdpid\t%0" 21032 [(set_attr "type" "other")]) 21033 21034;; Intirinsics for > i486 21035 21036(define_insn "wbinvd" 21037 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)] 21038 "" 21039 "wbinvd" 21040 [(set_attr "type" "other")]) 21041 21042(define_insn "wbnoinvd" 21043 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)] 21044 "TARGET_WBNOINVD" 21045 "wbnoinvd" 21046 [(set_attr "type" "other")]) 21047 21048;; MOVDIRI and MOVDIR64B 21049 21050(define_insn "movdiri<mode>" 21051 [(set (match_operand:SWI48 0 "memory_operand" "=m") 21052 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")] 21053 UNSPEC_MOVDIRI))] 21054 "TARGET_MOVDIRI" 21055 "movdiri\t{%1, %0|%0, %1}" 21056 [(set_attr "type" "other")]) 21057 21058(define_insn "@movdir64b_<mode>" 21059 [(set (mem:XI (match_operand:P 0 "register_operand" "r")) 21060 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")] 21061 UNSPEC_MOVDIR64B))] 21062 "TARGET_MOVDIR64B" 21063 "movdir64b\t{%1, %0|%0, %1}" 21064 [(set_attr "type" "other")]) 21065 21066;; ENQCMD and ENQCMDS 21067 21068(define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS]) 21069(define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")]) 21070 21071(define_insn "@enqcmd<enqcmd_sfx>_<mode>" 21072 [(set (reg:CCZ FLAGS_REG) 21073 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r") 21074 (match_operand:XI 1 "memory_operand" "m")] 21075 ENQCMD))] 21076 "TARGET_ENQCMD" 21077 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}" 21078 [(set_attr "type" "other")]) 21079 21080;; WAITPKG 21081 21082(define_insn "umwait" 21083 [(set (reg:CCC FLAGS_REG) 21084 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r") 21085 (match_operand:DI 1 "register_operand" "A")] 21086 UNSPECV_UMWAIT))] 21087 "!TARGET_64BIT && TARGET_WAITPKG" 21088 "umwait\t%0" 21089 [(set_attr "length" "3")]) 21090 21091(define_insn "umwait_rex64" 21092 [(set (reg:CCC FLAGS_REG) 21093 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r") 21094 (match_operand:SI 1 "register_operand" "a") 21095 (match_operand:SI 2 "register_operand" "d")] 21096 UNSPECV_UMWAIT))] 21097 "TARGET_64BIT && TARGET_WAITPKG" 21098 "umwait\t%0" 21099 [(set_attr "length" "3")]) 21100 21101(define_insn "@umonitor_<mode>" 21102 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 21103 UNSPECV_UMONITOR)] 21104 "TARGET_WAITPKG" 21105 "umonitor\t%0" 21106 [(set (attr "length") 21107 (symbol_ref ("(Pmode != word_mode) + 3")))]) 21108 21109(define_insn "tpause" 21110 [(set (reg:CCC FLAGS_REG) 21111 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r") 21112 (match_operand:DI 1 "register_operand" "A")] 21113 UNSPECV_TPAUSE))] 21114 "!TARGET_64BIT && TARGET_WAITPKG" 21115 "tpause\t%0" 21116 [(set_attr "length" "3")]) 21117 21118(define_insn "tpause_rex64" 21119 [(set (reg:CCC FLAGS_REG) 21120 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r") 21121 (match_operand:SI 1 "register_operand" "a") 21122 (match_operand:SI 2 "register_operand" "d")] 21123 UNSPECV_TPAUSE))] 21124 "TARGET_64BIT && TARGET_WAITPKG" 21125 "tpause\t%0" 21126 [(set_attr "length" "3")]) 21127 21128(define_insn "cldemote" 21129 [(unspec_volatile[(match_operand 0 "address_operand" "p")] 21130 UNSPECV_CLDEMOTE)] 21131 "TARGET_CLDEMOTE" 21132 "cldemote\t%a0" 21133 [(set_attr "type" "other") 21134 (set_attr "memory" "unknown")]) 21135 21136(define_insn "speculation_barrier" 21137 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)] 21138 "" 21139 "lfence" 21140 [(set_attr "type" "other") 21141 (set_attr "length" "3")]) 21142 21143(include "mmx.md") 21144(include "sse.md") 21145(include "sync.md") 21146